Blender
V3.3
|
#include "MEM_guardedalloc.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_scene_types.h"
#include "BLI_gsqueue.h"
#include "BLI_math_vector.h"
#include "BKE_customdata.h"
#include "BKE_lib_id.h"
#include "BKE_mesh.h"
#include "BKE_mesh_runtime.h"
#include "BKE_modifier.h"
#include "BKE_multires.h"
#include "BKE_subdiv.h"
#include "BKE_subsurf.h"
#include "bmesh.h"
#include "DEG_depsgraph_query.h"
#include "multires_reshape.h"
#include "multires_unsubdivide.h"
Go to the source code of this file.
Variables | |
static const char | lname [] = "l_remap_index" |
static const char | vname [] = "v_remap_index" |
This implements the un-subdivide algorithm, which generates a lower resolution base mesh and its corresponding grids to match a given original mesh.
Definition in file multires_unsubdivide.c.
Returns the next edge and vertex in the direction of a given edge.
Definition at line 494 of file multires_unsubdivide.c.
References BM_edge_other_vert(), BM_edge_share_quad_check(), BM_EDGES_OF_VERT, BM_ITER_ELEM, NULL, and v.
Referenced by multires_unsubdivide_extract_single_grid_from_face_edge(), and multires_unsubdivide_get_grid_corners_on_base_mesh().
Definition at line 511 of file multires_unsubdivide.c.
References BM_face_share_edge_check(), BM_FACES_OF_EDGE, and BM_ITER_ELEM.
Referenced by multires_unsubdivide_extract_single_grid_from_face_edge().
Definition at line 860 of file multires_unsubdivide.c.
References bm, BM_mesh_bm_from_me(), BM_mesh_create(), BMALLOC_TEMPLATE_FROM_ME, and mesh.
Referenced by multires_unsubdivide_extract_grids(), multires_unsubdivide_prepare_original_bmesh_for_extract(), and multires_unsubdivide_to_basemesh().
Returns the other edge which belongs to the face f which is different from edge_x and shares initial_vertex.
Definition at line 528 of file multires_unsubdivide.c.
References BM_EDGES_OF_FACE, BM_ITER_ELEM, NULL, BMEdge::v1, and BMEdge::v2.
Referenced by multires_unsubdivide_extract_single_grid_from_face_edge(), and multires_unsubdivide_get_grid_corners_on_base_mesh().
Returns true if from_v and to_v, which should be part of the same quad face, are diagonals.
Definition at line 148 of file multires_unsubdivide.c.
References BM_edge_exists().
Referenced by unsubdivide_face_center_vertex_tag().
Used to check if a vertex is in a disconnected element ID.
Definition at line 67 of file multires_unsubdivide.c.
References BM_elem_index_get, and v.
Referenced by unsubdivide_find_any_pole(), unsubdivide_is_center_vertex_tag_valid(), and unsubdivide_tag_disconnected_mesh_element().
Definition at line 78 of file multires_unsubdivide.c.
References BM_vert_edge_count(), BM_vert_is_boundary(), and v.
Referenced by unsubdivide_find_any_pole().
Definition at line 73 of file multires_unsubdivide.c.
References BM_vert_edge_count(), BM_vert_is_boundary(), and v.
Referenced by unsubdivide_find_any_pole().
|
static |
This function allocates new mdisps with the right size to fit the new extracted grids from the base mesh and copies the data to them.
Definition at line 1169 of file multires_unsubdivide.c.
References BKE_ccg_gridsize(), BLI_assert, CD_CALLOC, CD_MDISPS, blender::compositor::context, copy_v3_v3(), CustomData_add_layer(), CustomData_free_layers(), CustomData_has_layer(), MDisps::disps, float(), Mesh::ldata, MDisps::level, MEM_calloc_arrayN, MEM_freeN, NULL, pow_i(), MDisps::totdisp, and Mesh::totloop.
Referenced by multiresModifier_rebuild_subdiv().
Generates two data-layers to map loops and vertices from base mesh to original mesh after dissolving the vertices.
Definition at line 899 of file multires_unsubdivide.c.
References CD_CALLOC, CD_PROP_INT32, CustomData_add_layer_named(), Mesh::ldata, lname, mesh, multires_unsubdivide_free_original_datalayers(), NULL, Mesh::totloop, Mesh::totvert, Mesh::vdata, and vname.
Referenced by multires_unsubdivide_extract_grids(), and multires_unsubdivide_to_basemesh().
void multires_unsubdivide_context_free | ( | MultiresUnsubdivideContext * | context | ) |
Definition at line 1154 of file multires_unsubdivide.c.
References blender::compositor::context, MEM_SAFE_FREE, and multires_unsubdivide_private_extract_data_free().
Referenced by multiresModifier_rebuild_subdiv().
void multires_unsubdivide_context_init | ( | MultiresUnsubdivideContext * | context, |
Mesh * | original_mesh, | ||
struct MultiresModifierData * | mmd | ||
) |
Definition at line 1100 of file multires_unsubdivide.c.
References blender::compositor::context, and MultiresModifierData::totlvl.
Referenced by multiresModifier_rebuild_subdiv().
|
static |
Definition at line 984 of file multires_unsubdivide.c.
References BM_ELEM_CD_GET_INT, BM_elem_index_get, BM_FACE, BM_ITER_ELEM, BM_ITER_MESH, BM_LOOPS_OF_VERT, BM_mesh_elem_table_ensure(), BM_mesh_free(), BM_VERT, BM_vert_at_index(), BM_vert_in_face(), BM_VERTS_OF_MESH, CD_PROP_INT32, blender::compositor::context, CustomData_get_layer_named(), CustomData_get_n_offset(), CustomData_get_named_layer_index(), BMLoop::e, BMLoop::f, get_bmesh_from_mesh(), l, BMesh::ldata, Mesh::ldata, lname, MEM_calloc_arrayN, MEM_freeN, multires_unsubdivide_add_original_index_datalayers(), multires_unsubdivide_extract_single_grid_from_face_edge(), multires_unsubdivide_flip_grid_x_axis(), multires_unsubdivide_free_original_datalayers(), multires_unsubdivide_get_grid_corners_on_base_mesh(), Mesh::totloop, BMesh::totvert, Mesh::totvert, v, Mesh::vdata, and vname.
Referenced by multires_unsubdivide_to_basemesh().
|
static |
Main function to extract data from the original bmesh and MDISPS as grids for the new base mesh.
Definition at line 703 of file multires_unsubdivide.c.
References BKE_ccg_gridsize(), BM_edge_in_face(), BM_EDGES_OF_VERT, BM_elem_flag_test, BM_ELEM_TAG, BM_FACES_OF_EDGE, BM_ITER_ELEM, blender::compositor::context, edge_step(), face_step(), get_initial_edge_y(), MultiresUnsubdivideGrid::grid_co, MultiresUnsubdivideGrid::grid_size, MEM_calloc_arrayN, store_grid_data(), store_vertex_data(), BMEdge::v1, and BMEdge::v2.
Referenced by multires_unsubdivide_extract_grids().
|
static |
Checks the orientation of the loops to flip the x and y axis when extracting the grid if necessary.
Definition at line 964 of file multires_unsubdivide.c.
References MPoly::loopstart, mesh, Mesh::mloop, Mesh::mpoly, MPoly::totloop, and MLoop::v.
Referenced by multires_unsubdivide_extract_grids().
Definition at line 882 of file multires_unsubdivide.c.
References CD_PROP_INT32, CustomData_free_layer(), CustomData_get_named_layer_index(), Mesh::ldata, lname, mesh, Mesh::totloop, Mesh::totvert, Mesh::vdata, and vname.
Referenced by multires_unsubdivide_add_original_index_datalayers(), multires_unsubdivide_extract_grids(), and multires_unsubdivide_to_basemesh().
|
static |
Returns the l+1 and l-1 vertices of the base mesh poly were the grid from the face f1 and edge e1 is going to be extracted.
These vertices should always have an corresponding existing vertex on the base mesh.
Definition at line 818 of file multires_unsubdivide.c.
References BM_elem_flag_test, BM_ELEM_TAG, edge_step(), get_initial_edge_y(), BMEdge::v1, and BMEdge::v2.
Referenced by multires_unsubdivide_extract_grids().
|
static |
Definition at line 918 of file multires_unsubdivide.c.
References BM_EDGE, BM_elem_flag_set, BM_ELEM_SELECT, BM_ELEM_TAG, BM_FACE, BM_mesh_elem_hflag_disable_all(), BM_mesh_elem_table_ensure(), BM_VERT, BM_vert_at_index(), CD_PROP_INT32, blender::compositor::context, CustomData_get_layer_named(), get_bmesh_from_mesh(), l, MPoly::loopstart, MEM_calloc_arrayN, Mesh::mpoly, Mesh::totloop, MPoly::totloop, Mesh::totpoly, Mesh::totvert, v, Mesh::vdata, and vname.
Referenced by multires_unsubdivide_to_basemesh().
|
static |
Definition at line 1092 of file multires_unsubdivide.c.
References BM_mesh_free(), blender::compositor::context, MEM_SAFE_FREE, and NULL.
Referenced by multires_unsubdivide_context_free().
Main function to get a base mesh one level down from the current original mesh if it exists.
This searches for different un-subdivide solutions and stores them as a combination of BMVert flags for each disconnected mesh element.
If the solution for all elements are valid, it builds a new base mesh based on those tags by dissolving and merging vertices.
Definition at line 448 of file multires_unsubdivide.c.
References bm, BM_EDGE, BM_ELEM_SELECT, BM_ELEM_TAG, BM_FACE, BM_mesh_elem_hflag_disable_all(), BM_mesh_elem_table_ensure(), BM_mesh_elem_table_init(), BM_VERT, MEM_calloc_arrayN, MEM_freeN, BMesh::totvert, unsubdivide_build_base_mesh_from_tags(), unsubdivide_init_elem_ids(), unsubdivide_is_all_quads(), and unsubdivide_tag_disconnected_mesh_element().
Referenced by multires_unsubdivide_to_basemesh().
bool multires_unsubdivide_to_basemesh | ( | MultiresUnsubdivideContext * | context | ) |
Definition at line 1110 of file multires_unsubdivide.c.
References BKE_mesh_new_nomain(), BM_mesh_bm_to_me(), BM_mesh_free(), blender::compositor::context, get_bmesh_from_mesh(), multires_unsubdivide_add_original_index_datalayers(), multires_unsubdivide_extract_grids(), multires_unsubdivide_free_original_datalayers(), multires_unsubdivide_prepare_original_bmesh_for_extract(), multires_unsubdivide_single_level(), and NULL.
Referenced by multiresModifier_rebuild_subdiv().
int multiresModifier_rebuild_subdiv | ( | struct Depsgraph * | depsgraph, |
struct Object * | object, | ||
struct MultiresModifierData * | mmd, | ||
int | rebuild_limit, | ||
bool | switch_view_to_lower_level | ||
) |
Definition at line 1204 of file multires_unsubdivide.c.
References MultiresUnsubdivideContext::base_mesh, BKE_mesh_nomain_to_mesh(), CD_MASK_MESH, Object::data, depsgraph, if(), MultiresModifierData::lvl, MultiresUnsubdivideContext::max_new_levels, MultiresReshapeContext::mdisps, mesh, multires_create_grids_in_unsubdivided_base_mesh(), multires_force_sculpt_rebuild(), multires_reshape_assign_final_coords_from_mdisps(), multires_reshape_context_create_from_base_mesh(), multires_reshape_context_create_from_object(), multires_reshape_context_free(), multires_reshape_object_grids_to_tangent_displacement(), multires_reshape_store_original_grids(), multires_unsubdivide_context_free(), multires_unsubdivide_context_init(), multires_unsubdivide_to_basemesh(), MultiresUnsubdivideContext::num_new_levels, MultiresUnsubdivideContext::num_total_levels, MultiresUnsubdivideContext::original_mdisp, MultiresModifierData::renderlvl, MultiresModifierData::sculptlvl, and MultiresModifierData::totlvl.
Referenced by multires_rebuild_subdiv_exec(), and multires_unsubdivide_exec().
|
static |
Stores the data from the mdisps grids of the loops of the face f into the new grid for the new base mesh.
Used when there are already grids in the original mesh.
Definition at line 635 of file multires_unsubdivide.c.
References BKE_ccg_gridsize(), BM_elem_index_get, blender::compositor::context, float(), l, MPoly::loopstart, MEM_calloc_arrayN, MEM_freeN, Mesh::mloop, Mesh::mpoly, MPoly::totloop, BMLoop::v, v, write_face_grid_in_unsubdivide_grid(), and write_loop_in_face_grid().
Referenced by multires_unsubdivide_extract_single_grid_from_face_edge().
|
static |
Stores the data into the new grid from a BMVert. Used when there are no grids in the original mesh.
Definition at line 690 of file multires_unsubdivide.c.
References BMVert::co, copy_v3_v3(), MultiresUnsubdivideGrid::grid_co, MultiresUnsubdivideGrid::grid_size, and v.
Referenced by multires_unsubdivide_extract_single_grid_from_face_edge().
Builds a base mesh one subdivision level down from the current original mesh if the original mesh has a valid solution stored in the BMVert tags.
Definition at line 394 of file multires_unsubdivide.c.
References bm, BM_EDGE, BM_edge_other_vert(), BM_EDGES_OF_VERT, BM_elem_flag_set, BM_elem_flag_test, BM_ELEM_SELECT, BM_ELEM_TAG, BM_FACE, BM_ITER_ELEM, BM_ITER_MESH, BM_mesh_elem_hflag_disable_all(), BM_mesh_elem_hflag_enable_all(), BM_VERT, BM_VERTS_OF_MESH, BMO_FLAG_DEFAULTS, BMO_FLAG_RESPECT_HIDE, BMO_op_callf(), and v.
Referenced by multires_unsubdivide_single_level().
Generates a possible solution for un-subdivision by tagging the (0,0) vertices of the possible grids.
This works using a flood fill operation using the quads diagonals to jump to the next vertex.
If initial_vertex is part of the base mesh solution, the flood fill should tag only the (0.0) vertices of the grids that need to be dissolved, and nothing else.
Definition at line 162 of file multires_unsubdivide.c.
References BLI_gsqueue_free(), BLI_gsqueue_is_empty(), BLI_gsqueue_new(), BLI_gsqueue_pop(), BLI_gsqueue_push(), bm, BM_elem_flag_set, BM_elem_index_get, BM_ELEM_TAG, BM_FACES_OF_VERT, BM_ITER_ELEM, BM_VERTS_OF_FACE, is_vertex_diagonal(), MEM_calloc_arrayN, MEM_freeN, queue, and BMesh::totvert.
Referenced by unsubdivide_tag_disconnected_mesh_element().
Returns the first pole that is found in an element ID.
Tries to give priority to 3 vert poles as they generally generate better results in cases were the un-subdivide solution is ambiguous.
Definition at line 89 of file multires_unsubdivide.c.
References bm, BM_ITER_MESH, BM_VERTS_OF_MESH, is_vertex_in_id(), is_vertex_pole(), is_vertex_pole_three(), NULL, and v.
Referenced by unsubdivide_tag_disconnected_mesh_element().
|
static |
Uses a flood fill operation to generate a different ID for each disconnected mesh element.
Definition at line 353 of file multires_unsubdivide.c.
References BLI_gsqueue_free(), BLI_gsqueue_is_empty(), BLI_gsqueue_new(), BLI_gsqueue_pop(), BLI_gsqueue_push(), bm, BM_edge_other_vert(), BM_EDGES_OF_VERT, BM_elem_index_get, BM_ITER_ELEM, BM_vert_at_index(), MEM_calloc_arrayN, MEM_freeN, queue, and BMesh::totvert.
Referenced by multires_unsubdivide_single_level().
Checks if the mesh is all quads.
TODO(pablodp606): This can perform additional checks if they are faster than trying to search for an un-subdivide solution. This way it is possible to cancel the operation faster.
Definition at line 111 of file multires_unsubdivide.c.
References bm, BM_FACES_OF_MESH, BM_ITER_ELEM, BM_ITER_MESH, BM_vert_edge_count(), BM_vert_is_wire(), BM_VERTS_OF_FACE, BM_VERTS_OF_MESH, count, BMesh::totface, and v.
Referenced by multires_unsubdivide_single_level().
This function checks if the current status of the BMVert tags corresponds to a valid un-subdivide solution.
This means that all vertices corresponding to the (0,0) grid coordinate should be tagged.
On a valid solution, the following things should happen:
Definition at line 241 of file multires_unsubdivide.c.
References bm, BM_elem_flag_test, BM_ELEM_TAG, BM_FACES_OF_VERT, BM_ITER_ELEM, BM_ITER_MESH, BM_vert_is_boundary(), BM_VERTS_OF_FACE, BM_VERTS_OF_MESH, is_vertex_in_id(), and v.
Referenced by unsubdivide_tag_disconnected_mesh_element().
|
static |
Search and validates an un-subdivide solution for a given element ID.
Definition at line 286 of file multires_unsubdivide.c.
References BLI_gsqueue_free(), BLI_gsqueue_is_empty(), BLI_gsqueue_new(), BLI_gsqueue_pop(), BLI_gsqueue_push(), bm, BM_elem_flag_set, BM_ELEM_TAG, BM_FACES_OF_MESH, BM_ITER_ELEM, BM_ITER_MESH, BM_VERTS_OF_FACE, BM_VERTS_OF_MESH, is_vertex_in_id(), NULL, unsubdivide_face_center_vertex_tag(), unsubdivide_find_any_pole(), unsubdivide_is_center_vertex_tag_valid(), and v.
Referenced by multires_unsubdivide_single_level().
|
static |
Writes a buffer containing the 4 grids in the correct orientation of the 4 loops of a face into the main MultiresUnsubdivideGrid that is being extracted.
Definition at line 609 of file multires_unsubdivide.c.
References copy_v3_v3(), MultiresUnsubdivideGrid::grid_co, MultiresUnsubdivideGrid::grid_size, x, and y.
Referenced by store_grid_data().
|
static |
Writes the current mdisp data into the corresponding area of quad poly giving its corner's loop.
Definition at line 548 of file multires_unsubdivide.c.
References BLI_assert_msg, copy_v3_v3(), MDisps::disps, x, and y.
Referenced by store_grid_data().
|
static |
Definition at line 879 of file multires_unsubdivide.c.
Referenced by multires_unsubdivide_add_original_index_datalayers(), multires_unsubdivide_extract_grids(), and multires_unsubdivide_free_original_datalayers().
|
static |
Definition at line 880 of file multires_unsubdivide.c.
Referenced by multires_unsubdivide_add_original_index_datalayers(), multires_unsubdivide_extract_grids(), multires_unsubdivide_free_original_datalayers(), and multires_unsubdivide_prepare_original_bmesh_for_extract().