diff options
117 files changed, 90 insertions, 6737 deletions
diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake index 2a86f8136de..cdc63ef8fba 100644 --- a/build_files/cmake/macros.cmake +++ b/build_files/cmake/macros.cmake @@ -590,7 +590,6 @@ function(SETUP_BLENDER_SORTED_LIBS) bf_editor_object bf_editor_armature bf_editor_physics - bf_editor_hair bf_editor_render bf_editor_scene bf_editor_screen diff --git a/release/datafiles/brushicons/hairadd.png b/release/datafiles/brushicons/hairadd.png Binary files differdeleted file mode 100644 index 074111a5a0b..00000000000 --- a/release/datafiles/brushicons/hairadd.png +++ /dev/null diff --git a/release/datafiles/brushicons/haircomb.png b/release/datafiles/brushicons/haircomb.png Binary files differdeleted file mode 100644 index 074111a5a0b..00000000000 --- a/release/datafiles/brushicons/haircomb.png +++ /dev/null diff --git a/release/datafiles/brushicons/haircut.png b/release/datafiles/brushicons/haircut.png Binary files differdeleted file mode 100644 index 074111a5a0b..00000000000 --- a/release/datafiles/brushicons/haircut.png +++ /dev/null diff --git a/release/datafiles/brushicons/hairlength.png b/release/datafiles/brushicons/hairlength.png Binary files differdeleted file mode 100644 index 074111a5a0b..00000000000 --- a/release/datafiles/brushicons/hairlength.png +++ /dev/null diff --git a/release/datafiles/brushicons/hairpuff.png b/release/datafiles/brushicons/hairpuff.png Binary files differdeleted file mode 100644 index 074111a5a0b..00000000000 --- a/release/datafiles/brushicons/hairpuff.png +++ /dev/null diff --git a/release/datafiles/brushicons/hairsmooth.png b/release/datafiles/brushicons/hairsmooth.png Binary files differdeleted file mode 100644 index 074111a5a0b..00000000000 --- a/release/datafiles/brushicons/hairsmooth.png +++ /dev/null diff --git a/release/datafiles/brushicons/hairweight.png b/release/datafiles/brushicons/hairweight.png Binary files differdeleted file mode 100644 index 074111a5a0b..00000000000 --- a/release/datafiles/brushicons/hairweight.png +++ /dev/null diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index 6e3235ee186..20586b727d5 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -163,7 +163,6 @@ class BRUSH_OT_active_index_set(Operator): "vertex_paint": "use_paint_vertex", "weight_paint": "use_paint_weight", "image_paint": "use_paint_image", - "hair_edit": "use_hair_edit", } def execute(self, context): diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py index 1e6f9b0c776..bc8bc523e12 100644 --- a/release/scripts/startup/bl_ui/properties_paint_common.py +++ b/release/scripts/startup/bl_ui/properties_paint_common.py @@ -38,10 +38,10 @@ class UnifiedPaintPanel: elif context.image_paint_object: if (toolsettings.image_paint and toolsettings.image_paint.detect_data()): return toolsettings.image_paint + + return None elif context.particle_edit_object: return toolsettings.particle_edit - elif context.hair_edit_object: - return toolsettings.hair_edit return None diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 77af655422c..d449dd20c3e 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -52,12 +52,6 @@ class VIEW3D_HT_header(Header): # Particle edit if mode == 'PARTICLE_EDIT': row.prop(toolsettings.particle_edit, "select_mode", text="", expand=True) - elif mode == 'HAIR_EDIT': - row.prop(toolsettings.hair_edit, "select_mode", text="", expand=True) - row.prop(toolsettings.hair_edit, "hair_draw_mode", text="", expand=True) - if toolsettings.hair_edit.hair_draw_mode == 'FIBERS': - row.prop(toolsettings.hair_edit, "hair_draw_size", text="Size") - row.prop(toolsettings.hair_edit, "hair_draw_subdivision", text="Subdivide") # Occlude geometry if ((view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'} and (mode == 'PARTICLE_EDIT' or (mode == 'EDIT' and obj.type == 'MESH'))) or @@ -178,7 +172,7 @@ class VIEW3D_MT_editor_menus(Menu): layout.menu("VIEW3D_MT_select_paint_mask") elif mesh.use_paint_mask_vertex and mode_string in {'PAINT_WEIGHT', 'PAINT_VERTEX'}: layout.menu("VIEW3D_MT_select_paint_mask_vertex") - elif mode_string not in {'SCULPT'}: + elif mode_string != 'SCULPT': layout.menu("VIEW3D_MT_select_%s" % mode_string.lower()) if gp_edit: @@ -203,7 +197,7 @@ class VIEW3D_MT_editor_menus(Menu): elif obj: if mode_string != 'PAINT_TEXTURE': layout.menu("VIEW3D_MT_%s" % mode_string.lower()) - if mode_string in {'SCULPT', 'PAINT_VERTEX', 'PAINT_WEIGHT', 'PAINT_TEXTURE', 'HAIR'}: + if mode_string in {'SCULPT', 'PAINT_VERTEX', 'PAINT_WEIGHT', 'PAINT_TEXTURE'}: layout.menu("VIEW3D_MT_brush") if mode_string == 'SCULPT': layout.menu("VIEW3D_MT_hide_mask") @@ -1150,13 +1144,6 @@ class VIEW3D_MT_select_paint_mask_vertex(Menu): layout.operator("paint.vert_select_ungrouped", text="Ungrouped Verts") -class VIEW3D_MT_select_hair(Menu): - bl_label = "Select" - - def draw(self, context): - layout = self.layout - - class VIEW3D_MT_angle_control(Menu): bl_label = "Angle Control" @@ -1861,7 +1848,7 @@ class VIEW3D_MT_brush(Menu): return # brush paint modes - layout.menu("VIEW3D_MT_brush_object_modes") + layout.menu("VIEW3D_MT_brush_paint_modes") # brush tool if context.sculpt_object: @@ -1871,8 +1858,6 @@ class VIEW3D_MT_brush(Menu): layout.prop_menu_enum(brush, "image_tool") elif context.vertex_paint_object or context.weight_paint_object: layout.prop_menu_enum(brush, "vertex_tool") - elif context.hair_edit_object: - layout.prop_menu_enum(brush, "hair_tool") # TODO: still missing a lot of brush options here @@ -1896,7 +1881,7 @@ class VIEW3D_MT_brush(Menu): layout.operator("sculpt.set_persistent_base") -class VIEW3D_MT_brush_object_modes(Menu): +class VIEW3D_MT_brush_paint_modes(Menu): bl_label = "Enabled Modes" def draw(self, context): @@ -1909,7 +1894,6 @@ class VIEW3D_MT_brush_object_modes(Menu): layout.prop(brush, "use_paint_vertex", text="Vertex Paint") layout.prop(brush, "use_paint_weight", text="Weight Paint") layout.prop(brush, "use_paint_image", text="Texture Paint") - layout.prop(brush, "use_hair_edit", text="Hair Edit") class VIEW3D_MT_paint_vertex(Menu): @@ -2186,14 +2170,6 @@ class VIEW3D_MT_particle_specials(Menu): class VIEW3D_MT_particle_showhide(ShowHideMenu, Menu): _operator_name = "particle" -# ********** Hair menu ********** - -class VIEW3D_MT_hair(Menu): - bl_label = "Hair" - - def draw(self, context): - layout = self.layout - class VIEW3D_MT_pose(Menu): bl_label = "Pose" @@ -3893,7 +3869,6 @@ classes = ( VIEW3D_MT_select_pose, VIEW3D_MT_select_pose_more_less, VIEW3D_MT_select_particle, - VIEW3D_MT_select_hair, VIEW3D_MT_edit_mesh, VIEW3D_MT_edit_mesh_select_similar, VIEW3D_MT_edit_mesh_select_by_trait, @@ -3936,7 +3911,7 @@ classes = ( VIEW3D_MT_make_links, VIEW3D_MT_object_game, VIEW3D_MT_brush, - VIEW3D_MT_brush_object_modes, + VIEW3D_MT_brush_paint_modes, VIEW3D_MT_paint_vertex, VIEW3D_MT_hook, VIEW3D_MT_vertex_group, @@ -3946,7 +3921,6 @@ classes = ( VIEW3D_MT_particle, VIEW3D_MT_particle_specials, VIEW3D_MT_particle_showhide, - VIEW3D_MT_hair, VIEW3D_MT_pose, VIEW3D_MT_pose_transform, VIEW3D_MT_pose_slide, diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 268fac5b20e..134a91a8c1f 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -987,21 +987,6 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel): layout.row().prop(brush, "puff_mode", expand=True) layout.prop(brush, "use_puff_volume") - # Hair Mode # - - elif context.hair_edit_object and brush: - col = layout.column() - - row = col.row(align=True) - self.prop_unified_size(row, context, brush, "size", slider=True, text="Radius") - self.prop_unified_size(row, context, brush, "use_pressure_size") - - row = col.row(align=True) - self.prop_unified_strength(row, context, brush, "strength", text="Strength") - self.prop_unified_strength(row, context, brush, "use_pressure_strength") - - col.prop(brush, "hair_tool", text="Tool") - # Sculpt Mode # elif context.sculpt_object and brush: @@ -2027,23 +2012,6 @@ class VIEW3D_PT_tools_particlemode(View3DPanel, Panel): sub.prop(pe, "fade_frames", slider=True) -class VIEW3D_PT_tools_hairmode(View3DPanel, Panel): - """Tools for hair mode""" - bl_context = "hairmode" - bl_label = "Options" - bl_category = "Tools" - - def draw(self, context): - layout = self.layout - - settings = context.tool_settings.hair_edit - ob = context.active_object - - if ob.data: - col = layout.column(align=True) - col.prop(ob.data, "use_mirror_x") - - # Grease Pencil drawing tools class VIEW3D_PT_tools_grease_pencil_draw(GreasePencilDrawingToolsPanel, Panel): bl_space_type = 'VIEW_3D' diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h index 90cc706931b..7b071dc01a5 100644 --- a/source/blender/blenkernel/BKE_context.h +++ b/source/blender/blenkernel/BKE_context.h @@ -118,7 +118,6 @@ enum { CTX_MODE_PAINT_VERTEX, CTX_MODE_PAINT_TEXTURE, CTX_MODE_PARTICLE, - CTX_MODE_HAIR, CTX_MODE_OBJECT }; diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index cc5927e072e..51cd4da183a 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -57,8 +57,6 @@ extern const CustomDataMask CD_MASK_EDITMESH; extern const CustomDataMask CD_MASK_DERIVEDMESH; extern const CustomDataMask CD_MASK_BMESH; extern const CustomDataMask CD_MASK_FACECORNERS; -extern const CustomDataMask CD_MASK_STRANDS; -extern const CustomDataMask CD_MASK_STRANDS_BMESH; extern const CustomDataMask CD_MASK_EVERYTHING; /* for ORIGINDEX layer type, indicates no original index for this element */ @@ -271,7 +269,6 @@ void *CustomData_get(const struct CustomData *data, int index, int type); void *CustomData_get_n(const struct CustomData *data, int type, int index, int n); void *CustomData_bmesh_get(const struct CustomData *data, void *block, int type); void *CustomData_bmesh_get_n(const struct CustomData *data, void *block, int type, int n); -void *CustomData_bmesh_get_named(const struct CustomData *data, void *block, int type, const char *name); /* gets the layer at physical index n, with no type checking. */ diff --git a/source/blender/blenkernel/BKE_editstrands.h b/source/blender/blenkernel/BKE_editstrands.h deleted file mode 100644 index be04edb9fc6..00000000000 --- a/source/blender/blenkernel/BKE_editstrands.h +++ /dev/null @@ -1,106 +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) Blender Foundation - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Lukas Toenne - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifndef __BKE_EDITSTRANDS_H__ -#define __BKE_EDITSTRANDS_H__ - -/** \file blender/blenkernel/BKE_editstrands.h - * \ingroup bke - */ - -#include "BLI_utildefines.h" - -#include "DNA_customdata_types.h" - -#include "BKE_customdata.h" -#include "BKE_editmesh.h" - -#include "bmesh.h" - -struct BMesh; -struct DerivedMesh; -struct Mesh; -struct Object; - -typedef struct BMEditStrands { - BMEditMesh base; - - /* Scalp mesh for fixing root vertices */ - struct DerivedMesh *root_dm; - - int flag; - - unsigned int vertex_glbuf; // legacy gpu code - unsigned int elem_glbuf; // legacy gpu code - unsigned int dot_glbuf; // legacy gpu code - void *batch_cache; -} BMEditStrands; - -/* BMEditStrands->flag */ -typedef enum BMEditStrandsFlag { - BM_STRANDS_DIRTY_SEGLEN = (1 << 0), - BM_STRANDS_DIRTY_ROOTS = (1 << 1), -} BMEditStrandsFlag; - -struct BMEditStrands *BKE_editstrands_create(struct BMesh *bm, struct DerivedMesh *root_dm); -struct BMEditStrands *BKE_editstrands_copy(struct BMEditStrands *es); -struct BMEditStrands *BKE_editstrands_from_object_particles(struct Object *ob, struct ParticleSystem **r_psys); -struct BMEditStrands *BKE_editstrands_from_object(struct Object *ob); -void BKE_editstrands_update_linked_customdata(struct BMEditStrands *es); -void BKE_editstrands_free(struct BMEditStrands *es); - -/* === Constraints === */ - -/* Stores vertex locations for temporary reference: - * Vertex locations get modified by tools, but then need to be corrected - * by calculating a smooth solution based on the difference to original pre-tool locations. - */ -typedef float (*BMEditStrandsLocations)[3]; -BMEditStrandsLocations BKE_editstrands_get_locations(struct BMEditStrands *edit); -void BKE_editstrands_free_locations(BMEditStrandsLocations locs); - -void BKE_editstrands_solve_constraints(struct Object *ob, struct BMEditStrands *es, BMEditStrandsLocations orig); -void BKE_editstrands_ensure(struct BMEditStrands *es); - -/* === Particle Conversion === */ - -struct BMesh *BKE_editstrands_particles_to_bmesh(struct Object *ob, struct ParticleSystem *psys); -void BKE_editstrands_particles_from_bmesh(struct Object *ob, struct ParticleSystem *psys); - -/* === Mesh Conversion === */ -struct BMesh *BKE_editstrands_mesh_to_bmesh(struct Object *ob, struct Mesh *me); -void BKE_editstrands_mesh_from_bmesh(struct Object *ob); - -/* === Draw Cache === */ -enum { - BKE_STRANDS_BATCH_DIRTY_ALL = 0, - BKE_STRANDS_BATCH_DIRTY_SELECT = 1, -}; -void BKE_editstrands_batch_cache_dirty(struct BMEditStrands *es, int mode); -void BKE_editstrands_batch_cache_free(struct BMEditStrands *es); - -#endif diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 3b4df49fb88..af648bf1137 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -105,7 +105,6 @@ set(SRC intern/editmesh.c intern/editmesh_bvh.c intern/editmesh_tangent.c - intern/editstrands.c intern/effect.c intern/fcurve.c intern/fluidsim.c @@ -239,7 +238,6 @@ set(SRC BKE_deform.h BKE_displist.h BKE_dynamicpaint.h - BKE_editstrands.h BKE_editmesh.h BKE_editmesh_bvh.h BKE_editmesh_tangent.h diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 7f65cd7dd42..230db6dccff 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -70,7 +70,7 @@ static void brush_defaults(Brush *brush) brush->blend = 0; brush->flag = 0; - brush->ob_mode = OB_MODE_ALL_BRUSH; + brush->ob_mode = OB_MODE_ALL_PAINT; /* BRUSH SCULPT TOOL SETTINGS */ brush->weight = 1.0f; /* weight of brush 0 - 1.0 */ diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c index 587929721ee..0bd79a50673 100644 --- a/source/blender/blenkernel/intern/context.c +++ b/source/blender/blenkernel/intern/context.c @@ -1024,7 +1024,6 @@ int CTX_data_mode_enum_ex(const Object *obedit, const Object *ob) else if (ob->mode & OB_MODE_VERTEX_PAINT) return CTX_MODE_PAINT_VERTEX; else if (ob->mode & OB_MODE_TEXTURE_PAINT) return CTX_MODE_PAINT_TEXTURE; else if (ob->mode & OB_MODE_PARTICLE_EDIT) return CTX_MODE_PARTICLE; - else if (ob->mode & OB_MODE_HAIR_EDIT) return CTX_MODE_HAIR; } } @@ -1054,7 +1053,6 @@ static const char *data_mode_strings[] = { "vertexpaint", "imagepaint", "particlemode", - "hairmode", "objectmode", NULL }; diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 18ab463a1a3..3bf5784e674 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -52,7 +52,6 @@ #include "BKE_customdata.h" #include "BKE_customdata_file.h" -#include "BKE_editstrands.h" #include "BKE_global.h" #include "BKE_main.h" #include "BKE_mesh_mapping.h" @@ -1296,8 +1295,6 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { {sizeof(short[4][3]), "", 0, NULL, NULL, NULL, NULL, layerSwap_flnor, NULL}, /* 41: CD_CUSTOMLOOPNORMAL */ {sizeof(short[2]), "vec2s", 1, NULL, NULL, NULL, NULL, NULL, NULL}, - /* 42: CD_MESH_SAMPLE */ - {sizeof(MeshSample), "MeshSample", 1, NULL, NULL, NULL, NULL, NULL, NULL}, }; @@ -1313,7 +1310,7 @@ static const char *LAYERTYPENAMES[CD_NUMTYPES] = { /* 30-34 */ "CDSubSurfCrease", "CDOrigSpaceLoop", "CDPreviewLoopCol", "CDBMElemPyPtr", "CDPaintMask", /* 35-36 */ "CDGridPaintMask", "CDMVertSkin", /* 37-38 */ "CDFreestyleEdge", "CDFreestyleFace", - /* 39-42 */ "CDMLoopTangent", "CDTessLoopNormal", "CDCustomLoopNormal", "CDMeshSample", + /* 39-41 */ "CDMLoopTangent", "CDTessLoopNormal", "CDCustomLoopNormal", }; @@ -1358,17 +1355,6 @@ const CustomDataMask CD_MASK_FACECORNERS = CD_MASK_ORIGSPACE | CD_MASK_ORIGSPACE_MLOOP | CD_MASK_TESSLOOPNORMAL | CD_MASK_NORMAL | CD_MASK_TANGENT | CD_MASK_MLOOPTANGENT; -const CustomDataMask CD_MASK_STRANDS = - CD_MASK_MVERT | CD_MASK_MEDGE | - CD_MASK_MDEFORMVERT | CD_MASK_MCOL | - CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS | - CD_MASK_MVERT_SKIN | CD_MASK_FREESTYLE_EDGE | - CD_MASK_MSURFACE_SAMPLE; -const CustomDataMask CD_MASK_STRANDS_BMESH = - CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | - CD_MASK_PROP_STR | CD_MASK_SHAPEKEY | CD_MASK_SHAPE_KEYINDEX | CD_MASK_MDISPS | - CD_MASK_MVERT_SKIN | CD_MASK_FREESTYLE_EDGE | - CD_MASK_MSURFACE_SAMPLE; const CustomDataMask CD_MASK_EVERYTHING = CD_MASK_MVERT | CD_MASK_MDEFORMVERT | CD_MASK_MEDGE | CD_MASK_MFACE | CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_NORMAL /* | CD_MASK_POLYINDEX */ | CD_MASK_PROP_FLT | @@ -2914,18 +2900,6 @@ void *CustomData_bmesh_get_layer_n(const CustomData *data, void *block, int n) return POINTER_OFFSET(block, data->layers[n].offset); } -/*Bmesh Custom Data Functions. Should replace editmesh ones with these as well, due to more effecient memory alloc*/ -void *CustomData_bmesh_get_named(const CustomData *data, void *block, int type, const char *name) -{ - int layer_index; - - /* get the layer index of the named layer of type */ - layer_index = CustomData_get_named_layer_index(data, type, name); - if (layer_index == -1) return NULL; - - return (char *)block + data->layers[layer_index].offset; -} - bool CustomData_layer_has_math(const struct CustomData *data, int layer_n) { const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[layer_n].type); diff --git a/source/blender/blenkernel/intern/editstrands.c b/source/blender/blenkernel/intern/editstrands.c deleted file mode 100644 index 74d300751d3..00000000000 --- a/source/blender/blenkernel/intern/editstrands.c +++ /dev/null @@ -1,300 +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) Blender Foundation - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Lukas Toenne - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/blenkernel/intern/editstrands.c - * \ingroup bke - */ - -#include "MEM_guardedalloc.h" - -#include "BLI_listbase.h" -#include "BLI_math.h" -#include "BLI_mempool.h" - -#include "DNA_customdata_types.h" -#include "DNA_key_types.h" -#include "DNA_mesh_types.h" -#include "DNA_modifier_types.h" -#include "DNA_object_types.h" -#include "DNA_particle_types.h" - -#include "BKE_bvhutils.h" -#include "BKE_customdata.h" -#include "BKE_cdderivedmesh.h" -#include "BKE_DerivedMesh.h" -#include "BKE_editstrands.h" -#include "BKE_effect.h" -#include "BKE_hair.h" -#include "BKE_mesh_sample.h" -#include "BKE_object.h" -#include "BKE_particle.h" - -#include "BPH_strands.h" - -#include "intern/bmesh_mesh_conv.h" -#include "intern/bmesh_strands_conv.h" - -BMEditStrands *BKE_editstrands_create(BMesh *bm, DerivedMesh *root_dm) -{ - BMEditStrands *es = MEM_callocN(sizeof(BMEditStrands), __func__); - - es->base.bm = bm; - es->root_dm = CDDM_copy(root_dm); - - BKE_editstrands_batch_cache_dirty(es, BKE_STRANDS_BATCH_DIRTY_ALL); - - return es; -} - -BMEditStrands *BKE_editstrands_copy(BMEditStrands *es) -{ - BMEditStrands *es_copy = MEM_callocN(sizeof(BMEditStrands), __func__); - *es_copy = *es; - - es_copy->base.bm = BM_mesh_copy(es->base.bm); - es_copy->root_dm = CDDM_copy(es->root_dm); - - BKE_editstrands_batch_cache_dirty(es_copy, BKE_STRANDS_BATCH_DIRTY_ALL); - - return es_copy; -} - -/** - * \brief Return the BMEditStrands for a given object's particle systems - */ -BMEditStrands *BKE_editstrands_from_object_particles(Object *ob, ParticleSystem **r_psys) -{ - ParticleSystem *psys = psys_get_current(ob); - if (psys && psys->hairedit) { - if (r_psys) { - *r_psys = psys; - } - return psys->hairedit; - } - - if (r_psys) { - *r_psys = NULL; - } - return NULL; -} - -/** - * \brief Return the BMEditStrands for a given object - */ -BMEditStrands *BKE_editstrands_from_object(Object *ob) -{ - if (ob && ob->type == OB_MESH) { - Mesh *me = ob->data; - if (me->edit_strands) - return me->edit_strands; - } - - return BKE_editstrands_from_object_particles(ob, NULL); -} - -void BKE_editstrands_update_linked_customdata(BMEditStrands *UNUSED(es)) -{ -} - -/*does not free the BMEditStrands struct itself*/ -void BKE_editstrands_free(BMEditStrands *es) -{ - BKE_editstrands_batch_cache_free(es); - - if (es->base.bm) - BM_mesh_free(es->base.bm); - if (es->root_dm) - es->root_dm->release(es->root_dm); -} - -/* === Constraints === */ - -BMEditStrandsLocations BKE_editstrands_get_locations(BMEditStrands *edit) -{ - BMesh *bm = edit->base.bm; - BMEditStrandsLocations locs = MEM_mallocN(3*sizeof(float) * bm->totvert, "editstrands locations"); - - BMVert *v; - BMIter iter; - int i; - - BM_ITER_MESH_INDEX(v, &iter, bm, BM_VERTS_OF_MESH, i) { - copy_v3_v3(locs[i], v->co); - } - - return locs; -} - -void BKE_editstrands_free_locations(BMEditStrandsLocations locs) -{ - MEM_freeN(locs); -} - -void BKE_editstrands_solve_constraints(Object *ob, BMEditStrands *es, BMEditStrandsLocations orig) -{ - BKE_editstrands_ensure(es); - - BPH_strands_solve_constraints(ob, es, orig); - - BKE_editstrands_batch_cache_dirty(es, BKE_STRANDS_BATCH_DIRTY_ALL); -} - -static void editstrands_calc_segment_lengths(BMesh *bm) -{ - BMVert *root, *v, *vprev; - BMIter iter, iter_strand; - int k; - - BM_ITER_STRANDS(root, &iter, bm, BM_STRANDS_OF_MESH) { - BM_ITER_STRANDS_ELEM_INDEX(v, &iter_strand, root, BM_VERTS_OF_STRAND, k) { - if (k > 0) { - float length = len_v3v3(v->co, vprev->co); - BM_elem_float_data_named_set(&bm->vdata, v, CD_PROP_FLT, CD_HAIR_SEGMENT_LENGTH, length); - } - vprev = v; - } - } -} - -void BKE_editstrands_ensure(BMEditStrands *es) -{ - BM_strands_cd_flag_ensure(es->base.bm, 0); - - if (es->flag & BM_STRANDS_DIRTY_SEGLEN) { - editstrands_calc_segment_lengths(es->base.bm); - - es->flag &= ~BM_STRANDS_DIRTY_SEGLEN; - } -} - - -/* === Particle Conversion === */ - -BMesh *BKE_editstrands_particles_to_bmesh(Object *ob, ParticleSystem *psys) -{ - ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys); - - const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_PSYS(psys); - BMesh *bm; - - bm = BM_mesh_create(&allocsize, - &((struct BMeshCreateParams){.use_toolflags = false,})); - - if (psmd && psmd->dm_final) { - DM_ensure_tessface(psmd->dm_final); - - BM_strands_bm_from_psys(bm, ob, psys, psmd->dm_final, true, /*psys->shapenr*/ -1); - - editstrands_calc_segment_lengths(bm); - } - - return bm; -} - -void BKE_editstrands_particles_from_bmesh(Object *ob, ParticleSystem *psys) -{ - ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys); - BMesh *bm = psys->hairedit ? psys->hairedit->base.bm : NULL; - - if (bm) { - if (psmd && psmd->dm_final) { - BVHTreeFromMesh bvhtree = {NULL}; - - DM_ensure_tessface(psmd->dm_final); - - bvhtree_from_mesh_faces(&bvhtree, psmd->dm_final, 0.0, 2, 6); - - BM_strands_bm_to_psys(bm, ob, psys, psmd->dm_final, &bvhtree); - - free_bvhtree_from_mesh(&bvhtree); - } - } -} - - -/* === Mesh Conversion === */ - -BMesh *BKE_editstrands_mesh_to_bmesh(Object *ob, Mesh *me) -{ - const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(me); - BMesh *bm; - struct BMeshFromMeshParams params = {0}; - - bm = BM_mesh_create(&allocsize, - &((struct BMeshCreateParams){.use_toolflags = false,})); - - params.use_shapekey = true; - params.active_shapekey = ob->shapenr; - BM_mesh_bm_from_me(bm, me, ¶ms); - BM_strands_cd_flag_ensure(bm, 0); - - editstrands_calc_segment_lengths(bm); - - return bm; -} - -void BKE_editstrands_mesh_from_bmesh(Object *ob) -{ - Mesh *me = ob->data; - BMesh *bm = me->edit_strands->base.bm; - struct BMeshToMeshParams params = {0}; - - /* Workaround for T42360, 'ob->shapenr' should be 1 in this case. - * however this isn't synchronized between objects at the moment. */ - if (UNLIKELY((ob->shapenr == 0) && (me->key && !BLI_listbase_is_empty(&me->key->block)))) { - bm->shapenr = 1; - } - - BM_mesh_bm_to_me(bm, me, ¶ms); - -#ifdef USE_TESSFACE_DEFAULT - BKE_mesh_tessface_calc(me); -#endif - - /* free derived mesh. usually this would happen through depsgraph but there - * are exceptions like file save that will not cause this, and we want to - * avoid ending up with an invalid derived mesh then */ - BKE_object_free_derived_caches(ob); -} - -/* === Draw Cache === */ -void (*BKE_editstrands_batch_cache_dirty_cb)(BMEditStrands *es, int mode) = NULL; -void (*BKE_editstrands_batch_cache_free_cb)(BMEditStrands *es) = NULL; - -void BKE_editstrands_batch_cache_dirty(BMEditStrands *es, int mode) -{ - if (es->batch_cache) { - BKE_editstrands_batch_cache_dirty_cb(es, mode); - } -} - -void BKE_editstrands_batch_cache_free(BMEditStrands *es) -{ - if (es->batch_cache) { - BKE_editstrands_batch_cache_free_cb(es); - } -} diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index d2f94b7f220..39228891d51 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1009,7 +1009,6 @@ ParticleSystem *BKE_object_copy_particlesystem(ParticleSystem *psys, const int f psysn->pathcache = NULL; psysn->childcache = NULL; psysn->edit = NULL; - psysn->hairedit = NULL; psysn->pdd = NULL; psysn->effectors = NULL; psysn->tree = NULL; diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 79c4ad6e618..17b19d2f8de 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -65,7 +65,6 @@ #include "BKE_boids.h" #include "BKE_cloth.h" #include "BKE_colortools.h" -#include "BKE_editstrands.h" #include "BKE_effect.h" #include "BKE_global.h" #include "BKE_group.h" @@ -569,11 +568,6 @@ void psys_free(Object *ob, ParticleSystem *psys) if (psys->edit && psys->free_edit) psys->free_edit(psys->edit); - if (psys->hairedit) { - BKE_editstrands_free(psys->hairedit); - MEM_freeN(psys->hairedit); - psys->hairedit = NULL; - } if (psys->child) { MEM_freeN(psys->child); @@ -3218,7 +3212,7 @@ void object_remove_particle_system(Scene *UNUSED(scene), Object *ob) if (ob->particlesystem.first) ((ParticleSystem *) ob->particlesystem.first)->flag |= PSYS_CURRENT; else - ob->mode &= ~(OB_MODE_PARTICLE_EDIT | OB_MODE_HAIR_EDIT); + ob->mode &= ~OB_MODE_PARTICLE_EDIT; DEG_relations_tag_update(G.main); DEG_id_tag_update(&ob->id, OB_RECALC_DATA); diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 7bf05db280d..95f10cc9846 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -866,11 +866,6 @@ void BKE_scene_init(Scene *sce) sce->toolsettings->imapaint.normal_angle = 80; sce->toolsettings->imapaint.seam_bleed = 2; - sce->toolsettings->hair_edit.select_mode = HAIR_SELECT_VERTEX; - sce->toolsettings->hair_edit.hair_draw_mode = HAIR_DRAW_FIBERS; - sce->toolsettings->hair_edit.hair_draw_size = 2.5f; - sce->toolsettings->hair_edit.hair_draw_subdiv = 2; - sce->physics_settings.gravity[0] = 0.0f; sce->physics_settings.gravity[1] = 0.0f; sce->physics_settings.gravity[2] = -9.81f; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 60930fa4d13..14ab8d34d53 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4437,7 +4437,6 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles) psys->edit = NULL; psys->free_edit = NULL; - psys->hairedit = NULL; psys->pathcache = NULL; psys->childcache = NULL; BLI_listbase_clear(&psys->pathcachebufs); @@ -4680,7 +4679,6 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh) mesh->bb = NULL; mesh->edit_btmesh = NULL; - mesh->edit_strands = NULL; mesh->batch_cache = NULL; /* happens with old files */ @@ -5481,8 +5479,6 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) hmd->hair = newdataadr(fd, hmd->hair); direct_link_hair(fd, hmd->hair); - - hmd->edit = NULL; } } } @@ -5513,7 +5509,7 @@ static void direct_link_object(FileData *fd, Object *ob) * See [#34776, #42780] for more information. */ if (fd->memfile || (ob->id.tag & (LIB_TAG_EXTERN | LIB_TAG_INDIRECT))) { - ob->mode &= ~(OB_MODE_EDIT | OB_MODE_PARTICLE_EDIT | OB_MODE_HAIR_EDIT); + ob->mode &= ~(OB_MODE_EDIT | OB_MODE_PARTICLE_EDIT); if (!fd->memfile) { ob->mode &= ~OB_MODE_POSE; } @@ -5864,14 +5860,6 @@ static void lib_link_scene(FileData *fd, Main *main) sce->toolsettings->particle.shape_object = newlibadr(fd, sce->id.lib, sce->toolsettings->particle.shape_object); - { - HairEditSettings *hair_edit = &sce->toolsettings->hair_edit; - if (hair_edit->brush) - hair_edit->brush = newlibadr(fd, sce->id.lib, hair_edit->brush); - if (hair_edit->shape_object) - hair_edit->shape_object = newlibadr(fd, sce->id.lib, hair_edit->shape_object); - } - for (Base *base_legacy_next, *base_legacy = sce->base.first; base_legacy; base_legacy = base_legacy_next) { base_legacy_next = base_legacy->next; @@ -6183,7 +6171,6 @@ static void direct_link_scene(FileData *fd, Scene *sce, Main *bmain) sce->toolsettings->particle.scene_layer = NULL; sce->toolsettings->particle.object = NULL; sce->toolsettings->gp_sculpt.paintcursor = NULL; - sce->toolsettings->hair_edit.paint_cursor = NULL; /* relink grease pencil drawing brushes */ link_list(fd, &sce->toolsettings->gp_brushes); diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 5577bca648d..ac4f7a6f892 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -2289,7 +2289,6 @@ static void write_mesh(WriteData *wd, Mesh *mesh) CustomData_reset(&mesh->pdata); CustomData_reset(&mesh->ldata); mesh->edit_btmesh = NULL; - mesh->edit_strands = NULL; /* now fill in polys to mfaces */ /* XXX This breaks writing design, by using temp allocated memory, which will likely generate diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt index bbe5044f1bf..ea24da86626 100644 --- a/source/blender/bmesh/CMakeLists.txt +++ b/source/blender/bmesh/CMakeLists.txt @@ -119,10 +119,6 @@ set(SRC intern/bmesh_queries.c intern/bmesh_queries.h intern/bmesh_queries_inline.h - intern/bmesh_strands.c - intern/bmesh_strands.h - intern/bmesh_strands_conv.c - intern/bmesh_strands_conv.h intern/bmesh_structure.c intern/bmesh_structure.h intern/bmesh_structure_inline.h diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h index ab955b7826a..b84a3d5e559 100644 --- a/source/blender/bmesh/bmesh.h +++ b/source/blender/bmesh/bmesh.h @@ -244,8 +244,6 @@ extern "C" { #include "intern/bmesh_mesh_validate.h" #include "intern/bmesh_mods.h" #include "intern/bmesh_operators.h" -#include "intern/bmesh_strands.h" -#include "intern/bmesh_strands_conv.h" #include "intern/bmesh_polygon.h" #include "intern/bmesh_polygon_edgenet.h" #include "intern/bmesh_queries.h" diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c index f2b4f1c4343..00f8eb6df40 100644 --- a/source/blender/bmesh/intern/bmesh_interp.c +++ b/source/blender/bmesh/intern/bmesh_interp.c @@ -900,34 +900,6 @@ void BM_elem_float_data_set(CustomData *cd, void *element, int type, const float if (f) *f = val; } -float BM_elem_float_data_named_get(CustomData *cd, void *element, int type, const char *name) -{ - const float *f = CustomData_bmesh_get_named(cd, ((BMHeader *)element)->data, type, name); - return f ? *f : 0.0f; -} - -void BM_elem_float_data_named_set(CustomData *cd, void *element, int type, const char *name, const float val) -{ - float *f = CustomData_bmesh_get_named(cd, ((BMHeader *)element)->data, type, name); - if (f) *f = val; -} - -void BM_elem_meshsample_data_named_get(CustomData *cd, void *element, int type, const char *name, MeshSample *val) -{ - const MeshSample *s = CustomData_bmesh_get_named(cd, ((BMHeader *)element)->data, type, name); - if (s) - memcpy(val, s, sizeof(MeshSample)); - else - memset(val, 0, sizeof(MeshSample)); -} - -void BM_elem_meshsample_data_named_set(CustomData *cd, void *element, int type, const char *name, const MeshSample *val) -{ - MeshSample *s = CustomData_bmesh_get_named(cd, ((BMHeader *)element)->data, type, name); - if (s) - memcpy(s, val, sizeof(MeshSample)); -} - /** \name Loop interpolation functions: BM_vert_loop_groups_data_layer_*** * * Handling loop custom-data such as UV's, while keeping contiguous fans is rather tedious. diff --git a/source/blender/bmesh/intern/bmesh_interp.h b/source/blender/bmesh/intern/bmesh_interp.h index 970d1cf68b4..dabdd23cf6f 100644 --- a/source/blender/bmesh/intern/bmesh_interp.h +++ b/source/blender/bmesh/intern/bmesh_interp.h @@ -29,8 +29,6 @@ struct LinkNode; struct MemArena; -struct MeshSample; - void BM_loop_interp_multires_ex( BMesh *bm, BMLoop *l_dst, const BMFace *f_src, @@ -56,10 +54,6 @@ void BM_data_layer_copy(BMesh *bm, CustomData *data, int type, int src_n, int d float BM_elem_float_data_get(CustomData *cd, void *element, int type); void BM_elem_float_data_set(CustomData *cd, void *element, int type, const float val); -float BM_elem_float_data_named_get(CustomData *cd, void *element, int type, const char *name); -void BM_elem_float_data_named_set(CustomData *cd, void *element, int type, const char *name, const float val); -void BM_elem_meshsample_data_named_get(CustomData *cd, void *element, int type, const char *name, struct MeshSample *val); -void BM_elem_meshsample_data_named_set(CustomData *cd, void *element, int type, const char *name, const struct MeshSample *val); void BM_face_interp_from_face_ex( BMesh *bm, BMFace *f_dst, const BMFace *f_src, const bool do_vertex, diff --git a/source/blender/bmesh/intern/bmesh_iterators_inline.h b/source/blender/bmesh/intern/bmesh_iterators_inline.h index 43b054d7845..e68440021e6 100644 --- a/source/blender/bmesh/intern/bmesh_iterators_inline.h +++ b/source/blender/bmesh/intern/bmesh_iterators_inline.h @@ -29,8 +29,6 @@ #ifndef __BMESH_ITERATORS_INLINE_H__ #define __BMESH_ITERATORS_INLINE_H__ -#include "BLI_mempool.h" - /* inline here optimizes out the switch statement when called with * constant values (which is very common), nicer for loop-in-loop situations */ @@ -45,6 +43,7 @@ BLI_INLINE void *BM_iter_step(BMIter *iter) return iter->step(iter); } + /** * \brief Iterator Init * diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c index 1cf699b755d..6cc1f37db43 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_conv.c +++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c @@ -98,9 +98,6 @@ #include "bmesh.h" #include "intern/bmesh_private.h" /* for element checking */ -/* XXX stupid hack: linker otherwise strips bmesh_strands_conv.c because it is not used inside bmesh */ -void *__dummy_hack__ = &BM_strands_count_psys_keys; - void BM_mesh_cd_flag_ensure(BMesh *bm, Mesh *mesh, const char cd_flag) { const char cd_flag_all = BM_mesh_cd_flag_from_bmesh(bm) | cd_flag; @@ -211,14 +208,13 @@ void BM_mesh_bm_from_me( BMFace *f, **ftable = NULL; float (*keyco)[3] = NULL; int totloops, i; - CustomDataMask mask = CD_MASK_BMESH | params->cd_mask_extra; if (!me || !me->totvert) { if (me && is_new) { /*no verts? still copy customdata layout*/ - CustomData_copy(&me->vdata, &bm->vdata, mask, CD_ASSIGN, 0); - CustomData_copy(&me->edata, &bm->edata, mask, CD_ASSIGN, 0); - CustomData_copy(&me->ldata, &bm->ldata, mask, CD_ASSIGN, 0); - CustomData_copy(&me->pdata, &bm->pdata, mask, CD_ASSIGN, 0); + CustomData_copy(&me->vdata, &bm->vdata, CD_MASK_BMESH, CD_ASSIGN, 0); + CustomData_copy(&me->edata, &bm->edata, CD_MASK_BMESH, CD_ASSIGN, 0); + CustomData_copy(&me->ldata, &bm->ldata, CD_MASK_BMESH, CD_ASSIGN, 0); + CustomData_copy(&me->pdata, &bm->pdata, CD_MASK_BMESH, CD_ASSIGN, 0); CustomData_bmesh_init_pool(&bm->vdata, me->totvert, BM_VERT); CustomData_bmesh_init_pool(&bm->edata, me->totedge, BM_EDGE); @@ -229,10 +225,10 @@ void BM_mesh_bm_from_me( } if (is_new) { - CustomData_copy(&me->vdata, &bm->vdata, mask, CD_CALLOC, 0); - CustomData_copy(&me->edata, &bm->edata, mask, CD_CALLOC, 0); - CustomData_copy(&me->ldata, &bm->ldata, mask, CD_CALLOC, 0); - CustomData_copy(&me->pdata, &bm->pdata, mask, CD_CALLOC, 0); + CustomData_copy(&me->vdata, &bm->vdata, CD_MASK_BMESH, CD_CALLOC, 0); + CustomData_copy(&me->edata, &bm->edata, CD_MASK_BMESH, CD_CALLOC, 0); + CustomData_copy(&me->ldata, &bm->ldata, CD_MASK_BMESH, CD_CALLOC, 0); + CustomData_copy(&me->pdata, &bm->pdata, CD_MASK_BMESH, CD_CALLOC, 0); } /* -------------------------------------------------------------------- */ diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.h b/source/blender/bmesh/intern/bmesh_mesh_conv.h index e69f3d6c489..1974d364171 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_conv.h +++ b/source/blender/bmesh/intern/bmesh_mesh_conv.h @@ -32,10 +32,7 @@ * \ingroup bmesh */ -#include "BLI_sys_types.h" - struct Mesh; -typedef uint64_t CustomDataMask; void BM_mesh_cd_validate(BMesh *bm); void BM_mesh_cd_flag_ensure(BMesh *bm, struct Mesh *mesh, const char cd_flag); @@ -51,7 +48,6 @@ struct BMeshFromMeshParams { uint use_shapekey : 1; /* define the active shape key (index + 1) */ int active_shapekey; - int64_t cd_mask_extra; }; void BM_mesh_bm_from_me( BMesh *bm, struct Mesh *me, diff --git a/source/blender/bmesh/intern/bmesh_operators_private.h b/source/blender/bmesh/intern/bmesh_operators_private.h index c0896691fd3..5548ee7c361 100644 --- a/source/blender/bmesh/intern/bmesh_operators_private.h +++ b/source/blender/bmesh/intern/bmesh_operators_private.h @@ -54,7 +54,6 @@ void bmo_create_icosphere_exec(BMesh *bm, BMOperator *op); void bmo_create_monkey_exec(BMesh *bm, BMOperator *op); void bmo_create_uvsphere_exec(BMesh *bm, BMOperator *op); void bmo_create_vert_exec(BMesh *bm, BMOperator *op); -//void bmo_create_strand_exec(BMesh *bm, BMOperator *op); void bmo_delete_exec(BMesh *bm, BMOperator *op); void bmo_dissolve_edges_exec(BMesh *bm, BMOperator *op); void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op); diff --git a/source/blender/bmesh/intern/bmesh_strands.c b/source/blender/bmesh/intern/bmesh_strands.c deleted file mode 100644 index 87477716562..00000000000 --- a/source/blender/bmesh/intern/bmesh_strands.c +++ /dev/null @@ -1,158 +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): Lukas Toenne. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/bmesh/intern/bmesh_strands.c - * \ingroup bmesh - */ - -#include "MEM_guardedalloc.h" - -#include "BLI_utildefines.h" -#include "BLI_math.h" -#include "BLI_mempool.h" - -#include "bmesh.h" -#include "bmesh_private.h" - -/* - * STRANDS OF MESH CALLBACKS - */ - -void bmstranditer__strands_of_mesh_begin(struct BMIter__elem_of_mesh *iter) -{ - BLI_mempool_iternew(iter->pooliter.pool, &iter->pooliter); -} - -void *bmstranditer__strands_of_mesh_step(struct BMIter__elem_of_mesh *iter) -{ - BMVert *v; - - do { - v = BLI_mempool_iterstep(&iter->pooliter); - } while (v && !BM_strands_vert_is_root(v)); - - return v; -} - -/* - * VERTS OF STRAND CALLBACKS - */ - -/* BMIter__vert_of_strand is not included in the union in BMIter, just make sure it is big enough */ -BLI_STATIC_ASSERT(sizeof(BMIter__vert_of_strand) <= sizeof(BMIter), "BMIter must be at least as large as BMIter__vert_of_strand") - -void bmstranditer__verts_of_strand_begin(struct BMIter__vert_of_strand *iter) -{ - iter->e_next = iter->v_next->e; -} - -void *bmstranditer__verts_of_strand_step(struct BMIter__vert_of_strand *iter) -{ - BMVert *v_curr = iter->v_next; - - if (iter->e_next) { - BMEdge *e_first = iter->e_next; - - /* select the other vertex of the current edge */ - iter->v_next = (iter->v_next == iter->e_next->v1 ? iter->e_next->v2 : iter->e_next->v1); - - /* select the next edge of the current vertex */ - iter->e_next = bmesh_disk_edge_next(iter->e_next, iter->v_next); - if (iter->e_next == e_first) { - /* only one edge means the last segment, terminate */ - iter->e_next = NULL; - } - } - else - iter->v_next = NULL; /* last vertex, terminate */ - - return v_curr; -} - -/* ------------------------------------------------------------------------- */ - -int BM_strands_count(BMesh *bm) -{ - BMVert *v; - BMIter iter; - - int count = 0; - BM_ITER_STRANDS(v, &iter, bm, BM_STRANDS_OF_MESH) { - ++count; - } - - return count; -} - -int BM_strands_keys_count(BMVert *root) -{ - BMVert *v; - BMIter iter; - - int count = 0; - BM_ITER_STRANDS_ELEM(v, &iter, root, BM_VERTS_OF_STRAND) { - ++count; - } - - return count; -} - -int BM_strands_keys_count_max(BMesh *bm) -{ - BMVert *v; - BMIter iter; - int maxkeys = 0; - BM_ITER_STRANDS(v, &iter, bm, BM_STRANDS_OF_MESH) { - int n = BM_strands_keys_count(v); - if (n > maxkeys) - maxkeys = n; - } - return maxkeys; -} - -/* ------------------------------------------------------------------------- */ - -/* Create a new strand */ -BMVert *BM_strands_create(BMesh *bm, int len, bool set_defaults) -{ - float co[3] = {0.0f, 0.0f, 0.0f}; - - BMVert *root, *v, *vprev; - int k; - - for (k = 0; k < len; ++k) { - vprev = v; - v = BM_vert_create(bm, co, NULL, set_defaults ? BM_CREATE_NOP : BM_CREATE_SKIP_CD); - - zero_v3(v->no); - - /* root */ - if (k == 0) { - root = v; - } - else { - /*BMEdge *e =*/ BM_edge_create(bm, vprev, v, NULL, set_defaults ? BM_CREATE_NOP : BM_CREATE_SKIP_CD); - } - } - - return root; -} diff --git a/source/blender/bmesh/intern/bmesh_strands.h b/source/blender/bmesh/intern/bmesh_strands.h deleted file mode 100644 index 1f060fa2dae..00000000000 --- a/source/blender/bmesh/intern/bmesh_strands.h +++ /dev/null @@ -1,216 +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): Lukas Toenne. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifndef __BMESH_STRANDS_H__ -#define __BMESH_STRANDS_H__ - -/** \file blender/bmesh/intern/bmesh_strands.h - * \ingroup bmesh - */ - -#include "BLI_utildefines.h" - -#include "bmesh.h" -#include "bmesh_queries.h" -#include "bmesh_structure.h" - -/* True if v is the root of a strand */ -BLI_INLINE bool BM_strands_vert_is_root(BMVert *v) -{ - BMEdge *e_first = v->e; - BMEdge *e_next; - - if (!e_first) - return true; /* single vertex is both root and tip */ - e_next = bmesh_disk_edge_next(e_first, v); - - /* with a single edge, the vertex is either first or last of the curve; - * first vertex is defined as the root - */ - if (e_next == e_first) { - if (e_first->v1 == v) - return true; - } - return false; -} - -/* True if v is the tip of a strand */ -BLI_INLINE bool BM_strands_vert_is_tip(BMVert *v) -{ - BMEdge *e_first = v->e; - BMEdge *e_next; - - if (!e_first) - return true; /* single vertex is both root and tip */ - e_next = bmesh_disk_edge_next(e_first, v); - - /* with a single edge, the vertex is either first or last of the curve; - * last vertex is defined as the tip - */ - if (e_next == e_first) { - if (e_first->v2 == v) - return true; - } - return false; -} - -/* Next vertex on a strand */ -BLI_INLINE BMVert *BM_strands_vert_next(BMVert *v) -{ - BMEdge *e_first = v->e; - BMEdge *e_next; - - /* one of the edges leads to the previous vertex */ - if (e_first) { - if (e_first->v1 == v) - return e_first->v2; - - e_next = bmesh_disk_edge_next(e_first, v); - if (e_next->v1 == v) - return e_next->v2; - } - return NULL; -} - -/* Previous vertex on a strand */ -BLI_INLINE BMVert *BM_strands_vert_prev(BMVert *v) -{ - BMEdge *e_first = v->e; - BMEdge *e_next; - - /* one of the edges leads to the previous vertex */ - if (e_first) { - if (e_first->v2 == v) - return e_first->v1; - - e_next = bmesh_disk_edge_next(e_first, v); - if (e_next->v2 == v) - return e_next->v1; - } - return NULL; -} - -int BM_strands_count(BMesh *bm); -int BM_strands_keys_count(BMVert *root); -int BM_strands_keys_count_max(BMesh *bm); - -/* Create a new strand */ -struct BMVert *BM_strands_create(struct BMesh *bm, int len, bool set_defaults); - -/* ==== Iterators ==== */ - -typedef enum BMStrandsIterType { - BM_STRANDS_OF_MESH, - BM_VERTS_OF_STRAND, -} BMStrandsIterType; - -#define BM_ITER_STRANDS(ele, iter, bm, itype) \ - for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_strand_iter_new(iter, bm, itype, NULL); \ - ele; \ - BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_step(iter)) - -#define BM_ITER_STRANDS_INDEX(ele, iter, bm, itype, indexvar) \ - for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_strand_iter_new(iter, bm, itype, NULL), indexvar = 0; \ - ele; \ - BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_step(iter), (indexvar)++) - -#define BM_ITER_STRANDS_ELEM(ele, iter, data, itype) \ - for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_strand_iter_new(iter, NULL, itype, data); \ - ele; \ - BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_step(iter)) - -#define BM_ITER_STRANDS_ELEM_INDEX(ele, iter, data, itype, indexvar) \ - for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_strand_iter_new(iter, NULL, itype, data), indexvar = 0; \ - ele; \ - BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_step(iter), (indexvar)++) - -typedef struct BMIter__vert_of_strand { - BMVert *v_next; - BMEdge *e_next; -} BMIter__vert_of_strand; - -void bmstranditer__strands_of_mesh_begin(struct BMIter__elem_of_mesh *iter); -void *bmstranditer__strands_of_mesh_step(struct BMIter__elem_of_mesh *iter); - -void bmstranditer__verts_of_strand_begin(struct BMIter__vert_of_strand *iter); -void *bmstranditer__verts_of_strand_step(struct BMIter__vert_of_strand *iter); - -BLI_INLINE bool BM_strand_iter_init(BMIter *iter, BMesh *bm, const char itype, void *data) -{ - /* int argtype; */ - iter->itype = itype; - - /* inlining optimizes out this switch when called with the defined type */ - switch ((BMStrandsIterType)itype) { - case BM_STRANDS_OF_MESH: - BLI_assert(bm != NULL); - BLI_assert(data == NULL); - iter->begin = (BMIter__begin_cb)bmstranditer__strands_of_mesh_begin; - iter->step = (BMIter__step_cb)bmstranditer__strands_of_mesh_step; - iter->data.elem_of_mesh.pooliter.pool = bm->vpool; - break; - case BM_VERTS_OF_STRAND: { - BMVert *root; - - BLI_assert(data != NULL); - BLI_assert(((BMElem *)data)->head.htype == BM_VERT); - root = (BMVert *)data; - BLI_assert(BM_strands_vert_is_root(root)); - iter->begin = (BMIter__begin_cb)bmstranditer__verts_of_strand_begin; - iter->step = (BMIter__step_cb)bmstranditer__verts_of_strand_step; - ((BMIter__vert_of_strand *)(&iter->data))->v_next = root; - break; - } - default: - /* fallback to regular bmesh iterator */ - return BM_iter_init(iter, bm, itype, data); - break; - } - - iter->begin(iter); - - return true; -} - -/** - * \brief Iterator New - * - * Takes a bmesh iterator structure and fills - * it with the appropriate function pointers based - * upon its type and then calls BMeshIter_step() - * to return the first element of the iterator. - * - */ -BLI_INLINE void *BM_strand_iter_new(BMIter *iter, BMesh *bm, const char itype, void *data) -{ - if (LIKELY(BM_strand_iter_init(iter, bm, itype, data))) { - return BM_iter_step(iter); - } - else { - return NULL; - } -} - -#define BM_strand_iter_new(iter, bm, itype, data) \ - (BM_ITER_CHECK_TYPE_DATA(data), BM_strand_iter_new(iter, bm, itype, data)) - -#endif /* __BMESH_STRANDS_H__ */ diff --git a/source/blender/bmesh/intern/bmesh_strands_conv.c b/source/blender/bmesh/intern/bmesh_strands_conv.c deleted file mode 100644 index 6cd39798126..00000000000 --- a/source/blender/bmesh/intern/bmesh_strands_conv.c +++ /dev/null @@ -1,720 +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): Lukas Toenne. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/bmesh/intern/bmesh_strands_conv.c - * \ingroup bmesh - * - * BM mesh conversion functions. - */ - -#include "DNA_meshdata_types.h" -#include "DNA_object_types.h" -#include "DNA_particle_types.h" -#include "DNA_key_types.h" - -#include "MEM_guardedalloc.h" - -#include "BLI_listbase.h" -#include "BLI_math.h" - -#include "BKE_customdata.h" -#include "BKE_key.h" -#include "BKE_main.h" -#include "BKE_mesh_sample.h" -#include "BKE_particle.h" - -#include "bmesh.h" -#include "intern/bmesh_private.h" /* for element checking */ - -const char *CD_HAIR_SEGMENT_LENGTH = "HAIR_SEGMENT_LENGTH"; -const char *CD_HAIR_MASS = "HAIR_MASS"; -const char *CD_HAIR_WEIGHT = "HAIR_WEIGHT"; -const char *CD_HAIR_ROOT_LOCATION = "HAIR_ROOT_LOCATION"; - -/* ------------------------------------------------------------------------- */ - -/** - * Currently this is only used for Python scripts - * which may fail to keep matching UV/TexFace layers. - * - * \note This should only perform any changes in exceptional cases, - * if we need this to be faster we could inline #BM_data_layer_add and only - * call #update_data_blocks once at the end. - */ -void BM_strands_cd_validate(BMesh *UNUSED(bm)) -{ -} - -void BM_strands_cd_flag_ensure(BMesh *bm, const char cd_flag) -{ - const char cd_flag_all = BM_strands_cd_flag_from_bmesh(bm) | cd_flag; - BM_strands_cd_flag_apply(bm, cd_flag_all); -} - -void BM_strands_cd_flag_apply(BMesh *bm, const char UNUSED(cd_flag)) -{ - /* CustomData_bmesh_init_pool() must run first */ - BLI_assert(bm->vdata.totlayer == 0 || bm->vdata.pool != NULL); - BLI_assert(bm->edata.totlayer == 0 || bm->edata.pool != NULL); - - if (CustomData_get_named_layer_index(&bm->vdata, CD_PROP_FLT, CD_HAIR_MASS) < 0) { - BM_data_layer_add_named(bm, &bm->vdata, CD_PROP_FLT, CD_HAIR_MASS); - } - if (CustomData_get_named_layer_index(&bm->vdata, CD_PROP_FLT, CD_HAIR_WEIGHT) < 0) { - BM_data_layer_add_named(bm, &bm->vdata, CD_PROP_FLT, CD_HAIR_WEIGHT); - } - if (CustomData_get_named_layer_index(&bm->vdata, CD_MSURFACE_SAMPLE, CD_HAIR_ROOT_LOCATION) < 0) { - BM_data_layer_add_named(bm, &bm->vdata, CD_MSURFACE_SAMPLE, CD_HAIR_ROOT_LOCATION); - } - if (CustomData_get_named_layer_index(&bm->vdata, CD_PROP_FLT, CD_HAIR_SEGMENT_LENGTH) < 0) { - BM_data_layer_add_named(bm, &bm->vdata, CD_PROP_FLT, CD_HAIR_SEGMENT_LENGTH); - } -} - -char BM_strands_cd_flag_from_bmesh(BMesh *UNUSED(bm)) -{ - char cd_flag = 0; - return cd_flag; -} - -/* particles */ - -int BM_strands_count_psys_keys(ParticleSystem *psys) -{ - ParticleData *pa; - int p; - int totkeys = 0; - - for (p = 0, pa = psys->particles; p < psys->totpart; ++p, ++pa) - totkeys += pa->totkey; - - return totkeys; -} - -#if 0 -static KeyBlock *bm_set_shapekey_from_psys(BMesh *bm, ParticleSystem *psys, int totvert, int act_key_nr) -{ - KeyBlock *actkey, *block; - int i, j; - - if (!psys->key) { - return NULL; - } - - if (act_key_nr != 0) - actkey = BLI_findlink(&psys->key->block, act_key_nr - 1); - else - actkey = NULL; - - CustomData_add_layer(&bm->vdata, CD_SHAPE_KEYINDEX, CD_ASSIGN, NULL, 0); - - /* check if we need to generate unique ids for the shapekeys. - * this also exists in the file reading code, but is here for - * a sanity check */ - if (!psys->key->uidgen) { - fprintf(stderr, - "%s had to generate shape key uid's in a situation we shouldn't need to! " - "(bmesh internal error)\n", - __func__); - - psys->key->uidgen = 1; - for (block = psys->key->block.first; block; block = block->next) { - block->uid = psys->key->uidgen++; - } - } - - if (actkey && actkey->totelem == totvert) { - bm->shapenr = act_key_nr; - } - - for (i = 0, block = psys->key->block.first; block; block = block->next, i++) { - CustomData_add_layer_named(&bm->vdata, CD_SHAPEKEY, - CD_ASSIGN, NULL, 0, block->name); - - j = CustomData_get_layer_index_n(&bm->vdata, CD_SHAPEKEY, i); - bm->vdata.layers[j].uid = block->uid; - } - - return actkey; -} -#endif - -/* create vertex and edge data for BMesh based on particle hair keys */ -static void bm_make_particles(BMesh *bm, Object *ob, ParticleSystem *psys, struct DerivedMesh *emitter_dm, float (*keyco)[3], int UNUSED(cd_shape_keyindex_offset)) -{ -// KeyBlock *block; - ParticleData *pa; - HairKey *hkey; - int p, k; - - int vindex, eindex; - BMVert *v = NULL, *v_prev; - BMEdge *e; - - float hairmat[4][4]; - - /* XXX currently all particles and keys have the same mass, this may change */ - float mass = psys->part->mass; - - vindex = 0; - eindex = 0; - for (p = 0, pa = psys->particles; p < psys->totpart; ++p, ++pa) { - - /* hair keys are in a local "hair space", but edit data should be in object space */ - psys_mat_hair_to_object(ob, emitter_dm, psys->part->from, pa, hairmat); - - for (k = 0, hkey = pa->hair; k < pa->totkey; ++k, ++hkey) { - float co[3]; - - copy_v3_v3(co, keyco ? keyco[vindex] : hkey->co); - mul_m4_v3(hairmat, co); - - v_prev = v; - v = BM_vert_create(bm, co, NULL, BM_CREATE_SKIP_CD); - BM_elem_index_set(v, vindex); /* set_ok */ - - /* transfer flag */ -// v->head.hflag = BM_vert_flag_from_mflag(mvert->flag & ~SELECT); - - /* this is necessary for selection counts to work properly */ -// if (hkey->editflag & SELECT) { -// BM_vert_select_set(bm, v, true); -// } - -// normal_short_to_float_v3(v->no, mvert->no); - - /* Copy Custom Data */ -// CustomData_to_bmesh_block(&me->vdata, &bm->vdata, vindex, &v->head.data, true); - CustomData_bmesh_set_default(&bm->vdata, &v->head.data); - - BM_elem_float_data_named_set(&bm->vdata, v, CD_PROP_FLT, CD_HAIR_MASS, mass); - BM_elem_float_data_named_set(&bm->vdata, v, CD_PROP_FLT, CD_HAIR_WEIGHT, hkey->weight); - - /* root */ - if (k == 0) { - MeshSample root_loc; - if (BKE_mesh_sample_from_particle(&root_loc, psys, emitter_dm, pa)) { - BM_elem_meshsample_data_named_set(&bm->vdata, v, CD_MSURFACE_SAMPLE, CD_HAIR_ROOT_LOCATION, &root_loc); - } - } - -#if 0 - /* set shapekey data */ - if (psys->key) { - /* set shape key original index */ - if (cd_shape_keyindex_offset != -1) BM_ELEM_CD_SET_INT(v, cd_shape_keyindex_offset, vindex); - - for (block = psys->key->block.first, j = 0; block; block = block->next, j++) { - float *co = CustomData_bmesh_get_n(&bm->vdata, v->head.data, CD_SHAPEKEY, j); - - if (co) { - copy_v3_v3(co, ((float *)block->data) + 3 * vindex); - } - } - } -#endif - - vindex += 1; - - if (k > 0) { - e = BM_edge_create(bm, v_prev, v, NULL, BM_CREATE_SKIP_CD); - BM_elem_index_set(e, eindex); /* set_ok; one less edge than vertices for each particle */ - - /* transfer flags */ -// e->head.hflag = BM_edge_flag_from_mflag(medge->flag & ~SELECT); - - /* this is necessary for selection counts to work properly */ -// if (medge->flag & SELECT) { -// BM_edge_select_set(bm, e, true); -// } - - /* Copy Custom Data */ -// CustomData_to_bmesh_block(&me->edata, &bm->edata, eindex, &e->head.data, true); - CustomData_bmesh_set_default(&bm->edata, &e->head.data); - - eindex += 1; - } - - } /* hair keys */ - - } /* particles */ - - bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE); /* added in order, clear dirty flag */ -} - -/** - * \brief ParticleSystem -> BMesh - */ -void BM_strands_bm_from_psys(BMesh *bm, Object *ob, ParticleSystem *psys, struct DerivedMesh *emitter_dm, - const bool set_key, int UNUSED(act_key_nr)) -{ - /*KeyBlock *actkey;*/ - float (*keyco)[3] = NULL; - int totvert, totedge; - - int cd_shape_keyindex_offset; - - /* free custom data */ - /* this isnt needed in most cases but do just incase */ - CustomData_free(&bm->vdata, bm->totvert); - CustomData_free(&bm->edata, bm->totedge); - CustomData_free(&bm->ldata, bm->totloop); - CustomData_free(&bm->pdata, bm->totface); - - totvert = BM_strands_count_psys_keys(psys); - totedge = totvert - psys->totpart; - - if (!psys || !totvert || !totedge) { - if (psys) { /*no verts? still copy customdata layout*/ -// CustomData_copy(&me->vdata, &bm->vdata, CD_MASK_BMESH, CD_ASSIGN, 0); -// CustomData_copy(&me->edata, &bm->edata, CD_MASK_BMESH, CD_ASSIGN, 0); - - CustomData_bmesh_init_pool(&bm->vdata, totvert, BM_VERT); - CustomData_bmesh_init_pool(&bm->edata, totedge, BM_EDGE); - CustomData_bmesh_init_pool(&bm->ldata, 0, BM_LOOP); - CustomData_bmesh_init_pool(&bm->pdata, 0, BM_FACE); - } - return; /* sanity check */ - } - -#if 0 - actkey = bm_set_shapekey_from_psys(bm, psys, totvert, act_key_nr); - if (actkey) - keyco = actkey->data; -#endif - - CustomData_bmesh_init_pool(&bm->vdata, totvert, BM_VERT); - CustomData_bmesh_init_pool(&bm->edata, totedge, BM_EDGE); - - BM_strands_cd_flag_apply(bm, /*psys->cd_flag*/0); - - cd_shape_keyindex_offset = /*psys->key ? CustomData_get_offset(&bm->vdata, CD_SHAPE_KEYINDEX) :*/ -1; - - bm_make_particles(bm, ob, psys, emitter_dm, set_key ? keyco : NULL, cd_shape_keyindex_offset); - - -#if 0 /* TODO */ - if (me->mselect && me->totselect != 0) { - - BMVert **vert_array = MEM_mallocN(sizeof(BMVert *) * bm->totvert, "VSelConv"); - BMEdge **edge_array = MEM_mallocN(sizeof(BMEdge *) * bm->totedge, "ESelConv"); - BMFace **face_array = MEM_mallocN(sizeof(BMFace *) * bm->totface, "FSelConv"); - MSelect *msel; - -#pragma omp parallel sections if (bm->totvert + bm->totedge + bm->totface >= BM_OMP_LIMIT) - { -#pragma omp section - { BM_iter_as_array(bm, BM_VERTS_OF_MESH, NULL, (void **)vert_array, bm->totvert); } -#pragma omp section - { BM_iter_as_array(bm, BM_EDGES_OF_MESH, NULL, (void **)edge_array, bm->totedge); } -#pragma omp section - { BM_iter_as_array(bm, BM_FACES_OF_MESH, NULL, (void **)face_array, bm->totface); } - } - - for (i = 0, msel = me->mselect; i < me->totselect; i++, msel++) { - switch (msel->type) { - case ME_VSEL: - BM_select_history_store(bm, (BMElem *)vert_array[msel->index]); - break; - case ME_ESEL: - BM_select_history_store(bm, (BMElem *)edge_array[msel->index]); - break; - case ME_FSEL: - BM_select_history_store(bm, (BMElem *)face_array[msel->index]); - break; - } - } - - MEM_freeN(vert_array); - MEM_freeN(edge_array); - MEM_freeN(face_array); - } - else { - me->totselect = 0; - if (me->mselect) { - MEM_freeN(me->mselect); - me->mselect = NULL; - } - } -#endif -} - -#if 0 -/** - * \brief BMesh -> Mesh - */ -static BMVert **bm_to_mesh_vertex_map(BMesh *bm, int ototvert) -{ - const int cd_shape_keyindex_offset = CustomData_get_offset(&bm->vdata, CD_SHAPE_KEYINDEX); - BMVert **vertMap = NULL; - BMVert *eve; - int i = 0; - BMIter iter; - - /* caller needs to ensure this */ - BLI_assert(ototvert > 0); - - vertMap = MEM_callocN(sizeof(*vertMap) * ototvert, "vertMap"); - if (cd_shape_keyindex_offset != -1) { - BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) { - const int keyi = BM_ELEM_CD_GET_INT(eve, cd_shape_keyindex_offset); - if ((keyi != ORIGINDEX_NONE) && (keyi < ototvert)) { - vertMap[keyi] = eve; - } - } - } - else { - BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) { - if (i < ototvert) { - vertMap[i] = eve; - } - else { - break; - } - } - } - - return vertMap; -} - -/** - * returns customdata shapekey index from a keyblock or -1 - * \note could split this out into a more generic function */ -static int bm_to_mesh_shape_layer_index_from_kb(BMesh *bm, KeyBlock *currkey) -{ - int i; - int j = 0; - - for (i = 0; i < bm->vdata.totlayer; i++) { - if (bm->vdata.layers[i].type == CD_SHAPEKEY) { - if (currkey->uid == bm->vdata.layers[i].uid) { - return j; - } - j++; - } - } - return -1; -} - -BLI_INLINE void bmesh_quick_edgedraw_flag(MEdge *med, BMEdge *e) -{ - /* this is a cheap way to set the edge draw, its not precise and will - * pick the first 2 faces an edge uses. - * The dot comparison is a little arbitrary, but set so that a 5 subd - * IcoSphere won't vanish but subd 6 will (as with pre-bmesh blender) */ - - - if ( /* (med->flag & ME_EDGEDRAW) && */ /* assume to be true */ - (e->l && (e->l != e->l->radial_next)) && - (dot_v3v3(e->l->f->no, e->l->radial_next->f->no) > 0.9995f)) - { - med->flag &= ~ME_EDGEDRAW; - } - else { - med->flag |= ME_EDGEDRAW; - } -} -#endif - -static void make_particle_hair(BMesh *bm, BMVert *root, Object *ob, ParticleSystem *psys, struct DerivedMesh *emitter_dm, struct BVHTreeFromMesh *emitter_bvhtree, struct ParticleData *pa) -{ - int totkey = BM_strands_keys_count(root); - HairKey *hair; - - BMVert *v; - BMIter iter; - HairKey *hkey; - int k; - - float inv_hairmat[4][4]; - - pa->alive = PARS_ALIVE; - pa->flag = 0; - - pa->time = 0.0f; - pa->lifetime = 100.0f; - pa->dietime = 100.0f; - - pa->size = psys->part->size; - - // TODO define other particle stuff ... - - hair = MEM_callocN(totkey * sizeof(HairKey), "hair keys"); - - hkey = hair; - k = 0; - BM_ITER_STRANDS_ELEM(v, &iter, root, BM_VERTS_OF_STRAND) { - /* root */ - if (k == 0) { - MeshSample root_loc; - BM_elem_meshsample_data_named_get(&bm->vdata, v, CD_MSURFACE_SAMPLE, CD_HAIR_ROOT_LOCATION, &root_loc); - if (!BKE_mesh_sample_to_particle(&root_loc, psys, emitter_dm, emitter_bvhtree, pa)) { - pa->num = 0; - pa->num_dmcache = DMCACHE_NOTFOUND; - zero_v4(pa->fuv); - pa->foffset = 0.0f; - } - - /* edit data is in object space, hair keys must be converted back into "hair space" */ - psys_mat_hair_to_object(ob, emitter_dm, psys->part->from, pa, inv_hairmat); - invert_m4(inv_hairmat); - } - - mul_v3_m4v3(hkey->co, inv_hairmat, v->co); - mul_v3_m4v3(hkey->world_co, ob->obmat, v->co); - - hkey->time = totkey > 0 ? (float)k / (float)(totkey - 1) : 0.0f; - if (k == 0) { - /* weight 1.0 is used for pinning hair roots in particles */ - hkey->weight = 1.0f; - } - else { - hkey->weight = BM_elem_float_data_named_get(&bm->vdata, v, CD_PROP_FLT, CD_HAIR_WEIGHT); - } - - ++hkey; - ++k; - - BM_CHECK_ELEMENT(v); - } - - if (pa->hair) - MEM_freeN(pa->hair); - - pa->hair = hair; - pa->totkey = totkey; -} - -void BM_strands_bm_to_psys(BMesh *bm, Object *ob, ParticleSystem *psys, struct DerivedMesh *emitter_dm, struct BVHTreeFromMesh *emitter_bvhtree) -{ - ParticleData *particles, *oldparticles; - int ototpart, ntotpart; - - BMVert *root; - BMIter iter; - ParticleData *pa; - int p; - - ototpart = psys->totpart; - - ntotpart = BM_strands_count(bm); - - /* new particles block */ - if (bm->totvert == 0) particles = NULL; - else particles = MEM_callocN(ntotpart * sizeof(ParticleData), "particles"); - - /* lets save the old particles just in case we are actually working on - * a key ... we now do processing of the keys at the end */ - oldparticles = psys->particles; - - psys->totpart = ntotpart; - -// psys->cd_flag = BM_strands_cd_flag_from_bmesh(bm); - - pa = particles; - p = 0; - BM_ITER_STRANDS(root, &iter, bm, BM_STRANDS_OF_MESH) { - - make_particle_hair(bm, root, ob, psys, emitter_dm, emitter_bvhtree, pa); - - ++pa; - ++p; - } - bm->elem_index_dirty &= ~BM_VERT; - - -#if 0 // TODO - { - BMEditSelection *selected; - me->totselect = BLI_listbase_count(&(bm->selected)); - - if (me->mselect) MEM_freeN(me->mselect); - - me->mselect = MEM_callocN(sizeof(MSelect) * me->totselect, "Mesh selection history"); - - - for (i = 0, selected = bm->selected.first; selected; i++, selected = selected->next) { - if (selected->htype == BM_VERT) { - me->mselect[i].type = ME_VSEL; - - } - else if (selected->htype == BM_EDGE) { - me->mselect[i].type = ME_ESEL; - - } - else if (selected->htype == BM_FACE) { - me->mselect[i].type = ME_FSEL; - } - - me->mselect[i].index = BM_elem_index_get(selected->ele); - } - } -#endif - -#if 0 // TODO - /* see comment below, this logic is in twice */ - - if (me->key) { - const int cd_shape_keyindex_offset = CustomData_get_offset(&bm->vdata, CD_SHAPE_KEYINDEX); - - KeyBlock *currkey; - KeyBlock *actkey = BLI_findlink(&me->key->block, bm->shapenr - 1); - - float (*ofs)[3] = NULL; - - /* go through and find any shapekey customdata layers - * that might not have corresponding KeyBlocks, and add them if - * necessary */ - j = 0; - for (i = 0; i < bm->vdata.totlayer; i++) { - if (bm->vdata.layers[i].type != CD_SHAPEKEY) - continue; - - for (currkey = me->key->block.first; currkey; currkey = currkey->next) { - if (currkey->uid == bm->vdata.layers[i].uid) - break; - } - - if (!currkey) { - currkey = BKE_keyblock_add(me->key, bm->vdata.layers[i].name); - currkey->uid = bm->vdata.layers[i].uid; - } - - j++; - } - - - /* editing the base key should update others */ - if ((me->key->type == KEY_RELATIVE) && /* only need offsets for relative shape keys */ - (actkey != NULL) && /* unlikely, but the active key may not be valid if the - * bmesh and the mesh are out of sync */ - (oldverts != NULL)) /* not used here, but 'oldverts' is used later for applying 'ofs' */ - { - const bool act_is_basis = BKE_keyblock_is_basis(me->key, bm->shapenr - 1); - - /* active key is a base */ - if (act_is_basis && (cd_shape_keyindex_offset != -1)) { - float (*fp)[3] = actkey->data; - - ofs = MEM_callocN(sizeof(float) * 3 * bm->totvert, "currkey->data"); - mvert = me->mvert; - BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) { - const int keyi = BM_ELEM_CD_GET_INT(eve, cd_shape_keyindex_offset); - - if (keyi != ORIGINDEX_NONE) { - sub_v3_v3v3(ofs[i], mvert->co, fp[keyi]); - } - else { - /* if there are new vertices in the mesh, we can't propagate the offset - * because it will only work for the existing vertices and not the new - * ones, creating a mess when doing e.g. subdivide + translate */ - MEM_freeN(ofs); - ofs = NULL; - break; - } - - mvert++; - } - } - } - - for (currkey = me->key->block.first; currkey; currkey = currkey->next) { - const bool apply_offset = (ofs && (currkey != actkey) && (bm->shapenr - 1 == currkey->relative)); - int cd_shape_offset; - int keyi; - float (*ofs_pt)[3] = ofs; - float *newkey, (*oldkey)[3], *fp; - - j = bm_to_mesh_shape_layer_index_from_kb(bm, currkey); - cd_shape_offset = CustomData_get_n_offset(&bm->vdata, CD_SHAPEKEY, j); - - - fp = newkey = MEM_callocN(me->key->elemsize * bm->totvert, "currkey->data"); - oldkey = currkey->data; - - mvert = me->mvert; - BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { - - if (currkey == actkey) { - copy_v3_v3(fp, eve->co); - - if (actkey != me->key->refkey) { /* important see bug [#30771] */ - if (cd_shape_keyindex_offset != -1) { - if (oldverts) { - keyi = BM_ELEM_CD_GET_INT(eve, cd_shape_keyindex_offset); - if (keyi != ORIGINDEX_NONE && keyi < currkey->totelem) { /* valid old vertex */ - copy_v3_v3(mvert->co, oldverts[keyi].co); - } - } - } - } - } - else if (j != -1) { - /* in most cases this runs */ - copy_v3_v3(fp, BM_ELEM_CD_GET_VOID_P(eve, cd_shape_offset)); - } - else if ((oldkey != NULL) && - (cd_shape_keyindex_offset != -1) && - ((keyi = BM_ELEM_CD_GET_INT(eve, cd_shape_keyindex_offset)) != ORIGINDEX_NONE) && - (keyi < currkey->totelem)) - { - /* old method of reconstructing keys via vertice's original key indices, - * currently used if the new method above fails (which is theoretically - * possible in certain cases of undo) */ - copy_v3_v3(fp, oldkey[keyi]); - } - else { - /* fail! fill in with dummy value */ - copy_v3_v3(fp, mvert->co); - } - - /* propagate edited basis offsets to other shapes */ - if (apply_offset) { - add_v3_v3(fp, *ofs_pt++); - } - - fp += 3; - mvert++; - } - - currkey->totelem = bm->totvert; - if (currkey->data) { - MEM_freeN(currkey->data); - } - currkey->data = newkey; - } - - if (ofs) MEM_freeN(ofs); - } -#else - psys->particles = particles; -#endif - - if (oldparticles) { - ParticleData *opa; - int op; - for (op = 0, opa = oldparticles; op < ototpart; ++op, ++opa) - if (opa->hair) - MEM_freeN(opa->hair); - MEM_freeN(oldparticles); - } -} diff --git a/source/blender/bmesh/intern/bmesh_strands_conv.h b/source/blender/bmesh/intern/bmesh_strands_conv.h deleted file mode 100644 index 334fabb53a8..00000000000 --- a/source/blender/bmesh/intern/bmesh_strands_conv.h +++ /dev/null @@ -1,62 +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. - * - * The Original Code is: all of this file. - * - * Contributor(s): Lukas Toenne. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifndef __BMESH_STRANDS_CONV_H__ -#define __BMESH_STRANDS_CONV_H__ - -/** \file blender/bmesh/intern/bmesh_strands_conv.h - * \ingroup bmesh - */ - -struct BMesh; -struct Mesh; -struct Object; -struct ParticleSystem; -struct DerivedMesh; -struct BVHTreeFromMesh; - -extern const char *CD_HAIR_SEGMENT_LENGTH; -extern const char *CD_HAIR_MASS; -extern const char *CD_HAIR_WEIGHT; -extern const char *CD_HAIR_ROOT_LOCATION; - -void BM_strands_cd_validate(struct BMesh *bm); -void BM_strands_cd_flag_ensure(struct BMesh *bm, const char cd_flag); -void BM_strands_cd_flag_apply(struct BMesh *bm, const char cd_flag); -char BM_strands_cd_flag_from_bmesh(struct BMesh *bm); - -/* particles */ - -int BM_strands_count_psys_keys(struct ParticleSystem *psys); -void BM_strands_bm_from_psys(struct BMesh *bm, struct Object *ob, struct ParticleSystem *psys, struct DerivedMesh *emitter_dm, - const bool set_key, int act_key_nr); -void BM_strands_bm_to_psys(struct BMesh *bm, struct Object *ob, struct ParticleSystem *psys, struct DerivedMesh *emitter_dm, struct BVHTreeFromMesh *emitter_bvhtree); - -#define BMALLOC_TEMPLATE_FROM_PSYS(psys) { (CHECK_TYPE_INLINE(psys, ParticleSystem *), \ - BM_strands_count_psys_keys(psys)), (BM_strands_count_psys_keys(psys) - (psys)->totpart), 0, 0 } - -#endif /* __BMESH_STRANDS_CONV_H__ */ diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 012378e583b..3eee2847363 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -61,7 +61,6 @@ set(SRC intern/draw_cache_impl_lattice.c intern/draw_cache_impl_mesh.c intern/draw_cache_impl_particles.c - intern/draw_cache_impl_strands.c intern/draw_common.c intern/draw_hair.c intern/draw_manager.c @@ -74,7 +73,6 @@ set(SRC modes/edit_mesh_mode.c modes/edit_mesh_mode_text.c modes/edit_metaball_mode.c - modes/edit_strands_mode.c modes/edit_surface_mode.c modes/edit_text_mode.c modes/object_mode.c @@ -208,7 +206,6 @@ data_to_c_simple(modes/shaders/edit_lattice_overlay_frag.glsl SRC) data_to_c_simple(modes/shaders/edit_lattice_overlay_loosevert_vert.glsl SRC) data_to_c_simple(modes/shaders/edit_normals_vert.glsl SRC) data_to_c_simple(modes/shaders/edit_normals_geom.glsl SRC) -data_to_c_simple(modes/shaders/edit_strands_vert.glsl SRC) data_to_c_simple(modes/shaders/object_empty_image_frag.glsl SRC) data_to_c_simple(modes/shaders/object_empty_image_vert.glsl SRC) data_to_c_simple(modes/shaders/object_outline_resolve_frag.glsl SRC) diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index de82cae8c01..d045cb59060 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -35,7 +35,6 @@ #include "BLI_alloca.h" #include "BKE_DerivedMesh.h" -#include "BKE_editstrands.h" #include "BKE_particle.h" #include "BKE_paint.h" #include "BKE_pbvh.h" @@ -1229,7 +1228,7 @@ static void material_particle_hair(EEVEE_SceneLayerData *sldata, EEVEE_Data *ved bool use_hair = false; struct Gwn_Batch *hair_geom = NULL; - if ((ob->mode & OB_MODE_HAIR_EDIT) == 0) { + { int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as; if (draw_as == PART_DRAW_PATH && (psys->pathcache || psys->childcache)) { use_hair = true; @@ -1297,8 +1296,8 @@ static void material_hair(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata, Obje const DRWContextState *draw_ctx = DRW_context_state_get(); Scene *scene = draw_ctx->scene; GHash *material_hash = stl->g_data->hair_material_hash; - const HairEditSettings *tsettings = &scene->toolsettings->hair_edit; - + /* TODO */ + const int subdiv = 0; float mat[4][4]; copy_m4_m4(mat, ob->obmat); @@ -1314,7 +1313,7 @@ static void material_hair(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata, Obje DEG_evaluation_context_init(&eval_ctx, DAG_EVAL_VIEWPORT); scalp = mesh_get_derived_final(&eval_ctx, scene, ob, CD_MASK_BAREMESH); } - hair_geom = DRW_cache_hair_get_fibers(group, tsettings->hair_draw_subdiv, scalp, &fiber_buffer); + hair_geom = DRW_cache_hair_get_fibers(group, subdiv, scalp, &fiber_buffer); } if (!group->draw_texture_cache) { diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index 12395de070f..6cf64969ab6 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -2577,31 +2577,6 @@ Gwn_Batch *DRW_cache_particles_get_prim(int type) /* -------------------------------------------------------------------- */ -/** \name Strands - * \{ */ - -Gwn_Batch *DRW_cache_editstrands_get_tips(struct BMEditStrands *es) -{ - return DRW_editstrands_batch_cache_get_tips(es); -} - -Gwn_Batch *DRW_cache_editstrands_get_roots(struct BMEditStrands *es) -{ - return DRW_editstrands_batch_cache_get_roots(es); -} - -Gwn_Batch *DRW_cache_editstrands_get_points(struct BMEditStrands *es) -{ - return DRW_editstrands_batch_cache_get_points(es); -} - -Gwn_Batch *DRW_cache_editstrands_get_wires(struct BMEditStrands *es) -{ - return DRW_editstrands_batch_cache_get_wires(es); -} - -/* -------------------------------------------------------------------- */ - /** \name Hair */ Gwn_Batch *DRW_cache_hair_get_fibers(struct HairGroup *group, int subdiv, struct DerivedMesh *scalp, diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h index 50ffb07c667..d21a5ee996f 100644 --- a/source/blender/draw/intern/draw_cache.h +++ b/source/blender/draw/intern/draw_cache.h @@ -30,7 +30,6 @@ struct Gwn_Batch; struct GPUMaterial; struct Object; struct ModifierData; -struct BMEditStrands; struct HairGroup; struct DRWHairFiberTextureBuffer; struct DerivedMesh; @@ -161,12 +160,6 @@ struct Gwn_Batch *DRW_cache_particles_get_hair(struct ParticleSystem *psys, stru struct Gwn_Batch *DRW_cache_particles_get_dots(struct ParticleSystem *psys); struct Gwn_Batch *DRW_cache_particles_get_prim(int type); -/* Strands */ -struct Gwn_Batch *DRW_cache_editstrands_get_tips(struct BMEditStrands *es); -struct Gwn_Batch *DRW_cache_editstrands_get_roots(struct BMEditStrands *es); -struct Gwn_Batch *DRW_cache_editstrands_get_points(struct BMEditStrands *es); -struct Gwn_Batch *DRW_cache_editstrands_get_wires(struct BMEditStrands *es); - /* Hair */ struct Gwn_Batch *DRW_cache_hair_get_fibers(struct HairGroup *group, int subdiv, struct DerivedMesh *scalp, const struct DRWHairFiberTextureBuffer **r_buffer); diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h index 57ccdd15054..3ed493f3937 100644 --- a/source/blender/draw/intern/draw_cache_impl.h +++ b/source/blender/draw/intern/draw_cache_impl.h @@ -32,7 +32,6 @@ struct ListBase; struct CurveCache; struct ParticleSystem; struct ModifierData; -struct BMEditStrands; struct HairGroup; struct DRWHairFiberTextureBuffer; struct DerivedMesh; @@ -57,9 +56,6 @@ void DRW_particle_batch_cache_free(struct ParticleSystem *psys); void DRW_hair_batch_cache_dirty(struct HairGroup *group, int mode); void DRW_hair_batch_cache_free(struct HairGroup *group); -void DRW_editstrands_batch_cache_dirty(struct BMEditStrands *es, int mode); -void DRW_editstrands_batch_cache_free(struct BMEditStrands *es); - /* 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( @@ -117,12 +113,6 @@ void DRW_mesh_cache_sculpt_coords_ensure(struct Mesh *me); struct Gwn_Batch *DRW_particles_batch_cache_get_hair(struct ParticleSystem *psys, struct ModifierData *md); struct Gwn_Batch *DRW_particles_batch_cache_get_dots(struct ParticleSystem *psys); -/* Strands */ -struct Gwn_Batch *DRW_editstrands_batch_cache_get_wires(struct BMEditStrands *es); -struct Gwn_Batch *DRW_editstrands_batch_cache_get_tips(struct BMEditStrands *es); -struct Gwn_Batch *DRW_editstrands_batch_cache_get_roots(struct BMEditStrands *es); -struct Gwn_Batch *DRW_editstrands_batch_cache_get_points(struct BMEditStrands *es); - /* Hair */ struct Gwn_Batch *DRW_hair_batch_cache_get_fibers(struct HairGroup *group, int subdiv, struct DerivedMesh *scalp, const struct DRWHairFiberTextureBuffer **r_buffer); diff --git a/source/blender/draw/intern/draw_cache_impl_strands.c b/source/blender/draw/intern/draw_cache_impl_strands.c deleted file mode 100644 index 94803a9512c..00000000000 --- a/source/blender/draw/intern/draw_cache_impl_strands.c +++ /dev/null @@ -1,341 +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) 2017 by Blender Foundation. - * All rights reserved. - * - * Contributor(s): Blender Foundation, Mike Erwin, Dalai Felinto - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file draw_cache_impl_strands.c - * \ingroup draw - * - * \brief Strands API for render engines - */ - -#include "MEM_guardedalloc.h" - -#include "BLI_utildefines.h" -#include "BLI_math_vector.h" -#include "BLI_ghash.h" - -#include "DNA_hair_types.h" -#include "DNA_scene_types.h" - -#include "BKE_editstrands.h" - -#include "GPU_batch.h" -#include "GPU_extensions.h" -#include "GPU_texture.h" - -#include "draw_common.h" -#include "draw_cache_impl.h" /* own include */ -#include "DRW_render.h" - -// timing -//#define DEBUG_TIME -#ifdef DEBUG_TIME -# include "PIL_time_utildefines.h" -#else -# define TIMEIT_START(var) -# define TIMEIT_VALUE(var) -# define TIMEIT_VALUE_PRINT(var) -# define TIMEIT_END(var) -# define TIMEIT_BENCH(expr, id) (expr) -# define TIMEIT_BLOCK_INIT(var) -# define TIMEIT_BLOCK_START(var) -# define TIMEIT_BLOCK_END(var) -# define TIMEIT_BLOCK_STATS(var) -#endif - -/* ---------------------------------------------------------------------- */ -/* Strands Gwn_Batch Cache */ - -typedef enum VertexDrawFlags -{ - STRANDS_VERTEX_SELECT = (1 << 0), -} VertexDrawFlags; - -typedef struct StrandsBatchCache { - Gwn_VertBuf *pos; - Gwn_IndexBuf *segments; - Gwn_IndexBuf *tips_idx; - Gwn_IndexBuf *roots_idx; - - Gwn_Batch *wires; - Gwn_Batch *tips; - Gwn_Batch *roots; - Gwn_Batch *points; - - int segment_count; - int point_count; - - /* settings to determine if cache is invalid */ - bool is_dirty; -} StrandsBatchCache; - -/* Gwn_Batch cache management. */ - -static void editstrands_batch_cache_clear(BMEditStrands *es); - -static bool editstrands_batch_cache_valid(BMEditStrands *es) -{ - StrandsBatchCache *cache = es->batch_cache; - - if (cache == NULL) { - return false; - } - - if (cache->is_dirty) { - return false; - } - - return true; -} - -static void editstrands_batch_cache_init(BMEditStrands *es) -{ - StrandsBatchCache *cache = es->batch_cache; - - if (!cache) { - cache = es->batch_cache = MEM_callocN(sizeof(*cache), __func__); - } - else { - memset(cache, 0, sizeof(*cache)); - } - - cache->is_dirty = false; -} - -static StrandsBatchCache *editstrands_batch_cache_get(BMEditStrands *es) -{ - if (!editstrands_batch_cache_valid(es)) { - editstrands_batch_cache_clear(es); - editstrands_batch_cache_init(es); - } - return es->batch_cache; -} - -void DRW_editstrands_batch_cache_dirty(BMEditStrands *es, int mode) -{ - StrandsBatchCache *cache = es->batch_cache; - if (cache == NULL) { - return; - } - switch (mode) { - case BKE_STRANDS_BATCH_DIRTY_ALL: - case BKE_STRANDS_BATCH_DIRTY_SELECT: - cache->is_dirty = true; - break; - default: - BLI_assert(0); - } -} - -static void editstrands_batch_cache_clear(BMEditStrands *es) -{ - StrandsBatchCache *cache = es->batch_cache; - - if (cache) { - GWN_BATCH_DISCARD_SAFE(cache->wires); - GWN_BATCH_DISCARD_SAFE(cache->points); - GWN_BATCH_DISCARD_SAFE(cache->tips); - GWN_BATCH_DISCARD_SAFE(cache->roots); - GWN_VERTBUF_DISCARD_SAFE(cache->pos); - GWN_INDEXBUF_DISCARD_SAFE(cache->segments); - } -} - -void DRW_editstrands_batch_cache_free(BMEditStrands *es) -{ - editstrands_batch_cache_clear(es); - MEM_SAFE_FREE(es->batch_cache); -} - -static void editstrands_batch_cache_ensure_pos(BMEditStrands *es, StrandsBatchCache *cache) -{ - if (cache->pos) { - return; - } - - GWN_VERTBUF_DISCARD_SAFE(cache->pos); - - static Gwn_VertFormat format = { 0 }; - static unsigned pos_id, flag_id; - - /* initialize vertex format */ - if (format.attrib_ct == 0) { - pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); - flag_id = GWN_vertformat_attr_add(&format, "flag", GWN_COMP_U8, 1, GWN_FETCH_INT); - } - - BMesh *bm = es->base.bm; - BMVert *vert; - BMIter iter; - int curr_point; - - cache->pos = GWN_vertbuf_create_with_format(&format); - GWN_vertbuf_data_alloc(cache->pos, bm->totvert); - - BM_ITER_MESH_INDEX(vert, &iter, bm, BM_VERTS_OF_MESH, curr_point) { - GWN_vertbuf_attr_set(cache->pos, pos_id, curr_point, vert->co); - - uint8_t flag = 0; - if (BM_elem_flag_test(vert, BM_ELEM_SELECT)) - flag |= STRANDS_VERTEX_SELECT; - GWN_vertbuf_attr_set(cache->pos, flag_id, curr_point, &flag); - } -} - -static void editstrands_batch_cache_ensure_segments(BMEditStrands *es, StrandsBatchCache *cache) -{ - if (cache->segments) { - return; - } - - GWN_INDEXBUF_DISCARD_SAFE(cache->segments); - - BMesh *bm = es->base.bm; - BMEdge *edge; - BMIter iter; - - Gwn_IndexBufBuilder elb; - GWN_indexbuf_init(&elb, GWN_PRIM_LINES, bm->totedge, bm->totvert); - - BM_mesh_elem_index_ensure(bm, BM_VERT); - - BM_ITER_MESH(edge, &iter, bm, BM_EDGES_OF_MESH) { - GWN_indexbuf_add_line_verts(&elb, BM_elem_index_get(edge->v1), BM_elem_index_get(edge->v2)); - } - - cache->segments = GWN_indexbuf_build(&elb); -} - -static void editstrands_batch_cache_ensure_tips_idx(BMEditStrands *es, StrandsBatchCache *cache) -{ - if (cache->tips_idx) { - return; - } - - GWN_INDEXBUF_DISCARD_SAFE(cache->tips_idx); - - BMesh *bm = es->base.bm; - int totstrands = BM_strands_count(bm); - BMVert *root, *vert; - BMIter iter, iter_strand; - - Gwn_IndexBufBuilder elb; - GWN_indexbuf_init(&elb, GWN_PRIM_POINTS, totstrands, bm->totvert); - - BM_mesh_elem_index_ensure(bm, BM_VERT); - - BM_ITER_STRANDS(root, &iter, bm, BM_STRANDS_OF_MESH) { - BM_ITER_STRANDS_ELEM(vert, &iter_strand, root, BM_VERTS_OF_STRAND) - { - if (BM_strands_vert_is_tip(vert)) { - GWN_indexbuf_add_point_vert(&elb, BM_elem_index_get(vert)); - break; - } - } - } - - cache->tips_idx = GWN_indexbuf_build(&elb); -} - -static void editstrands_batch_cache_ensure_roots_idx(BMEditStrands *es, StrandsBatchCache *cache) -{ - if (cache->roots_idx) { - return; - } - - GWN_INDEXBUF_DISCARD_SAFE(cache->roots_idx); - - BMesh *bm = es->base.bm; - int totstrands = BM_strands_count(bm); - BMVert *root, *vert; - BMIter iter, iter_strand; - - Gwn_IndexBufBuilder elb; - GWN_indexbuf_init(&elb, GWN_PRIM_POINTS, totstrands, bm->totvert); - - BM_mesh_elem_index_ensure(bm, BM_VERT); - - BM_ITER_STRANDS(root, &iter, bm, BM_STRANDS_OF_MESH) { - BM_ITER_STRANDS_ELEM(vert, &iter_strand, root, BM_VERTS_OF_STRAND) - { - if (BM_strands_vert_is_root(vert)) { - GWN_indexbuf_add_point_vert(&elb, BM_elem_index_get(vert)); - break; - } - } - } - - cache->roots_idx = GWN_indexbuf_build(&elb); -} - -Gwn_Batch *DRW_editstrands_batch_cache_get_wires(BMEditStrands *es) -{ - StrandsBatchCache *cache = editstrands_batch_cache_get(es); - - if (cache->wires == NULL) { - editstrands_batch_cache_ensure_pos(es, cache); - editstrands_batch_cache_ensure_segments(es, cache); - cache->wires = GWN_batch_create(GWN_PRIM_LINES, cache->pos, cache->segments); - } - - return cache->wires; -} - -Gwn_Batch *DRW_editstrands_batch_cache_get_tips(BMEditStrands *es) -{ - StrandsBatchCache *cache = editstrands_batch_cache_get(es); - - if (cache->tips == NULL) { - editstrands_batch_cache_ensure_pos(es, cache); - editstrands_batch_cache_ensure_tips_idx(es, cache); - cache->tips = GWN_batch_create(GWN_PRIM_POINTS, cache->pos, cache->tips_idx); - } - - return cache->tips; -} - -Gwn_Batch *DRW_editstrands_batch_cache_get_roots(BMEditStrands *es) -{ - StrandsBatchCache *cache = editstrands_batch_cache_get(es); - - if (cache->roots == NULL) { - editstrands_batch_cache_ensure_pos(es, cache); - editstrands_batch_cache_ensure_roots_idx(es, cache); - cache->roots = GWN_batch_create(GWN_PRIM_POINTS, cache->pos, cache->roots_idx); - } - - return cache->roots; -} - -Gwn_Batch *DRW_editstrands_batch_cache_get_points(BMEditStrands *es) -{ - StrandsBatchCache *cache = editstrands_batch_cache_get(es); - - if (cache->points == NULL) { - editstrands_batch_cache_ensure_pos(es, cache); - cache->points = GWN_batch_create(GWN_PRIM_POINTS, cache->pos, NULL); - } - - return cache->points; -} diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 403ca95d1a1..4c9bf1499b9 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -3023,9 +3023,6 @@ static void DRW_engines_enable_from_mode(int mode) case CTX_MODE_PARTICLE: use_drw_engine(&draw_engine_particle_type); break; - case CTX_MODE_HAIR: - use_drw_engine(&draw_engine_edit_strands_type); - break; case CTX_MODE_OBJECT: break; default: @@ -3767,7 +3764,6 @@ void DRW_engines_register(void) DRW_engine_register(&draw_engine_edit_lattice_type); DRW_engine_register(&draw_engine_edit_mesh_type); DRW_engine_register(&draw_engine_edit_metaball_type); - DRW_engine_register(&draw_engine_edit_strands_type); DRW_engine_register(&draw_engine_edit_surface_type); DRW_engine_register(&draw_engine_edit_text_type); DRW_engine_register(&draw_engine_paint_texture_type); @@ -3791,9 +3787,6 @@ 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: editstrands.c */ - extern void *BKE_editstrands_batch_cache_dirty_cb; - extern void *BKE_editstrands_batch_cache_free_cb; /* BKE: hair.c */ extern void *BKE_hair_batch_cache_dirty_cb; extern void *BKE_hair_batch_cache_free_cb; @@ -3810,9 +3803,6 @@ 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_editstrands_batch_cache_dirty_cb = DRW_editstrands_batch_cache_dirty; - BKE_editstrands_batch_cache_free_cb = DRW_editstrands_batch_cache_free; - BKE_hair_batch_cache_dirty_cb = DRW_hair_batch_cache_dirty; BKE_hair_batch_cache_free_cb = DRW_hair_batch_cache_free; } diff --git a/source/blender/draw/modes/draw_mode_engines.h b/source/blender/draw/modes/draw_mode_engines.h index 4a0ff1e6b15..23fedbba5a5 100644 --- a/source/blender/draw/modes/draw_mode_engines.h +++ b/source/blender/draw/modes/draw_mode_engines.h @@ -32,7 +32,6 @@ extern DrawEngineType draw_engine_edit_curve_type; extern DrawEngineType draw_engine_edit_lattice_type; extern DrawEngineType draw_engine_edit_mesh_type; extern DrawEngineType draw_engine_edit_metaball_type; -extern DrawEngineType draw_engine_edit_strands_type; extern DrawEngineType draw_engine_edit_surface_type; extern DrawEngineType draw_engine_edit_text_type; extern DrawEngineType draw_engine_paint_texture_type; @@ -42,4 +41,4 @@ extern DrawEngineType draw_engine_particle_type; extern DrawEngineType draw_engine_pose_type; extern DrawEngineType draw_engine_sculpt_type; -#endif /* __DRAW_MODE_ENGINES_H__ */ +#endif /* __DRAW_MODE_ENGINES_H__ */
\ No newline at end of file diff --git a/source/blender/draw/modes/edit_strands_mode.c b/source/blender/draw/modes/edit_strands_mode.c deleted file mode 100644 index 38b601efc9b..00000000000 --- a/source/blender/draw/modes/edit_strands_mode.c +++ /dev/null @@ -1,308 +0,0 @@ -/* - * 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 blender/draw/modes/particle_mode.c - * \ingroup draw - */ - -#include "DRW_engine.h" -#include "DRW_render.h" - -#include "BLI_ghash.h" - -#include "DNA_view3d_types.h" - -#include "BKE_editstrands.h" - -#include "GPU_shader.h" -#include "GPU_texture.h" - -#include "draw_common.h" - -#include "draw_mode_engines.h" - -extern GlobalsUboStorage ts; - -extern char datatoc_edit_strands_vert_glsl[]; -extern char datatoc_gpu_shader_point_varying_color_frag_glsl[]; -extern char datatoc_gpu_shader_3D_smooth_color_frag_glsl[]; - -/* *********** LISTS *********** */ -/* All lists are per viewport specific datas. - * They are all free when viewport changes engines - * or is free itself. Use EDIT_STRANDS_engine_init() to - * initialize most of them and EDIT_STRANDS_cache_init() - * for EDIT_STRANDS_PassList */ - -typedef struct EDIT_STRANDS_PassList { - /* Declare all passes here and init them in - * EDIT_STRANDS_cache_init(). - * Only contains (DRWPass *) */ - struct DRWPass *wires; - struct DRWPass *tips; - struct DRWPass *roots; - struct DRWPass *points; -} EDIT_STRANDS_PassList; - -typedef struct EDIT_STRANDS_StorageList { - /* Contains any other memory block that the engine needs. - * Only directly MEM_(m/c)allocN'ed blocks because they are - * free with MEM_freeN() when viewport is freed. - * (not per object) */ - struct CustomStruct *block; - struct EDIT_STRANDS_PrivateData *g_data; -} EDIT_STRANDS_StorageList; - -typedef struct EDIT_STRANDS_Data { - /* Struct returned by DRW_viewport_engine_data_get. - * If you don't use one of these, just make it a (void *) */ - // void *fbl; - void *engine_type; /* Required */ - DRWViewportEmptyList *fbl; - DRWViewportEmptyList *txl; - EDIT_STRANDS_PassList *psl; - EDIT_STRANDS_StorageList *stl; -} EDIT_STRANDS_Data; - -/* *********** STATIC *********** */ - -static struct { - /* Custom shaders : - * Add sources to source/blender/draw/modes/shaders - * init in EDIT_STRANDS_engine_init(); - * free in EDIT_STRANDS_engine_free(); */ - struct GPUShader *edit_point_shader; - struct GPUShader *edit_wire_shader; -} e_data = {NULL}; /* Engine data */ - -typedef struct EDIT_STRANDS_PrivateData { - /* resulting curve as 'wire' for fast editmode drawing */ - DRWShadingGroup *wires_shgrp; - DRWShadingGroup *tips_shgrp; - DRWShadingGroup *roots_shgrp; - DRWShadingGroup *points_shgrp; -} EDIT_STRANDS_PrivateData; /* Transient data */ - -/* *********** FUNCTIONS *********** */ - -/* Init Textures, Framebuffers, Storage and Shaders. - * It is called for every frames. - * (Optional) */ -static void EDIT_STRANDS_engine_init(void *vedata) -{ - EDIT_STRANDS_StorageList *stl = ((EDIT_STRANDS_Data *)vedata)->stl; - - UNUSED_VARS(stl); - - /* Init Framebuffers like this: order is attachment order (for color texs) */ - /* - * DRWFboTexture tex[2] = {{&txl->depth, DRW_TEX_DEPTH_24, 0}, - * {&txl->color, DRW_TEX_RGBA_8, DRW_TEX_FILTER}}; - */ - - /* DRW_framebuffer_init takes care of checking if - * the framebuffer is valid and has the right size*/ - /* - * float *viewport_size = DRW_viewport_size_get(); - * DRW_framebuffer_init(&fbl->occlude_wire_fb, - * (int)viewport_size[0], (int)viewport_size[1], - * tex, 2); - */ - - if (!e_data.edit_point_shader) { - e_data.edit_point_shader = DRW_shader_create( - datatoc_edit_strands_vert_glsl, - NULL, - datatoc_gpu_shader_point_varying_color_frag_glsl, - NULL); - } - - if (!e_data.edit_wire_shader) { - e_data.edit_wire_shader = DRW_shader_create( - datatoc_edit_strands_vert_glsl, - NULL, - datatoc_gpu_shader_3D_smooth_color_frag_glsl, - NULL); - } -} - -/* Cleanup when destroying the engine. - * This is not per viewport ! only when quitting blender. - * Mostly used for freeing shaders */ -static void EDIT_STRANDS_engine_free(void) -{ - DRW_SHADER_FREE_SAFE(e_data.edit_point_shader); - DRW_SHADER_FREE_SAFE(e_data.edit_wire_shader); -} - -/* Here init all passes and shading groups - * Assume that all Passes are NULL */ -static void EDIT_STRANDS_cache_init(void *vedata) -{ - EDIT_STRANDS_PassList *psl = ((EDIT_STRANDS_Data *)vedata)->psl; - EDIT_STRANDS_StorageList *stl = ((EDIT_STRANDS_Data *)vedata)->stl; - - if (!stl->g_data) { - /* Alloc transient pointers */ - stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__); - } - - { - /* Strand wires */ - DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND; - psl->wires = DRW_pass_create("Strand Wire Verts Pass", state); - - stl->g_data->wires_shgrp = DRW_shgroup_create(e_data.edit_wire_shader, psl->wires); - DRW_shgroup_uniform_vec4(stl->g_data->wires_shgrp, "color", ts.colorWireEdit, 1); - DRW_shgroup_uniform_vec4(stl->g_data->wires_shgrp, "colorSelect", ts.colorEdgeSelect, 1); - } - - { - /* Tip vertices */ - DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND; - psl->tips = DRW_pass_create("Strand Tip Verts Pass", state); - - stl->g_data->tips_shgrp = DRW_shgroup_create(e_data.edit_point_shader, psl->tips); - DRW_shgroup_uniform_vec4(stl->g_data->tips_shgrp, "color", ts.colorVertex, 1); - DRW_shgroup_uniform_vec4(stl->g_data->tips_shgrp, "colorSelect", ts.colorVertexSelect, 1); - DRW_shgroup_uniform_float(stl->g_data->tips_shgrp, "sizeVertex", &ts.sizeVertex, 1); - } - - { - /* Root vertices */ - DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND; - psl->roots = DRW_pass_create("Strand Root Verts Pass", state); - - stl->g_data->roots_shgrp = DRW_shgroup_create(e_data.edit_point_shader, psl->roots); - DRW_shgroup_uniform_vec4(stl->g_data->roots_shgrp, "color", ts.colorVertex, 1); - DRW_shgroup_uniform_vec4(stl->g_data->roots_shgrp, "colorSelect", ts.colorVertexSelect, 1); - DRW_shgroup_uniform_float(stl->g_data->roots_shgrp, "sizeVertex", &ts.sizeVertex, 1); - } - - { - /* Interior vertices */ - DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND; - psl->points = DRW_pass_create("Strand Interior Verts Pass", state); - - stl->g_data->points_shgrp = DRW_shgroup_create(e_data.edit_point_shader, psl->points); - DRW_shgroup_uniform_vec4(stl->g_data->points_shgrp, "color", ts.colorVertex, 1); - DRW_shgroup_uniform_vec4(stl->g_data->points_shgrp, "colorSelect", ts.colorVertexSelect, 1); - DRW_shgroup_uniform_float(stl->g_data->points_shgrp, "sizeVertex", &ts.sizeVertex, 1); - } -} - -static void edit_strands_add_ob_to_pass( - Scene *scene, Object *ob, BMEditStrands *edit, - DRWShadingGroup *tips_shgrp, - DRWShadingGroup *roots_shgrp, - DRWShadingGroup *points_shgrp, - DRWShadingGroup *wires_shgrp) -{ - HairEditSettings *tsettings = &scene->toolsettings->hair_edit; - - { - struct Gwn_Batch *geom = DRW_cache_editstrands_get_wires(edit); - DRW_shgroup_call_add(wires_shgrp, geom, ob->obmat); - } - - switch (tsettings->select_mode) { - case HAIR_SELECT_TIP: { - struct Gwn_Batch *geom = DRW_cache_editstrands_get_tips(edit); - DRW_shgroup_call_add(tips_shgrp, geom, ob->obmat); - break; - } - - case HAIR_SELECT_STRAND: { -#if 0 - struct Gwn_Batch *geom = DRW_cache_editstrands_get_roots(edit); - DRW_shgroup_call_add(roots_shgrp, geom, ob->obmat); -#else - UNUSED_VARS(roots_shgrp); -#endif - break; - } - - case HAIR_SELECT_VERTEX: { - struct Gwn_Batch *geom = DRW_cache_editstrands_get_points(edit); - DRW_shgroup_call_add(points_shgrp, geom, ob->obmat); - break; - } - } -} - -/* Add geometry to shadingGroups. Execute for each objects */ -static void EDIT_STRANDS_cache_populate(void *vedata, Object *ob) -{ - EDIT_STRANDS_StorageList *stl = ((EDIT_STRANDS_Data *)vedata)->stl; - - BMEditStrands *edit = BKE_editstrands_from_object(ob); - const DRWContextState *draw_ctx = DRW_context_state_get(); - Scene *scene = draw_ctx->scene; - - // Don't draw strands while editing the object itself - if (ob == scene->obedit) - return; - - if (edit) { - edit_strands_add_ob_to_pass(scene, ob, edit, - stl->g_data->tips_shgrp, stl->g_data->roots_shgrp, - stl->g_data->points_shgrp, stl->g_data->wires_shgrp); - } -} - -/* Optional: Post-cache_populate callback */ -static void EDIT_STRANDS_cache_finish(void *vedata) -{ - EDIT_STRANDS_PassList *psl = ((EDIT_STRANDS_Data *)vedata)->psl; - EDIT_STRANDS_StorageList *stl = ((EDIT_STRANDS_Data *)vedata)->stl; - - /* Do something here! dependant on the objects gathered */ - UNUSED_VARS(psl, stl); -} - -/* Draw time ! Control rendering pipeline from here */ -static void EDIT_STRANDS_draw_scene(void *vedata) -{ - EDIT_STRANDS_PassList *psl = ((EDIT_STRANDS_Data *)vedata)->psl; - - DRW_draw_pass(psl->wires); - DRW_draw_pass(psl->points); - DRW_draw_pass(psl->roots); - DRW_draw_pass(psl->tips); - - /* If you changed framebuffer, double check you rebind - * the default one with its textures attached before finishing */ -} - -static const DrawEngineDataSize STRANDS_data_size = DRW_VIEWPORT_DATA_SIZE(EDIT_STRANDS_Data); - -DrawEngineType draw_engine_edit_strands_type = { - NULL, NULL, - N_("EditStrandsMode"), - &STRANDS_data_size, - EDIT_STRANDS_engine_init, - EDIT_STRANDS_engine_free, - &EDIT_STRANDS_cache_init, - &EDIT_STRANDS_cache_populate, - &EDIT_STRANDS_cache_finish, - NULL, /* draw_background but not needed by mode engines */ - &EDIT_STRANDS_draw_scene -}; diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index be073b1395c..ee2e8d6d236 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -1736,8 +1736,6 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) SceneLayer *sl = draw_ctx->scene_layer; View3D *v3d = draw_ctx->v3d; int theme_id = TH_UNDEFINED; - const bool is_edited = (ob == scene->obedit) || - ((ob == draw_ctx->obact) && (ob->mode & OB_MODE_ALL_BRUSH)); if (!BKE_object_is_visible(ob)) { return; @@ -1749,7 +1747,8 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) bool do_outlines = ((ob->base_flag & BASE_SELECTED) != 0); if (do_outlines) { - if (!is_edited) { + Object *obedit = scene->obedit; + if (ob != obedit && !((ob == draw_ctx->obact) && (ob->mode & OB_MODE_ALL_PAINT))) { struct Gwn_Batch *geom = DRW_cache_object_surface_get(ob); if (geom) { theme_id = DRW_object_wire_theme_get(ob, sl, NULL); @@ -1766,7 +1765,8 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) { Mesh *me = ob->data; if (me->totpoly == 0) { - if (!is_edited) { + Object *obedit = scene->obedit; + if (ob != obedit) { struct Gwn_Batch *geom = DRW_cache_mesh_edges_get(ob); if (geom) { if (theme_id == TH_UNDEFINED) { @@ -1786,7 +1786,8 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) break; case OB_LATTICE: { - if (!is_edited) { + Object *obedit = scene->obedit; + if (ob != obedit) { struct Gwn_Batch *geom = DRW_cache_lattice_wire_get(ob, false); if (theme_id == TH_UNDEFINED) { theme_id = DRW_object_wire_theme_get(ob, sl, NULL); @@ -1800,7 +1801,8 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) case OB_CURVE: { - if (!is_edited) { + Object *obedit = scene->obedit; + if (ob != obedit) { struct Gwn_Batch *geom = DRW_cache_curve_edge_wire_get(ob); if (theme_id == TH_UNDEFINED) { theme_id = DRW_object_wire_theme_get(ob, sl, NULL); diff --git a/source/blender/draw/modes/shaders/edit_strands_vert.glsl b/source/blender/draw/modes/shaders/edit_strands_vert.glsl deleted file mode 100644 index 5e54bb5112a..00000000000 --- a/source/blender/draw/modes/shaders/edit_strands_vert.glsl +++ /dev/null @@ -1,28 +0,0 @@ - -/* Draw Curve Vertices */ - -uniform mat4 ModelViewProjectionMatrix; -uniform vec2 viewportSize; -uniform vec4 color; -uniform vec4 colorSelect; -uniform float sizeVertex; - -in vec3 pos; -in int flag; - -out vec4 finalColor; - -#define VERTEX_SELECTED (1 << 0) - -void main() -{ - gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); - gl_PointSize = sizeVertex; - - if ((flag & VERTEX_SELECTED) != 0) { - finalColor = colorSelect; - } - else { - finalColor = color; - } -} diff --git a/source/blender/editors/CMakeLists.txt b/source/blender/editors/CMakeLists.txt index b419ca7eede..757fca0a1b2 100644 --- a/source/blender/editors/CMakeLists.txt +++ b/source/blender/editors/CMakeLists.txt @@ -27,7 +27,6 @@ if(WITH_BLENDER) add_subdirectory(armature) add_subdirectory(curve) add_subdirectory(gpencil) - add_subdirectory(hair) add_subdirectory(interface) add_subdirectory(io) add_subdirectory(manipulator_library) diff --git a/source/blender/editors/armature/armature_utils.c b/source/blender/editors/armature/armature_utils.c index 0bf7c529fa9..f27c4fdd96f 100644 --- a/source/blender/editors/armature/armature_utils.c +++ b/source/blender/editors/armature/armature_utils.c @@ -835,7 +835,7 @@ static void *get_armature_edit(bContext *C) void undo_push_armature(bContext *C, const char *name) { // XXX solve getdata() - undo_editmode_push(C, name, CTX_data_edit_object, get_armature_edit, free_undoBones, undoBones_to_editBones, editBones_to_undoBones, NULL); + undo_editmode_push(C, name, get_armature_edit, free_undoBones, undoBones_to_editBones, editBones_to_undoBones, NULL); } /* *************************************************************** */ diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 21f822665d4..85715bf575b 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -6307,7 +6307,7 @@ static void *get_data(bContext *C) /* and this is all the undo system needs to know */ void undo_push_curve(bContext *C, const char *name) { - undo_editmode_push(C, name, CTX_data_edit_object, get_data, free_undoCurve, undoCurve_to_editCurve, editCurve_to_undoCurve, NULL); + undo_editmode_push(C, name, get_data, free_undoCurve, undoCurve_to_editCurve, editCurve_to_undoCurve, NULL); } void ED_curve_beztcpy(EditNurb *editnurb, BezTriple *dst, BezTriple *src, int count) diff --git a/source/blender/editors/curve/editfont_undo.c b/source/blender/editors/curve/editfont_undo.c index 75f3df73118..a61f863b61e 100644 --- a/source/blender/editors/curve/editfont_undo.c +++ b/source/blender/editors/curve/editfont_undo.c @@ -307,5 +307,5 @@ static void *get_undoFont(bContext *C) /* and this is all the undo system needs to know */ void undo_push_font(bContext *C, const char *name) { - undo_editmode_push(C, name, CTX_data_edit_object, get_undoFont, free_undoFont, undoFont_to_editFont, editFont_to_undoFont, NULL); + undo_editmode_push(C, name, get_undoFont, free_undoFont, undoFont_to_editFont, editFont_to_undoFont, NULL); } diff --git a/source/blender/editors/datafiles/CMakeLists.txt b/source/blender/editors/datafiles/CMakeLists.txt index 2ac800ee6e0..2a84ca7f297 100644 --- a/source/blender/editors/datafiles/CMakeLists.txt +++ b/source/blender/editors/datafiles/CMakeLists.txt @@ -78,13 +78,6 @@ if(WITH_BLENDER) data_to_c_simple(../../../../release/datafiles/brushicons/fill.png SRC) data_to_c_simple(../../../../release/datafiles/brushicons/flatten.png SRC) data_to_c_simple(../../../../release/datafiles/brushicons/grab.png SRC) - data_to_c_simple(../../../../release/datafiles/brushicons/hairadd.png SRC) - data_to_c_simple(../../../../release/datafiles/brushicons/haircomb.png SRC) - data_to_c_simple(../../../../release/datafiles/brushicons/haircut.png SRC) - data_to_c_simple(../../../../release/datafiles/brushicons/hairlength.png SRC) - data_to_c_simple(../../../../release/datafiles/brushicons/hairpuff.png SRC) - data_to_c_simple(../../../../release/datafiles/brushicons/hairsmooth.png SRC) - data_to_c_simple(../../../../release/datafiles/brushicons/hairweight.png SRC) data_to_c_simple(../../../../release/datafiles/brushicons/inflate.png SRC) data_to_c_simple(../../../../release/datafiles/brushicons/layer.png SRC) data_to_c_simple(../../../../release/datafiles/brushicons/lighten.png SRC) diff --git a/source/blender/editors/hair/CMakeLists.txt b/source/blender/editors/hair/CMakeLists.txt deleted file mode 100644 index 97c18009560..00000000000 --- a/source/blender/editors/hair/CMakeLists.txt +++ /dev/null @@ -1,57 +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): Jacques Beaurain. -# -# ***** END GPL LICENSE BLOCK ***** - -set(INC - ../include - ../sculpt_paint - ../../blenfont - ../../blenkernel - ../../blenlib - ../../bmesh - ../../depsgraph - ../../gpu - ../../makesdna - ../../makesrna - ../../windowmanager - ../../../../intern/guardedalloc - ../../../../intern/glew-mx -) - -set(INC_SYS - ${GLEW_INCLUDE_PATH} -) - -set(SRC - hair_cursor.c - hair_edit.c - hair_mirror.c - hair_object_mesh.c - hair_object_particles.c - hair_ops.c - hair_select.c - hair_stroke.c - hair_undo.c - - hair_intern.h -) - -add_definitions(${GL_DEFINITIONS}) - -blender_add_lib(bf_editor_hair "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/editors/hair/SConscript b/source/blender/editors/hair/SConscript deleted file mode 100644 index 2e715a05e7c..00000000000 --- a/source/blender/editors/hair/SConscript +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env python -# -# ***** 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) 2006, Blender Foundation -# All rights reserved. -# -# The Original Code is: all of this file. -# -# Contributor(s): Nathan Letwory. -# -# ***** END GPL LICENSE BLOCK ***** - -Import ('env') - -sources = env.Glob('*.c') - -incs = [ - '#/intern/guardedalloc', - env['BF_GLEW_INC'], - '#/intern/glew-mx', - '../include', - '../sculpt_paint', - '../../blenfont', - '../../blenkernel', - '../../blenlib', - '../../bmesh', - '../../gpu', - '../../makesdna', - '../../makesrna', - '../../windowmanager', - ] -incs = ' '.join(incs) - -defs = ['BF_GL_DEFINITIONS'] - -if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'): - incs += ' ' + env['BF_PTHREADS_INC'] - -env.BlenderLib ( 'bf_editors_hair', sources, Split(incs), defs, libtype=['core'], priority=[45] ) diff --git a/source/blender/editors/hair/hair_cursor.c b/source/blender/editors/hair/hair_cursor.c deleted file mode 100644 index 110e6a8db07..00000000000 --- a/source/blender/editors/hair/hair_cursor.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) Blender Foundation - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Lukas Toenne - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/hair/hair_cursor.c - * \ingroup edhair - */ - -#include "MEM_guardedalloc.h" - -#include "BLI_utildefines.h" -#include "BLI_math.h" - -#include "DNA_brush_types.h" -#include "DNA_scene_types.h" -#include "DNA_screen_types.h" -#include "DNA_view3d_types.h" - -#include "BKE_brush.h" -#include "BKE_context.h" - -#include "GPU_immediate.h" -#include "GPU_immediate_util.h" - -#include "WM_api.h" -#include "WM_types.h" - -#include "BIF_gl.h" -#include "BIF_glutil.h" - -#include "ED_view3d.h" - -#include "hair_intern.h" - -static void hair_draw_cursor(bContext *C, int x, int y, void *UNUSED(customdata)) -{ - Scene *scene = CTX_data_scene(C); - UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; - HairEditSettings *settings = &scene->toolsettings->hair_edit; - Brush *brush = settings->brush; - if (!brush) - return; - - float final_radius = BKE_brush_size_get(scene, brush); - float col[4]; - - /* set various defaults */ - copy_v3_v3(col, brush->add_col); - col[3] = 0.5f; - - Gwn_VertFormat *format = immVertexFormat(); - uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - - immUniformColor4fv(col); - - /* draw an inner brush */ - if (ups->stroke_active && BKE_brush_use_size_pressure(scene, brush)) { - /* inner at full alpha */ - imm_draw_circle_wire_2d(pos, x, y, final_radius * ups->size_pressure_value, 40); - /* outer at half alpha */ - immUniformColor3fvAlpha(col, col[3]*0.5f); - } - imm_draw_circle_wire_2d(pos, x, y, final_radius, 40); - - immUnbindProgram(); -} - -void hair_edit_cursor_start(bContext *C, int (*poll)(bContext *C)) -{ - Scene *scene = CTX_data_scene(C); - HairEditSettings *settings = &scene->toolsettings->hair_edit; - - if (!settings->paint_cursor) - settings->paint_cursor = WM_paint_cursor_activate(CTX_wm_manager(C), poll, hair_draw_cursor, NULL); -} diff --git a/source/blender/editors/hair/hair_edit.c b/source/blender/editors/hair/hair_edit.c deleted file mode 100644 index b8f7bf3e2de..00000000000 --- a/source/blender/editors/hair/hair_edit.c +++ /dev/null @@ -1,468 +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) Blender Foundation - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Lukas Toenne - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/hair/hair_edit.c - * \ingroup edhair - */ - -#include <stdlib.h> - -#include "MEM_guardedalloc.h" - -#include "BLI_utildefines.h" -#include "BLI_math.h" - -#include "DNA_brush_types.h" -#include "DNA_mesh_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" -#include "DNA_screen_types.h" -#include "DNA_view3d_types.h" - -#include "BKE_brush.h" -#include "BKE_cdderivedmesh.h" -#include "BKE_context.h" -#include "BKE_DerivedMesh.h" -#include "BKE_editstrands.h" -#include "BKE_paint.h" - -#include "DEG_depsgraph.h" - -#include "bmesh.h" - -#include "RNA_access.h" -#include "RNA_define.h" - -#include "WM_api.h" -#include "WM_types.h" - -#include "ED_object.h" -#include "ED_view3d.h" - -#include "hair_intern.h" -#include "paint_intern.h" - -#define USE_PARTICLES 1 - -int hair_edit_poll(bContext *C) -{ - Object *obact; - - obact = CTX_data_active_object(C); - if ((obact && obact->mode & OB_MODE_HAIR_EDIT) && CTX_wm_region_view3d(C)) { - return true; - } - - return false; -} - -bool hair_use_mirror_x(Object *ob) -{ - if (ob->type == OB_MESH) - return ((Mesh *)ob->data)->editflag & ME_EDIT_MIRROR_X; - else - return false; -} - -bool hair_use_mirror_topology(Object *ob) -{ - if (ob->type == OB_MESH) - return ((Mesh *)ob->data)->editflag & ME_EDIT_MIRROR_TOPO; - else - return false; -} - - -/* ==== BMesh utilities ==== */ - -void hair_bm_min_max(BMEditStrands *edit, float min[3], float max[3]) -{ - BMesh *bm = edit->base.bm; - BMVert *v; - BMIter iter; - - if (bm->totvert > 0) { - INIT_MINMAX(min, max); - - BM_ITER_MESH(v, &iter, bm, BM_VERTS_OF_MESH) { - minmax_v3v3_v3(min, max, v->co); - } - } - else { - zero_v3(min); - zero_v3(max); - } -} - - -/* ==== edit mode toggle ==== */ - -int hair_edit_toggle_poll(bContext *C) -{ - Object *ob = CTX_data_active_object(C); - - if (ob == NULL) - return false; - if (!ob->data || ((ID *)ob->data)->lib) - return false; - if (CTX_data_edit_object(C)) - return false; - -#if USE_PARTICLES - return ED_hair_object_has_hair_particle_data(ob); -#else - return ob->type == OB_MESH; -#endif -} - -static void toggle_hair_cursor(bContext *C, bool enable) -{ - wmWindowManager *wm = CTX_wm_manager(C); - Scene *scene = CTX_data_scene(C); - HairEditSettings *settings = &scene->toolsettings->hair_edit; - - if (enable) { - hair_edit_cursor_start(C, hair_edit_toggle_poll); - } - else { - if (settings->paint_cursor) { - WM_paint_cursor_end(wm, settings->paint_cursor); - settings->paint_cursor = NULL; - } - } -} - -static int hair_edit_toggle_exec(bContext *C, wmOperator *op) -{ - Scene *scene = CTX_data_scene(C); - Object *ob = CTX_data_active_object(C); - const int mode_flag = OB_MODE_HAIR_EDIT; - const bool is_mode_set = (ob->mode & mode_flag) != 0; - EvaluationContext eval_ctx; - CTX_data_eval_ctx(C, &eval_ctx); - - if (!is_mode_set) { - if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) { - return OPERATOR_CANCELLED; - } - } - - if (!is_mode_set) { -#if USE_PARTICLES - ED_hair_object_init_particle_edit(&eval_ctx, scene, ob); -#else - ED_hair_object_init_mesh_edit(&eval_ctx, scene, ob); -#endif - ob->mode |= mode_flag; - - toggle_hair_cursor(C, true); - WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_HAIR, NULL); - } - else { -#if USE_PARTICLES - ED_hair_object_apply_particle_edit(ob); -#else - ED_hair_object_apply_mesh_edit(ob); -#endif - ob->mode &= ~mode_flag; - - toggle_hair_cursor(C, false); - WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_HAIR, NULL); - } - - DEG_id_tag_update(&ob->id, OB_RECALC_DATA); - - return OPERATOR_FINISHED; -} - -void HAIR_OT_hair_edit_toggle(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Hair Edit Toggle"; - ot->idname = "HAIR_OT_hair_edit_toggle"; - ot->description = "Toggle hair edit mode"; - - /* api callbacks */ - ot->exec = hair_edit_toggle_exec; - ot->poll = hair_edit_toggle_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - - -/* ==== brush stroke ==== */ - -void hair_init_viewcontext(bContext *C, ViewContext *vc) -{ - View3D *v3d; - bool has_zbuf; - - view3d_set_viewcontext(C, vc); - - v3d = vc->v3d; - has_zbuf = (v3d->drawtype > OB_WIRE) && (v3d->flag & V3D_ZBUF_SELECT); - - if (has_zbuf) { - if (v3d->flag & V3D_INVALID_BACKBUF) { - EvaluationContext eval_ctx; - CTX_data_eval_ctx(C, &eval_ctx); - - /* needed or else the draw matrix can be incorrect */ - view3d_operator_needs_opengl(C); - - ED_view3d_backbuf_validate(&eval_ctx, vc); - /* we may need to force an update here by setting the rv3d as dirty - * for now it seems ok, but take care!: - * rv3d->depths->dirty = 1; */ - ED_view3d_depth_update(vc->ar); - } - } -} - -typedef struct HairStroke { - Scene *scene; - Object *ob; - BMEditStrands *edit; - - bool first; - float lastmouse[2]; - float zfac; - - float smoothdir[2]; -} HairStroke; - -static int hair_stroke_init(bContext *C, wmOperator *op) -{ - Scene *scene = CTX_data_scene(C); - Object *ob = CTX_data_active_object(C); - BMEditStrands *edit = BKE_editstrands_from_object(ob); - ARegion *ar = CTX_wm_region(C); - - HairStroke *stroke; - float min[3], max[3], center[3]; - - /* set the 'distance factor' for grabbing (used in comb etc) */ - hair_bm_min_max(edit, min, max); - mid_v3_v3v3(center, min, max); - - stroke = MEM_callocN(sizeof(HairStroke), "HairStroke"); - stroke->first = true; - op->customdata = stroke; - - stroke->scene = scene; - stroke->ob = ob; - stroke->edit = edit; - - stroke->zfac = ED_view3d_calc_zfac(ar->regiondata, center, NULL); - - return 1; -} - -static bool hair_stroke_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) -{ - HairStroke *stroke = op->customdata; - Scene *scene = stroke->scene; - Object *ob = stroke->ob; - BMEditStrands *edit = stroke->edit; - HairEditSettings *settings = &scene->toolsettings->hair_edit; - ARegion *ar = CTX_wm_region(C); - const float smoothfac = 0.9f; /* XXX should this be configurable? */ - - float mouse[2], mdelta[2], zvec[3], delta_max; - int totsteps, step; - HairToolData tool_data; - bool updated = false; - - RNA_float_get_array(itemptr, "mouse", mouse); - - if (stroke->first) { - copy_v2_v2(stroke->lastmouse, mouse); - zero_v2(stroke->smoothdir); - stroke->first = false; - } - - if (!settings->brush) - return false; - - sub_v2_v2v2(mdelta, mouse, stroke->lastmouse); - delta_max = max_ff(fabsf(mdelta[0]), fabsf(mdelta[1])); - - totsteps = delta_max / (0.2f * BKE_brush_size_get(scene, settings->brush)) + 1; - mul_v2_fl(mdelta, 1.0f / (float)totsteps); - - /* low-pass filter to smooth out jittery pixel increments in the direction */ - interp_v2_v2v2(stroke->smoothdir, mdelta, stroke->smoothdir, smoothfac); - - hair_init_viewcontext(C, &tool_data.vc); - tool_data.scene = scene; - tool_data.ob = ob; - tool_data.edit = edit; - tool_data.settings = settings; - - invert_m4_m4(tool_data.imat, ob->obmat); - copy_v2_v2(tool_data.mval, mouse); - tool_data.mdepth = stroke->zfac; - - zvec[0] = 0.0f; zvec[1] = 0.0f; zvec[2] = stroke->zfac; - ED_view3d_win_to_3d(tool_data.vc.v3d, ar, zvec, mouse, tool_data.loc); - ED_view3d_win_to_delta(ar, stroke->smoothdir, tool_data.delta, stroke->zfac); - /* tools work in object space */ - mul_m4_v3(tool_data.imat, tool_data.loc); - mul_mat3_m4_v3(tool_data.imat, tool_data.delta); - - for (step = 0; step < totsteps; ++step) { - bool step_updated = hair_brush_step(&tool_data); - - if (step_updated) - BKE_editstrands_solve_constraints(ob, edit, NULL); - - updated |= step_updated; - } - - copy_v2_v2(stroke->lastmouse, mouse); - - return updated; -} - -static void hair_stroke_exit(wmOperator *op) -{ - HairStroke *stroke = op->customdata; - MEM_freeN(stroke); -} - -static int hair_stroke_exec(bContext *C, wmOperator *op) -{ - HairStroke *stroke = op->customdata; - Object *ob = stroke->ob; - - bool updated = false; - - if (!hair_stroke_init(C, op)) - return OPERATOR_CANCELLED; - - RNA_BEGIN (op->ptr, itemptr, "stroke") - { - updated |= hair_stroke_apply(C, op, &itemptr); - } - RNA_END; - - if (updated) { - DEG_id_tag_update(&ob->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); - } - - hair_stroke_exit(op); - - return OPERATOR_FINISHED; -} - -static void hair_stroke_apply_event(bContext *C, wmOperator *op, const wmEvent *event) -{ - HairStroke *stroke = op->customdata; - Object *ob = stroke->ob; - - PointerRNA itemptr; - float mouse[2]; - bool updated = false; - - mouse[0] = event->mval[0]; - mouse[1] = event->mval[1]; - - /* fill in stroke */ - RNA_collection_add(op->ptr, "stroke", &itemptr); - - RNA_float_set_array(&itemptr, "mouse", mouse); - - /* apply */ - updated |= hair_stroke_apply(C, op, &itemptr); - - if (updated) { - DEG_id_tag_update(&ob->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); - } - else { - /* even if nothing was changed, still trigger redraw - * for brush drawing during the modal operator - */ - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); - } -} - -static int hair_stroke_invoke(bContext *C, wmOperator *op, const wmEvent *event) -{ - if (!hair_stroke_init(C, op)) - return OPERATOR_CANCELLED; - - hair_stroke_apply_event(C, op, event); - - WM_event_add_modal_handler(C, op); - - return OPERATOR_RUNNING_MODAL; -} - -static int hair_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event) -{ - switch (event->type) { - case LEFTMOUSE: - case MIDDLEMOUSE: - case RIGHTMOUSE: // XXX hardcoded - hair_stroke_exit(op); - return OPERATOR_FINISHED; - case MOUSEMOVE: - hair_stroke_apply_event(C, op, event); - break; - } - - return OPERATOR_RUNNING_MODAL; -} - -static void hair_stroke_cancel(bContext *UNUSED(C), wmOperator *op) -{ - hair_stroke_exit(op); -} - -void HAIR_OT_stroke(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Hair Stroke"; - ot->idname = "HAIR_OT_stroke"; - ot->description = "Use a stroke tool on hair strands"; - - /* api callbacks */ - ot->exec = hair_stroke_exec; - ot->invoke = hair_stroke_invoke; - ot->modal = hair_stroke_modal; - ot->cancel = hair_stroke_cancel; - ot->poll = hair_edit_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; - - /* properties */ - RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", ""); -} diff --git a/source/blender/editors/hair/hair_intern.h b/source/blender/editors/hair/hair_intern.h deleted file mode 100644 index 2a8590d5679..00000000000 --- a/source/blender/editors/hair/hair_intern.h +++ /dev/null @@ -1,115 +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) Blender Foundation - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Lukas Toenne - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/hair/hair_intern.h - * \ingroup edhair - */ - -#ifndef __HAIR_INTERN_H__ -#define __HAIR_INTERN_H__ - -#include "BIF_glutil.h" - -#include "ED_view3d.h" - -struct ARegion; -struct bContext; -struct wmOperatorType; -struct rcti; -struct EvaluationContext; - -struct Object; - -/* hair_edit.c */ -bool hair_use_mirror_x(struct Object *ob); -bool hair_use_mirror_topology(struct Object *ob); - -int hair_edit_toggle_poll(struct bContext *C); -int hair_edit_poll(struct bContext *C); - -void HAIR_OT_hair_edit_toggle(struct wmOperatorType *ot); - -/* hair_select.c */ -void HAIR_OT_select_all(struct wmOperatorType *ot); -void HAIR_OT_select_linked(struct wmOperatorType *ot); - -/* hair_stroke.c */ -void HAIR_OT_stroke(struct wmOperatorType *ot); - -/* hair_object_mesh.c */ -bool ED_hair_object_init_mesh_edit(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob); -bool ED_hair_object_apply_mesh_edit(struct Object *ob); - -/* hair_object_particles.c */ -bool ED_hair_object_has_hair_particle_data(struct Object *ob); -bool ED_hair_object_init_particle_edit(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob); -bool ED_hair_object_apply_particle_edit(struct Object *ob); - - -/* ==== Hair Brush ==== */ - -void hair_init_viewcontext(struct bContext *C, struct ViewContext *vc); - -bool hair_test_depth(struct ViewContext *vc, const float co[3], const int screen_co[2]); -bool hair_test_vertex_inside_circle(struct ViewContext *vc, const float mval[2], float radsq, - struct BMVert *v, float *r_dist); -bool hair_test_edge_inside_circle(struct ViewContext *vc, const float mval[2], float radsq, - struct BMVert *v1, struct BMVert *v2, float *r_dist, float *r_lambda); -bool hair_test_vertex_inside_rect(struct ViewContext *vc, struct rcti *rect, struct BMVert *v); -bool hair_test_vertex_inside_lasso(struct ViewContext *vc, const int mcoords[][2], short moves, struct BMVert *v); - -typedef struct HairToolData { - /* context */ - struct Scene *scene; - struct Object *ob; - struct BMEditStrands *edit; - struct HairEditSettings *settings; - ViewContext vc; - - /* view space */ - float mval[2]; /* mouse coordinates */ - float mdepth; /* mouse z depth */ - - /* object space */ - float imat[4][4]; /* obmat inverse */ - float loc[3]; /* start location */ - float delta[3]; /* stroke step */ -} HairToolData; - -bool hair_brush_step(struct HairToolData *data); - -/* ==== Cursor ==== */ - -void hair_edit_cursor_start(struct bContext *C, int (*poll)(struct bContext *C)); - -/* ==== BMesh utilities ==== */ - -struct BMEditStrands; - -void hair_bm_min_max(struct BMEditStrands *edit, float min[3], float max[3]); - -#endif diff --git a/source/blender/editors/hair/hair_mirror.c b/source/blender/editors/hair/hair_mirror.c deleted file mode 100644 index ee377a3634b..00000000000 --- a/source/blender/editors/hair/hair_mirror.c +++ /dev/null @@ -1,217 +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) Blender Foundation - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Lukas Toenne - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/hair/hair_mirror.c - * \ingroup edhair - */ - -#include <stdlib.h> - -#include "MEM_guardedalloc.h" - -#include "BLI_utildefines.h" -#include "BLI_math.h" - -#include "BKE_editmesh_bvh.h" -#include "BKE_editstrands.h" - -#include "ED_physics.h" -#include "ED_util.h" - -#include "bmesh.h" - -#include "hair_intern.h" - -/* TODO use_topology is not yet implemented for strands. - * Native strand topology is not very useful for this. - * Instead, the topology of the scalp mesh should be used for finding mirrored strand roots, - * then the arc- or parametric length of a vertex from the root to find mirrored verts. - */ - -#define BM_SEARCH_MAXDIST_MIRR 0.00002f -#define BM_CD_LAYER_ID "__mirror_index" -/** - * \param edit Edit strands. - * \param use_self Allow a vertex to point to its self (middle verts). - * \param use_select Restrict to selected verts. - * \param use_topology Use topology mirror. - * \param maxdist Distance for close point test. - * \param r_index Optional array to write into, as an alternative to a customdata layer (length of total verts). - */ -void ED_strands_mirror_cache_begin_ex(BMEditStrands *edit, const int axis, const bool use_self, const bool use_select, - /* extra args */ - const bool UNUSED(use_topology), float maxdist, int *r_index) -{ - BMesh *bm = edit->base.bm; - BMIter iter; - BMVert *v; - int cd_vmirr_offset; - int i; - - /* one or the other is used depending if topo is enabled */ - struct BMBVHTree *tree = NULL; - - BM_mesh_elem_table_ensure(bm, BM_VERT); - - if (r_index == NULL) { - const char *layer_id = BM_CD_LAYER_ID; - int mirror_cdlayer = CustomData_get_named_layer_index(&bm->vdata, CD_PROP_INT, layer_id); - if (mirror_cdlayer == -1) { - BM_data_layer_add_named(bm, &bm->vdata, CD_PROP_INT, layer_id); - mirror_cdlayer = CustomData_get_named_layer_index(&bm->vdata, CD_PROP_INT, layer_id); - } - - cd_vmirr_offset = CustomData_get_n_offset(&bm->vdata, CD_PROP_INT, - mirror_cdlayer - CustomData_get_layer_index(&bm->vdata, CD_PROP_INT)); - - bm->vdata.layers[mirror_cdlayer].flag |= CD_FLAG_TEMPORARY; - - edit->base.mirror_cdlayer = mirror_cdlayer; - } - - BM_mesh_elem_index_ensure(bm, BM_VERT); - - tree = BKE_bmbvh_new(edit->base.bm, NULL, 0, 0, NULL, false); - -#define VERT_INTPTR(_v, _i) r_index ? &r_index[_i] : BM_ELEM_CD_GET_VOID_P(_v, cd_vmirr_offset); - - BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) { - BLI_assert(BM_elem_index_get(v) == i); - - /* temporary for testing, check for selection */ - if (use_select && !BM_elem_flag_test(v, BM_ELEM_SELECT)) { - /* do nothing */ - } - else { - BMVert *v_mirr; - float co[3]; - int *idx = VERT_INTPTR(v, i); - - copy_v3_v3(co, v->co); - co[axis] *= -1.0f; - v_mirr = BKE_bmbvh_find_vert_closest(tree, co, maxdist); - - if (v_mirr && (use_self || (v_mirr != v))) { - const int i_mirr = BM_elem_index_get(v_mirr); - *idx = i_mirr; - idx = VERT_INTPTR(v_mirr, i_mirr); - *idx = i; - } - else { - *idx = -1; - } - } - - } - -#undef VERT_INTPTR - - BKE_bmbvh_free(tree); -} - -void ED_strands_mirror_cache_begin(BMEditStrands *edit, const int axis, - const bool use_self, const bool use_select, - const bool use_topology) -{ - ED_strands_mirror_cache_begin_ex(edit, axis, - use_self, use_select, - /* extra args */ - use_topology, BM_SEARCH_MAXDIST_MIRR, NULL); -} - -BMVert *ED_strands_mirror_get(BMEditStrands *edit, BMVert *v) -{ - BMesh *bm = edit->base.bm; - int mirror_cdlayer = edit->base.mirror_cdlayer; - const int *mirr = CustomData_bmesh_get_layer_n(&bm->vdata, v->head.data, mirror_cdlayer); - - BLI_assert(mirror_cdlayer != -1); /* invalid use */ - - if (mirr && *mirr >= 0 && *mirr < bm->totvert) { - if (!bm->vtable) { - printf("err: should only be called between " - "ED_strands_mirror_cache_begin and ED_strands_mirror_cache_end\n"); - return NULL; - } - - return bm->vtable[*mirr]; - } - - return NULL; -} - -BMEdge *ED_strands_mirror_get_edge(BMEditStrands *edit, BMEdge *e) -{ - BMVert *v1_mirr = ED_strands_mirror_get(edit, e->v1); - if (v1_mirr) { - BMVert *v2_mirr = ED_strands_mirror_get(edit, e->v2); - if (v2_mirr) { - return BM_edge_exists(v1_mirr, v2_mirr); - } - } - - return NULL; -} - -void ED_strands_mirror_cache_clear(BMEditStrands *edit, BMVert *v) -{ - BMesh *bm = edit->base.bm; - int mirror_cdlayer = edit->base.mirror_cdlayer; - int *mirr = CustomData_bmesh_get_layer_n(&bm->vdata, v->head.data, mirror_cdlayer); - - BLI_assert(mirror_cdlayer != -1); /* invalid use */ - - if (mirr) { - *mirr = -1; - } -} - -void ED_strands_mirror_cache_end(BMEditStrands *edit) -{ - edit->base.mirror_cdlayer = -1; -} - -void ED_strands_mirror_apply(BMEditStrands *edit, const int sel_from, const int sel_to) -{ - BMesh *bm = edit->base.bm; - BMIter iter; - BMVert *v; - - BLI_assert((bm->vtable != NULL) && ((bm->elem_table_dirty & BM_VERT) == 0)); - - BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { - if (BM_elem_flag_test(v, BM_ELEM_SELECT) == sel_from) { - BMVert *mirr = ED_strands_mirror_get(edit, v); - if (mirr) { - if (BM_elem_flag_test(mirr, BM_ELEM_SELECT) == sel_to) { - copy_v3_v3(mirr->co, v->co); - mirr->co[0] *= -1.0f; - } - } - } - } -} diff --git a/source/blender/editors/hair/hair_object_mesh.c b/source/blender/editors/hair/hair_object_mesh.c deleted file mode 100644 index 887eed12042..00000000000 --- a/source/blender/editors/hair/hair_object_mesh.c +++ /dev/null @@ -1,86 +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) Blender Foundation - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Lukas Toenne - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/hair/hair_object_mesh.c - * \ingroup edhair - */ - -#include <stdlib.h> - -#include "MEM_guardedalloc.h" - -#include "BLI_utildefines.h" - -#include "DNA_mesh_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" - -#include "BKE_cdderivedmesh.h" -#include "BKE_DerivedMesh.h" -#include "BKE_editstrands.h" - -#include "bmesh.h" - -#include "hair_intern.h" - -bool ED_hair_object_init_mesh_edit(struct EvaluationContext *UNUSED(eval_ctx), Scene *UNUSED(scene), Object *ob) -{ - if (ob->type == OB_MESH) { - Mesh *me = ob->data; - - if (!me->edit_strands) { - BMesh *bm = BKE_editstrands_mesh_to_bmesh(ob, me); - DerivedMesh *root_dm = CDDM_new(0, 0, 0, 0, 0); - - me->edit_strands = BKE_editstrands_create(bm, root_dm); - - root_dm->release(root_dm); - } - return true; - } - - return false; -} - -bool ED_hair_object_apply_mesh_edit(Object *ob) -{ - if (ob->type == OB_MESH) { - Mesh *me = ob->data; - - if (me->edit_strands) { - BKE_editstrands_mesh_from_bmesh(ob); - - BKE_editstrands_free(me->edit_strands); - MEM_freeN(me->edit_strands); - me->edit_strands = NULL; - } - - return true; - } - - return false; -} diff --git a/source/blender/editors/hair/hair_object_particles.c b/source/blender/editors/hair/hair_object_particles.c deleted file mode 100644 index 3aa446db983..00000000000 --- a/source/blender/editors/hair/hair_object_particles.c +++ /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) Blender Foundation - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Lukas Toenne - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/hair/hair_object_particles.c - * \ingroup edhair - */ - -#include <stdlib.h> - -#include "MEM_guardedalloc.h" - -#include "BLI_utildefines.h" - -#include "DNA_mesh_types.h" -#include "DNA_object_types.h" -#include "DNA_particle_types.h" -#include "DNA_scene_types.h" - -#include "BKE_cdderivedmesh.h" -#include "BKE_DerivedMesh.h" -#include "BKE_editstrands.h" -#include "BKE_particle.h" - -#include "bmesh.h" - -#include "hair_intern.h" - -bool ED_hair_object_has_hair_particle_data(Object *ob) -{ - ParticleSystem *psys = psys_get_current(ob); - if (psys && psys->part->type == PART_HAIR) - return true; - - return false; -} - -bool ED_hair_object_init_particle_edit(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob) -{ - ParticleSystem *psys = psys_get_current(ob); - BMesh *bm; - DerivedMesh *dm; - - if (psys && psys->part->type == PART_HAIR) { - if (!psys->hairedit) { - bm = BKE_editstrands_particles_to_bmesh(ob, psys); - - if (ob->type == OB_MESH || ob->derivedFinal) - dm = ob->derivedFinal ? ob->derivedFinal : mesh_get_derived_final(eval_ctx, scene, ob, CD_MASK_BAREMESH); - else - dm = NULL; - - psys->hairedit = BKE_editstrands_create(bm, dm); - } - return true; - } - - return false; -} - -bool ED_hair_object_apply_particle_edit(Object *ob) -{ - ParticleSystem *psys = psys_get_current(ob); - if (psys->part->type == PART_HAIR) { - if (psys->hairedit) { - BKE_editstrands_particles_from_bmesh(ob, psys); - psys->flag |= PSYS_EDITED; - - BKE_editstrands_free(psys->hairedit); - MEM_freeN(psys->hairedit); - psys->hairedit = NULL; - } - - return true; - } - - return false; -} diff --git a/source/blender/editors/hair/hair_ops.c b/source/blender/editors/hair/hair_ops.c deleted file mode 100644 index bb3b027cf20..00000000000 --- a/source/blender/editors/hair/hair_ops.c +++ /dev/null @@ -1,143 +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) Blender Foundation - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Lukas Toenne - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/hair/hair_ops.c - * \ingroup edhair - */ - -#include "BLI_utildefines.h" - -#include "DNA_object_types.h" - -#include "BKE_context.h" - -#include "RNA_access.h" - -#include "WM_api.h" -#include "WM_types.h" - -#include "ED_physics.h" - -#include "hair_intern.h" -#include "paint_intern.h" - -void ED_operatortypes_hair(void) -{ - WM_operatortype_append(HAIR_OT_hair_edit_toggle); - - WM_operatortype_append(HAIR_OT_select_all); - WM_operatortype_append(HAIR_OT_select_linked); - - WM_operatortype_append(HAIR_OT_stroke); -} - -static int hair_poll(bContext *C) -{ - if (hair_edit_toggle_poll(C)) - if (CTX_data_active_object(C)->mode & OB_MODE_HAIR_EDIT) - return true; - - return false; -} - -static void ed_keymap_hair_brush_switch(wmKeyMap *keymap, const char *mode) -{ - wmKeyMapItem *kmi; - int i; - /* index 0-9 (zero key is tenth), shift key for index 10-19 */ - for (i = 0; i < 20; i++) { - kmi = WM_keymap_add_item(keymap, "BRUSH_OT_active_index_set", - ZEROKEY + ((i + 1) % 10), KM_PRESS, i < 10 ? 0 : KM_SHIFT, 0); - RNA_string_set(kmi->ptr, "mode", mode); - RNA_int_set(kmi->ptr, "index", i); - } -} - -static void ed_keymap_hair_brush_size(wmKeyMap *keymap, const char *UNUSED(path)) -{ - wmKeyMapItem *kmi; - - kmi = WM_keymap_add_item(keymap, "BRUSH_OT_scale_size", LEFTBRACKETKEY, KM_PRESS, 0, 0); - RNA_float_set(kmi->ptr, "scalar", 0.9); - - kmi = WM_keymap_add_item(keymap, "BRUSH_OT_scale_size", RIGHTBRACKETKEY, KM_PRESS, 0, 0); - RNA_float_set(kmi->ptr, "scalar", 10.0 / 9.0); // 1.1111.... -} - -static void ed_keymap_hair_brush_radial_control(wmKeyMap *keymap, const char *settings, RCFlags flags) -{ - wmKeyMapItem *kmi; - /* only size needs to follow zoom, strength shows fixed size circle */ - int flags_nozoom = flags & (~RC_ZOOM); - int flags_noradial_secondary = flags & (~(RC_SECONDARY_ROTATION | RC_ZOOM)); - - kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, 0, 0); - set_brush_rc_props(kmi->ptr, settings, "size", "use_unified_size", flags); - - kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0); - set_brush_rc_props(kmi->ptr, settings, "strength", "use_unified_strength", flags_nozoom); - - if (flags & RC_WEIGHT) { - kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", WKEY, KM_PRESS, 0, 0); - set_brush_rc_props(kmi->ptr, settings, "weight", "use_unified_weight", flags_nozoom); - } - - if (flags & RC_ROTATION) { - kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, KM_CTRL, 0); - set_brush_rc_props(kmi->ptr, settings, "texture_slot.angle", NULL, flags_noradial_secondary); - } - - if (flags & RC_SECONDARY_ROTATION) { - kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, KM_CTRL | KM_ALT, 0); - set_brush_rc_props(kmi->ptr, settings, "mask_texture_slot.angle", NULL, flags_nozoom); - } -} - -void ED_keymap_hair(wmKeyConfig *keyconf) -{ - wmKeyMap *keymap; - wmKeyMapItem *kmi; - - keymap = WM_keymap_find(keyconf, "Hair", 0, 0); - keymap->poll = hair_poll; - - kmi = WM_keymap_add_item(keymap, "HAIR_OT_select_all", AKEY, KM_PRESS, 0, 0); - RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE); - kmi = WM_keymap_add_item(keymap, "HAIR_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0); - RNA_enum_set(kmi->ptr, "action", SEL_INVERT); - - kmi = WM_keymap_add_item(keymap, "HAIR_OT_select_linked", LKEY, KM_PRESS, 0, 0); - RNA_boolean_set(kmi->ptr, "deselect", false); - kmi = WM_keymap_add_item(keymap, "HAIR_OT_select_linked", LKEY, KM_PRESS, KM_SHIFT, 0); - RNA_boolean_set(kmi->ptr, "deselect", true); - - kmi = WM_keymap_add_item(keymap, "HAIR_OT_stroke", LEFTMOUSE, KM_PRESS, 0, 0); - - ed_keymap_hair_brush_switch(keymap, "hair_edit"); - ed_keymap_hair_brush_size(keymap, "tool_settings.hair_edit.brush.size"); - ed_keymap_hair_brush_radial_control(keymap, "hair_edit", 0); -} diff --git a/source/blender/editors/hair/hair_select.c b/source/blender/editors/hair/hair_select.c deleted file mode 100644 index 90ccfcabd0d..00000000000 --- a/source/blender/editors/hair/hair_select.c +++ /dev/null @@ -1,506 +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) Blender Foundation - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Lukas Toenne - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/hair/hair_select.c - * \ingroup edhair - */ - -#include <stdlib.h> - -#include "MEM_guardedalloc.h" - -#include "BLI_utildefines.h" -#include "BLI_math.h" -#include "BLI_rect.h" - -#include "DNA_object_types.h" -#include "DNA_scene_types.h" -#include "DNA_screen_types.h" -#include "DNA_view3d_types.h" - -#include "BKE_context.h" -#include "BKE_editstrands.h" - -#include "DEG_depsgraph.h" - -#include "bmesh.h" - -#include "RNA_access.h" -#include "RNA_define.h" - -#include "WM_api.h" -#include "WM_types.h" - -#include "ED_object.h" -#include "ED_physics.h" -#include "ED_view3d.h" - -#include "hair_intern.h" - -BLI_INLINE bool apply_select_action_flag(BMVert *v, int action) -{ - bool cursel = BM_elem_flag_test_bool(v, BM_ELEM_SELECT); - bool newsel; - - switch (action) { - case SEL_SELECT: - newsel = true; - break; - case SEL_DESELECT: - newsel = false; - break; - case SEL_INVERT: - newsel = !cursel; - break; - case SEL_TOGGLE: - /* toggle case should be converted to SELECT or DESELECT based on global state */ - BLI_assert(false); - break; - } - - if (newsel != cursel) { - BM_elem_flag_set(v, BM_ELEM_SELECT, newsel); - return true; - } - else - return false; -} - -/* poll function */ -typedef bool (*PollVertexCb)(void *userdata, struct BMVert *v); -/* distance metric function */ -typedef bool (*DistanceVertexCb)(void *userdata, struct BMVert *v, float *dist); -typedef void (*ActionVertexCb)(void *userdata, struct BMVert *v, int action); - -static int hair_select_verts_filter(bContext *C, Object *ob, BMEditStrands *edit, - HairEditSelectMode select_mode, int action, - PollVertexCb cb, void *userdata) -{ - BMesh *bm = edit->base.bm; - - BMVert *v; - BMIter iter; - int tot = 0; - - bm->selectmode = BM_VERT; - - switch (select_mode) { - case HAIR_SELECT_STRAND: - break; - case HAIR_SELECT_VERTEX: - BM_ITER_MESH(v, &iter, bm, BM_VERTS_OF_MESH) { - if (!cb(userdata, v)) - continue; - - if (apply_select_action_flag(v, action)) - ++tot; - } - break; - case HAIR_SELECT_TIP: - BM_ITER_MESH(v, &iter, bm, BM_VERTS_OF_MESH) { - if (!BM_strands_vert_is_tip(v)) - continue; - if (!cb(userdata, v)) - continue; - - if (apply_select_action_flag(v, action)) - ++tot; - } - break; - } - - BM_mesh_select_mode_flush(bm); - - if (tot > 0) { - BKE_editstrands_batch_cache_dirty(edit, BKE_STRANDS_BATCH_DIRTY_SELECT); - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data); - } - - return tot; -} - -static bool hair_select_verts_closest(bContext *C, Object *ob, BMEditStrands *edit, HairEditSelectMode select_mode, int action, DistanceVertexCb cb, ActionVertexCb action_cb, void *userdata) -{ - BMesh *bm = edit->base.bm; - - BMVert *v; - BMIter iter; - - float dist; - BMVert *closest_v = NULL; - float closest_dist = FLT_MAX; - - bm->selectmode = BM_VERT; - - switch (select_mode) { - case HAIR_SELECT_STRAND: - break; - case HAIR_SELECT_VERTEX: - BM_ITER_MESH(v, &iter, bm, BM_VERTS_OF_MESH) { - if (!cb(userdata, v, &dist)) - continue; - - if (dist < closest_dist) { - closest_v = v; - closest_dist = dist; - } - } - break; - case HAIR_SELECT_TIP: - BM_ITER_MESH(v, &iter, bm, BM_VERTS_OF_MESH) { - if (!BM_strands_vert_is_tip(v)) - continue; - if (!cb(userdata, v, &dist)) - continue; - - if (dist < closest_dist) { - closest_v = v; - closest_dist = dist; - } - } - break; - } - - if (closest_v) { - action_cb(userdata, closest_v, action); - - BM_mesh_select_mode_flush(bm); - - BKE_editstrands_batch_cache_dirty(edit, BKE_STRANDS_BATCH_DIRTY_SELECT); - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data); - - return true; - } - else - return false; -} - -static void hair_deselect_all(BMEditStrands *edit) -{ - BMesh *bm = edit->base.bm; - - BMVert *v; - BMIter iter; - - BM_ITER_MESH(v, &iter, bm, BM_VERTS_OF_MESH) { - BM_elem_flag_set(v, BM_ELEM_SELECT, false); - } -} - -/* ------------------------------------------------------------------------- */ - -/************************ select/deselect all operator ************************/ - -static bool poll_vertex_all(void *UNUSED(userdata), struct BMVert *UNUSED(v)) -{ - return true; -} - -static int select_all_exec(bContext *C, wmOperator *op) -{ - Scene *scene = CTX_data_scene(C); - Object *ob = CTX_data_active_object(C); - BMEditStrands *edit = BKE_editstrands_from_object(ob); - HairEditSettings *settings = &scene->toolsettings->hair_edit; - int action = RNA_enum_get(op->ptr, "action"); - - if (!edit) - return 0; - - /* toggle action depends on current global selection state */ - if (action == SEL_TOGGLE) { - if (edit->base.bm->totvertsel == 0) - action = SEL_SELECT; - else - action = SEL_DESELECT; - } - - hair_select_verts_filter(C, ob, edit, settings->select_mode, action, poll_vertex_all, NULL); - - return OPERATOR_FINISHED; -} - -void HAIR_OT_select_all(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Select/Deselect All"; - ot->idname = "HAIR_OT_select_all"; - ot->description = "Select/Deselect all hair vertices"; - - /* api callbacks */ - ot->exec = select_all_exec; - ot->poll = hair_edit_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - WM_operator_properties_select_all(ot); -} - -/************************ mouse select operator ************************/ - -typedef struct DistanceVertexCirleData { - ViewContext vc; - float mval[2]; - float radsq; -} DistanceVertexCirleData; - -static bool distance_vertex_circle(void *userdata, struct BMVert *v, float *dist) -{ - DistanceVertexCirleData *data = userdata; - - return hair_test_vertex_inside_circle(&data->vc, data->mval, data->radsq, v, dist); -} - -static void closest_vertex_select(void *UNUSED(userdata), struct BMVert *v, int action) -{ - apply_select_action_flag(v, action); -} - -int ED_hair_mouse_select(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle) -{ - Scene *scene = CTX_data_scene(C); - Object *ob = CTX_data_active_object(C); - BMEditStrands *edit = BKE_editstrands_from_object(ob); - HairEditSettings *settings = &scene->toolsettings->hair_edit; - float select_radius = ED_view3d_select_dist_px(); - - DistanceVertexCirleData data; - int action; - - if (!extend && !deselect && !toggle) { - hair_deselect_all(edit); - } - - hair_init_viewcontext(C, &data.vc); - data.mval[0] = mval[0]; - data.mval[1] = mval[1]; - data.radsq = select_radius * select_radius; - - if (extend) - action = SEL_SELECT; - else if (deselect) - action = SEL_DESELECT; - else - action = SEL_INVERT; - - hair_select_verts_closest(C, ob, edit, settings->select_mode, action, distance_vertex_circle, closest_vertex_select, &data); - - return OPERATOR_FINISHED; -} - -/************************ select linked operator ************************/ - -static void linked_vertices_select(void *UNUSED(userdata), struct BMVert *v, int action) -{ - BMVert *lv; - - apply_select_action_flag(v, action); - - for (lv = BM_strands_vert_prev(v); lv; lv = BM_strands_vert_prev(lv)) - apply_select_action_flag(lv, action); - for (lv = BM_strands_vert_next(v); lv; lv = BM_strands_vert_next(lv)) - apply_select_action_flag(lv, action); -} - -static int select_linked_exec(bContext *C, wmOperator *op) -{ - Scene *scene = CTX_data_scene(C); - Object *ob = CTX_data_active_object(C); - BMEditStrands *edit = BKE_editstrands_from_object(ob); - HairEditSettings *settings = &scene->toolsettings->hair_edit; - float select_radius = ED_view3d_select_dist_px(); - - DistanceVertexCirleData data; - int location[2]; - int action; - - RNA_int_get_array(op->ptr, "location", location); - - hair_init_viewcontext(C, &data.vc); - data.mval[0] = location[0]; - data.mval[1] = location[1]; - data.radsq = select_radius * select_radius; - - action = RNA_boolean_get(op->ptr, "deselect") ? SEL_DESELECT : SEL_SELECT; - - hair_select_verts_closest(C, ob, edit, settings->select_mode, action, distance_vertex_circle, linked_vertices_select, &data); - - return OPERATOR_FINISHED; -} - -static int select_linked_invoke(bContext *C, wmOperator *op, const wmEvent *event) -{ - RNA_int_set_array(op->ptr, "location", event->mval); - return select_linked_exec(C, op); -} - -void HAIR_OT_select_linked(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Select Linked"; - ot->idname = "HAIR_OT_select_linked"; - ot->description = "Select connected vertices"; - - /* api callbacks */ - ot->exec = select_linked_exec; - ot->invoke = select_linked_invoke; - ot->poll = hair_edit_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* properties */ - RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Deselect linked keys rather than selecting them"); - RNA_def_int_vector(ot->srna, "location", 2, NULL, 0, INT_MAX, "Location", "", 0, 16384); -} - -/************************ border select operator ************************/ - -typedef struct PollVertexRectData { - ViewContext vc; - rcti rect; -} PollVertexRectData; - -static bool poll_vertex_inside_rect(void *userdata, struct BMVert *v) -{ - PollVertexRectData *data = userdata; - - return hair_test_vertex_inside_rect(&data->vc, &data->rect, v); -} - -int ED_hair_border_select(bContext *C, rcti *rect, bool select, bool extend) -{ - Scene *scene = CTX_data_scene(C); - Object *ob = CTX_data_active_object(C); - BMEditStrands *edit = BKE_editstrands_from_object(ob); - HairEditSettings *settings = &scene->toolsettings->hair_edit; - - PollVertexRectData data; - int action; - - if (!extend && select) - hair_deselect_all(edit); - - hair_init_viewcontext(C, &data.vc); - data.rect = *rect; - - if (extend) - action = SEL_SELECT; - else if (select) - action = SEL_INVERT; - else - action = SEL_DESELECT; - - hair_select_verts_filter(C, ob, edit, settings->select_mode, action, poll_vertex_inside_rect, &data); - - return OPERATOR_FINISHED; -} - -/************************ circle select operator ************************/ - -typedef struct PollVertexCirleData { - ViewContext vc; - float mval[2]; - float radsq; -} PollVertexCirleData; - -static bool poll_vertex_inside_circle(void *userdata, struct BMVert *v) -{ - PollVertexCirleData *data = userdata; - float dist; - - return hair_test_vertex_inside_circle(&data->vc, data->mval, data->radsq, v, &dist); -} - -int ED_hair_circle_select(bContext *C, bool select, const int mval[2], float radius) -{ - Scene *scene = CTX_data_scene(C); - Object *ob = CTX_data_active_object(C); - BMEditStrands *edit = BKE_editstrands_from_object(ob); - HairEditSettings *settings = &scene->toolsettings->hair_edit; - int action = select ? SEL_SELECT : SEL_DESELECT; - - PollVertexCirleData data; - int tot; - - if (!edit) - return 0; - - hair_init_viewcontext(C, &data.vc); - data.mval[0] = mval[0]; - data.mval[1] = mval[1]; - data.radsq = radius * radius; - - tot = hair_select_verts_filter(C, ob, edit, settings->select_mode, action, poll_vertex_inside_circle, &data); - - return tot; -} - -/************************ lasso select operator ************************/ - -typedef struct PollVertexLassoData { - ViewContext vc; - const int (*mcoords)[2]; - short moves; -} PollVertexLassoData; - -static bool poll_vertex_inside_lasso(void *userdata, struct BMVert *v) -{ - PollVertexLassoData *data = userdata; - - return hair_test_vertex_inside_lasso(&data->vc, data->mcoords, data->moves, v); -} - -int ED_hair_lasso_select(bContext *C, const int mcoords[][2], const short moves, bool extend, bool select) -{ - Scene *scene = CTX_data_scene(C); - Object *ob = CTX_data_active_object(C); - BMEditStrands *edit = BKE_editstrands_from_object(ob); - HairEditSettings *settings = &scene->toolsettings->hair_edit; - - PollVertexLassoData data; - int action; - - if (!extend && select) - hair_deselect_all(edit); - - hair_init_viewcontext(C, &data.vc); - data.mcoords = mcoords; - data.moves = moves; - - if (extend) - action = SEL_SELECT; - else if (select) - action = SEL_INVERT; - else - action = SEL_DESELECT; - - hair_select_verts_filter(C, ob, edit, settings->select_mode, action, poll_vertex_inside_lasso, &data); - - return OPERATOR_FINISHED; -} diff --git a/source/blender/editors/hair/hair_stroke.c b/source/blender/editors/hair/hair_stroke.c deleted file mode 100644 index a2ffb160067..00000000000 --- a/source/blender/editors/hair/hair_stroke.c +++ /dev/null @@ -1,501 +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) Blender Foundation - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Lukas Toenne - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/hair/hair_edit.c - * \ingroup edhair - */ - -#include <stdlib.h> - -#include "MEM_guardedalloc.h" - -#include "BLI_utildefines.h" -#include "BLI_lasso.h" -#include "BLI_math.h" -#include "BLI_rect.h" - -#include "DNA_brush_types.h" -#include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" -#include "DNA_view3d_types.h" - -#include "BKE_brush.h" -#include "BKE_DerivedMesh.h" -#include "BKE_editstrands.h" -#include "BKE_effect.h" -#include "BKE_mesh_sample.h" - -#include "bmesh.h" - -#include "BIF_gl.h" -#include "BIF_glutil.h" - -#include "ED_physics.h" -#include "ED_view3d.h" - -#include "hair_intern.h" - -bool hair_test_depth(ViewContext *vc, const float co[3], const int screen_co[2]) -{ - View3D *v3d = vc->v3d; - ViewDepths *vd = vc->rv3d->depths; - const bool has_zbuf = (v3d->drawtype > OB_WIRE) && (v3d->flag & V3D_ZBUF_SELECT); - - float uco[3]; - float depth; - - /* nothing to do */ - if (!has_zbuf) - return true; - - ED_view3d_project(vc->ar, co, uco); - - /* check if screen_co is within bounds because brush_cut uses out of screen coords */ - if (screen_co[0] >= 0 && screen_co[0] < vd->w && screen_co[1] >= 0 && screen_co[1] < vd->h) { - BLI_assert(vd && vd->depths); - /* we know its not clipped */ - depth = vd->depths[screen_co[1] * vd->w + screen_co[0]]; - - return ((float)uco[2] - 0.00001f <= depth); - } - - return false; -} - -bool hair_test_vertex_inside_circle(ViewContext *vc, const float mval[2], float radsq, BMVert *v, float *r_dist) -{ - float (*obmat)[4] = vc->obact->obmat; - float co_world[3]; - float dx, dy, distsq; - int screen_co[2]; - - mul_v3_m4v3(co_world, obmat, v->co); - - /* TODO, should this check V3D_PROJ_TEST_CLIP_BB too? */ - if (ED_view3d_project_int_global(vc->ar, co_world, screen_co, V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_OK) - return false; - - dx = mval[0] - (float)screen_co[0]; - dy = mval[1] - (float)screen_co[1]; - distsq = dx * dx + dy * dy; - - if (distsq > radsq) - return false; - - if (hair_test_depth(vc, v->co, screen_co)) { - *r_dist = sqrtf(distsq); - return true; - } - else - return false; -} - -bool hair_test_edge_inside_circle(ViewContext *vc, const float mval[2], float radsq, BMVert *v1, BMVert *v2, float *r_dist, float *r_lambda) -{ - float (*obmat)[4] = vc->obact->obmat; - float world_co1[3], world_co2[3]; - float dx, dy, distsq; - int screen_co1[2], screen_co2[2], screen_cp[2]; - float lambda, world_cp[3], screen_cpf[2], screen_co1f[2], screen_co2f[2]; - - mul_v3_m4v3(world_co1, obmat, v1->co); - mul_v3_m4v3(world_co2, obmat, v2->co); - - /* TODO, should this check V3D_PROJ_TEST_CLIP_BB too? */ - if (ED_view3d_project_int_global(vc->ar, world_co1, screen_co1, V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_OK) - return false; - if (ED_view3d_project_int_global(vc->ar, world_co2, screen_co2, V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_OK) - return false; - - screen_co1f[0] = screen_co1[0]; - screen_co1f[1] = screen_co1[1]; - screen_co2f[0] = screen_co2[0]; - screen_co2f[1] = screen_co2[1]; - lambda = closest_to_line_v2(screen_cpf, mval, screen_co1f, screen_co2f); - if (lambda < 0.0f || lambda > 1.0f) { - CLAMP(lambda, 0.0f, 1.0f); - interp_v2_v2v2(screen_cpf, screen_co1f, screen_co2f, lambda); - } - - dx = mval[0] - screen_cpf[0]; - dy = mval[1] - screen_cpf[1]; - distsq = dx * dx + dy * dy; - - if (distsq > radsq) - return false; - - interp_v3_v3v3(world_cp, world_co1, world_co2, lambda); - - screen_cp[0] = screen_cpf[0]; - screen_cp[1] = screen_cpf[1]; - if (hair_test_depth(vc, world_cp, screen_cp)) { - *r_dist = sqrtf(distsq); - *r_lambda = lambda; - return true; - } - else - return false; -} - -bool hair_test_vertex_inside_rect(ViewContext *vc, rcti *rect, BMVert *v) -{ - float (*obmat)[4] = vc->obact->obmat; - float co_world[3]; - int screen_co[2]; - - mul_v3_m4v3(co_world, obmat, v->co); - - /* TODO, should this check V3D_PROJ_TEST_CLIP_BB too? */ - if (ED_view3d_project_int_global(vc->ar, co_world, screen_co, V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_OK) - return false; - - if (!BLI_rcti_isect_pt_v(rect, screen_co)) - return false; - - if (hair_test_depth(vc, v->co, screen_co)) - return true; - else - return false; -} - -bool hair_test_vertex_inside_lasso(ViewContext *vc, const int mcoords[][2], short moves, BMVert *v) -{ - float (*obmat)[4] = vc->obact->obmat; - float co_world[3]; - int screen_co[2]; - - mul_v3_m4v3(co_world, obmat, v->co); - - /* TODO, should this check V3D_PROJ_TEST_CLIP_BB too? */ - if (ED_view3d_project_int_global(vc->ar, co_world, screen_co, V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_OK) - return false; - - if (!BLI_lasso_is_point_inside(mcoords, moves, screen_co[0], screen_co[1], IS_CLIPPED)) - return false; - - if (hair_test_depth(vc, v->co, screen_co)) - return true; - else - return false; -} - -/* ------------------------------------------------------------------------- */ - -typedef void (*VertexToolCb)(HairToolData *data, void *userdata, BMVert *v, float factor); - -/* apply tool directly to each vertex inside the filter area */ -static int UNUSED_FUNCTION(hair_tool_apply_vertex)(HairToolData *data, VertexToolCb cb, void *userdata) -{ - BMesh *bm = data->edit->base.bm; - Scene *scene = data->scene; - Brush *brush = data->settings->brush; - const float rad = BKE_brush_size_get(scene, brush); - const float radsq = rad*rad; - const float threshold = 0.0f; /* XXX could be useful, is it needed? */ - const bool use_mirror = hair_use_mirror_x(data->ob); - - BMVert *v, *v_mirr; - BMIter iter; - int tot = 0; - float dist, factor; - - if (use_mirror) - ED_strands_mirror_cache_begin(data->edit, 0, false, false, hair_use_mirror_topology(data->ob)); - - BM_ITER_MESH(v, &iter, bm, BM_VERTS_OF_MESH) { - if (!hair_test_vertex_inside_circle(&data->vc, data->mval, radsq, v, &dist)) - continue; - - factor = 1.0f - dist / rad; - if (factor > threshold) { - cb(data, userdata, v, factor); - ++tot; - - if (use_mirror) { - v_mirr = ED_strands_mirror_get(data->edit, v); - if (v_mirr) - cb(data, userdata, v_mirr, factor); - } - } - } - - /* apply mirror */ - if (use_mirror) - ED_strands_mirror_cache_end(data->edit); - - return tot; -} - -/* ------------------------------------------------------------------------- */ - -typedef void (*EdgeToolCb)(HairToolData *data, void *userdata, BMVert *v1, BMVert *v2, float factor, float edge_param); - -static int hair_tool_apply_strand_edges(HairToolData *data, EdgeToolCb cb, void *userdata, BMVert *root) -{ - Scene *scene = data->scene; - Brush *brush = data->settings->brush; - const float rad = BKE_brush_size_get(scene, brush); - const float radsq = rad*rad; - const float threshold = 0.0f; /* XXX could be useful, is it needed? */ - const bool use_mirror = hair_use_mirror_x(data->ob); - - BMVert *v, *v_mirr, *vprev, *vprev_mirr; - BMIter iter; - int k; - int tot = 0; - - BM_ITER_STRANDS_ELEM_INDEX(v, &iter, root, BM_VERTS_OF_STRAND, k) { - if (use_mirror) - v_mirr = ED_strands_mirror_get(data->edit, v); - - if (k > 0) { - float dist, lambda; - - if (hair_test_edge_inside_circle(&data->vc, data->mval, radsq, vprev, v, &dist, &lambda)) { - float factor = 1.0f - dist / rad; - if (factor > threshold) { - cb(data, userdata, vprev, v, factor, lambda); - ++tot; - - if (use_mirror) { - if (vprev_mirr && v_mirr) - cb(data, userdata, vprev_mirr, v_mirr, factor, lambda); - } - } - } - } - - vprev = v; - vprev_mirr = v_mirr; - } - - return tot; -} - -/* apply tool to vertices of edges inside the filter area, - * using the closest edge point for weighting - */ -static int hair_tool_apply_edge(HairToolData *data, EdgeToolCb cb, void *userdata) -{ - BMesh *bm = data->edit->base.bm; - BMVert *root; - BMIter iter; - int tot = 0; - - if (hair_use_mirror_x(data->ob)) - ED_strands_mirror_cache_begin(data->edit, 0, false, false, hair_use_mirror_topology(data->ob)); - - BM_ITER_STRANDS(root, &iter, bm, BM_STRANDS_OF_MESH) { - tot += hair_tool_apply_strand_edges(data, cb, userdata, root); - } - - /* apply mirror */ - if (hair_use_mirror_x(data->ob)) - ED_strands_mirror_cache_end(data->edit); - - return tot; -} - -/* ------------------------------------------------------------------------- */ - -typedef struct CombData { - float power; -} CombData; - -static void UNUSED_FUNCTION(hair_vertex_comb)(HairToolData *data, void *userdata, BMVert *v, float factor) -{ - CombData *combdata = userdata; - - float combfactor = powf(factor, combdata->power); - - madd_v3_v3fl(v->co, data->delta, combfactor); -} - -/* Edge-based combing tool: - * Unlike the vertex tool (which simply displaces vertices), the edge tool - * adjusts edge orientations to follow the stroke direction. - */ -static void hair_edge_comb(HairToolData *data, void *userdata, BMVert *v1, BMVert *v2, float factor, float UNUSED(edge_param)) -{ - CombData *combdata = userdata; - float strokedir[3], edge[3], edgedir[3], strokelen, edgelen; - float edge_proj[3]; - - float combfactor = powf(factor, combdata->power); - float effect; - - strokelen = normalize_v3_v3(strokedir, data->delta); - - sub_v3_v3v3(edge, v2->co, v1->co); - edgelen = normalize_v3_v3(edgedir, edge); - if (edgelen == 0.0f) - return; - - /* This factor prevents sudden changes in direction with small stroke lengths. - * The arctan maps the 0..inf range of the length ratio to 0..1 smoothly. - */ - effect = atan(strokelen / edgelen * 4.0f / (0.5f*M_PI)); - - mul_v3_v3fl(edge_proj, strokedir, edgelen); - - interp_v3_v3v3(edge, edge, edge_proj, combfactor * effect); - - add_v3_v3v3(v2->co, v1->co, edge); -} - - -BLI_INLINE void construct_m4_loc_nor_tan(float mat[4][4], const float loc[3], const float nor[3], const float tang[3]) -{ - float cotang[3]; - - cross_v3_v3v3(cotang, nor, tang); - - copy_v3_v3(mat[0], tang); - copy_v3_v3(mat[1], cotang); - copy_v3_v3(mat[2], nor); - copy_v3_v3(mat[3], loc); - mat[0][3] = 0.0f; - mat[1][3] = 0.0f; - mat[2][3] = 0.0f; - mat[3][3] = 1.0f; -} - -static void grow_hair(BMEditStrands *edit, MeshSample *sample) -{ - BMesh *bm = edit->base.bm; - DerivedMesh *dm = edit->root_dm; - const float len = 1.5f; - - float root_mat[4][4]; - BMVert *root, *v; - BMIter iter; - int i; - - { - float co[3], nor[3], tang[3]; - BKE_mesh_sample_eval(dm, sample, co, nor, tang); - construct_m4_loc_nor_tan(root_mat, co, nor, tang); - } - - root = BM_strands_create(bm, 5, true); - - BM_elem_meshsample_data_named_set(&bm->vdata, root, CD_MSURFACE_SAMPLE, CD_HAIR_ROOT_LOCATION, sample); - - BM_ITER_STRANDS_ELEM_INDEX(v, &iter, root, BM_VERTS_OF_STRAND, i) { - float co[3]; - - co[0] = co[1] = 0.0f; - co[2] = len * (float)i / (float)(len - 1); - - mul_m4_v3(root_mat, co); - - copy_v3_v3(v->co, co); - } - - BM_mesh_elem_index_ensure(bm, BM_ALL); -} - -static bool hair_add_ray_cb(void *vdata, void *UNUSED(thread_ctx), float ray_start[3], float ray_end[3]) -{ - HairToolData *data = vdata; - ViewContext *vc = &data->vc; - - ED_view3d_win_to_segment(vc->ar, vc->v3d, data->mval, ray_start, ray_end, true); - - mul_m4_v3(data->imat, ray_start); - mul_m4_v3(data->imat, ray_end); - - return true; -} - -static bool hair_get_surface_sample(HairToolData *data, MeshSample *sample) -{ - DerivedMesh *dm = data->edit->root_dm; - - MeshSampleGenerator *gen; - bool ok; - - gen = BKE_mesh_sample_gen_surface_raycast(NULL, NULL, hair_add_ray_cb, data); - BKE_mesh_sample_generator_bind(gen, dm); - ok = BKE_mesh_sample_generate(gen, sample); - BKE_mesh_sample_free_generator(gen); - - return ok; -} - -static bool hair_add(HairToolData *data) -{ - MeshSample sample; - - if (!hair_get_surface_sample(data, &sample)) - return false; - - grow_hair(data->edit, &sample); - - return true; -} - - -bool hair_brush_step(HairToolData *data) -{ - Brush *brush = data->settings->brush; - BrushHairTool hair_tool = brush->hair_tool; - BMEditStrands *edit = data->edit; - int tot = 0; - - switch (hair_tool) { - case HAIR_TOOL_COMB: { - CombData combdata; - combdata.power = (brush->alpha - 0.5f) * 2.0f; - if (combdata.power < 0.0f) - combdata.power = 1.0f - 9.0f * combdata.power; - else - combdata.power = 1.0f - combdata.power; - - tot = hair_tool_apply_edge(data, hair_edge_comb, &combdata); - break; - } - case HAIR_TOOL_CUT: - break; - case HAIR_TOOL_LENGTH: - break; - case HAIR_TOOL_PUFF: - break; - case HAIR_TOOL_ADD: - if (hair_add(data)) - edit->flag |= BM_STRANDS_DIRTY_SEGLEN; - break; - case HAIR_TOOL_SMOOTH: - break; - case HAIR_TOOL_WEIGHT: - break; - } - - return tot > 0; -} diff --git a/source/blender/editors/hair/hair_undo.c b/source/blender/editors/hair/hair_undo.c deleted file mode 100644 index cb5ae43f5dd..00000000000 --- a/source/blender/editors/hair/hair_undo.c +++ /dev/null @@ -1,195 +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) Blender Foundation - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Lukas Toenne - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/hair/hair_undo.c - * \ingroup edhair - */ - -#include <stdlib.h> - -#include "MEM_guardedalloc.h" - -#include "BLI_utildefines.h" - -#include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" -#include "DNA_view3d_types.h" - -#include "BKE_context.h" -#include "BKE_DerivedMesh.h" -#include "BKE_editstrands.h" -#include "BKE_key.h" -#include "BKE_mesh.h" -#include "BKE_mesh_sample.h" - -#include "ED_physics.h" -#include "ED_util.h" - -#include "bmesh.h" - -#include "hair_intern.h" - -static void *strands_get_edit(bContext *C) -{ - Object *obact = CTX_data_active_object(C); - const int mode_flag = OB_MODE_HAIR_EDIT; - const bool is_mode_set = ((obact->mode & mode_flag) != 0); - - if (obact && is_mode_set) { - BMEditStrands *edit = BKE_editstrands_from_object(obact); - return edit; - } - return NULL; -} - -typedef struct UndoStrands { - Mesh me; /* Mesh supports all the customdata we need, easiest way to implement undo storage */ - int selectmode; - - /** \note - * this isn't a prefect solution, if you edit keys and change shapes this works well (fixing [#32442]), - * but editing shape keys, going into object mode, removing or changing their order, - * then go back into editmode and undo will give issues - where the old index will be out of sync - * with the new object index. - * - * There are a few ways this could be made to work but for now its a known limitation with mixing - * object and editmode operations - Campbell */ - int shapenr; -} UndoStrands; - -/* undo simply makes copies of a bmesh */ -static void *strands_edit_to_undo(void *editv, void *UNUSED(obdata)) -{ - BMEditStrands *edit = editv; - BMesh *bm = edit->base.bm; -// Mesh *obme = obdata; - struct BMeshToMeshParams params = {0}; - - UndoStrands *undo = MEM_callocN(sizeof(UndoStrands), "undo Strands"); - - /* make sure shape keys work */ -// um->me.key = obme->key ? BKE_key_copy_nolib(obme->key) : NULL; - - /* BM_mesh_validate(em->bm); */ /* for troubleshooting */ - - params.cd_mask_extra = CD_MASK_STRANDS; - BM_mesh_bm_to_me(bm, &undo->me, ¶ms); - - undo->selectmode = bm->selectmode; - undo->shapenr = bm->shapenr; - - return undo; -} - -static void strands_undo_to_edit(void *undov, void *editv, void *UNUSED(obdata)) -{ - UndoStrands *undo = undov; - BMEditStrands *edit = editv, *edit_tmp; - Object *ob = edit->base.ob; - DerivedMesh *dm = edit->root_dm; - BMesh *bm; -// Key *key = ((Mesh *) obdata)->key; - struct BMeshFromMeshParams params = {0}; - - const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(&undo->me); - - edit->base.bm->shapenr = undo->shapenr; - - bm = BM_mesh_create(&allocsize, - &((struct BMeshCreateParams){.use_toolflags = false,})); - params.cd_mask_extra = CD_MASK_STRANDS_BMESH; - params.active_shapekey = undo->shapenr; - BM_mesh_bm_from_me(bm, &undo->me, ¶ms); - - /* note: have to create the new edit before freeing the old one, - * because it owns the root_dm and we have to copy it before - * it gets released when freeing the old edit. - */ - edit_tmp = BKE_editstrands_create(bm, dm); - BKE_editstrands_free(edit); - *edit = *edit_tmp; - - bm->selectmode = undo->selectmode; - edit->base.ob = ob; - -#if 0 - /* 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)) { - /* Since we can't add, remove or reorder keyblocks in editmode, it's safe to assume - * shapenr from restored bmesh and keyblock indices are in sync. */ - const int kb_act_idx = ob->shapenr - 1; - - /* If it is, let's patch the current mesh key block to its restored value. - * Else, the offsets won't be computed and it won't matter. */ - if (BKE_keyblock_is_basis(key, kb_act_idx)) { - KeyBlock *kb_act = BLI_findlink(&key->block, kb_act_idx); - - if (kb_act->totelem != undo->me.totvert) { - /* The current mesh has some extra/missing verts compared to the undo, adjust. */ - MEM_SAFE_FREE(kb_act->data); - kb_act->data = MEM_mallocN((size_t)(key->elemsize * bm->totvert), __func__); - kb_act->totelem = undo->me.totvert; - } - - BKE_keyblock_update_from_mesh(&undo->me, kb_act); - } - } -#endif - - ob->shapenr = undo->shapenr; - - MEM_freeN(edit_tmp); -} - -static void strands_free_undo(void *undov) -{ - UndoStrands *undo = undov; - - if (undo->me.key) { - BKE_key_free(undo->me.key); - MEM_freeN(undo->me.key); - } - - BKE_mesh_free(&undo->me); - MEM_freeN(undo); -} - -/* and this is all the undo system needs to know */ -void undo_push_strands(bContext *C, const char *name) -{ - /* edit->ob gets out of date and crashes on mesh undo, - * this is an easy way to ensure its OK - * though we could investigate the matter further. */ - Object *obact = CTX_data_active_object(C); - BMEditStrands *edit = BKE_editstrands_from_object(obact); - edit->base.ob = obact; - - undo_editmode_push(C, name, CTX_data_active_object, strands_get_edit, strands_free_undo, strands_undo_to_edit, strands_edit_to_undo, NULL); -} diff --git a/source/blender/editors/include/ED_datafiles.h b/source/blender/editors/include/ED_datafiles.h index 5e2c6bb8c44..661ab58b98c 100644 --- a/source/blender/editors/include/ED_datafiles.h +++ b/source/blender/editors/include/ED_datafiles.h @@ -165,27 +165,6 @@ extern char datatoc_twist_png[]; extern int datatoc_vertexdraw_png_size; extern char datatoc_vertexdraw_png[]; -extern int datatoc_haircomb_png_size; -extern char datatoc_haircomb_png[]; - -extern int datatoc_haircut_png_size; -extern char datatoc_haircut_png[]; - -extern int datatoc_hairlength_png_size; -extern char datatoc_hairlength_png[]; - -extern int datatoc_hairpuff_png_size; -extern char datatoc_hairpuff_png[]; - -extern int datatoc_hairadd_png_size; -extern char datatoc_hairadd_png[]; - -extern int datatoc_hairsmooth_png_size; -extern char datatoc_hairsmooth_png[]; - -extern int datatoc_hairweight_png_size; -extern char datatoc_hairweight_png[]; - /* Matcap files */ extern int datatoc_mc01_jpg_size; diff --git a/source/blender/editors/include/ED_physics.h b/source/blender/editors/include/ED_physics.h index f805aff386d..fed842c969e 100644 --- a/source/blender/editors/include/ED_physics.h +++ b/source/blender/editors/include/ED_physics.h @@ -35,13 +35,9 @@ struct bContext; struct ReportList; struct wmKeyConfig; -struct ViewContext; -struct rcti; -struct Main; struct Scene; struct Object; -struct BMEditStrands; /* particle_edit.c */ int PE_poll(struct bContext *C); @@ -60,28 +56,5 @@ void ED_rigidbody_constraint_remove(struct Main *bmain, struct Scene *scene, str void ED_operatortypes_physics(void); void ED_keymap_physics(struct wmKeyConfig *keyconf); -/* hair edit */ -void undo_push_strands(struct bContext *C, const char *name); - -void ED_strands_mirror_cache_begin_ex(struct BMEditStrands *edit, const int axis, - const bool use_self, const bool use_select, - const bool use_topology, float maxdist, int *r_index); -void ED_strands_mirror_cache_begin(struct BMEditStrands *edit, const int axis, - const bool use_self, const bool use_select, - const bool use_topology); -void ED_strands_mirror_apply(struct BMEditStrands *edit, const int sel_from, const int sel_to); -struct BMVert *ED_strands_mirror_get(struct BMEditStrands *edit, struct BMVert *v); -struct BMEdge *ED_strands_mirror_get_edge(struct BMEditStrands *edit, struct BMEdge *e); -void ED_strands_mirror_cache_clear(struct BMEditStrands *edit, struct BMVert *v); -void ED_strands_mirror_cache_end(struct BMEditStrands *edit); - -int ED_hair_mouse_select(struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle); -int ED_hair_border_select(struct bContext *C, struct rcti *rect, bool select, bool extend); -int ED_hair_circle_select(struct bContext *C, bool select, const int mval[2], float radius); -int ED_hair_lasso_select(struct bContext *C, const int mcoords[][2], short moves, bool extend, bool select); - -void ED_operatortypes_hair(void); -void ED_keymap_hair(struct wmKeyConfig *keyconf); - #endif /* __ED_PHYSICS_H__ */ diff --git a/source/blender/editors/include/ED_util.h b/source/blender/editors/include/ED_util.h index 70075767c9a..60c4b3593aa 100644 --- a/source/blender/editors/include/ED_util.h +++ b/source/blender/editors/include/ED_util.h @@ -32,8 +32,6 @@ #define __ED_UTIL_H__ struct bContext; -struct PackedFile; -struct ScrArea; struct SpaceLink; struct wmOperator; struct wmOperatorType; @@ -74,7 +72,6 @@ bool ED_undo_is_valid(const struct bContext *C, const char *undoname); /* undo_editmode.c */ void undo_editmode_push(struct bContext *C, const char *name, - struct Object *(*get_object)(const struct bContext * C), void * (*getdata)(struct bContext *C), void (*freedata)(void *), void (*to_editmode)(void *, void *, void *), diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h index 9d889f71051..0c83038b7a3 100644 --- a/source/blender/editors/include/UI_icons.h +++ b/source/blender/editors/include/UI_icons.h @@ -977,13 +977,6 @@ DEF_ICON(BRUSH_TEXMASK) DEF_ICON(BRUSH_THUMB) DEF_ICON(BRUSH_ROTATE) DEF_ICON(BRUSH_VERTEXDRAW) -DEF_ICON(BRUSH_HAIR_COMB) -DEF_ICON(BRUSH_HAIR_CUT) -DEF_ICON(BRUSH_HAIR_LENGTH) -DEF_ICON(BRUSH_HAIR_PUFF) -DEF_ICON(BRUSH_HAIR_ADD) -DEF_ICON(BRUSH_HAIR_SMOOTH) -DEF_ICON(BRUSH_HAIR_WEIGHT) /* Matcaps */ DEF_ICON(MATCAP_01) diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index 25c2511884b..d048324d35e 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -415,13 +415,6 @@ static void init_brush_icons(void) INIT_BRUSH_ICON(ICON_BRUSH_THUMB, thumb); INIT_BRUSH_ICON(ICON_BRUSH_ROTATE, twist); INIT_BRUSH_ICON(ICON_BRUSH_VERTEXDRAW, vertexdraw); - INIT_BRUSH_ICON(ICON_BRUSH_HAIR_COMB, haircomb); - INIT_BRUSH_ICON(ICON_BRUSH_HAIR_CUT, haircut); - INIT_BRUSH_ICON(ICON_BRUSH_HAIR_LENGTH, hairlength); - INIT_BRUSH_ICON(ICON_BRUSH_HAIR_PUFF, hairpuff); - INIT_BRUSH_ICON(ICON_BRUSH_HAIR_ADD, hairadd); - INIT_BRUSH_ICON(ICON_BRUSH_HAIR_SMOOTH, hairsmooth); - INIT_BRUSH_ICON(ICON_BRUSH_HAIR_WEIGHT, hairweight); #undef INIT_BRUSH_ICON } @@ -1216,8 +1209,6 @@ static int ui_id_brush_get_icon(const bContext *C, ID *id) mode = OB_MODE_VERTEX_PAINT; else if (ob->mode & OB_MODE_TEXTURE_PAINT) mode = OB_MODE_TEXTURE_PAINT; - else if (ob->mode & OB_MODE_HAIR_EDIT) - mode = OB_MODE_HAIR_EDIT; } else if ((sima = CTX_wm_space_image(C)) && (sima->mode == SI_MODE_PAINT)) @@ -1238,10 +1229,6 @@ static int ui_id_brush_get_icon(const bContext *C, ID *id) items = rna_enum_brush_image_tool_items; tool = br->imagepaint_tool; } - else if (mode == OB_MODE_HAIR_EDIT) { - items = brush_hair_tool_items; - tool = br->hair_tool; - } if (!items || !RNA_enum_icon_from_value(items, tool, &id->icon_id)) id->icon_id = 0; diff --git a/source/blender/editors/mesh/editmesh_undo.c b/source/blender/editors/mesh/editmesh_undo.c index a35f70caef3..534ca22178e 100644 --- a/source/blender/editors/mesh/editmesh_undo.c +++ b/source/blender/editors/mesh/editmesh_undo.c @@ -665,5 +665,5 @@ void undo_push_mesh(bContext *C, const char *name) BMEditMesh *em = BKE_editmesh_from_object(obedit); em->ob = obedit; - undo_editmode_push(C, name, CTX_data_edit_object, getEditMesh, free_undo, undoMesh_to_editbtMesh, editbtMesh_to_undoMesh, NULL); + undo_editmode_push(C, name, getEditMesh, free_undo, undoMesh_to_editbtMesh, editbtMesh_to_undoMesh, NULL); } diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c index a43e5f1a92c..175b40d72ff 100644 --- a/source/blender/editors/metaball/mball_edit.c +++ b/source/blender/editors/metaball/mball_edit.c @@ -752,5 +752,5 @@ static void *get_data(bContext *C) /* this is undo system for MetaBalls */ void undo_push_mball(bContext *C, const char *name) { - undo_editmode_push(C, name, CTX_data_edit_object, get_data, free_undoMball, undoMball_to_editMball, editMball_to_undoMball, NULL); + undo_editmode_push(C, name, get_data, free_undoMball, undoMball_to_editMball, editMball_to_undoMball, NULL); } diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt index 69c897359e6..8050508983b 100644 --- a/source/blender/editors/object/CMakeLists.txt +++ b/source/blender/editors/object/CMakeLists.txt @@ -49,7 +49,6 @@ set(SRC object_edit.c object_facemap_ops.c object_group.c - object_hair.c object_hook.c object_lattice.c object_lod.c diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index a0a4ad751d1..bbe5c274537 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -1415,7 +1415,7 @@ 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_MODE_HAIR_EDIT) && (ob->type == OB_MESH)) || + OB_MODE_WEIGHT_PAINT, OB_MODE_TEXTURE_PAINT) && (ob->type == OB_MESH)) || (input->value == OB_MODE_OBJECT)) { RNA_enum_item_add(&item, &totitem, input); @@ -1457,8 +1457,6 @@ static const char *object_mode_op_string(int mode) return "PAINT_OT_texture_paint_toggle"; if (mode == OB_MODE_PARTICLE_EDIT) return "PARTICLE_OT_particle_edit_toggle"; - if (mode == OB_MODE_HAIR_EDIT) - return "HAIR_OT_hair_edit_toggle"; if (mode == OB_MODE_POSE) return "OBJECT_OT_posemode_toggle"; if (mode == OB_MODE_GPENCIL) @@ -1480,7 +1478,7 @@ static bool object_mode_compat_test(Object *ob, eObjectMode mode) switch (ob->type) { case OB_MESH: if (mode & (OB_MODE_EDIT | OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | - OB_MODE_TEXTURE_PAINT | OB_MODE_PARTICLE_EDIT | OB_MODE_HAIR_EDIT)) + OB_MODE_TEXTURE_PAINT | OB_MODE_PARTICLE_EDIT)) { return true; } diff --git a/source/blender/editors/object/object_hair.c b/source/blender/editors/object/object_hair.c deleted file mode 100644 index b5bcdbb5a3c..00000000000 --- a/source/blender/editors/object/object_hair.c +++ /dev/null @@ -1,117 +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) Blender Foundation - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Lukas Toenne - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/object/object_hair.c - * \ingroup edobj - */ - -#include "MEM_guardedalloc.h" - -#include "BLI_utildefines.h" - -#include "DNA_hair_types.h" -#include "DNA_modifier_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" - -#include "RNA_access.h" -#include "RNA_define.h" - -#include "BKE_context.h" -#include "BKE_DerivedMesh.h" -#include "BKE_hair.h" -#include "DEG_depsgraph.h" - -#include "ED_object.h" - -#include "WM_api.h" -#include "WM_types.h" - -#include "object_intern.h" - -/************************ Hair Follicle Generation Operator *********************/ - -static int hair_follicles_generate_poll(bContext *C) -{ - return edit_modifier_poll_generic(C, &RNA_HairModifier, 0); -} - -static int hair_follicles_generate_exec(bContext *C, wmOperator *op) -{ - Scene *scene = CTX_data_scene(C); - Object *ob = ED_object_active_context(C); - HairModifierData *hmd = (HairModifierData *)edit_modifier_property_get(op, ob, eModifierType_Hair); - EvaluationContext eval_ctx; - CTX_data_eval_ctx(C, &eval_ctx); - - if (!hmd) - return OPERATOR_CANCELLED; - - CustomDataMask mask = CD_MASK_BAREMESH; - DerivedMesh *scalp = mesh_get_derived_final(&eval_ctx, scene, ob, mask); - if (!scalp) - return OPERATOR_CANCELLED; - - int count = RNA_int_get(op->ptr, "count"); - unsigned int seed = RNA_int_get(op->ptr, "seed"); - - BKE_hair_follicles_generate(hmd->hair, scalp, count, seed); - - DEG_id_tag_update(&ob->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); - return OPERATOR_FINISHED; -} - -static int hair_follicles_generate_invoke(bContext *C, wmOperator *op, const wmEvent *event) -{ - if (edit_modifier_invoke_properties(C, op)) { - return WM_operator_props_popup_confirm(C, op, event); - } - else { - return OPERATOR_CANCELLED; - } -} - -void OBJECT_OT_hair_follicles_generate(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Generate Hair Follicles"; - ot->description = "Generate hair follicle data"; - ot->idname = "OBJECT_OT_hair_follicles_generate"; - - /* api callbacks */ - ot->poll = hair_follicles_generate_poll; - ot->invoke = hair_follicles_generate_invoke; - ot->exec = hair_follicles_generate_exec; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; - - edit_modifier_properties(ot); - RNA_def_int(ot->srna, "count", 1000, 0, INT_MAX, "Count", "Number of hair follicles to generate", 1, 1000000); - RNA_def_int(ot->srna, "seed", 0, 0, INT_MAX, "Seed", "Seed value for randomization", 0, INT_MAX); -} diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index fe68adf1362..3e655fa04a4 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -286,8 +286,5 @@ void TRANSFORM_OT_vertex_random(struct wmOperatorType *ot); void OBJECT_OT_data_transfer(struct wmOperatorType *ot); void OBJECT_OT_datalayout_transfer(struct wmOperatorType *ot); -/* object_hair.c */ -void OBJECT_OT_hair_follicles_generate(struct wmOperatorType *ot); - #endif /* __OBJECT_INTERN_H__ */ diff --git a/source/blender/editors/object/object_lattice.c b/source/blender/editors/object/object_lattice.c index 83408988960..557e0a0eccf 100644 --- a/source/blender/editors/object/object_lattice.c +++ b/source/blender/editors/object/object_lattice.c @@ -982,6 +982,6 @@ static void *get_editlatt(bContext *C) /* and this is all the undo system needs to know */ void undo_push_lattice(bContext *C, const char *name) { - undo_editmode_push(C, name, CTX_data_edit_object, get_editlatt, free_undoLatt, undoLatt_to_editLatt, editLatt_to_undoLatt, validate_undoLatt); + undo_editmode_push(C, name, get_editlatt, free_undoLatt, undoLatt_to_editLatt, editLatt_to_undoLatt, validate_undoLatt); } diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 66e54c1436b..07922f2d3b2 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -260,8 +260,6 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_data_transfer); WM_operatortype_append(OBJECT_OT_datalayout_transfer); WM_operatortype_append(OBJECT_OT_surfacedeform_bind); - - WM_operatortype_append(OBJECT_OT_hair_follicles_generate); } void ED_operatormacros_object(void) diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c index 219c990ba03..b8575b2da2a 100644 --- a/source/blender/editors/screen/screen_context.c +++ b/source/blender/editors/screen/screen_context.c @@ -73,7 +73,7 @@ const char *screen_context_dir[] = { "visible_pose_bones", "selected_pose_bones", "active_bone", "active_pose_bone", "active_base", "active_object", "object", "edit_object", "sculpt_object", "vertex_paint_object", "weight_paint_object", - "image_paint_object", "particle_edit_object", "hair_edit_object", + "image_paint_object", "particle_edit_object", "sequences", "selected_sequences", "selected_editable_sequences", /* sequencer */ "gpencil_data", "gpencil_data_owner", /* grease pencil data */ "visible_gpencil_layers", "editable_gpencil_layers", "editable_gpencil_strokes", @@ -400,12 +400,6 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult return 1; } - else if (CTX_data_equals(member, "hair_edit_object")) { - if (obact && (obact->mode & OB_MODE_HAIR_EDIT)) - CTX_data_id_pointer_set(result, &obact->id); - - return 1; - } else if (CTX_data_equals(member, "sequences")) { Editing *ed = BKE_sequencer_editing_get(scene, false); if (ed) { diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index f9a35c10e54..40210d63566 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -44,7 +44,6 @@ #include "ED_screen.h" #include "ED_image.h" #include "UI_resources.h" -#include "UI_interface.h" #include "WM_api.h" #include "WM_types.h" @@ -61,40 +60,20 @@ #include <stddef.h> /* Brush operators */ - static int brush_add_exec(bContext *C, wmOperator *UNUSED(op)) { /*int type = RNA_enum_get(op->ptr, "type");*/ + Paint *paint = BKE_paint_get_active_from_context(C); + Brush *br = BKE_paint_brush(paint); Main *bmain = CTX_data_main(C); ePaintMode mode = BKE_paintmode_get_active_from_context(C); - Scene *scene = CTX_data_scene(C); - Object *ob = CTX_data_active_object(C); - Paint *paint = NULL; - HairEditSettings *hair_edit = NULL; - Brush *br = NULL; - - /* get active brush context */ - if (ob->mode == OB_MODE_HAIR_EDIT) { - hair_edit = &scene->toolsettings->hair_edit; - br = hair_edit->brush; - } - else { - paint = BKE_paint_get_active_from_context(C); - br = BKE_paint_brush(paint); - } - + if (br) br = BKE_brush_copy(bmain, br); else br = BKE_brush_add(bmain, "Brush", BKE_paint_object_mode_from_paint_mode(mode)); - /* set new brush pointer in the context */ - if (ob->mode == OB_MODE_HAIR_EDIT) { - hair_edit->brush = br; - } - else { - BKE_paint_brush_set(paint, br); - } + BKE_paint_brush_set(paint, br); return OPERATOR_FINISHED; } @@ -117,20 +96,11 @@ static void BRUSH_OT_add(wmOperatorType *ot) static int brush_scale_size_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Object *ob = CTX_data_active_object(C); - Brush *brush; + Paint *paint = BKE_paint_get_active_from_context(C); + Brush *brush = BKE_paint_brush(paint); + // Object *ob = CTX_data_active_object(C); float scalar = RNA_float_get(op->ptr, "scalar"); - /* get active brush context */ - if (ob->mode == OB_MODE_HAIR_EDIT) { - HairEditSettings *hair_edit = &scene->toolsettings->hair_edit; - brush = hair_edit->brush; - } - else { - Paint *paint = BKE_paint_get_active_from_context(C); - brush = BKE_paint_brush(paint); - } - if (brush) { // pixel radius { @@ -440,7 +410,7 @@ static int brush_select_exec(bContext *C, wmOperator *op) Object *ob = CTX_data_active_object(C); if (ob) { /* select current paint mode */ - paint_mode = ob->mode & OB_MODE_ALL_BRUSH; + paint_mode = ob->mode & OB_MODE_ALL_PAINT; } else { return OPERATOR_CANCELLED; diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c index fa7dcc27c0a..32f6ac40d12 100644 --- a/source/blender/editors/space_api/spacetypes.c +++ b/source/blender/editors/space_api/spacetypes.c @@ -107,7 +107,6 @@ void ED_spacetypes_init(void) ED_operatortypes_anim(); ED_operatortypes_animchannels(); ED_operatortypes_gpencil(); - ED_operatortypes_hair(); ED_operatortypes_object(); ED_operatortypes_mesh(); ED_operatortypes_sculpt(); @@ -195,7 +194,6 @@ void ED_spacetypes_keymap(wmKeyConfig *keyconf) ED_keymap_anim(keyconf); ED_keymap_animchannels(keyconf); ED_keymap_gpencil(keyconf); - ED_keymap_hair(keyconf); ED_keymap_object(keyconf); /* defines lattice also */ ED_keymap_mesh(keyconf); ED_keymap_uvedit(keyconf); diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt index 6bf0d142aa4..db79d578b5d 100644 --- a/source/blender/editors/space_view3d/CMakeLists.txt +++ b/source/blender/editors/space_view3d/CMakeLists.txt @@ -48,7 +48,6 @@ set(SRC drawmesh.c drawobject.c drawsimdebug.c - drawstrands.c drawvolume.c space_view3d.c view3d_buttons.c diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index c1ae28cab94..e75c353a34d 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -59,7 +59,6 @@ #include "BKE_DerivedMesh.h" #include "BKE_deform.h" #include "BKE_displist.h" -#include "BKE_editstrands.h" #include "BKE_font.h" #include "BKE_global.h" #include "BKE_image.h" @@ -4229,7 +4228,7 @@ static void draw_em_fancy_new(Scene *UNUSED(scene), ARegion *UNUSED(ar), View3D void draw_mesh_object_outline(View3D *v3d, Object *ob, DerivedMesh *dm, const unsigned char ob_wire_col[4]) /* LEGACY */ { if ((v3d->transp == false) && /* not when we draw the transparent pass */ - (ob->mode & OB_MODE_ALL_BRUSH) == false) /* not when painting (its distracting) - campbell */ + (ob->mode & OB_MODE_ALL_PAINT) == false) /* not when painting (its distracting) - campbell */ { glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f); glDepthMask(GL_FALSE); @@ -8750,7 +8749,7 @@ void draw_object( if (!skip_object) { /* draw outline for selected objects, mesh does itself */ if ((v3d->flag & V3D_SELECT_OUTLINE) && !render_override && ob->type != OB_MESH) { - if (dt > OB_WIRE && (ob->mode & (OB_MODE_EDIT | OB_MODE_HAIR_EDIT)) == 0 && (dflag & DRAW_SCENESET) == 0) { + if (dt > OB_WIRE && (ob->mode & OB_MODE_EDIT) == 0 && (dflag & DRAW_SCENESET) == 0) { if (!(ob->dtx & OB_DRAWWIRE) && (base->flag & BASE_SELECTED) && !(dflag & (DRAW_PICKING | DRAW_CONSTCOLOR))) { draw_object_selected_outline(eval_ctx, scene, sl, v3d, ar, base, ob_wire_col); } @@ -8941,16 +8940,14 @@ afterdraw: view3d_cached_text_draw_begin(); for (psys = ob->particlesystem.first; psys; psys = psys->next) { - if (!(ob->mode & OB_MODE_HAIR_EDIT)) { - /* run this so that possible child particles get cached */ - if (ob->mode & OB_MODE_PARTICLE_EDIT && is_obact) { - PTCacheEdit *edit = PE_create_current(eval_ctx, scene, ob); - if (edit && edit->psys == psys) - draw_update_ptcache_edit(eval_ctx, scene, sl, ob, edit); - } - - draw_new_particle_system(eval_ctx, scene, v3d, rv3d, base, psys, dt, dflag); + /* run this so that possible child particles get cached */ + if (ob->mode & OB_MODE_PARTICLE_EDIT && is_obact) { + PTCacheEdit *edit = PE_create_current(eval_ctx, scene, ob); + if (edit && edit->psys == psys) + draw_update_ptcache_edit(eval_ctx, scene, sl, ob, edit); } + + draw_new_particle_system(eval_ctx, scene, v3d, rv3d, base, psys, dt, dflag); } invert_m4_m4(ob->imat, ob->obmat); view3d_cached_text_draw_end(v3d, ar, 0); @@ -8974,13 +8971,6 @@ afterdraw: gpuMultMatrix(ob->obmat); } } - - if (ob->mode & OB_MODE_HAIR_EDIT && is_obact) { - BMEditStrands *edit = BKE_editstrands_from_object(ob); - if (edit) { - draw_strands_edit_hair(scene, v3d, ar, edit); - } - } } /* draw code for smoke, only draw domains */ @@ -9169,7 +9159,7 @@ afterdraw: } /* object centers, need to be drawn in viewmat space for speed, but OK for picking select */ - if (!is_obact || !(ob->mode & OB_MODE_ALL_BRUSH)) { + if (!is_obact || !(ob->mode & OB_MODE_ALL_PAINT)) { int do_draw_center = -1; /* defines below are zero or positive... */ if (render_override) { diff --git a/source/blender/editors/space_view3d/drawstrands.c b/source/blender/editors/space_view3d/drawstrands.c deleted file mode 100644 index dd37e4144f5..00000000000 --- a/source/blender/editors/space_view3d/drawstrands.c +++ /dev/null @@ -1,382 +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): Lukas Toenne. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/space_view3d/drawstrands.c - * \ingroup spview3d - */ - -#include "BLI_utildefines.h" -#include "BLI_math.h" - -#include "DNA_object_types.h" -#include "DNA_scene_types.h" -#include "DNA_view3d_types.h" - -#include "BKE_editstrands.h" -#include "BKE_main.h" - -#include "bmesh.h" - -#include "ED_screen.h" -#include "ED_types.h" - -#include "UI_resources.h" -#include "UI_interface_icons.h" - -#include "BIF_gl.h" -#include "BIF_glutil.h" - -#include "GPU_draw.h" -#include "GPU_extensions.h" -#include "GPU_select.h" - -#include "view3d_intern.h" - -typedef enum StrandsShadeMode { - STRANDS_SHADE_FLAT, - STRANDS_SHADE_HAIR, -} StrandsShadeMode; - -typedef struct StrandsDrawInfo { - bool has_zbuf; - bool use_zbuf_select; - - StrandsShadeMode shade_mode; - int select_mode; - - float col_base[4]; - float col_select[4]; -} StrandsDrawInfo; - -BLI_INLINE bool strands_use_normals(const StrandsDrawInfo *info) -{ - return ELEM(info->shade_mode, STRANDS_SHADE_HAIR); -} - -static void init_draw_info(StrandsDrawInfo *info, View3D *v3d, - StrandsShadeMode shade_mode, int select_mode) -{ - info->has_zbuf = v3d->zbuf; - info->use_zbuf_select = (v3d->flag & V3D_ZBUF_SELECT); - - info->shade_mode = shade_mode; - info->select_mode = select_mode; - - /* get selection theme colors */ - UI_GetThemeColor4fv(TH_VERTEX, info->col_base); - UI_GetThemeColor4fv(TH_VERTEX_SELECT, info->col_select); -} - -static void set_opengl_state_strands(const StrandsDrawInfo *info) -{ - if (!info->use_zbuf_select) - glDisable(GL_DEPTH_TEST); - glEnable(GL_BLEND); - - if (ELEM(info->shade_mode, STRANDS_SHADE_HAIR)) { - glEnable(GL_LIGHTING); - glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); - glEnable(GL_COLOR_MATERIAL); - glShadeModel(GL_SMOOTH); - } - else { - glDisable(GL_LIGHTING); - } - - glEnableClientState(GL_VERTEX_ARRAY); - if (strands_use_normals(info)) - glEnableClientState(GL_NORMAL_ARRAY); -} - -static void set_opengl_state_dots(const StrandsDrawInfo *info) -{ - if (!info->use_zbuf_select) - glDisable(GL_DEPTH_TEST); - glEnable(GL_BLEND); - - glDisable(GL_LIGHTING); - - glEnableClientState(GL_VERTEX_ARRAY); - glPointSize(3.0); -} - -static void restore_opengl_state(const StrandsDrawInfo *info) -{ - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - - glDisable(GL_BLEND); - glDisable(GL_LIGHTING); - glDisable(GL_COLOR_MATERIAL); - glShadeModel(GL_FLAT); - if (info->has_zbuf) - glEnable(GL_DEPTH_TEST); - glLineWidth(1.0f); - glPointSize(1.0); -} - -/* ------------------------------------------------------------------------- */ -/* strands */ - -static void setup_gpu_buffers_strands(BMEditStrands *edit, const StrandsDrawInfo *info) -{ - const size_t size_v3 = sizeof(float) * 3; - const size_t size_vertex = (strands_use_normals(info) ? 2*size_v3 : size_v3); - BMesh *bm = edit->base.bm; - -// int totstrands = BM_strands_count(edit->bm); - int totvert = bm->totvert; - int totedge = bm->totedge; - - if (!edit->vertex_glbuf) - glGenBuffers(1, &edit->vertex_glbuf); - if (!edit->elem_glbuf) - glGenBuffers(1, &edit->elem_glbuf); - - glBindBuffer(GL_ARRAY_BUFFER, edit->vertex_glbuf); - glBufferData(GL_ARRAY_BUFFER, size_vertex * totvert, NULL, GL_DYNAMIC_DRAW); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, edit->elem_glbuf); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * totedge * 2, NULL, GL_DYNAMIC_DRAW); - - glVertexPointer(3, GL_FLOAT, size_vertex, NULL); - if (strands_use_normals(info)) - glNormalPointer(GL_FLOAT, size_vertex, (GLubyte *)NULL + size_v3); -} - -static void unbind_gpu_buffers_strands(void) -{ - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); -} - -static int write_gpu_buffers_strands(BMEditStrands *edit, const StrandsDrawInfo *info) -{ - const size_t size_v3 = sizeof(float) * 3; - const size_t size_vertex = (strands_use_normals(info) ? 2*size_v3 : size_v3); - BMesh *bm = edit->base.bm; - - GLubyte *vertex_data; - unsigned int *elem_data; - BMVert *root, *v, *vprev; - BMIter iter, iter_strand; - int index, indexprev, index_edge; - int k; - - vertex_data = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); - elem_data = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); - if (!vertex_data || !elem_data) - return 0; - - BM_mesh_elem_index_ensure(bm, BM_VERT); - - index_edge = 0; - BM_ITER_STRANDS(root, &iter, bm, BM_STRANDS_OF_MESH) { - BM_ITER_STRANDS_ELEM_INDEX(v, &iter_strand, root, BM_VERTS_OF_STRAND, k) { - size_t offset_co; - - index = BM_elem_index_get(v); - - offset_co = index * size_vertex; - copy_v3_v3((float *)(vertex_data + offset_co), v->co); - - if (k > 0) { - if (strands_use_normals(info)) { - size_t offset_nor = offset_co + size_v3; - float nor[3]; - sub_v3_v3v3(nor, v->co, vprev->co); - normalize_v3(nor); - copy_v3_v3((float *)(vertex_data + offset_nor), nor); - - if (k == 1) { - /* define root normal: same as first segment */ - size_t offset_root_nor = indexprev * size_vertex + size_v3; - copy_v3_v3((float *)(vertex_data + offset_root_nor), nor); - } - } - - { - elem_data[index_edge + 0] = indexprev; - elem_data[index_edge + 1] = index; - index_edge += 2; - } - } - - vprev = v; - indexprev = index; - } - } - - glUnmapBuffer(GL_ARRAY_BUFFER); - glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); - - return index_edge; -} - -/* ------------------------------------------------------------------------- */ -/* dots */ - -static void setup_gpu_buffers_dots(BMEditStrands *edit, const StrandsDrawInfo *info, bool selected) -{ - const size_t size_v3 = sizeof(float) * 3; - const size_t size_vertex = size_v3; - BMesh *bm = edit->base.bm; - - BMVert *v; - BMIter iter; - int totvert; - - switch (info->select_mode) { - case HAIR_SELECT_STRAND: - totvert = 0; - break; - case HAIR_SELECT_VERTEX: - totvert = selected ? bm->totvertsel : bm->totvert - bm->totvertsel; - break; - case HAIR_SELECT_TIP: - totvert = 0; - BM_ITER_MESH(v, &iter, bm, BM_VERTS_OF_MESH) { - if (BM_elem_flag_test_bool(v, BM_ELEM_SELECT) != selected) - continue; - if (!BM_strands_vert_is_tip(v)) - continue; - - ++totvert; - } - break; - } - - if (totvert == 0) - return; - - if (!edit->dot_glbuf) - glGenBuffers(1, &edit->dot_glbuf); - - glBindBuffer(GL_ARRAY_BUFFER, edit->dot_glbuf); - glBufferData(GL_ARRAY_BUFFER, size_vertex * totvert, NULL, GL_DYNAMIC_DRAW); - - glVertexPointer(3, GL_FLOAT, size_vertex, NULL); -} - -static void unbind_gpu_buffers_dots(void) -{ - glBindBuffer(GL_ARRAY_BUFFER, 0); -} - -static int write_gpu_buffers_dots(BMEditStrands *edit, const StrandsDrawInfo *info, bool selected) -{ - const size_t size_v3 = sizeof(float) * 3; - const size_t size_vertex = size_v3; - BMesh *bm = edit->base.bm; - - GLubyte *vertex_data; - BMVert *v; - BMIter iter; - int index_dot; - - if (info->select_mode == HAIR_SELECT_STRAND) - return 0; - - vertex_data = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); - if (!vertex_data) - return 0; - - BM_mesh_elem_index_ensure(bm, BM_VERT); - - index_dot = 0; - switch (info->select_mode) { - case HAIR_SELECT_STRAND: - /* already exited, but keep the case for the compiler */ - break; - case HAIR_SELECT_VERTEX: - BM_ITER_MESH(v, &iter, bm, BM_VERTS_OF_MESH) { - size_t offset_co; - - if (BM_elem_flag_test_bool(v, BM_ELEM_SELECT) != selected) - continue; - - offset_co = index_dot * size_vertex; - copy_v3_v3((float *)(vertex_data + offset_co), v->co); - ++index_dot; - } - break; - case HAIR_SELECT_TIP: - BM_ITER_MESH(v, &iter, bm, BM_VERTS_OF_MESH) { - size_t offset_co; - - if (BM_elem_flag_test_bool(v, BM_ELEM_SELECT) != selected) - continue; - if (!BM_strands_vert_is_tip(v)) - continue; - - offset_co = index_dot * size_vertex; - copy_v3_v3((float *)(vertex_data + offset_co), v->co); - ++index_dot; - } - break; - } - - glUnmapBuffer(GL_ARRAY_BUFFER); - - return index_dot; -} - -/* ------------------------------------------------------------------------- */ - -static void draw_dots(BMEditStrands *edit, const StrandsDrawInfo *info, bool selected) -{ - int totelem; - - if (selected) - glColor3fv(info->col_select); - else - glColor3fv(info->col_base); - - setup_gpu_buffers_dots(edit, info, selected); - totelem = write_gpu_buffers_dots(edit, info, selected); - if (totelem > 0) - glDrawArrays(GL_POINTS, 0, totelem); -} - -void draw_strands_edit_hair(Scene *scene, View3D *v3d, ARegion *UNUSED(ar), BMEditStrands *edit) -{ - HairEditSettings *settings = &scene->toolsettings->hair_edit; - - StrandsDrawInfo info; - int totelem; - - init_draw_info(&info, v3d, STRANDS_SHADE_HAIR, settings->select_mode); - - set_opengl_state_strands(&info); - setup_gpu_buffers_strands(edit, &info); - totelem = write_gpu_buffers_strands(edit, &info); - if (totelem > 0) - glDrawElements(GL_LINES, totelem, GL_UNSIGNED_INT, NULL); - unbind_gpu_buffers_strands(); - - set_opengl_state_dots(&info); - draw_dots(edit, &info, false); - draw_dots(edit, &info, true); - unbind_gpu_buffers_dots(); - - restore_opengl_state(&info); -} diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 83de02c3774..0ec41fed13f 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -533,9 +533,6 @@ static void view3d_main_region_init(wmWindowManager *wm, ARegion *ar) keymap = WM_keymap_find(wm->defaultconf, "Particle", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); - keymap = WM_keymap_find(wm->defaultconf, "Hair", 0, 0); - WM_event_add_keymap_handler(&ar->handlers, keymap); - /* editfont keymap swallows all... */ keymap = WM_keymap_find(wm->defaultconf, "Font", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index a5635be0634..d8599610197 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -309,7 +309,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) if (obedit == NULL && is_paint) { /* Manipulators aren't used in paint modes */ - if (!ELEM(ob->mode, OB_MODE_SCULPT, OB_MODE_PARTICLE_EDIT, OB_MODE_HAIR_EDIT)) { + if (!ELEM(ob->mode, OB_MODE_SCULPT, OB_MODE_PARTICLE_EDIT)) { /* masks aren't used for sculpt and particle painting */ PointerRNA meshptr; diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 82d4e5b5ace..6cdc9b02da6 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -48,8 +48,6 @@ struct bMotionPath; struct bPoseChannel; struct Mesh; struct SceneLayer; -struct BMEditStrands; - struct wmOperatorType; struct wmWindowManager; struct wmKeyConfig; @@ -214,9 +212,6 @@ void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d, /* drawsimdebug.c */ void draw_sim_debug_data(Scene *scene, View3D *v3d, ARegion *ar); -/* drawstrands.c */ -void draw_strands_edit_hair(Scene *scene, View3D *v3d, ARegion *ar, struct BMEditStrands *edit); - /* view3d_draw.c */ void view3d_main_region_draw(const struct bContext *C, struct ARegion *ar); void view3d_draw_region_info(const struct bContext *C, struct ARegion *ar, const int offset); diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 20cd1fd98d8..5408269ce13 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -84,11 +84,9 @@ #include "ED_armature.h" #include "ED_curve.h" -#include "ED_physics.h" #include "ED_particle.h" #include "ED_mesh.h" #include "ED_object.h" -#include "ED_physics.h" #include "ED_screen.h" #include "ED_sculpt.h" #include "ED_mball.h" @@ -825,9 +823,6 @@ static void view3d_lasso_select(bContext *C, ViewContext *vc, else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT)) { PE_lasso_select(C, mcords, moves, extend, select); } - else if (ob && (ob->mode & OB_MODE_HAIR_EDIT)) { - ED_hair_lasso_select(C, mcords, moves, extend, select); - } else { do_lasso_select_objects(vc, mcords, moves, extend, select); WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, vc->scene); @@ -2223,9 +2218,6 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op) else if (vc.obact && vc.obact->mode & OB_MODE_PARTICLE_EDIT) { ret = PE_border_select(C, &rect, select, extend); } - else if (vc.obact && vc.obact->mode & OB_MODE_HAIR_EDIT) { - ret = ED_hair_border_select(C, &rect, select, extend); - } else { /* object mode with none active */ ret = do_object_pose_box_select(C, &vc, &rect, select, extend); } @@ -2358,8 +2350,6 @@ static int view3d_select_exec(bContext *C, wmOperator *op) } else if (obact && obact->mode & OB_MODE_PARTICLE_EDIT) return PE_mouse_particles(C, location, extend, deselect, toggle); - else if (obact && obact->mode & OB_MODE_HAIR_EDIT) - return ED_hair_mouse_select(C, location, extend, deselect, toggle); else if (obact && BKE_paint_select_face_test(obact)) retval = paintface_mouse_select(C, obact, location, extend, deselect, toggle); else if (BKE_paint_select_vert_test(obact)) @@ -2875,7 +2865,7 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op) RNA_int_get(op->ptr, "y")}; if (CTX_data_edit_object(C) || BKE_paint_select_elem_test(obact) || - (obact && (obact->mode & (OB_MODE_PARTICLE_EDIT | OB_MODE_POSE | OB_MODE_HAIR_EDIT))) ) + (obact && (obact->mode & (OB_MODE_PARTICLE_EDIT | OB_MODE_POSE))) ) { EvaluationContext eval_ctx; ViewContext vc; @@ -2897,15 +2887,10 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op) paint_vertsel_circle_select(&eval_ctx, &vc, select, mval, (float)radius); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data); } - else if (obact->mode & OB_MODE_POSE) { + else if (obact->mode & OB_MODE_POSE) pose_circle_select(&vc, select, mval, (float)radius); - } - else if (obact->mode & OB_MODE_HAIR_EDIT) { - ED_hair_circle_select(C, select, mval, (float)radius); - } - else { + else return PE_circle_select(C, select, mval, (float)radius); - } } else if (obact && obact->mode & OB_MODE_SCULPT) { return OPERATOR_CANCELLED; diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 2f18a3a84fe..60ad61e3475 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -634,7 +634,6 @@ void flushTransGraphData(TransInfo *t); void remake_graph_transdata(TransInfo *t, struct ListBase *anim_data); void flushTransUVs(TransInfo *t); void flushTransParticles(TransInfo *t); -void flushTransStrands(TransInfo *t); bool clipUVTransform(TransInfo *t, float vec[2], const bool resize); void clipUVData(TransInfo *t); void flushTransNodes(TransInfo *t); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index d59c8ffff64..ed215a84dc7 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -68,7 +68,6 @@ #include "BKE_context.h" #include "BKE_crazyspace.h" #include "BKE_curve.h" -#include "BKE_editstrands.h" #include "BKE_fcurve.h" #include "BKE_global.h" #include "BKE_gpencil.h" @@ -2057,226 +2056,6 @@ void flushTransParticles(TransInfo *t) PE_update_object(&eval_ctx, scene, sl, OBACT_NEW(sl), 1); } - -/* ******************* hair edit **************** */ - -static void editmesh_set_connectivity_distance(BMesh *bm, float mtx[3][3], float *dists, int *index); -static struct TransIslandData *bmesh_islands_info_calc( - BMesh *bm, short selectmode, int *r_island_tot, int **r_island_vert_map, - bool calc_single_islands); - -static void StrandVertsToTransData(TransInfo *t, TransData *td, - BMEditStrands *UNUSED(edit), BMVert *eve, const float nor[3], const float tang[3], - struct TransIslandData *v_island) -{ - BLI_assert(BM_elem_flag_test(eve, BM_ELEM_HIDDEN) == 0); - - td->flag = 0; - td->loc = eve->co; - copy_v3_v3(td->iloc, td->loc); - - if (v_island) { - copy_v3_v3(td->center, v_island->co); - copy_m3_m3(td->axismtx, v_island->axismtx); - } - else if (t->around == V3D_AROUND_LOCAL_ORIGINS) { - copy_v3_v3(td->center, td->loc); - createSpaceNormalTangent(td->axismtx, nor, tang); - } - else { - copy_v3_v3(td->center, td->loc); - - /* Setting normals */ - copy_v3_v3(td->axismtx[2], nor); - td->axismtx[0][0] = - td->axismtx[0][1] = - td->axismtx[0][2] = - td->axismtx[1][0] = - td->axismtx[1][1] = - td->axismtx[1][2] = 0.0f; - } - - td->ext = NULL; - td->val = NULL; - td->extra = NULL; -} - -static void createTransStrandVerts(TransInfo *t) -{ - SceneLayer *sl = t->scene_layer; - Object *ob = OBACT_NEW(sl); - BMEditStrands *edit = BKE_editstrands_from_object(ob); - BMesh *bm = edit->base.bm; - TransData *tob = NULL; - BMVert *eve; - BMIter iter; - float mtx[3][3], smtx[3][3]; - float *dists = NULL; - int a; - int prop_mode = (t->flag & T_PROP_EDIT) ? (t->flag & T_PROP_EDIT_ALL) : 0; - int mirror = 0; - - struct TransIslandData *island_info = NULL; - int island_info_tot; - int *island_vert_map = NULL; - - /* Even for translation this is needed because of island-orientation, see: T51651. */ - const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS); - /* Original index of our connected vertex when connected distances are calculated. - * Optional, allocate if needed. */ - int *dists_index = NULL; - - if (t->flag & T_MIRROR) { -#if 0 // TODO mirror relies on EDBM functions which don't have an equivalent for editstrands yet - EDBM_verts_mirror_cache_begin(em, 0, false, (t->flag & T_PROP_EDIT) == 0, false); - mirror = 1; -#endif - } - - /* quick check if we can transform */ - /* note: in prop mode we need at least 1 selected */ - if (bm->totvertsel == 0) { - goto cleanup; - } - - if (prop_mode) { - unsigned int count = 0; - BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { - if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { - count++; - } - } - - t->total = count; - - /* allocating scratch arrays */ - if (prop_mode & T_PROP_CONNECTED) { - dists = MEM_mallocN(bm->totvert * sizeof(float), "scratch nears"); - if (is_island_center) { - dists_index = MEM_mallocN(bm->totvert * sizeof(int), __func__); - } - } - } - else { - t->total = bm->totvertsel; - } - - tob = t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Strands EditMode)"); - - copy_m3_m4(mtx, ob->obmat); - /* we use a pseudoinverse so that when one of the axes is scaled to 0, - * matrix inversion still works and we can still moving along the other */ - pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); - - if (prop_mode & T_PROP_CONNECTED) { - editmesh_set_connectivity_distance(bm, mtx, dists, dists_index); - } - - if (is_island_center) { - /* In this specific case, near-by vertices will need to know the island of the nearest connected vertex. */ - const bool calc_single_islands = (prop_mode & T_PROP_CONNECTED); - - island_info = bmesh_islands_info_calc(bm, SCE_SELECT_VERTEX, &island_info_tot, &island_vert_map, calc_single_islands); - } - - /* find out which half we do */ - if (mirror) { -#if 0 // TODO - BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { - if (BM_elem_flag_test(eve, BM_ELEM_SELECT) && eve->co[0] != 0.0f) { - if (eve->co[0] < 0.0f) { - t->mirror = -1; - mirror = -1; - } - break; - } - } -#endif - } - - t->custom.type.data = BKE_editstrands_get_locations(edit); - t->custom.type.use_free = true; - - BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, a) { - if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { - if (prop_mode || BM_elem_flag_test(eve, BM_ELEM_SELECT)) { - struct TransIslandData *v_island = (island_info && island_vert_map[a] != -1) ? - &island_info[island_vert_map[a]] : NULL; - /* XXX TODO calculate normal and tangent along the strand */ - float nor[3], tang[3]; - nor[0] = 0.0f; nor[1] = 0.0f; nor[2] = 1.0f; - tang[0] = 0.0f; tang[1] = 1.0f; tang[2] = 0.0f; - - StrandVertsToTransData(t, tob, edit, eve, nor, tang, v_island); - - /* selected */ - if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) - tob->flag |= TD_SELECTED; - - if (prop_mode) { - if (prop_mode & T_PROP_CONNECTED) { - tob->dist = dists[a]; - } - else { - tob->flag |= TD_NOTCONNECTED; - tob->dist = FLT_MAX; - } - } - - copy_m3_m3(tob->smtx, smtx); - copy_m3_m3(tob->mtx, mtx); - - /* Mirror? */ - if ((mirror > 0 && tob->iloc[0] > 0.0f) || (mirror < 0 && tob->iloc[0] < 0.0f)) { -#if 0 // TODO - BMVert *vmir = EDBM_verts_mirror_get(em, eve); - if (vmir && vmir != eve) { - tob->extra = vmir; - } -#endif - } - tob++; - } - } - } - - if (island_info) { - MEM_freeN(island_info); - MEM_freeN(island_vert_map); - } - - if (mirror != 0) { -#if 0 // TODO - tob = t->data; - for (a = 0; a < t->total; a++, tob++) { - if (ABS(tob->loc[0]) <= 0.00001f) { - tob->flag |= TD_MIRROR_EDGE; - } - } -#endif - } - -cleanup: - if (dists) - MEM_freeN(dists); - - if (t->flag & T_MIRROR) { -#if 0 // TODO - EDBM_verts_mirror_cache_end(em); -#endif - } -} - -void flushTransStrands(TransInfo *t) -{ - SceneLayer *sl = t->scene_layer; - Object *ob = OBACT_NEW(sl); - BMEditStrands *edit = BKE_editstrands_from_object(ob); - BMEditStrandsLocations origlocs = t->custom.type.data; - - BKE_editstrands_solve_constraints(ob, edit, origlocs); -} - /* ********************* mesh ****************** */ static bool bmesh_test_dist_add( @@ -2455,10 +2234,11 @@ static void editmesh_set_connectivity_distance(BMesh *bm, float mtx[3][3], float } } -static struct TransIslandData *bmesh_islands_info_calc( - BMesh *bm, short selectmode, int *r_island_tot, int **r_island_vert_map, +static struct TransIslandData *editmesh_islands_info_calc( + BMEditMesh *em, int *r_island_tot, int **r_island_vert_map, bool calc_single_islands) { + BMesh *bm = em->bm; struct TransIslandData *trans_islands; char htype; char itype; @@ -2472,7 +2252,7 @@ static struct TransIslandData *bmesh_islands_info_calc( int *vert_map; - if (selectmode & (SCE_SELECT_VERTEX | SCE_SELECT_EDGE)) { + if (em->selectmode & (SCE_SELECT_VERTEX | SCE_SELECT_EDGE)) { groups_array = MEM_mallocN(sizeof(*groups_array) * bm->totedgesel, __func__); group_tot = BM_mesh_calc_edge_groups(bm, groups_array, &group_index, NULL, NULL, @@ -2779,9 +2559,10 @@ static void createTransEditVerts(TransInfo *t) /* In this specific case, near-by vertices will need to know the island of the nearest connected vertex. */ const bool calc_single_islands = ( (prop_mode & T_PROP_CONNECTED) && + (t->around == V3D_AROUND_LOCAL_ORIGINS) && (em->selectmode & SCE_SELECT_VERTEX)); - island_info = bmesh_islands_info_calc(em->bm, em->selectmode, &island_info_tot, &island_vert_map, calc_single_islands); + island_info = editmesh_islands_info_calc(em, &island_info_tot, &island_vert_map, calc_single_islands); } /* detect CrazySpace [tm] */ @@ -6732,11 +6513,6 @@ void special_aftertrans_update(bContext *C, TransInfo *t) { /* do nothing */ } - else if ((ob->mode & OB_MODE_HAIR_EDIT) && - BKE_editstrands_from_object(ob)) - { - /* do nothing */ - } else { /* Objects */ int i; @@ -8499,16 +8275,6 @@ void createTransData(bContext *C, TransInfo *t) sort_trans_data_dist(t); } } - else if (ob && (ob->mode & OB_MODE_HAIR_EDIT) && BKE_editstrands_from_object(ob)) { - createTransStrandVerts(t); - t->flag |= T_POINTS; - - if (t->data && t->flag & T_PROP_EDIT) { - sort_trans_data(t); // makes selected become first in array - set_prop_dist(t, 1); - sort_trans_data_dist(t); - } - } else if (ob && (ob->mode & OB_MODE_ALL_PAINT)) { if ((t->options & CTX_PAINT_CURVE) && !ELEM(t->mode, TFM_SHEAR, TFM_SHRINKFATTEN)) { t->flag |= T_POINTS | T_2D_EDIT; diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index e6246af391f..5081b65c215 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -71,7 +71,6 @@ #include "BKE_action.h" #include "BKE_armature.h" #include "BKE_curve.h" -#include "BKE_editstrands.h" #include "BKE_fcurve.h" #include "BKE_lattice.h" #include "BKE_library.h" @@ -912,12 +911,6 @@ static void recalcData_objects(TransInfo *t) } flushTransParticles(t); } - else if (base && (base->object->mode & OB_MODE_HAIR_EDIT) && BKE_editstrands_from_object(base->object)) { - if (t->state != TRANS_CANCEL) { - applyProject(t); - } - flushTransStrands(t); - } else { int i; diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index 4f436a24ef5..e91db762eb1 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -1039,7 +1039,7 @@ int getTransformOrientation_ex(const bContext *C, float normal[3], float plane[3 result = ORIENTATION_EDGE; } } - else if (ob && (ob->mode & (OB_MODE_ALL_BRUSH | OB_MODE_PARTICLE_EDIT))) { + else if (ob && (ob->mode & (OB_MODE_ALL_PAINT | OB_MODE_PARTICLE_EDIT))) { /* pass */ } else { diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c index 82bd2f5046e..d0f29abc62f 100644 --- a/source/blender/editors/util/ed_util.c +++ b/source/blender/editors/util/ed_util.c @@ -52,7 +52,6 @@ #include "BLT_translation.h" #include "BKE_context.h" -#include "BKE_editstrands.h" #include "BKE_global.h" #include "BKE_main.h" #include "BKE_multires.h" @@ -130,7 +129,6 @@ void ED_editors_exit(bContext *C) { Main *bmain = CTX_data_main(C); Scene *sce; - Object *ob; if (!bmain) return; @@ -141,7 +139,7 @@ void ED_editors_exit(bContext *C) for (sce = bmain->scene.first; sce; sce = sce->id.next) { if (sce->obedit) { - ob = sce->obedit; + Object *ob = sce->obedit; if (ob) { if (ob->type == OB_MESH) { @@ -158,17 +156,6 @@ void ED_editors_exit(bContext *C) } } } - - for (ob = bmain->object.first; ob; ob = ob->id.next) { - if (ob->type == OB_MESH) { - Mesh *me = ob->data; - if (me->edit_strands) { - BKE_editstrands_free(me->edit_strands); - MEM_freeN(me->edit_strands); - me->edit_strands = NULL; - } - } - } /* global in meshtools... */ ED_mesh_mirror_spatial_table(NULL, NULL, NULL, NULL, 'e'); diff --git a/source/blender/editors/util/editmode_undo.c b/source/blender/editors/util/editmode_undo.c index 7f3ac1cdcda..d9f777771a8 100644 --- a/source/blender/editors/util/editmode_undo.c +++ b/source/blender/editors/util/editmode_undo.c @@ -85,7 +85,6 @@ typedef struct UndoElem { void *undodata; uintptr_t undosize; char name[BKE_UNDO_STR_MAX]; - Object *(*get_object)(const bContext *C); void * (*getdata)(bContext * C); void (*freedata)(void *); void (*to_editmode)(void *, void *, void *); @@ -108,15 +107,14 @@ static void undo_restore(UndoElem *undo, void *editdata, void *obdata) /* name can be a dynamic string */ void undo_editmode_push(bContext *C, const char *name, - Object *(*get_object)(const bContext *C), - void * (*getdata)(bContext *C), + void * (*getdata)(bContext * C), void (*freedata)(void *), void (*to_editmode)(void *, void *, void *), void *(*from_editmode)(void *, void *), int (*validate_undo)(void *, void *)) { UndoElem *uel; - Object *obedit = get_object(C); + Object *obedit = CTX_data_edit_object(C); void *editdata; int nr; uintptr_t memused, totmem, maxmem; @@ -136,7 +134,6 @@ void undo_editmode_push(bContext *C, const char *name, BLI_strncpy(uel->name, name, sizeof(uel->name)); BLI_addtail(&undobase, uel); - uel->get_object = get_object; uel->getdata = getdata; uel->freedata = freedata; uel->to_editmode = to_editmode; @@ -197,19 +194,19 @@ void undo_editmode_push(bContext *C, const char *name, static void undo_clean_stack(bContext *C) { UndoElem *uel, *next; + Object *obedit = CTX_data_edit_object(C); /* global undo changes pointers, so we also allow identical names */ /* side effect: when deleting/renaming object and start editing new one with same name */ uel = undobase.first; while (uel) { - Object *obedit = uel->get_object(C); void *editdata = uel->getdata(C); bool is_valid = false; next = uel->next; /* for when objects are converted, renamed, or global undo changes pointers... */ - if (obedit && uel->type == obedit->type) { + if (uel->type == obedit->type) { if (STREQ(uel->id.name, obedit->id.name)) { if (uel->validate_undo == NULL) is_valid = true; @@ -236,13 +233,12 @@ static void undo_clean_stack(bContext *C) /* 1 = an undo, -1 is a redo. we have to make sure 'curundo' remains at current situation */ void undo_editmode_step(bContext *C, int step) { - Object *obedit; + Object *obedit = CTX_data_edit_object(C); /* prevent undo to happen on wrong object, stack can be a mix */ undo_clean_stack(C); if (step == 0) { - obedit = curundo->get_object(C); undo_restore(curundo, curundo->getdata(C), obedit->data); } else if (step == 1) { @@ -253,7 +249,6 @@ void undo_editmode_step(bContext *C, int step) else { if (G.debug & G_DEBUG) printf("undo %s\n", curundo->name); curundo = curundo->prev; - obedit = curundo->get_object(C); undo_restore(curundo, curundo->getdata(C), obedit->data); } } @@ -264,19 +259,15 @@ void undo_editmode_step(bContext *C, int step) error("No more steps to redo"); } else { - obedit = curundo->get_object(C); undo_restore(curundo->next, curundo->getdata(C), obedit->data); curundo = curundo->next; if (G.debug & G_DEBUG) printf("redo %s\n", curundo->name); } } - obedit = curundo->get_object(C); - /* special case for editmesh, mode must be copied back to the scene */ if (obedit->type == OB_MESH) { - if (obedit == CTX_data_edit_object(C)) - EDBM_selectmode_to_scene(C); + EDBM_selectmode_to_scene(C); } DEG_id_tag_update(&obedit->id, OB_RECALC_DATA); diff --git a/source/blender/editors/util/undo.c b/source/blender/editors/util/undo.c index c20765206fc..5b91ee4fc29 100644 --- a/source/blender/editors/util/undo.c +++ b/source/blender/editors/util/undo.c @@ -55,7 +55,6 @@ #include "ED_mball.h" #include "ED_mesh.h" #include "ED_object.h" -#include "ED_physics.h" #include "ED_render.h" #include "ED_screen.h" #include "ED_paint.h" @@ -104,9 +103,6 @@ void ED_undo_push(bContext *C, const char *str) PE_undo_push(CTX_data_scene(C), CTX_data_scene_layer(C), str); } - else if (obact && obact->mode & OB_MODE_HAIR_EDIT) { - undo_push_strands(C, str); - } else if (obact && obact->mode & OB_MODE_SCULPT) { /* do nothing for now */ } @@ -189,14 +185,6 @@ static int ed_undo_step(bContext *C, int step, const char *undoname) else PE_redo(scene, sl); } - else if (obact && obact->mode & OB_MODE_HAIR_EDIT) { - if (undoname) - undo_editmode_name(C, undoname); - else - undo_editmode_step(C, step); - - WM_event_add_notifier(C, NC_GEOM | ND_DATA, NULL); - } else if (U.uiflag & USER_GLOBALUNDO) { // note python defines not valid here anymore. //#ifdef WITH_PYTHON diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h index 2341c3a49fb..407d59f09da 100644 --- a/source/blender/makesdna/DNA_brush_types.h +++ b/source/blender/makesdna/DNA_brush_types.h @@ -106,9 +106,6 @@ typedef struct Brush { char vertexpaint_tool; /* active vertex/weight paint blend mode (poorly named) */ char imagepaint_tool; /* active image paint tool */ char mask_tool; /* enum eBrushMaskTool, only used if sculpt_tool is SCULPT_TOOL_MASK */ - char hair_tool; /* active hair tool */ - char pad2[3]; - int pad3; float autosmooth_factor; @@ -307,16 +304,6 @@ typedef enum eBrushImagePaintTool { PAINT_TOOL_MASK = 5 } eBrushImagePaintTool; -typedef enum BrushHairTool { - HAIR_TOOL_COMB = 1, - HAIR_TOOL_CUT = 2, - HAIR_TOOL_LENGTH = 3, - HAIR_TOOL_PUFF = 4, - HAIR_TOOL_ADD = 5, - HAIR_TOOL_SMOOTH = 6, - HAIR_TOOL_WEIGHT = 7, -} BrushHairTool; - /* direction that the brush displaces along */ enum { SCULPT_DISP_DIR_AREA = 0, diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index 5b1eeb798d7..0e0b1d669d9 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -63,9 +63,10 @@ typedef struct CustomDataExternal { * layers, each with a data type (e.g. MTFace, MDeformVert, etc.). */ typedef struct CustomData { CustomDataLayer *layers; /* CustomDataLayers, ordered by type */ - int typemap[43]; /* runtime only! - maps types to indices of first layer of that type, + int typemap[42]; /* runtime only! - maps types to indices of first layer of that type, * MUST be >= CD_NUMTYPES, but we cant use a define here. * Correct size is ensured in CustomData_update_typemap assert() */ + int pad_i1; int totlayer, maxlayer; /* number of layers, size of layers array */ int totsize; /* in editmode, total size of all data layers */ struct BLI_mempool *pool; /* (BMesh Only): Memory pool for allocation of blocks */ @@ -129,9 +130,7 @@ typedef enum CustomDataType { CD_TESSLOOPNORMAL = 40, CD_CUSTOMLOOPNORMAL = 41, - CD_MSURFACE_SAMPLE = 42, - - CD_NUMTYPES = 43 + CD_NUMTYPES = 42 } CustomDataType; /* Bits for CustomDataMask */ @@ -180,8 +179,6 @@ typedef enum CustomDataType { #define CD_MASK_TESSLOOPNORMAL (1LL << CD_TESSLOOPNORMAL) #define CD_MASK_CUSTOMLOOPNORMAL (1LL << CD_CUSTOMLOOPNORMAL) -#define CD_MASK_MSURFACE_SAMPLE (1LL << CD_MSURFACE_SAMPLE) - /* CustomData.flag */ enum { /* Indicates layer should not be copied by CustomData_from_template or CustomData_copy_data */ diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h index 9794f37e997..505b1f7157b 100644 --- a/source/blender/makesdna/DNA_mesh_types.h +++ b/source/blender/makesdna/DNA_mesh_types.h @@ -87,7 +87,6 @@ typedef struct Mesh { /* When the object is available, the preferred access method is: BKE_editmesh_from_object(ob) */ struct BMEditMesh *edit_btmesh; /* not saved in file! */ - struct BMEditStrands *edit_strands; /* not saved in file! */ struct CustomData vdata, edata, fdata; diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 6df26d73cf6..b863f68781d 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -1635,8 +1635,6 @@ typedef struct HairModifierData { int pad; struct HairPattern *hair; - - struct BMEditStrands *edit; /* edit data (runtime) */ } HairModifierData; #endif /* __DNA_MODIFIER_TYPES_H__ */ diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 9b44e17f811..6187a46dcd7 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -712,12 +712,10 @@ typedef enum eObjectMode { 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_HAIR_EDIT = 1 << 8, } eObjectMode; /* any mode where the brush system is used */ #define OB_MODE_ALL_PAINT (OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT) -#define OB_MODE_ALL_BRUSH (OB_MODE_ALL_PAINT | OB_MODE_HAIR_EDIT) /* any mode that uses ob->sculpt */ #define OB_MODE_ALL_SCULPT (OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT) diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index 54fe5d7da56..ea7905eb2ad 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -278,7 +278,6 @@ typedef struct ParticleSystem { struct PTCacheEdit *edit; /* particle editmode (runtime) */ void (*free_edit)(struct PTCacheEdit *edit); /* free callback */ - struct BMEditStrands *hairedit; /* hair edit data (runtime) */ struct ParticleCacheKey **pathcache; /* path cache (runtime) */ struct ParticleCacheKey **childcache; /* child cache (runtime) */ diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 77f7da632e5..f05369a0d58 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1085,42 +1085,6 @@ typedef struct ParticleEditSettings { } ParticleEditSettings; /* ------------------------------------------- */ -/* Hair Edit */ - -/* HairEditSettings->select_mode */ -typedef enum HairEditSelectMode { - HAIR_SELECT_STRAND = 0, - HAIR_SELECT_VERTEX = 1, - HAIR_SELECT_TIP = 2, -} HairEditSelectMode; - -/* HairEditSettings->hair_draw_mode */ -typedef enum HairEditDrawMode { - HAIR_DRAW_NONE = 0, - HAIR_DRAW_FIBERS = 1, -} HairEditDrawMode; - -/* HairEditSettings->flag */ -typedef enum HairEditFlag { - HAIR_EDIT_SHOW_BRUSH = (1 << 0), - HAIR_EDIT_SHOW_DEBUG = (1 << 16), -} HairEditFlag; - -typedef struct HairEditSettings { - int flag; - short select_mode; - short hair_draw_mode; - float hair_draw_size; - int hair_draw_subdiv; - - struct Brush *brush; - struct Object *shape_object; - - /* WM Paint cursor */ - void *paint_cursor; -} HairEditSettings; - -/* ------------------------------------------- */ /* Sculpt */ /* Sculpt */ @@ -1509,10 +1473,7 @@ typedef struct ToolSettings { /* Particle Editing */ struct ParticleEditSettings particle; - - /* Hair Editing */ - struct HairEditSettings hair_edit; - + /* Transform Proportional Area of Effect */ float proportional_size; diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h index 3b24b2dd6df..760ddb34368 100644 --- a/source/blender/makesrna/RNA_enum_types.h +++ b/source/blender/makesrna/RNA_enum_types.h @@ -108,7 +108,6 @@ extern const EnumPropertyItem rna_enum_motionpath_bake_location_items[]; extern const EnumPropertyItem rna_enum_event_value_items[]; extern const EnumPropertyItem rna_enum_event_type_items[]; extern const EnumPropertyItem rna_enum_operator_return_items[]; -extern EnumPropertyItem brush_hair_tool_items[]; extern const EnumPropertyItem rna_enum_brush_sculpt_tool_items[]; extern const EnumPropertyItem rna_enum_brush_vertex_tool_items[]; diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index 8bfdb72e28f..b7d108fc769 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -122,17 +122,6 @@ const EnumPropertyItem rna_enum_brush_image_tool_items[] = { {0, NULL, 0, NULL, NULL} }; -EnumPropertyItem brush_hair_tool_items[] = { - {HAIR_TOOL_COMB, "COMB", ICON_BRUSH_HAIR_COMB, "Comb", "Align hairs to the stroke direction"}, - {HAIR_TOOL_CUT, "CUT", ICON_BRUSH_HAIR_CUT, "Cut", "Shorten and/or remove hairs"}, - {HAIR_TOOL_LENGTH, "LENGTH", ICON_BRUSH_HAIR_LENGTH, "Length", "Increase hair length"}, - {HAIR_TOOL_PUFF, "PUFF", ICON_BRUSH_HAIR_PUFF, "Puff", "Increase spacing between hairs"}, - {HAIR_TOOL_ADD, "ADD", ICON_BRUSH_HAIR_ADD, "Add", "Add more hairs on the object"}, - {HAIR_TOOL_SMOOTH, "SMOOTH", ICON_BRUSH_HAIR_SMOOTH, "Smooth", "Align hairs in the same direction"}, - {HAIR_TOOL_WEIGHT, "WEIGHT", ICON_BRUSH_HAIR_WEIGHT, "Weight", "Set hair vertex weights"}, - {0, NULL, 0, NULL, NULL} -}; - #ifdef RNA_RUNTIME #include "MEM_guardedalloc.h" @@ -429,13 +418,6 @@ static void rna_Brush_imagepaint_tool_update(Main *bmain, Scene *scene, PointerR rna_Brush_update(bmain, scene, ptr); } -static void rna_Brush_hair_tool_update(Main *bmain, Scene *scene, PointerRNA *ptr) -{ - Brush *br = (Brush *)ptr->data; - rna_Brush_reset_icon(br, "hair"); - rna_Brush_update(bmain, scene, ptr); -} - static void rna_Brush_stroke_update(Main *bmain, Scene *scene, PointerRNA *ptr) { WM_main_add_notifier(NC_SCENE | ND_TOOLSETTINGS, scene); @@ -929,12 +911,6 @@ static void rna_def_brush(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Image Paint Tool", ""); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, "rna_Brush_imagepaint_tool_update"); - prop = RNA_def_property(srna, "hair_tool", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "hair_tool"); - RNA_def_property_enum_items(prop, brush_hair_tool_items); - RNA_def_property_ui_text(prop, "Hair Tool", ""); - RNA_def_property_update(prop, 0, "rna_Brush_hair_tool_update"); - 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); @@ -1398,10 +1374,6 @@ 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_hair_edit", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "ob_mode", OB_MODE_HAIR_EDIT); - RNA_def_property_ui_text(prop, "Use Hair", "Use this brush in hair edit mode"); - /* texture */ prop = RNA_def_property(srna, "texture_slot", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "BrushTextureSlot"); diff --git a/source/blender/makesrna/intern/rna_context.c b/source/blender/makesrna/intern/rna_context.c index a67a333ff40..39f050924f4 100644 --- a/source/blender/makesrna/intern/rna_context.c +++ b/source/blender/makesrna/intern/rna_context.c @@ -210,7 +210,6 @@ void RNA_def_context(BlenderRNA *brna) {CTX_MODE_PAINT_VERTEX, "PAINT_VERTEX", 0, "Vertex Paint", ""}, {CTX_MODE_PAINT_TEXTURE, "PAINT_TEXTURE", 0, "Texture Paint", ""}, {CTX_MODE_PARTICLE, "PARTICLE", 0, "Particle", ""}, - {CTX_MODE_HAIR, "HAIR", 0, "Hair", ""}, {CTX_MODE_OBJECT, "OBJECT", 0, "Object", ""}, {0, NULL, 0, NULL, NULL} }; diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index ab206f741ad..5effcc39ee2 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -72,7 +72,6 @@ const EnumPropertyItem rna_enum_object_mode_items[] = { {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_HAIR_EDIT, "HAIR_EDIT", ICON_PARTICLEMODE, "Hair Edit", ""}, {0, NULL, 0, NULL, NULL} }; diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index acb1b088117..26f1ac845d4 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -2520,10 +2520,6 @@ static void rna_def_tool_settings(BlenderRNA *brna) RNA_def_property_pointer_sdna(prop, NULL, "particle"); RNA_def_property_ui_text(prop, "Particle Edit", ""); - prop = RNA_def_property(srna, "hair_edit", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "hair_edit"); - RNA_def_property_ui_text(prop, "Hair Edit", ""); - prop = RNA_def_property(srna, "use_uv_sculpt", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "use_uv_sculpt", 1); RNA_def_property_ui_text(prop, "UV Sculpt", "Enable brush for UV sculpting"); diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index bcdb3e8ae5a..551b38771f9 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -103,8 +103,6 @@ const EnumPropertyItem rna_enum_symmetrize_direction_items[] = { #include "BKE_context.h" #include "BKE_DerivedMesh.h" -#include "BKE_editstrands.h" -#include "BKE_effect.h" #include "BKE_pointcache.h" #include "BKE_particle.h" #include "BKE_pbvh.h" @@ -260,8 +258,6 @@ static int 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->hair_edit) - mode = OB_MODE_HAIR_EDIT; return brush->ob_mode & mode; } @@ -433,28 +429,6 @@ static char *rna_GPencilSculptBrush_path(PointerRNA *UNUSED(ptr)) return BLI_strdup("tool_settings.gpencil_sculpt.brush"); } -/* ==== Hair Edit ==== */ - -static char *rna_HairEdit_path(PointerRNA *UNUSED(ptr)) -{ - return BLI_strdup("tool_settings.hair_edit"); -} - -static void rna_HairEdit_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr)) -{ - Object *ob = OBACT; - - if (ob) - DEG_id_tag_update(&ob->id, OB_RECALC_DATA); -} - -static void rna_HairEdit_brush_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) -{ - HairEditSettings *settings = ptr->data; - Brush *brush = settings->brush; - BKE_paint_invalidate_overlay_all(); - WM_main_add_notifier(NC_BRUSH | NA_EDITED, brush); -} #else @@ -1154,72 +1128,6 @@ static void rna_def_gpencil_sculpt(BlenderRNA *brna) RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); } -static void rna_def_hair_edit(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - static EnumPropertyItem select_mode_items[] = { - {HAIR_SELECT_STRAND, "STRAND", ICON_PARTICLE_PATH, "Strand", "Strand edit mode"}, - {HAIR_SELECT_VERTEX, "VERTEX", ICON_PARTICLE_POINT, "Vertex", "Vertex select mode"}, - {HAIR_SELECT_TIP, "TIP", ICON_PARTICLE_TIP, "Tip", "Tip select mode"}, - {0, NULL, 0, NULL, NULL} - }; - - static EnumPropertyItem hair_draw_mode_items[] = { - {HAIR_DRAW_NONE, "NONE", ICON_NONE, "None", "Don't show hair while editing"}, - {HAIR_DRAW_FIBERS, "FIBERS", ICON_STRANDS, "Fibers", "Draw hair fibers"}, - {0, NULL, 0, NULL, NULL} - }; - - srna = RNA_def_struct(brna, "HairEdit", NULL); - RNA_def_struct_sdna(srna, "HairEditSettings"); - RNA_def_struct_path_func(srna, "rna_HairEdit_path"); - RNA_def_struct_ui_text(srna, "Hair Edit", "Settings for hair editing mode"); - - prop = RNA_def_property(srna, "brush", PROP_POINTER, PROP_NONE); - RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_Brush_mode_poll"); - RNA_def_property_ui_text(prop, "Brush", "Active Brush"); - RNA_def_property_update(prop, 0, "rna_HairEdit_brush_update"); - - prop = RNA_def_property(srna, "show_brush", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", HAIR_EDIT_SHOW_BRUSH); - RNA_def_property_ui_text(prop, "Show Brush", ""); - RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); - - prop = RNA_def_property(srna, "select_mode", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "select_mode"); - RNA_def_property_enum_items(prop, select_mode_items); - RNA_def_property_ui_text(prop, "Selection Mode", "Hair selection mode"); - RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_HairEdit_update"); - - prop = RNA_def_property(srna, "hair_draw_mode", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "hair_draw_mode"); - RNA_def_property_enum_items(prop, hair_draw_mode_items); - RNA_def_property_ui_text(prop, "Hair Draw Mode", "Draw mode for edited hair results"); - RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_HairEdit_update"); - - prop = RNA_def_property(srna, "hair_draw_size", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "hair_draw_size"); - RNA_def_property_range(prop, 0.0f, FLT_MAX); - RNA_def_property_ui_range(prop, 1.0f, 10.0f, 1.0f, 1); - RNA_def_property_ui_text(prop, "Hair Draw Size", "Width of hair fibers in pixels"); - RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_HairEdit_update"); - - prop = RNA_def_property(srna, "hair_draw_subdivision", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "hair_draw_subdiv"); - RNA_def_property_range(prop, 0, INT_MAX); - RNA_def_property_ui_range(prop, 0, 5, 1, -1); - RNA_def_property_ui_text(prop, "Hair Draw Subdivision", "Subdivide hair fibers"); - RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_HairEdit_update"); - - prop = RNA_def_property(srna, "shape_object", PROP_POINTER, PROP_NONE); - RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Shape Object", "Outer shape to use for tools"); - RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_HairEdit_update"); -} - void RNA_def_sculpt_paint(BlenderRNA *brna) { /* *** Non-Animated *** */ @@ -1232,7 +1140,6 @@ void RNA_def_sculpt_paint(BlenderRNA *brna) rna_def_image_paint(brna); rna_def_particle_edit(brna); rna_def_gpencil_sculpt(brna); - rna_def_hair_edit(brna); RNA_define_animate_sdna(true); } diff --git a/source/blender/modifiers/intern/MOD_hair.c b/source/blender/modifiers/intern/MOD_hair.c index d17a629e055..9ec59676414 100644 --- a/source/blender/modifiers/intern/MOD_hair.c +++ b/source/blender/modifiers/intern/MOD_hair.c @@ -40,7 +40,6 @@ #include "DNA_hair_types.h" #include "BKE_cdderivedmesh.h" -#include "BKE_editstrands.h" #include "BKE_hair.h" #include "BKE_library.h" #include "BKE_library_query.h" @@ -58,8 +57,6 @@ static void initData(ModifierData *md) hmd->hair = BKE_hair_new(); hmd->flag |= 0; - - hmd->edit = NULL; } static void copyData(ModifierData *md, ModifierData *target) @@ -76,8 +73,6 @@ static void copyData(ModifierData *md, ModifierData *target) if (hmd->hair) { thmd->hair = BKE_hair_copy(hmd->hair); } - - thmd->edit = NULL; } static void freeData(ModifierData *md) @@ -87,11 +82,6 @@ static void freeData(ModifierData *md) if (hmd->hair) { BKE_hair_free(hmd->hair); } - - if (hmd->edit) { - BKE_editstrands_free(hmd->edit); - MEM_freeN(hmd->edit); - } } static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), diff --git a/source/blender/physics/BPH_strands.h b/source/blender/physics/BPH_strands.h deleted file mode 100644 index 068c47f1c4c..00000000000 --- a/source/blender/physics/BPH_strands.h +++ /dev/null @@ -1,44 +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) Blender Foundation - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Lukas Toenne - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifndef __BPH_STRANDS_H__ -#define __BPH_STRANDS_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -struct Object; -struct BMEditStrands; - -void BPH_strands_solve_constraints(struct Object *ob, struct BMEditStrands *es, float (*orig)[3]); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/source/blender/physics/CMakeLists.txt b/source/blender/physics/CMakeLists.txt index 81c4bcdac31..0a4ff3fe0f0 100644 --- a/source/blender/physics/CMakeLists.txt +++ b/source/blender/physics/CMakeLists.txt @@ -28,7 +28,6 @@ set(INC intern ../blenlib ../blenkernel - ../bmesh ../imbuf ../makesdna ../../../intern/guardedalloc @@ -46,10 +45,8 @@ set(SRC intern/implicit_blender.c intern/implicit_eigen.cpp intern/eigen_utils.h - intern/strands.cpp BPH_mass_spring.h - BPH_strands.h ) blender_add_lib(bf_physics "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/physics/intern/eigen_utils.h b/source/blender/physics/intern/eigen_utils.h index ebfed7cb690..e4a4f306aeb 100644 --- a/source/blender/physics/intern/eigen_utils.h +++ b/source/blender/physics/intern/eigen_utils.h @@ -39,7 +39,6 @@ #endif #include <Eigen/Sparse> -#include <Eigen/SVD> #include <Eigen/src/Core/util/DisableStupidWarnings.h> #ifdef __GNUC__ @@ -114,7 +113,6 @@ public: }; typedef Eigen::VectorXf lVector; -typedef Eigen::VectorXf VectorX; /* Extension of dense Eigen vectors, * providing 3-float block access for blenlib math functions @@ -148,7 +146,6 @@ public: typedef Eigen::Triplet<Scalar> Triplet; typedef std::vector<Triplet> TripletList; -typedef Eigen::MatrixXf MatrixX; typedef Eigen::SparseMatrix<Scalar> lMatrix; /* Constructor type that provides more convenient handling of Eigen triplets @@ -204,33 +201,6 @@ typedef Eigen::ConjugateGradient<lMatrix, Eigen::Lower, Eigen::DiagonalPrecondit using Eigen::ComputationInfo; -template <typename MatrixType> -BLI_INLINE MatrixType pseudo_inverse(const MatrixType& mat, double epsilon = std::numeric_limits<double>::epsilon()) -{ - typedef Eigen::JacobiSVD<MatrixType> SVD; -// typedef typename SVD::SingularValuesType SingularValues; - - SVD svd(mat, Eigen::ComputeThinU | Eigen::ComputeThinV); - - double tolerance = epsilon * std::max(mat.cols(), mat.rows()) * svd.singularValues().array().abs()(0); - return svd.matrixV() * (svd.singularValues().array().abs() > tolerance).select(svd.singularValues().array().inverse(), 0).matrix().asDiagonal() * svd.matrixU().adjoint(); - -// const double pinvtoler=1.e-6; // choose your tolerance wisely! -// SingularValues singularValues_inv = svd.singularValues(); -// for (long i = 0; i < mat.cols(); ++i) { -// if (svd.singularValues(i) > pinvtoler ) -// singularValues_inv(i) = 1.0 / svd.singularValues(i); -// else singularValues_inv(i) = 0; -// } - -// return (svd.matrixV() * singularValues_inv.asDiagonal() * svd.matrixU().transpose()); -} - -BLI_INLINE void print_matrix_elem(float v) -{ - printf("%-8.3f", v); -} - BLI_INLINE void print_lvector(const lVector3f &v) { for (int i = 0; i < v.rows(); ++i) { @@ -251,7 +221,7 @@ BLI_INLINE void print_lmatrix(const lMatrix &m) if (i > 0 && i % 3 == 0) printf(" "); - print_matrix_elem(m.coeff(j, i)); + implicit_print_matrix_elem(m.coeff(j, i)); } printf("\n"); } diff --git a/source/blender/physics/intern/implicit.h b/source/blender/physics/intern/implicit.h index d632ce267a1..2f62ab98e12 100644 --- a/source/blender/physics/intern/implicit.h +++ b/source/blender/physics/intern/implicit.h @@ -67,6 +67,11 @@ typedef struct ImplicitSolverResult { float error; } ImplicitSolverResult; +BLI_INLINE void implicit_print_matrix_elem(float v) +{ + printf("%-8.3f", v); +} + void BPH_mass_spring_set_vertex_mass(struct Implicit_Data *data, int index, float mass); void BPH_mass_spring_set_rest_transform(struct Implicit_Data *data, int index, float rot[3][3]); diff --git a/source/blender/physics/intern/implicit_blender.c b/source/blender/physics/intern/implicit_blender.c index bfc78f140b0..16cd335dc0c 100644 --- a/source/blender/physics/intern/implicit_blender.c +++ b/source/blender/physics/intern/implicit_blender.c @@ -333,7 +333,7 @@ static void print_bfmatrix(fmatrix3x3 *m) if (i > 0 && i % 3 == 0) printf(" "); - print_matrix_elem(t[i + j * size]); + implicit_print_matrix_elem(t[i + j * size]); } printf("\n"); } diff --git a/source/blender/physics/intern/implicit_eigen.cpp b/source/blender/physics/intern/implicit_eigen.cpp index db27d8ee223..ff4c705ed61 100644 --- a/source/blender/physics/intern/implicit_eigen.cpp +++ b/source/blender/physics/intern/implicit_eigen.cpp @@ -268,7 +268,7 @@ static void print_lmatrix(const lMatrix &m) if (i > 0 && i % 3 == 0) printf(" "); - print_matrix_elem(m.coeff(j, i)); + implicit_print_matrix_elem(m.coeff(j, i)); } printf("\n"); } diff --git a/source/blender/physics/intern/strands.cpp b/source/blender/physics/intern/strands.cpp deleted file mode 100644 index 6d7c8e58f51..00000000000 --- a/source/blender/physics/intern/strands.cpp +++ /dev/null @@ -1,434 +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) Blender Foundation - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Lukas Toenne - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/physics/intern/strands.c - * \ingroup bke - */ - -extern "C" { -#include "MEM_guardedalloc.h" - -#include "BLI_math.h" - -#include "DNA_customdata_types.h" -#include "DNA_object_types.h" - -#include "BKE_bvhutils.h" -#include "BKE_customdata.h" -#include "BKE_cdderivedmesh.h" -#include "BKE_DerivedMesh.h" -#include "BKE_editstrands.h" -#include "BKE_effect.h" -#include "BKE_mesh_sample.h" - -#include "bmesh.h" -} - -#include "BPH_strands.h" - -#include "eigen_utils.h" - -/* === constraints === */ - -static bool strand_get_root_vectors(BMEditStrands *edit, BMVert *root, float loc[3], float nor[3], float tang[3]) -{ - BMesh *bm = edit->base.bm; - DerivedMesh *root_dm = edit->root_dm; - MeshSample root_sample; - - BM_elem_meshsample_data_named_get(&bm->vdata, root, CD_MSURFACE_SAMPLE, CD_HAIR_ROOT_LOCATION, &root_sample); - return BKE_mesh_sample_eval(root_dm, &root_sample, loc, nor, tang); -} - -static int strand_count_vertices(BMVert *root) -{ - BMVert *v; - BMIter iter; - - int len = 0; - BM_ITER_STRANDS_ELEM(v, &iter, root, BM_VERTS_OF_STRAND) { - ++len; - } - return len; -} - -static int UNUSED_FUNCTION(strands_get_max_length)(BMEditStrands *edit) -{ - BMesh *bm = edit->base.bm; - BMVert *root; - BMIter iter; - int maxlen = 0; - - BM_ITER_STRANDS(root, &iter, bm, BM_STRANDS_OF_MESH) { - int len = strand_count_vertices(root); - if (len > maxlen) - maxlen = len; - } - return maxlen; -} - -static void strands_apply_root_locations(BMEditStrands *edit) -{ - BMesh *bm = edit->base.bm; - BMVert *root; - BMIter iter; - - if (!edit->root_dm) - return; - - BM_ITER_STRANDS(root, &iter, bm, BM_STRANDS_OF_MESH) { - float loc[3], nor[3], tang[3]; - - if (strand_get_root_vectors(edit, root, loc, nor, tang)) - copy_v3_v3(root->co, loc); - } -} - -static void strands_adjust_segment_lengths(BMesh *bm) -{ - BMVert *root, *v, *vprev; - BMIter iter, iter_strand; - int k; - - BM_ITER_STRANDS(root, &iter, bm, BM_STRANDS_OF_MESH) { - BM_ITER_STRANDS_ELEM_INDEX(v, &iter_strand, root, BM_VERTS_OF_STRAND, k) { - if (k > 0) { - float base_length = BM_elem_float_data_named_get(&bm->vdata, v, CD_PROP_FLT, CD_HAIR_SEGMENT_LENGTH); - float dist[3]; - float length; - - sub_v3_v3v3(dist, v->co, vprev->co); - length = len_v3(dist); - if (length > 0.0f) - madd_v3_v3v3fl(v->co, vprev->co, dist, base_length / length); - } - vprev = v; - } - } -} - -/* try to find a nice solution to keep distances between neighboring keys */ -/* XXX Stub implementation ported from particles: - * Successively relax each segment starting from the root, - * repeat this for every vertex (O(n^2) !!) - * This should be replaced by a more advanced method using a least-squares - * error metric with length and root location constraints (IK solver) - */ -static void strands_solve_edge_relaxation(BMEditStrands *edit) -{ - BMesh *bm = edit->base.bm; - const int Nmax = BM_strands_keys_count_max(bm); - /* cache for vertex positions and segment lengths, for easier indexing */ - float **co = (float **)MEM_mallocN(sizeof(float*) * Nmax, "strand positions"); - float *target_length = (float *)MEM_mallocN(sizeof(float) * Nmax, "strand segment lengths"); - - BMVert *root; - BMIter iter; - BM_ITER_STRANDS(root, &iter, bm, BM_STRANDS_OF_MESH) { - const int S = 1; /* TODO particles use PE_LOCK_FIRST option */ - const int N = BM_strands_keys_count(root); - const float divN = 1.0f / (float)N; - - /* setup positions cache */ - { - BMVert *v; - BMIter viter; - int k; - BM_ITER_STRANDS_ELEM_INDEX(v, &viter, root, BM_VERTS_OF_STRAND, k) { - co[k] = v->co; - target_length[k] = BM_elem_float_data_named_get(&bm->vdata, v, CD_PROP_FLT, CD_HAIR_SEGMENT_LENGTH); - } - } - - for (int iter = 1; iter < N; iter++) { - float correct_first[3] = {0.0f, 0.0f, 0.0f}; - float correct_second[3] = {0.0f, 0.0f, 0.0f}; - - for (int k = S; k < N; k++) { - if (k > 0) { - /* calculate correction for the first vertex */ - float dir[3]; - sub_v3_v3v3(dir, co[k-1], co[k]); - float length = normalize_v3(dir); - - mul_v3_v3fl(correct_first, dir, divN * (length - target_length[k])); - } - - if (k < N-1) { - /* calculate correction for the second vertex */ - float dir[3]; - sub_v3_v3v3(dir, co[k+1], co[k]); - float length_next = normalize_v3(dir); - - mul_v3_v3fl(correct_second, dir, divN * (length_next - target_length[k+1])); - } - - /* apply both corrections (try to satisfy both sides equally) */ - add_v3_v3(co[k], correct_first); - add_v3_v3(co[k], correct_second); - } - } - } - - if (co) - MEM_freeN(co); - if (target_length) - MEM_freeN(target_length); - - strands_adjust_segment_lengths(bm); -} - -typedef struct IKTarget { - BMVert *vertex; - float weight; -} IKTarget; - -static int strand_find_ik_targets(BMVert *root, IKTarget *targets) -{ - BMVert *v; - BMIter iter; - int k, index; - - index = 0; - BM_ITER_STRANDS_ELEM_INDEX(v, &iter, root, BM_VERTS_OF_STRAND, k) { - /* XXX TODO allow multiple targets and do weight calculation here */ - if (BM_strands_vert_is_tip(v)) { - IKTarget *target = &targets[index]; - target->vertex = v; - target->weight = 1.0f; - ++index; - } - } - - return index; -} - -static void calc_jacobian_entry(Object *ob, BMEditStrands *UNUSED(edit), IKTarget *target, int index_target, int index_angle, - const float point[3], const float axis1[3], const float axis2[3], MatrixX &J) -{ - float (*obmat)[4] = ob->obmat; - - float dist[3], jac1[3], jac2[3]; - - sub_v3_v3v3(dist, target->vertex->co, point); - - cross_v3_v3v3(jac1, axis1, dist); - cross_v3_v3v3(jac2, axis2, dist); - - for (int i = 0; i < 3; ++i) { - J.coeffRef(index_target + i, index_angle + 0) = jac1[i]; - J.coeffRef(index_target + i, index_angle + 1) = jac2[i]; - } - -#if 1 - { - float wco[3], wdir[3]; - - mul_v3_m4v3(wco, obmat, point); - - mul_v3_m4v3(wdir, obmat, jac1); - BKE_sim_debug_data_add_vector(wco, wdir, 1,1,0, "strands", index_angle, 1); - mul_v3_m4v3(wdir, obmat, jac2); - BKE_sim_debug_data_add_vector(wco, wdir, 0,1,1, "strands", index_angle + 1, 2); - } -#endif -} - -static MatrixX strand_calc_target_jacobian(Object *ob, BMEditStrands *edit, BMVert *root, int numjoints, IKTarget *targets, int numtargets) -{ - BMVert *v, *vprev; - BMIter iter_strand; - int k; - - float loc[3], axis[3], dir[3]; - - MatrixX J(3 * numtargets, 2 * numjoints); - if (!strand_get_root_vectors(edit, root, loc, dir, axis)) { - return J; - } - - BM_ITER_STRANDS_ELEM_INDEX(v, &iter_strand, root, BM_VERTS_OF_STRAND, k) { - float dirprev[3]; - - if (k > 0) { - float rot[3][3]; - - copy_v3_v3(dirprev, dir); - sub_v3_v3v3(dir, v->co, vprev->co); - normalize_v3(dir); - - rotation_between_vecs_to_mat3(rot, dirprev, dir); - mul_m3_v3(rot, axis); - } - - calc_jacobian_entry(ob, edit, &targets[0], 0, 2*k, v->co, axis, dir, J); - -#if 0 - { - float (*obmat)[4] = ob->obmat; - float wco[3], wdir[3]; - - mul_v3_m4v3(wco, obmat, v->co); - - mul_v3_m4v3(wdir, obmat, axis); - BKE_sim_debug_data_add_vector(edit->debug_data, wco, wdir, 1,0,0, "strands", BM_elem_index_get(v), 1); - mul_v3_m4v3(wdir, obmat, dir); - BKE_sim_debug_data_add_vector(edit->debug_data, wco, wdir, 0,1,0, "strands", BM_elem_index_get(v), 2); - cross_v3_v3v3(wdir, axis, dir); - mul_m4_v3(obmat, wdir); - BKE_sim_debug_data_add_vector(edit->debug_data, wco, wdir, 0,0,1, "strands", BM_elem_index_get(v), 3); - } -#endif - - vprev = v; - } - - return J; -} - -static VectorX strand_angles_to_loc(Object *UNUSED(ob), BMEditStrands *edit, BMVert *root, int numjoints, const VectorX &angles) -{ - BMesh *bm = edit->base.bm; - BMVert *v, *vprev; - BMIter iter_strand; - int k; - - float loc[3], axis[3], dir[3]; - float mat_theta[3][3], mat_phi[3][3]; - - if (!strand_get_root_vectors(edit, root, loc, dir, axis)) - return VectorX(); - - VectorX result(3*numjoints); - - BM_ITER_STRANDS_ELEM_INDEX(v, &iter_strand, root, BM_VERTS_OF_STRAND, k) { - float dirprev[3]; - - if (k > 0) { - const float base_length = BM_elem_float_data_named_get(&bm->vdata, v, CD_PROP_FLT, CD_HAIR_SEGMENT_LENGTH); - float rot[3][3]; - - copy_v3_v3(dirprev, dir); - sub_v3_v3v3(dir, v->co, vprev->co); - normalize_v3(dir); - - rotation_between_vecs_to_mat3(rot, dirprev, dir); - mul_m3_v3(rot, axis); - - /* apply rotations from previous joint on the vertex */ - float vec[3]; - mul_v3_v3fl(vec, dir, base_length); - - mul_m3_v3(mat_theta, vec); - mul_m3_v3(mat_phi, vec); - add_v3_v3v3(&result.coeffRef(3*k), &result.coeff(3*(k-1)), vec); - } - else { - copy_v3_v3(&result.coeffRef(3*k), v->co); - } - - float theta = angles[2*k + 0]; - float phi = angles[2*k + 1]; - axis_angle_normalized_to_mat3(mat_theta, axis, theta); - axis_angle_normalized_to_mat3(mat_phi, dir, phi); - - vprev = v; - } - - return result; -} - -static void UNUSED_FUNCTION(strand_apply_ik_result)(Object *UNUSED(ob), BMEditStrands *UNUSED(edit), BMVert *root, const VectorX &solution) -{ - BMVert *v; - BMIter iter_strand; - int k; - - BM_ITER_STRANDS_ELEM_INDEX(v, &iter_strand, root, BM_VERTS_OF_STRAND, k) { - copy_v3_v3(v->co, &solution.coeff(3*k)); - } -} - -static void strands_solve_inverse_kinematics(Object *ob, BMEditStrands *edit, float (*orig)[3]) -{ - BMesh *bm = edit->base.bm; - - BMVert *root; - BMIter iter; - - BM_ITER_STRANDS(root, &iter, bm, BM_STRANDS_OF_MESH) { - int numjoints = strand_count_vertices(root); - if (numjoints <= 0) - continue; - - IKTarget targets[1]; /* XXX placeholder, later should be allocated to max. strand length */ - int numtargets = strand_find_ik_targets(root, targets); - - MatrixX J = strand_calc_target_jacobian(ob, edit, root, numjoints, targets, numtargets); - MatrixX Jinv = pseudo_inverse(J, 1.e-6); - - VectorX x(3 * numtargets); - for (int i = 0; i < numtargets; ++i) { - sub_v3_v3v3(&x.coeffRef(3*i), targets[i].vertex->co, orig[i]); - /* TODO calculate deviation of vertices from their origin (whatever that is) */ -// x[3*i + 0] = 0.0f; -// x[3*i + 1] = 0.0f; -// x[3*i + 2] = 0.0f; - } - VectorX angles = Jinv * x; - VectorX solution = strand_angles_to_loc(ob, edit, root, numjoints, angles); - -// strand_apply_ik_result(ob, edit, root, solution); - -#if 1 - { - BMVert *v; - BMIter iter_strand; - int k; - float wco[3]; - - BM_ITER_STRANDS_ELEM_INDEX(v, &iter_strand, root, BM_VERTS_OF_STRAND, k) { - mul_v3_m4v3(wco, ob->obmat, &solution.coeff(3*k)); - BKE_sim_debug_data_add_circle(wco, 0.05f, 1,0,1, "strands", k, BM_elem_index_get(root), 2344); - } - } -#endif - } -} - -void BPH_strands_solve_constraints(Object *ob, BMEditStrands *edit, float (*orig)[3]) -{ - strands_apply_root_locations(edit); - - if (true) { - strands_solve_edge_relaxation(edit); - } - else { - if (orig) - strands_solve_inverse_kinematics(ob, edit, orig); - } -} diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index d0f6ee06c64..f48a2cef1e6 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -384,7 +384,6 @@ typedef struct wmNotifier { #define NS_EDITMODE_ARMATURE (8<<8) #define NS_MODE_POSE (9<<8) #define NS_MODE_PARTICLE (10<<8) -#define NS_MODE_HAIR (11<<8) /* subtype 3d view editing */ #define NS_VIEW3D_GPU (16<<8) |