Geometry Node: Make Capture Attributes more lazy #105264
|
@ -216,7 +216,7 @@ def use_upstream_workflow(args: argparse.Namespace) -> bool:
|
|||
return make_utils.git_remote_exist(args.git_command, "upstream")
|
||||
|
||||
|
||||
def work_tree_update_upstream_workflow(args: argparse.Namespace, use_fetch=True) -> str:
|
||||
def work_tree_update_upstream_workflow(args: argparse.Namespace, use_fetch: bool = True) -> str:
|
||||
"""
|
||||
Update the Blender repository using the Github style of fork organization
|
||||
|
||||
|
@ -240,7 +240,7 @@ def work_tree_update_upstream_workflow(args: argparse.Namespace, use_fetch=True)
|
|||
return ""
|
||||
|
||||
|
||||
def work_tree_update(args: argparse.Namespace, use_fetch=True) -> str:
|
||||
def work_tree_update(args: argparse.Namespace, use_fetch: bool = True) -> str:
|
||||
"""
|
||||
Update the Git working tree using the best strategy
|
||||
|
||||
|
@ -295,7 +295,7 @@ def external_script_copy_old_submodule_over(args: argparse.Namespace, directory_
|
|||
shutil.copytree(bare_repo_dir, external_dir / ".git")
|
||||
|
||||
git_config = external_dir / ".git" / "config"
|
||||
call((args.git_command, "config", "--file", git_config, "--unset", "core.worktree"))
|
||||
call((args.git_command, "config", "--file", str(git_config), "--unset", "core.worktree"))
|
||||
|
||||
|
||||
def external_script_initialize_if_needed(args: argparse.Namespace,
|
||||
|
@ -322,12 +322,12 @@ def external_script_initialize_if_needed(args: argparse.Namespace,
|
|||
blender_url = make_utils.git_get_remote_url(args.git_command, origin_name)
|
||||
external_url = resolve_external_url(blender_url, repo_name)
|
||||
|
||||
call((args.git_command, "clone", "--origin", origin_name, external_url, external_dir))
|
||||
call((args.git_command, "clone", "--origin", origin_name, external_url, str(external_dir)))
|
||||
|
||||
|
||||
def external_script_add_origin_if_needed(args: argparse.Namespace,
|
||||
repo_name: str,
|
||||
directory_name: str) -> str:
|
||||
directory_name: str) -> None:
|
||||
"""
|
||||
Add remote called 'origin' if there is a fork of the external repository available
|
||||
|
||||
|
@ -335,7 +335,7 @@ def external_script_add_origin_if_needed(args: argparse.Namespace,
|
|||
"""
|
||||
|
||||
if not use_upstream_workflow(args):
|
||||
return ""
|
||||
return
|
||||
|
||||
cwd = os.getcwd()
|
||||
|
||||
|
@ -382,7 +382,7 @@ def external_script_add_origin_if_needed(args: argparse.Namespace,
|
|||
finally:
|
||||
os.chdir(cwd)
|
||||
|
||||
return ""
|
||||
return
|
||||
|
||||
|
||||
def external_scripts_update(args: argparse.Namespace,
|
||||
|
|
|
@ -68,7 +68,7 @@ def git_branch_exists(git_command: str, branch: str) -> bool:
|
|||
)
|
||||
|
||||
|
||||
def git_get_remote_url(git_command: str, remote_name: str) -> bool:
|
||||
def git_get_remote_url(git_command: str, remote_name: str) -> str:
|
||||
return check_output((git_command, "ls-remote", "--get-url", remote_name))
|
||||
|
||||
|
||||
|
|
|
@ -1228,4 +1228,4 @@ void GHOST_GetVulkanBackbuffer(GHOST_WindowHandle windowhandle,
|
|||
window->getVulkanBackbuffer(image, framebuffer, render_pass, extent, fb_id);
|
||||
}
|
||||
|
||||
#endif /* WITH_VULKAN */
|
||||
#endif /* WITH_VULKAN_BACKEND */
|
||||
|
|
|
@ -1226,7 +1226,7 @@ static GHOST_Context *create_glx_context(Window window,
|
|||
|
||||
GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type)
|
||||
{
|
||||
#if defined(WITH_VULKAN)
|
||||
#if defined(WITH_VULKAN_BACKEND)
|
||||
if (type == GHOST_kDrawingContextTypeVulkan) {
|
||||
GHOST_Context *context = new GHOST_ContextVK(m_wantStereoVisual,
|
||||
GHOST_kVulkanPlatformX11,
|
||||
|
|
|
@ -363,6 +363,7 @@ const bTheme U_theme_default = {
|
|||
.handle_sel_vect = RGBA(0x40c030ff),
|
||||
.handle_sel_align = RGBA(0xf090a0ff),
|
||||
.vertex_size = 3,
|
||||
.edge_width = 1,
|
||||
.outline_width = 1,
|
||||
.obcenter_dia = 6,
|
||||
.facedot_size = 3,
|
||||
|
@ -717,6 +718,7 @@ const bTheme U_theme_default = {
|
|||
.handle_sel_auto = RGBA(0xf0ff40ff),
|
||||
.handle_sel_align = RGBA(0xf090a0ff),
|
||||
.vertex_size = 3,
|
||||
.edge_width = 1,
|
||||
.outline_width = 1,
|
||||
.facedot_size = 3,
|
||||
.editmesh_active = RGBA(0xffffff40),
|
||||
|
|
|
@ -60,12 +60,12 @@ extern "C" {
|
|||
/**
|
||||
* Call after changing vertex positions to tag lazily calculated caches for recomputation.
|
||||
*/
|
||||
void BKE_mesh_tag_coords_changed(struct Mesh *mesh);
|
||||
void BKE_mesh_tag_positions_changed(struct Mesh *mesh);
|
||||
|
||||
/**
|
||||
* Call after moving every mesh vertex by the same translation.
|
||||
*/
|
||||
void BKE_mesh_tag_coords_changed_uniformly(struct Mesh *mesh);
|
||||
void BKE_mesh_tag_positions_changed_uniformly(struct Mesh *mesh);
|
||||
|
||||
void BKE_mesh_tag_topology_changed(struct Mesh *mesh);
|
||||
|
||||
|
@ -164,6 +164,7 @@ struct Mesh *BKE_mesh_new_nomain_from_template(
|
|||
struct Mesh *BKE_mesh_new_nomain_from_template_ex(const struct Mesh *me_src,
|
||||
int verts_len,
|
||||
int edges_len,
|
||||
int tessface_len,
|
||||
int loops_len,
|
||||
int polys_len,
|
||||
struct CustomData_MeshMasks mask);
|
||||
|
@ -341,7 +342,7 @@ void BKE_mesh_recalc_looptri_with_normals(const struct MLoop *mloop,
|
|||
* from a vertices surrounding faces, or the normalized position of vertices connected to no faces.
|
||||
* \warning May still return null if the mesh is empty.
|
||||
*/
|
||||
const float (*BKE_mesh_vertex_normals_ensure(const struct Mesh *mesh))[3];
|
||||
const float (*BKE_mesh_vert_normals_ensure(const struct Mesh *mesh))[3];
|
||||
|
||||
/**
|
||||
* Return the normal direction of every polygon, which is defined by the winding direction of its
|
||||
|
@ -364,13 +365,13 @@ void BKE_mesh_normals_tag_dirty(struct Mesh *mesh);
|
|||
* calculated automatically.
|
||||
*
|
||||
* \note In order to clear the dirty flag, this function should be followed by a call to
|
||||
* #BKE_mesh_vertex_normals_clear_dirty. This is separate so that normals are still tagged dirty
|
||||
* #BKE_mesh_vert_normals_clear_dirty. This is separate so that normals are still tagged dirty
|
||||
* while they are being assigned.
|
||||
*
|
||||
* \warning The memory returned by this function is not initialized if it was not previously
|
||||
* allocated.
|
||||
*/
|
||||
float (*BKE_mesh_vertex_normals_for_write(struct Mesh *mesh))[3];
|
||||
float (*BKE_mesh_vert_normals_for_write(struct Mesh *mesh))[3];
|
||||
|
||||
/**
|
||||
* Retrieve write access to the cached polygon normals, ensuring that they are allocated but *not*
|
||||
|
@ -389,7 +390,7 @@ float (*BKE_mesh_poly_normals_for_write(struct Mesh *mesh))[3];
|
|||
/**
|
||||
* Mark the mesh's vertex normals non-dirty, for when they are calculated or assigned manually.
|
||||
*/
|
||||
void BKE_mesh_vertex_normals_clear_dirty(struct Mesh *mesh);
|
||||
void BKE_mesh_vert_normals_clear_dirty(struct Mesh *mesh);
|
||||
|
||||
/**
|
||||
* Mark the mesh's poly normals non-dirty, for when they are calculated or assigned manually.
|
||||
|
@ -400,7 +401,7 @@ void BKE_mesh_poly_normals_clear_dirty(struct Mesh *mesh);
|
|||
* Return true if the mesh vertex normals either are not stored or are dirty.
|
||||
* This can be used to help decide whether to transfer them when copying a mesh.
|
||||
*/
|
||||
bool BKE_mesh_vertex_normals_are_dirty(const struct Mesh *mesh);
|
||||
bool BKE_mesh_vert_normals_are_dirty(const struct Mesh *mesh);
|
||||
|
||||
/**
|
||||
* Return true if the mesh polygon normals either are not stored or are dirty.
|
||||
|
@ -430,7 +431,7 @@ void BKE_mesh_calc_normals_poly(const float (*vert_positions)[3],
|
|||
/**
|
||||
* Calculate face and vertex normals directly into result arrays.
|
||||
*
|
||||
* \note Usually #BKE_mesh_vertex_normals_ensure is the preferred way to access vertex normals,
|
||||
* \note Usually #BKE_mesh_vert_normals_ensure is the preferred way to access vertex normals,
|
||||
* since they may already be calculated and cached on the mesh.
|
||||
*/
|
||||
void BKE_mesh_calc_normals_poly_and_vertex(const float (*vert_positions)[3],
|
||||
|
@ -446,7 +447,7 @@ void BKE_mesh_calc_normals_poly_and_vertex(const float (*vert_positions)[3],
|
|||
* Calculate vertex and face normals, storing the result in custom data layers on the mesh.
|
||||
*
|
||||
* \note It is usually preferable to calculate normals lazily with
|
||||
* #BKE_mesh_vertex_normals_ensure, but some areas (perhaps unnecessarily)
|
||||
* #BKE_mesh_vert_normals_ensure, but some areas (perhaps unnecessarily)
|
||||
* can also calculate them eagerly.
|
||||
*/
|
||||
void BKE_mesh_calc_normals(struct Mesh *me);
|
||||
|
@ -1059,9 +1060,9 @@ inline blender::Span<blender::float3> Mesh::poly_normals() const
|
|||
this->totpoly};
|
||||
}
|
||||
|
||||
inline blender::Span<blender::float3> Mesh::vertex_normals() const
|
||||
inline blender::Span<blender::float3> Mesh::vert_normals() const
|
||||
{
|
||||
return {reinterpret_cast<const blender::float3 *>(BKE_mesh_vertex_normals_ensure(this)),
|
||||
return {reinterpret_cast<const blender::float3 *>(BKE_mesh_vert_normals_ensure(this)),
|
||||
this->totvert};
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ void BKE_mesh_runtime_reset_edit_data(struct Mesh *mesh);
|
|||
* directly or making other large changes to topology. It does not need to be called on new meshes.
|
||||
*
|
||||
* For "smaller" changes to meshes like updating positions, consider calling a more specific update
|
||||
* function like #BKE_mesh_tag_coords_changed.
|
||||
* function like #BKE_mesh_tag_positions_changed.
|
||||
*
|
||||
* Also note that some derived caches like #CD_NORMAL and #CD_TANGENT are stored directly in
|
||||
* #CustomData.
|
||||
|
|
|
@ -21,9 +21,9 @@ struct MovieDistortion;
|
|||
|
||||
/**
|
||||
* Checks if image was already loaded, then returns same image otherwise creates new.
|
||||
* does not load ibuf itself pass on optional frame for #name images.
|
||||
* does not load ibuf itself pass on optional frame for `filepath` images.
|
||||
*/
|
||||
struct MovieClip *BKE_movieclip_file_add(struct Main *bmain, const char *name);
|
||||
struct MovieClip *BKE_movieclip_file_add(struct Main *bmain, const char *filepath);
|
||||
struct MovieClip *BKE_movieclip_file_add_exists_ex(struct Main *bmain,
|
||||
const char *filepath,
|
||||
bool *r_exists);
|
||||
|
@ -106,9 +106,9 @@ bool BKE_movieclip_proxy_enabled(struct MovieClip *clip);
|
|||
float BKE_movieclip_remap_scene_to_clip_frame(const struct MovieClip *clip, float framenr);
|
||||
float BKE_movieclip_remap_clip_to_scene_frame(const struct MovieClip *clip, float framenr);
|
||||
|
||||
void BKE_movieclip_filename_for_frame(struct MovieClip *clip,
|
||||
void BKE_movieclip_filepath_for_frame(struct MovieClip *clip,
|
||||
const struct MovieClipUser *user,
|
||||
char *name);
|
||||
char *filepath);
|
||||
|
||||
/**
|
||||
* Read image buffer from the given movie clip without acquiring the #LOCK_MOVIECLIP lock.
|
||||
|
|
|
@ -103,9 +103,9 @@ bool txt_add_char(struct Text *text, unsigned int add);
|
|||
bool txt_add_raw_char(struct Text *text, unsigned int add);
|
||||
bool txt_replace_char(struct Text *text, unsigned int add);
|
||||
bool txt_unindent(struct Text *text);
|
||||
void txt_comment(struct Text *text);
|
||||
void txt_indent(struct Text *text);
|
||||
bool txt_uncomment(struct Text *text);
|
||||
void txt_comment(struct Text *text, const char *prefix);
|
||||
bool txt_uncomment(struct Text *text, const char *prefix);
|
||||
void txt_move_lines(struct Text *text, int direction);
|
||||
void txt_duplicate_line(struct Text *text);
|
||||
int txt_setcurr_tab_spaces(struct Text *text, int space);
|
||||
|
|
|
@ -54,6 +54,10 @@ bool BKE_vfont_is_builtin(const struct VFont *vfont);
|
|||
void BKE_vfont_builtin_register(const void *mem, int size);
|
||||
|
||||
void BKE_vfont_free_data(struct VFont *vfont);
|
||||
/**
|
||||
* Return the built-in #VFont, without adding a user (the user-count may be zero).
|
||||
* The caller is responsible for adding a user.
|
||||
*/
|
||||
struct VFont *BKE_vfont_builtin_get(void);
|
||||
struct VFont *BKE_vfont_load(struct Main *bmain, const char *filepath);
|
||||
struct VFont *BKE_vfont_load_exists_ex(struct Main *bmain, const char *filepath, bool *r_exists);
|
||||
|
|
|
@ -580,7 +580,7 @@ static void bvhtree_from_mesh_setup_data(BVHTree *tree,
|
|||
const MEdge *edge,
|
||||
const MFace *face,
|
||||
const MLoop *loop,
|
||||
const MLoopTri *looptri,
|
||||
const Span<MLoopTri> looptris,
|
||||
BVHTreeFromMesh *r_data)
|
||||
{
|
||||
memset(r_data, 0, sizeof(*r_data));
|
||||
|
@ -591,7 +591,7 @@ static void bvhtree_from_mesh_setup_data(BVHTree *tree,
|
|||
r_data->edge = edge;
|
||||
r_data->face = face;
|
||||
r_data->loop = loop;
|
||||
r_data->looptri = looptri;
|
||||
r_data->looptri = looptris.data();
|
||||
|
||||
switch (bvh_cache_type) {
|
||||
case BVHTREE_FROM_VERTS:
|
||||
|
@ -779,7 +779,7 @@ BVHTree *bvhtree_from_mesh_verts_ex(BVHTreeFromMesh *data,
|
|||
if (data) {
|
||||
/* Setup BVHTreeFromMesh */
|
||||
bvhtree_from_mesh_setup_data(
|
||||
tree, BVHTREE_FROM_VERTS, vert_positions, nullptr, nullptr, nullptr, nullptr, data);
|
||||
tree, BVHTREE_FROM_VERTS, vert_positions, nullptr, nullptr, nullptr, {}, data);
|
||||
}
|
||||
|
||||
return tree;
|
||||
|
@ -914,7 +914,7 @@ BVHTree *bvhtree_from_mesh_edges_ex(BVHTreeFromMesh *data,
|
|||
if (data) {
|
||||
/* Setup BVHTreeFromMesh */
|
||||
bvhtree_from_mesh_setup_data(
|
||||
tree, BVHTREE_FROM_EDGES, vert_positions, edge, nullptr, nullptr, nullptr, data);
|
||||
tree, BVHTREE_FROM_EDGES, vert_positions, edge, nullptr, nullptr, {}, data);
|
||||
}
|
||||
|
||||
return tree;
|
||||
|
@ -1037,16 +1037,15 @@ static BVHTree *bvhtree_from_mesh_looptri_create_tree(float epsilon,
|
|||
int axis,
|
||||
const float (*positions)[3],
|
||||
const MLoop *mloop,
|
||||
const MLoopTri *looptri,
|
||||
const int looptri_num,
|
||||
const Span<MLoopTri> looptris,
|
||||
const BitSpan looptri_mask,
|
||||
int looptri_num_active)
|
||||
{
|
||||
if (!looptri_mask.is_empty()) {
|
||||
BLI_assert(IN_RANGE_INCL(looptri_num_active, 0, looptri_num));
|
||||
BLI_assert(IN_RANGE_INCL(looptri_num_active, 0, looptris.size()));
|
||||
}
|
||||
else {
|
||||
looptri_num_active = looptri_num;
|
||||
looptri_num_active = looptris.size();
|
||||
}
|
||||
if (looptri_num_active == 0) {
|
||||
return nullptr;
|
||||
|
@ -1059,16 +1058,16 @@ static BVHTree *bvhtree_from_mesh_looptri_create_tree(float epsilon,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
if (positions && looptri) {
|
||||
for (int i = 0; i < looptri_num; i++) {
|
||||
if (positions && !looptris.is_empty()) {
|
||||
for (const int i : looptris.index_range()) {
|
||||
float co[3][3];
|
||||
if (!looptri_mask.is_empty() && !looptri_mask[i]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
copy_v3_v3(co[0], positions[mloop[looptri[i].tri[0]].v]);
|
||||
copy_v3_v3(co[1], positions[mloop[looptri[i].tri[1]].v]);
|
||||
copy_v3_v3(co[2], positions[mloop[looptri[i].tri[2]].v]);
|
||||
copy_v3_v3(co[0], positions[mloop[looptris[i].tri[0]].v]);
|
||||
copy_v3_v3(co[1], positions[mloop[looptris[i].tri[1]].v]);
|
||||
copy_v3_v3(co[2], positions[mloop[looptris[i].tri[2]].v]);
|
||||
|
||||
BLI_bvhtree_insert(tree, i, co[0], 3);
|
||||
}
|
||||
|
@ -1121,8 +1120,7 @@ BVHTree *bvhtree_from_mesh_looptri_ex(BVHTreeFromMesh *data,
|
|||
axis,
|
||||
vert_positions,
|
||||
mloop,
|
||||
looptri,
|
||||
looptri_num,
|
||||
{looptri, looptri_num},
|
||||
looptri_mask,
|
||||
looptri_num_active);
|
||||
|
||||
|
@ -1130,8 +1128,14 @@ BVHTree *bvhtree_from_mesh_looptri_ex(BVHTreeFromMesh *data,
|
|||
|
||||
if (data) {
|
||||
/* Setup BVHTreeFromMesh */
|
||||
bvhtree_from_mesh_setup_data(
|
||||
tree, BVHTREE_FROM_LOOPTRI, vert_positions, nullptr, nullptr, mloop, looptri, data);
|
||||
bvhtree_from_mesh_setup_data(tree,
|
||||
BVHTREE_FROM_LOOPTRI,
|
||||
vert_positions,
|
||||
nullptr,
|
||||
nullptr,
|
||||
mloop,
|
||||
{looptri, looptri_num},
|
||||
data);
|
||||
}
|
||||
|
||||
return tree;
|
||||
|
@ -1208,11 +1212,9 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
|
|||
{
|
||||
BVHCache **bvh_cache_p = (BVHCache **)&mesh->runtime->bvh_cache;
|
||||
|
||||
const MLoopTri *looptri = nullptr;
|
||||
int looptri_len = 0;
|
||||
Span<MLoopTri> looptris;
|
||||
if (ELEM(bvh_cache_type, BVHTREE_FROM_LOOPTRI, BVHTREE_FROM_LOOPTRI_NO_HIDDEN)) {
|
||||
looptri = BKE_mesh_runtime_looptri_ensure(mesh);
|
||||
looptri_len = BKE_mesh_runtime_looptri_len(mesh);
|
||||
looptris = mesh->looptris();
|
||||
}
|
||||
const float(*positions)[3] = reinterpret_cast<const float(*)[3]>(mesh->vert_positions().data());
|
||||
const Span<MEdge> edges = mesh->edges();
|
||||
|
@ -1225,7 +1227,7 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
|
|||
edges.data(),
|
||||
(const MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE),
|
||||
loops.data(),
|
||||
looptri,
|
||||
looptris,
|
||||
data);
|
||||
|
||||
bool lock_started = false;
|
||||
|
@ -1278,20 +1280,13 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
|
|||
mask = looptri_no_hidden_map_get(
|
||||
mesh->polys(),
|
||||
attributes.lookup_or_default(".hide_poly", ATTR_DOMAIN_FACE, false),
|
||||
looptri_len,
|
||||
looptris.size(),
|
||||
&mask_bits_act_len);
|
||||
ATTR_FALLTHROUGH;
|
||||
}
|
||||
case BVHTREE_FROM_LOOPTRI:
|
||||
data->tree = bvhtree_from_mesh_looptri_create_tree(0.0f,
|
||||
tree_type,
|
||||
6,
|
||||
positions,
|
||||
loops.data(),
|
||||
looptri,
|
||||
looptri_len,
|
||||
mask,
|
||||
mask_bits_act_len);
|
||||
data->tree = bvhtree_from_mesh_looptri_create_tree(
|
||||
0.0f, tree_type, 6, positions, loops.data(), looptris, mask, mask_bits_act_len);
|
||||
break;
|
||||
case BVHTREE_FROM_EM_VERTS:
|
||||
case BVHTREE_FROM_EM_EDGES:
|
||||
|
|
|
@ -222,7 +222,7 @@ static DerivedMesh *cdDM_from_mesh_ex(Mesh *mesh,
|
|||
&dm->vertData, CD_PROP_FLOAT3, "position", mesh->totvert));
|
||||
/* Though this may be an unnecessary calculation, simply retrieving the layer may return nothing
|
||||
* or dirty normals. */
|
||||
cddm->vert_normals = BKE_mesh_vertex_normals_ensure(mesh);
|
||||
cddm->vert_normals = BKE_mesh_vert_normals_ensure(mesh);
|
||||
cddm->medge = static_cast<MEdge *>(
|
||||
CustomData_get_layer_for_write(&dm->edgeData, CD_MEDGE, mesh->totedge));
|
||||
cddm->mloop = static_cast<MLoop *>(
|
||||
|
|
|
@ -836,9 +836,8 @@ static bool cloth_from_object(
|
|||
static void cloth_from_mesh(ClothModifierData *clmd, const Object *ob, Mesh *mesh)
|
||||
{
|
||||
const blender::Span<MLoop> loops = mesh->loops();
|
||||
const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(mesh);
|
||||
const blender::Span<MLoopTri> looptris = mesh->looptris();
|
||||
const uint mvert_num = mesh->totvert;
|
||||
const uint looptri_num = BKE_mesh_runtime_looptri_len(mesh);
|
||||
|
||||
/* Allocate our vertices. */
|
||||
clmd->clothObject->mvert_num = mvert_num;
|
||||
|
@ -853,14 +852,14 @@ static void cloth_from_mesh(ClothModifierData *clmd, const Object *ob, Mesh *mes
|
|||
|
||||
/* save face information */
|
||||
if (clmd->hairdata == nullptr) {
|
||||
clmd->clothObject->primitive_num = looptri_num;
|
||||
clmd->clothObject->primitive_num = looptris.size();
|
||||
}
|
||||
else {
|
||||
clmd->clothObject->primitive_num = mesh->totedge;
|
||||
}
|
||||
|
||||
clmd->clothObject->tri = static_cast<MVertTri *>(
|
||||
MEM_malloc_arrayN(looptri_num, sizeof(MVertTri), __func__));
|
||||
MEM_malloc_arrayN(looptris.size(), sizeof(MVertTri), __func__));
|
||||
if (clmd->clothObject->tri == nullptr) {
|
||||
cloth_free_modifier(clmd);
|
||||
BKE_modifier_set_error(
|
||||
|
@ -869,7 +868,7 @@ static void cloth_from_mesh(ClothModifierData *clmd, const Object *ob, Mesh *mes
|
|||
return;
|
||||
}
|
||||
BKE_mesh_runtime_verttri_from_looptri(
|
||||
clmd->clothObject->tri, loops.data(), looptri, looptri_num);
|
||||
clmd->clothObject->tri, loops.data(), looptris.data(), looptris.size());
|
||||
|
||||
clmd->clothObject->edges = mesh->edges().data();
|
||||
|
||||
|
@ -1185,7 +1184,7 @@ static Mesh *cloth_make_rest_mesh(ClothModifierData *clmd, Mesh *mesh)
|
|||
for (const int i : positions.index_range()) {
|
||||
positions[i] = verts[i].xrest;
|
||||
}
|
||||
BKE_mesh_tag_coords_changed(new_mesh);
|
||||
BKE_mesh_tag_positions_changed(new_mesh);
|
||||
|
||||
return new_mesh;
|
||||
}
|
||||
|
@ -1531,7 +1530,7 @@ static bool cloth_build_springs(ClothModifierData *clmd, Mesh *mesh)
|
|||
BKE_bvhtree_from_mesh_get(&treedata, tmp_mesh ? tmp_mesh : mesh, BVHTREE_FROM_LOOPTRI, 2);
|
||||
rng = BLI_rng_new_srandom(0);
|
||||
|
||||
const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(tmp_mesh ? tmp_mesh : mesh);
|
||||
const float(*vert_normals)[3] = BKE_mesh_vert_normals_ensure(tmp_mesh ? tmp_mesh : mesh);
|
||||
|
||||
for (int i = 0; i < mvert_num; i++) {
|
||||
if (find_internal_spring_target_vertex(
|
||||
|
|
|
@ -546,7 +546,7 @@ static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[
|
|||
}
|
||||
}
|
||||
else if (me_eval) {
|
||||
const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(me_eval);
|
||||
const float(*vert_normals)[3] = BKE_mesh_vert_normals_ensure(me_eval);
|
||||
const MDeformVert *dvert = CustomData_get_layer(&me_eval->vdata, CD_MDEFORMVERT);
|
||||
const float(*positions)[3] = BKE_mesh_vert_positions(me_eval);
|
||||
int numVerts = me_eval->totvert;
|
||||
|
|
|
@ -383,7 +383,7 @@ static void data_transfer_dtdata_type_preprocess(Mesh *me_src,
|
|||
const bool *sharp_edges = static_cast<const bool *>(
|
||||
CustomData_get_layer_named(&me_dst->edata, CD_PROP_BOOL, "sharp_edge"));
|
||||
BKE_mesh_normals_loop_split(positions_dst,
|
||||
BKE_mesh_vertex_normals_ensure(me_dst),
|
||||
BKE_mesh_vert_normals_ensure(me_dst),
|
||||
num_verts_dst,
|
||||
edges_dst.data(),
|
||||
edges_dst.size(),
|
||||
|
@ -442,7 +442,7 @@ static void data_transfer_dtdata_type_postprocess(Object * /*ob_src*/,
|
|||
|
||||
/* Note loop_nors_dst contains our custom normals as transferred from source... */
|
||||
BKE_mesh_normals_loop_custom_set(positions_dst,
|
||||
BKE_mesh_vertex_normals_ensure(me_dst),
|
||||
BKE_mesh_vert_normals_ensure(me_dst),
|
||||
num_verts_dst,
|
||||
edges_dst.data(),
|
||||
edges_dst.size(),
|
||||
|
@ -1344,7 +1344,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
|
|||
BLI_assert((ob_src != ob_dst) && (ob_src->type == OB_MESH) && (ob_dst->type == OB_MESH));
|
||||
|
||||
if (me_dst) {
|
||||
dirty_nors_dst = BKE_mesh_vertex_normals_are_dirty(me_dst);
|
||||
dirty_nors_dst = BKE_mesh_vert_normals_are_dirty(me_dst);
|
||||
/* Never create needed custom layers on passed destination mesh
|
||||
* (assumed to *not* be ob_dst->data, aka modifier case). */
|
||||
use_create = false;
|
||||
|
|
|
@ -1481,7 +1481,7 @@ struct DynamicPaintSetInitColorData {
|
|||
|
||||
blender::Span<MLoop> loops;
|
||||
const float (*mloopuv)[2];
|
||||
const MLoopTri *mlooptri;
|
||||
blender::Span<MLoopTri> looptris;
|
||||
const MLoopCol *mloopcol;
|
||||
ImagePool *pool;
|
||||
|
||||
|
@ -1498,7 +1498,7 @@ static void dynamic_paint_set_init_color_tex_to_vcol_cb(void *__restrict userdat
|
|||
PaintPoint *pPoint = (PaintPoint *)sData->type_data;
|
||||
|
||||
const blender::Span<MLoop> loops = data->loops;
|
||||
const MLoopTri *mlooptri = data->mlooptri;
|
||||
const blender::Span<MLoopTri> looptris = data->looptris;
|
||||
const float(*mloopuv)[2] = data->mloopuv;
|
||||
ImagePool *pool = data->pool;
|
||||
Tex *tex = data->surface->init_texture;
|
||||
|
@ -1509,11 +1509,11 @@ static void dynamic_paint_set_init_color_tex_to_vcol_cb(void *__restrict userdat
|
|||
|
||||
for (int j = 3; j--;) {
|
||||
TexResult texres = {0};
|
||||
const uint vert = loops[mlooptri[i].tri[j]].v;
|
||||
const uint vert = loops[looptris[i].tri[j]].v;
|
||||
|
||||
/* remap to [-1.0, 1.0] */
|
||||
uv[0] = mloopuv[mlooptri[i].tri[j]][0] * 2.0f - 1.0f;
|
||||
uv[1] = mloopuv[mlooptri[i].tri[j]][1] * 2.0f - 1.0f;
|
||||
uv[0] = mloopuv[looptris[i].tri[j]][0] * 2.0f - 1.0f;
|
||||
uv[1] = mloopuv[looptris[i].tri[j]][1] * 2.0f - 1.0f;
|
||||
|
||||
multitex_ext_safe(tex, uv, &texres, pool, scene_color_manage, false);
|
||||
|
||||
|
@ -1533,7 +1533,7 @@ static void dynamic_paint_set_init_color_tex_to_imseq_cb(void *__restrict userda
|
|||
const PaintSurfaceData *sData = data->surface->data;
|
||||
PaintPoint *pPoint = (PaintPoint *)sData->type_data;
|
||||
|
||||
const MLoopTri *mlooptri = data->mlooptri;
|
||||
const blender::Span<MLoopTri> looptris = data->looptris;
|
||||
const float(*mloopuv)[2] = data->mloopuv;
|
||||
Tex *tex = data->surface->init_texture;
|
||||
ImgSeqFormatData *f_data = (ImgSeqFormatData *)sData->format_data;
|
||||
|
@ -1548,7 +1548,7 @@ static void dynamic_paint_set_init_color_tex_to_imseq_cb(void *__restrict userda
|
|||
|
||||
/* collect all uvs */
|
||||
for (int j = 3; j--;) {
|
||||
copy_v2_v2(&uv[j * 3], mloopuv[mlooptri[f_data->uv_p[i].tri_index].tri[j]]);
|
||||
copy_v2_v2(&uv[j * 3], mloopuv[looptris[f_data->uv_p[i].tri_index].tri[j]]);
|
||||
}
|
||||
|
||||
/* interpolate final uv pos */
|
||||
|
@ -1572,7 +1572,7 @@ static void dynamic_paint_set_init_color_vcol_to_imseq_cb(
|
|||
const PaintSurfaceData *sData = data->surface->data;
|
||||
PaintPoint *pPoint = (PaintPoint *)sData->type_data;
|
||||
|
||||
const MLoopTri *mlooptri = data->mlooptri;
|
||||
const blender::Span<MLoopTri> looptris = data->looptris;
|
||||
const MLoopCol *mloopcol = data->mloopcol;
|
||||
ImgSeqFormatData *f_data = (ImgSeqFormatData *)sData->format_data;
|
||||
const int samples = (data->surface->flags & MOD_DPAINT_ANTIALIAS) ? 5 : 1;
|
||||
|
@ -1583,7 +1583,7 @@ static void dynamic_paint_set_init_color_vcol_to_imseq_cb(
|
|||
|
||||
/* collect color values */
|
||||
for (int j = 3; j--;) {
|
||||
rgba_uchar_to_float(colors[j], (const uchar *)&mloopcol[mlooptri[tri_idx].tri[j]].r);
|
||||
rgba_uchar_to_float(colors[j], (const uchar *)&mloopcol[looptris[tri_idx].tri[j]].r);
|
||||
}
|
||||
|
||||
/* interpolate final color */
|
||||
|
@ -1619,8 +1619,7 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface
|
|||
Tex *tex = surface->init_texture;
|
||||
|
||||
const blender::Span<MLoop> loops = mesh->loops();
|
||||
const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(mesh);
|
||||
const int tottri = BKE_mesh_runtime_looptri_len(mesh);
|
||||
const blender::Span<MLoopTri> looptris = mesh->looptris();
|
||||
|
||||
char uvname[MAX_CUSTOMDATA_LAYER_NAME];
|
||||
|
||||
|
@ -1645,22 +1644,22 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface
|
|||
DynamicPaintSetInitColorData data{};
|
||||
data.surface = surface;
|
||||
data.loops = loops;
|
||||
data.mlooptri = mlooptri;
|
||||
data.looptris = looptris;
|
||||
data.mloopuv = mloopuv;
|
||||
data.pool = pool;
|
||||
data.scene_color_manage = scene_color_manage;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BLI_parallel_range_settings_defaults(&settings);
|
||||
settings.use_threading = (tottri > 1000);
|
||||
settings.use_threading = (looptris.size() > 1000);
|
||||
BLI_task_parallel_range(
|
||||
0, tottri, &data, dynamic_paint_set_init_color_tex_to_vcol_cb, &settings);
|
||||
0, looptris.size(), &data, dynamic_paint_set_init_color_tex_to_vcol_cb, &settings);
|
||||
BKE_image_pool_free(pool);
|
||||
}
|
||||
else if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) {
|
||||
DynamicPaintSetInitColorData data{};
|
||||
data.surface = surface;
|
||||
data.mlooptri = mlooptri;
|
||||
data.looptris = looptris;
|
||||
data.mloopuv = mloopuv;
|
||||
data.scene_color_manage = scene_color_manage;
|
||||
|
||||
|
@ -1688,7 +1687,7 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface
|
|||
}
|
||||
}
|
||||
else if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) {
|
||||
const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(mesh);
|
||||
const blender::Span<MLoopTri> looptris = mesh->looptris();
|
||||
const MLoopCol *col = static_cast<const MLoopCol *>(
|
||||
CustomData_get_layer_named(&mesh->ldata, CD_PROP_BYTE_COLOR, surface->init_layername));
|
||||
if (!col) {
|
||||
|
@ -1697,7 +1696,7 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface
|
|||
|
||||
DynamicPaintSetInitColorData data{};
|
||||
data.surface = surface;
|
||||
data.mlooptri = mlooptri;
|
||||
data.looptris = looptris;
|
||||
data.mloopcol = col;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
|
@ -1828,7 +1827,7 @@ static void dynamicPaint_applySurfaceDisplace(DynamicPaintSurface *surface, Mesh
|
|||
DynamicPaintModifierApplyData data{};
|
||||
data.surface = surface;
|
||||
data.vert_positions = BKE_mesh_vert_positions_for_write(result);
|
||||
data.vert_normals = BKE_mesh_vertex_normals_ensure(result);
|
||||
data.vert_normals = BKE_mesh_vert_normals_ensure(result);
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BLI_parallel_range_settings_defaults(&settings);
|
||||
|
@ -2029,20 +2028,20 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object *
|
|||
DynamicPaintModifierApplyData data{};
|
||||
data.surface = surface;
|
||||
data.vert_positions = BKE_mesh_vert_positions_for_write(result);
|
||||
data.vert_normals = BKE_mesh_vertex_normals_ensure(result);
|
||||
data.vert_normals = BKE_mesh_vert_normals_ensure(result);
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BLI_parallel_range_settings_defaults(&settings);
|
||||
settings.use_threading = (sData->total_points > 1000);
|
||||
BLI_task_parallel_range(
|
||||
0, sData->total_points, &data, dynamic_paint_apply_surface_wave_cb, &settings);
|
||||
BKE_mesh_tag_coords_changed(result);
|
||||
BKE_mesh_tag_positions_changed(result);
|
||||
}
|
||||
|
||||
/* displace */
|
||||
if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) {
|
||||
dynamicPaint_applySurfaceDisplace(surface, result);
|
||||
BKE_mesh_tag_coords_changed(result);
|
||||
BKE_mesh_tag_positions_changed(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2192,10 +2191,9 @@ struct DynamicPaintCreateUVSurfaceData {
|
|||
PaintUVPoint *tempPoints;
|
||||
Vec3f *tempWeights;
|
||||
|
||||
const MLoopTri *mlooptri;
|
||||
blender::Span<MLoopTri> looptris;
|
||||
const float (*mloopuv)[2];
|
||||
blender::Span<MLoop> loops;
|
||||
int tottri;
|
||||
|
||||
const Bounds2D *faceBB;
|
||||
uint32_t *active_points;
|
||||
|
@ -2212,10 +2210,9 @@ static void dynamic_paint_create_uv_surface_direct_cb(void *__restrict userdata,
|
|||
PaintUVPoint *tempPoints = data->tempPoints;
|
||||
Vec3f *tempWeights = data->tempWeights;
|
||||
|
||||
const MLoopTri *mlooptri = data->mlooptri;
|
||||
const blender::Span<MLoopTri> looptris = data->looptris;
|
||||
const float(*mloopuv)[2] = data->mloopuv;
|
||||
const blender::Span<MLoop> loops = data->loops;
|
||||
const int tottri = data->tottri;
|
||||
|
||||
const Bounds2D *faceBB = data->faceBB;
|
||||
|
||||
|
@ -2259,16 +2256,16 @@ static void dynamic_paint_create_uv_surface_direct_cb(void *__restrict userdata,
|
|||
/* Loop through every face in the mesh */
|
||||
/* XXX TODO: This is *horrible* with big meshes, should use a 2D BVHTree over UV tris here!
|
||||
*/
|
||||
for (int i = 0; i < tottri; i++) {
|
||||
for (const int i : looptris.index_range()) {
|
||||
/* Check uv bb */
|
||||
if ((faceBB[i].min[0] > point[sample][0]) || (faceBB[i].min[1] > point[sample][1]) ||
|
||||
(faceBB[i].max[0] < point[sample][0]) || (faceBB[i].max[1] < point[sample][1])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const float *uv1 = mloopuv[mlooptri[i].tri[0]];
|
||||
const float *uv2 = mloopuv[mlooptri[i].tri[1]];
|
||||
const float *uv3 = mloopuv[mlooptri[i].tri[2]];
|
||||
const float *uv1 = mloopuv[looptris[i].tri[0]];
|
||||
const float *uv2 = mloopuv[looptris[i].tri[1]];
|
||||
const float *uv3 = mloopuv[looptris[i].tri[2]];
|
||||
|
||||
/* If point is inside the face */
|
||||
if (isect_point_tri_v2(point[sample], uv1, uv2, uv3) != 0) {
|
||||
|
@ -2286,9 +2283,9 @@ static void dynamic_paint_create_uv_surface_direct_cb(void *__restrict userdata,
|
|||
tPoint->tri_index = i;
|
||||
|
||||
/* save vertex indexes */
|
||||
tPoint->v1 = loops[mlooptri[i].tri[0]].v;
|
||||
tPoint->v2 = loops[mlooptri[i].tri[1]].v;
|
||||
tPoint->v3 = loops[mlooptri[i].tri[2]].v;
|
||||
tPoint->v1 = loops[looptris[i].tri[0]].v;
|
||||
tPoint->v2 = loops[looptris[i].tri[1]].v;
|
||||
tPoint->v3 = loops[looptris[i].tri[2]].v;
|
||||
|
||||
sample = 5; /* make sure we exit sample loop as well */
|
||||
break;
|
||||
|
@ -2309,7 +2306,7 @@ static void dynamic_paint_create_uv_surface_neighbor_cb(void *__restrict userdat
|
|||
PaintUVPoint *tempPoints = data->tempPoints;
|
||||
Vec3f *tempWeights = data->tempWeights;
|
||||
|
||||
const MLoopTri *mlooptri = data->mlooptri;
|
||||
const blender::Span<MLoopTri> looptris = data->looptris;
|
||||
const float(*mloopuv)[2] = data->mloopuv;
|
||||
const blender::Span<MLoop> loops = data->loops;
|
||||
|
||||
|
@ -2351,9 +2348,9 @@ static void dynamic_paint_create_uv_surface_neighbor_cb(void *__restrict userdat
|
|||
if (tempPoints[ind].neighbor_pixel == -1 && tempPoints[ind].tri_index != -1) {
|
||||
float uv[2];
|
||||
const int i = tempPoints[ind].tri_index;
|
||||
const float *uv1 = mloopuv[mlooptri[i].tri[0]];
|
||||
const float *uv2 = mloopuv[mlooptri[i].tri[1]];
|
||||
const float *uv3 = mloopuv[mlooptri[i].tri[2]];
|
||||
const float *uv1 = mloopuv[looptris[i].tri[0]];
|
||||
const float *uv2 = mloopuv[looptris[i].tri[1]];
|
||||
const float *uv3 = mloopuv[looptris[i].tri[2]];
|
||||
|
||||
/* tri index */
|
||||
/* There is a low possibility of actually having a neighbor point which tri is
|
||||
|
@ -2376,9 +2373,9 @@ static void dynamic_paint_create_uv_surface_neighbor_cb(void *__restrict userdat
|
|||
}
|
||||
|
||||
/* save vertex indexes */
|
||||
tPoint->v1 = loops[mlooptri[i].tri[0]].v;
|
||||
tPoint->v2 = loops[mlooptri[i].tri[1]].v;
|
||||
tPoint->v3 = loops[mlooptri[i].tri[2]].v;
|
||||
tPoint->v1 = loops[looptris[i].tri[0]].v;
|
||||
tPoint->v2 = loops[looptris[i].tri[1]].v;
|
||||
tPoint->v3 = loops[looptris[i].tri[2]].v;
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -2396,7 +2393,7 @@ static void dynamic_paint_create_uv_surface_neighbor_cb(void *__restrict userdat
|
|||
|
||||
#undef JITTER_SAMPLES
|
||||
|
||||
static float dist_squared_to_looptri_uv_edges(const MLoopTri *mlooptri,
|
||||
static float dist_squared_to_looptri_uv_edges(const blender::Span<MLoopTri> looptris,
|
||||
const float (*mloopuv)[2],
|
||||
int tri_index,
|
||||
const float point[2])
|
||||
|
@ -2408,8 +2405,8 @@ static float dist_squared_to_looptri_uv_edges(const MLoopTri *mlooptri,
|
|||
for (int i = 0; i < 3; i++) {
|
||||
const float dist_squared = dist_squared_to_line_segment_v2(
|
||||
point,
|
||||
mloopuv[mlooptri[tri_index].tri[(i + 0)]],
|
||||
mloopuv[mlooptri[tri_index].tri[(i + 1) % 3]]);
|
||||
mloopuv[looptris[tri_index].tri[(i + 0)]],
|
||||
mloopuv[looptris[tri_index].tri[(i + 1) % 3]]);
|
||||
|
||||
if (dist_squared < min_distance) {
|
||||
min_distance = dist_squared;
|
||||
|
@ -2520,10 +2517,10 @@ static void dynamic_paint_find_island_border(const DynamicPaintCreateUVSurfaceDa
|
|||
int depth)
|
||||
{
|
||||
const blender::Span<MLoop> loops = data->loops;
|
||||
const MLoopTri *mlooptri = data->mlooptri;
|
||||
const blender::Span<MLoopTri> looptris = data->looptris;
|
||||
const float(*mloopuv)[2] = data->mloopuv;
|
||||
|
||||
const uint *loop_idx = mlooptri[tri_index].tri;
|
||||
const uint *loop_idx = looptris[tri_index].tri;
|
||||
|
||||
/* Enumerate all edges of the triangle, rotating the vertex list accordingly. */
|
||||
for (int edge_idx = 0; edge_idx < 3; edge_idx++) {
|
||||
|
@ -2577,7 +2574,7 @@ static void dynamic_paint_find_island_border(const DynamicPaintCreateUVSurfaceDa
|
|||
continue;
|
||||
}
|
||||
|
||||
const uint *other_loop_idx = mlooptri[lt_index].tri;
|
||||
const uint *other_loop_idx = looptris[lt_index].tri;
|
||||
|
||||
/* Check edges for match, looping in the same order as the outer loop. */
|
||||
for (int j = 0; j < 3; j++) {
|
||||
|
@ -2680,7 +2677,7 @@ static void dynamic_paint_find_island_border(const DynamicPaintCreateUVSurfaceDa
|
|||
const float final_pt[2] = {((final_index % w) + 0.5f) / w, ((final_index / w) + 0.5f) / h};
|
||||
const float threshold = square_f(0.7f) / (w * h);
|
||||
|
||||
if (dist_squared_to_looptri_uv_edges(mlooptri, mloopuv, final_tri_index, final_pt) >
|
||||
if (dist_squared_to_looptri_uv_edges(looptris, mloopuv, final_tri_index, final_pt) >
|
||||
threshold) {
|
||||
continue;
|
||||
}
|
||||
|
@ -2818,7 +2815,6 @@ int dynamicPaint_createUVSurface(Scene *scene,
|
|||
|
||||
PaintUVPoint *tempPoints = nullptr;
|
||||
Vec3f *tempWeights = nullptr;
|
||||
const MLoopTri *mlooptri = nullptr;
|
||||
const float(*mloopuv)[2] = nullptr;
|
||||
|
||||
Bounds2D *faceBB = nullptr;
|
||||
|
@ -2835,8 +2831,7 @@ int dynamicPaint_createUVSurface(Scene *scene,
|
|||
}
|
||||
|
||||
const blender::Span<MLoop> loops = mesh->loops();
|
||||
mlooptri = BKE_mesh_runtime_looptri_ensure(mesh);
|
||||
const int tottri = BKE_mesh_runtime_looptri_len(mesh);
|
||||
const blender::Span<MLoopTri> looptris = mesh->looptris();
|
||||
|
||||
/* get uv map */
|
||||
if (CustomData_has_layer(&mesh->ldata, CD_PROP_FLOAT2)) {
|
||||
|
@ -2859,7 +2854,8 @@ int dynamicPaint_createUVSurface(Scene *scene,
|
|||
/*
|
||||
* Start generating the surface
|
||||
*/
|
||||
CLOG_INFO(&LOG, 1, "Preparing UV surface of %ix%i pixels and %i tris.", w, h, tottri);
|
||||
CLOG_INFO(
|
||||
&LOG, 1, "Preparing UV surface of %ix%i pixels and %i tris.", w, h, int(looptris.size()));
|
||||
|
||||
/* Init data struct */
|
||||
if (surface->data) {
|
||||
|
@ -2893,7 +2889,8 @@ int dynamicPaint_createUVSurface(Scene *scene,
|
|||
* the pixel-inside-a-face search.
|
||||
*/
|
||||
if (!error) {
|
||||
faceBB = static_cast<Bounds2D *>(MEM_mallocN(tottri * sizeof(*faceBB), "MPCanvasFaceBB"));
|
||||
faceBB = static_cast<Bounds2D *>(
|
||||
MEM_malloc_arrayN(looptris.size(), sizeof(*faceBB), "MPCanvasFaceBB"));
|
||||
if (!faceBB) {
|
||||
error = true;
|
||||
}
|
||||
|
@ -2903,12 +2900,12 @@ int dynamicPaint_createUVSurface(Scene *scene,
|
|||
*do_update = true;
|
||||
|
||||
if (!error) {
|
||||
for (int i = 0; i < tottri; i++) {
|
||||
copy_v2_v2(faceBB[i].min, mloopuv[mlooptri[i].tri[0]]);
|
||||
copy_v2_v2(faceBB[i].max, mloopuv[mlooptri[i].tri[0]]);
|
||||
for (const int i : looptris.index_range()) {
|
||||
copy_v2_v2(faceBB[i].min, mloopuv[looptris[i].tri[0]]);
|
||||
copy_v2_v2(faceBB[i].max, mloopuv[looptris[i].tri[0]]);
|
||||
|
||||
for (int j = 1; j < 3; j++) {
|
||||
minmax_v2v2_v2(faceBB[i].min, faceBB[i].max, mloopuv[mlooptri[i].tri[j]]);
|
||||
minmax_v2v2_v2(faceBB[i].min, faceBB[i].max, mloopuv[looptris[i].tri[j]]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2920,16 +2917,15 @@ int dynamicPaint_createUVSurface(Scene *scene,
|
|||
data.surface = surface;
|
||||
data.tempPoints = tempPoints;
|
||||
data.tempWeights = tempWeights;
|
||||
data.mlooptri = mlooptri;
|
||||
data.looptris = looptris;
|
||||
data.mloopuv = mloopuv;
|
||||
data.loops = loops;
|
||||
data.tottri = tottri;
|
||||
data.faceBB = faceBB;
|
||||
|
||||
{
|
||||
TaskParallelSettings settings;
|
||||
BLI_parallel_range_settings_defaults(&settings);
|
||||
settings.use_threading = (h > 64 || tottri > 1000);
|
||||
settings.use_threading = (h > 64 || looptris.size() > 1000);
|
||||
BLI_task_parallel_range(0, h, &data, dynamic_paint_create_uv_surface_direct_cb, &settings);
|
||||
}
|
||||
|
||||
|
@ -2979,8 +2975,8 @@ int dynamicPaint_createUVSurface(Scene *scene,
|
|||
BKE_mesh_vert_looptri_map_create(&vert_to_looptri_map,
|
||||
&vert_to_looptri_map_mem,
|
||||
mesh->totvert,
|
||||
mlooptri,
|
||||
tottri,
|
||||
looptris.data(),
|
||||
looptris.size(),
|
||||
loops.data(),
|
||||
mesh->totloop);
|
||||
|
||||
|
@ -3439,15 +3435,15 @@ static void mesh_tris_spherecast_dp(void *userdata,
|
|||
{
|
||||
const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata;
|
||||
const float(*positions)[3] = data->vert_positions;
|
||||
const MLoopTri *mlooptri = data->looptri;
|
||||
const MLoopTri *looptris = data->looptri;
|
||||
const MLoop *loops = data->loop;
|
||||
|
||||
const float *t0, *t1, *t2;
|
||||
float dist;
|
||||
|
||||
t0 = positions[loops[mlooptri[index].tri[0]].v];
|
||||
t1 = positions[loops[mlooptri[index].tri[1]].v];
|
||||
t2 = positions[loops[mlooptri[index].tri[2]].v];
|
||||
t0 = positions[loops[looptris[index].tri[0]].v];
|
||||
t1 = positions[loops[looptris[index].tri[1]].v];
|
||||
t2 = positions[loops[looptris[index].tri[2]].v];
|
||||
|
||||
dist = bvhtree_ray_tri_intersection(ray, hit->dist, t0, t1, t2);
|
||||
|
||||
|
@ -3471,14 +3467,14 @@ static void mesh_tris_nearest_point_dp(void *userdata,
|
|||
{
|
||||
const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata;
|
||||
const float(*positions)[3] = data->vert_positions;
|
||||
const MLoopTri *mlooptri = data->looptri;
|
||||
const MLoopTri *looptris = data->looptri;
|
||||
const MLoop *loops = data->loop;
|
||||
float nearest_tmp[3], dist_sq;
|
||||
|
||||
const float *t0, *t1, *t2;
|
||||
t0 = positions[loops[mlooptri[index].tri[0]].v];
|
||||
t1 = positions[loops[mlooptri[index].tri[1]].v];
|
||||
t2 = positions[loops[mlooptri[index].tri[2]].v];
|
||||
t0 = positions[loops[looptris[index].tri[0]].v];
|
||||
t1 = positions[loops[looptris[index].tri[1]].v];
|
||||
t2 = positions[loops[looptris[index].tri[2]].v];
|
||||
|
||||
closest_on_tri_to_point_v3(nearest_tmp, co, t0, t1, t2);
|
||||
dist_sq = len_squared_v3v3(co, nearest_tmp);
|
||||
|
@ -3912,7 +3908,7 @@ struct DynamicPaintPaintData {
|
|||
Mesh *mesh;
|
||||
const float (*positions)[3];
|
||||
blender::Span<MLoop> loops;
|
||||
const MLoopTri *mlooptri;
|
||||
blender::Span<MLoopTri> looptris;
|
||||
float brush_radius;
|
||||
const float *avg_brushNor;
|
||||
const Vec3f *brushVelocity;
|
||||
|
@ -3946,7 +3942,7 @@ static void dynamic_paint_paint_mesh_cell_point_cb_ex(void *__restrict userdata,
|
|||
|
||||
const float(*positions)[3] = data->positions;
|
||||
const blender::Span<MLoop> loops = data->loops;
|
||||
const MLoopTri *mlooptri = data->mlooptri;
|
||||
const blender::Span<MLoopTri> looptris = data->looptris;
|
||||
const float brush_radius = data->brush_radius;
|
||||
const float *avg_brushNor = data->avg_brushNor;
|
||||
const Vec3f *brushVelocity = data->brushVelocity;
|
||||
|
@ -4019,9 +4015,9 @@ static void dynamic_paint_paint_mesh_cell_point_cb_ex(void *__restrict userdata,
|
|||
|
||||
/* For optimization sake, hit point normal isn't calculated in ray cast loop */
|
||||
const int vtri[3] = {
|
||||
int(loops[mlooptri[hit.index].tri[0]].v),
|
||||
int(loops[mlooptri[hit.index].tri[1]].v),
|
||||
int(loops[mlooptri[hit.index].tri[2]].v),
|
||||
int(loops[looptris[hit.index].tri[0]].v),
|
||||
int(loops[looptris[hit.index].tri[1]].v),
|
||||
int(loops[looptris[hit.index].tri[2]].v),
|
||||
};
|
||||
float dot;
|
||||
|
||||
|
@ -4169,9 +4165,9 @@ static void dynamic_paint_paint_mesh_cell_point_cb_ex(void *__restrict userdata,
|
|||
float brushPointVelocity[3];
|
||||
float velocity[3];
|
||||
|
||||
const int v1 = loops[mlooptri[hitTri].tri[0]].v;
|
||||
const int v2 = loops[mlooptri[hitTri].tri[1]].v;
|
||||
const int v3 = loops[mlooptri[hitTri].tri[2]].v;
|
||||
const int v1 = loops[looptris[hitTri].tri[0]].v;
|
||||
const int v2 = loops[looptris[hitTri].tri[1]].v;
|
||||
const int v3 = loops[looptris[hitTri].tri[2]].v;
|
||||
|
||||
/* calculate barycentric weights for hit point */
|
||||
interp_weights_tri_v3(weights, positions[v1], positions[v2], positions[v3], hitCoord);
|
||||
|
@ -4270,7 +4266,6 @@ static bool dynamicPaint_paintMesh(Depsgraph *depsgraph,
|
|||
PaintBakeData *bData = sData->bData;
|
||||
Mesh *mesh = nullptr;
|
||||
Vec3f *brushVelocity = nullptr;
|
||||
const MLoopTri *mlooptri = nullptr;
|
||||
|
||||
if (brush->flags & MOD_DPAINT_USES_VELOCITY) {
|
||||
dynamicPaint_brushMeshCalculateVelocity(
|
||||
|
@ -4293,8 +4288,8 @@ static bool dynamicPaint_paintMesh(Depsgraph *depsgraph,
|
|||
|
||||
mesh = BKE_mesh_copy_for_eval(brush_mesh, false);
|
||||
float(*positions)[3] = BKE_mesh_vert_positions_for_write(mesh);
|
||||
const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh);
|
||||
mlooptri = BKE_mesh_runtime_looptri_ensure(mesh);
|
||||
const float(*vert_normals)[3] = BKE_mesh_vert_normals_ensure(mesh);
|
||||
const blender::Span<MLoopTri> looptris = mesh->looptris();
|
||||
const blender::Span<MLoop> loops = mesh->loops();
|
||||
numOfVerts = mesh->totvert;
|
||||
|
||||
|
@ -4350,7 +4345,7 @@ static bool dynamicPaint_paintMesh(Depsgraph *depsgraph,
|
|||
data.mesh = mesh;
|
||||
data.positions = positions;
|
||||
data.loops = loops;
|
||||
data.mlooptri = mlooptri;
|
||||
data.looptris = looptris;
|
||||
data.brush_radius = brush_radius;
|
||||
data.avg_brushNor = avg_brushNor;
|
||||
data.brushVelocity = brushVelocity;
|
||||
|
@ -6154,7 +6149,7 @@ static bool dynamicPaint_generateBakeData(DynamicPaintSurface *surface,
|
|||
data.surface = surface;
|
||||
data.ob = ob;
|
||||
data.positions = positions;
|
||||
data.vert_normals = BKE_mesh_vertex_normals_ensure(mesh);
|
||||
data.vert_normals = BKE_mesh_vert_normals_ensure(mesh);
|
||||
data.canvas_verts = canvas_verts;
|
||||
data.do_velocity_data = do_velocity_data;
|
||||
data.new_bdata = new_bdata;
|
||||
|
|
|
@ -703,7 +703,7 @@ bool get_effector_data(EffectorCache *eff,
|
|||
/* TODO: hair and points object support */
|
||||
const Mesh *me_eval = BKE_object_get_evaluated_mesh(eff->ob);
|
||||
const float(*positions)[3] = BKE_mesh_vert_positions(me_eval);
|
||||
const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(me_eval);
|
||||
const float(*vert_normals)[3] = BKE_mesh_vert_normals_ensure(me_eval);
|
||||
if (me_eval != NULL) {
|
||||
copy_v3_v3(efd->loc, positions[*efd->index]);
|
||||
copy_v3_v3(efd->nor, vert_normals[*efd->index]);
|
||||
|
|
|
@ -939,7 +939,7 @@ struct ObstaclesFromDMData {
|
|||
|
||||
const float (*vert_positions)[3];
|
||||
const MLoop *mloop;
|
||||
const MLoopTri *mlooptri;
|
||||
blender::Span<MLoopTri> looptris;
|
||||
|
||||
BVHTreeFromMesh *tree;
|
||||
FluidObjectBB *bb;
|
||||
|
@ -974,7 +974,7 @@ static void obstacles_from_mesh_task_cb(void *__restrict userdata,
|
|||
update_velocities(data->fes,
|
||||
data->vert_positions,
|
||||
data->mloop,
|
||||
data->mlooptri,
|
||||
data->looptris.data(),
|
||||
bb->velocity,
|
||||
index,
|
||||
data->tree,
|
||||
|
@ -997,7 +997,6 @@ static void obstacles_from_mesh(Object *coll_ob,
|
|||
float dt)
|
||||
{
|
||||
if (fes->mesh) {
|
||||
const MLoopTri *looptri;
|
||||
BVHTreeFromMesh tree_data = {nullptr};
|
||||
int numverts, i;
|
||||
|
||||
|
@ -1010,7 +1009,7 @@ static void obstacles_from_mesh(Object *coll_ob,
|
|||
int min[3], max[3], res[3];
|
||||
|
||||
const MLoop *mloop = BKE_mesh_loops(me);
|
||||
looptri = BKE_mesh_runtime_looptri_ensure(me);
|
||||
const blender::Span<MLoopTri> looptris = me->looptris();
|
||||
numverts = me->totvert;
|
||||
|
||||
/* TODO(sebbas): Make initialization of vertex velocities optional? */
|
||||
|
@ -1074,7 +1073,7 @@ static void obstacles_from_mesh(Object *coll_ob,
|
|||
data.fes = fes;
|
||||
data.vert_positions = positions;
|
||||
data.mloop = mloop;
|
||||
data.mlooptri = looptri;
|
||||
data.looptris = looptris;
|
||||
data.tree = &tree_data;
|
||||
data.bb = bb;
|
||||
data.has_velocity = has_velocity;
|
||||
|
@ -1983,7 +1982,7 @@ struct EmitFromDMData {
|
|||
const float (*vert_positions)[3];
|
||||
const float (*vert_normals)[3];
|
||||
const MLoop *mloop;
|
||||
const MLoopTri *mlooptri;
|
||||
blender::Span<MLoopTri> looptris;
|
||||
const float (*mloopuv)[2];
|
||||
const MDeformVert *dvert;
|
||||
int defgrp_index;
|
||||
|
@ -2017,7 +2016,7 @@ static void emit_from_mesh_task_cb(void *__restrict userdata,
|
|||
data->vert_positions,
|
||||
data->vert_normals,
|
||||
data->mloop,
|
||||
data->mlooptri,
|
||||
data->looptris.data(),
|
||||
data->mloopuv,
|
||||
bb->influence,
|
||||
bb->velocity,
|
||||
|
@ -2067,7 +2066,7 @@ static void emit_from_mesh(
|
|||
float(*positions)[3] = BKE_mesh_vert_positions_for_write(me);
|
||||
|
||||
const MLoop *mloop = BKE_mesh_loops(me);
|
||||
const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(me);
|
||||
const blender::Span<MLoopTri> looptris = me->looptris();
|
||||
const int numverts = me->totvert;
|
||||
const MDeformVert *dvert = BKE_mesh_deform_verts(me);
|
||||
const float(*mloopuv)[2] = static_cast<const float(*)[2]>(
|
||||
|
@ -2092,8 +2091,8 @@ static void emit_from_mesh(
|
|||
|
||||
/* Transform mesh vertices to domain grid space for fast lookups.
|
||||
* This is valid because the mesh is copied above. */
|
||||
BKE_mesh_vertex_normals_ensure(me);
|
||||
float(*vert_normals)[3] = BKE_mesh_vertex_normals_for_write(me);
|
||||
BKE_mesh_vert_normals_ensure(me);
|
||||
float(*vert_normals)[3] = BKE_mesh_vert_normals_for_write(me);
|
||||
for (i = 0; i < numverts; i++) {
|
||||
/* Vertex position. */
|
||||
mul_m4_v3(flow_ob->object_to_world, positions[i]);
|
||||
|
@ -2144,7 +2143,7 @@ static void emit_from_mesh(
|
|||
data.vert_positions = positions;
|
||||
data.vert_normals = vert_normals;
|
||||
data.mloop = mloop;
|
||||
data.mlooptri = mlooptri;
|
||||
data.looptris = looptris;
|
||||
data.mloopuv = mloopuv;
|
||||
data.dvert = dvert;
|
||||
data.defgrp_index = defgrp_index;
|
||||
|
|
|
@ -127,14 +127,14 @@ VArray<float3> mesh_normals_varray(const Mesh &mesh,
|
|||
return VArray<float3>::ForSpan(mesh.poly_normals());
|
||||
}
|
||||
case ATTR_DOMAIN_POINT: {
|
||||
return VArray<float3>::ForSpan(mesh.vertex_normals());
|
||||
return VArray<float3>::ForSpan(mesh.vert_normals());
|
||||
}
|
||||
case ATTR_DOMAIN_EDGE: {
|
||||
/* In this case, start with vertex normals and convert to the edge domain, since the
|
||||
* conversion from edges to vertices is very simple. Use "manual" domain interpolation
|
||||
* instead of the GeometryComponent API to avoid calculating unnecessary values and to
|
||||
* allow normalizing the result more simply. */
|
||||
Span<float3> vert_normals = mesh.vertex_normals();
|
||||
Span<float3> vert_normals = mesh.vert_normals();
|
||||
const Span<MEdge> edges = mesh.edges();
|
||||
Array<float3> edge_normals(mask.min_array_size());
|
||||
for (const int i : mask) {
|
||||
|
@ -909,7 +909,7 @@ static void tag_component_positions_changed(void *owner)
|
|||
{
|
||||
Mesh *mesh = static_cast<Mesh *>(owner);
|
||||
if (mesh != nullptr) {
|
||||
BKE_mesh_tag_coords_changed(mesh);
|
||||
BKE_mesh_tag_positions_changed(mesh);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2497,7 +2497,7 @@ static void gpencil_generate_edgeloops(Object *ob,
|
|||
const Span<float3> vert_positions = me->vert_positions();
|
||||
const Span<MEdge> edges = me->edges();
|
||||
const Span<MDeformVert> dverts = me->deform_verts();
|
||||
const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(me);
|
||||
const float(*vert_normals)[3] = BKE_mesh_vert_normals_ensure(me);
|
||||
|
||||
/* Arrays for all edge vertices (forward and backward) that form a edge loop.
|
||||
* This is reused for each edge-loop to create gpencil stroke. */
|
||||
|
|
|
@ -1496,11 +1496,10 @@ Mesh *BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob)
|
|||
for (int i = 0; i < mesh->totvert; i++) {
|
||||
normalize_v3(process.no[i]);
|
||||
}
|
||||
memcpy(BKE_mesh_vertex_normals_for_write(mesh),
|
||||
process.no,
|
||||
sizeof(float[3]) * size_t(mesh->totvert));
|
||||
memcpy(
|
||||
BKE_mesh_vert_normals_for_write(mesh), process.no, sizeof(float[3]) * size_t(mesh->totvert));
|
||||
MEM_freeN(process.no);
|
||||
BKE_mesh_vertex_normals_clear_dirty(mesh);
|
||||
BKE_mesh_vert_normals_clear_dirty(mesh);
|
||||
|
||||
mesh->totloop = loop_offset;
|
||||
|
||||
|
|
|
@ -1054,17 +1054,21 @@ void BKE_mesh_copy_parameters_for_eval(Mesh *me_dst, const Mesh *me_src)
|
|||
Mesh *BKE_mesh_new_nomain_from_template_ex(const Mesh *me_src,
|
||||
int verts_len,
|
||||
int edges_len,
|
||||
int tessface_len,
|
||||
int loops_len,
|
||||
int polys_len,
|
||||
CustomData_MeshMasks mask)
|
||||
{
|
||||
/* Only do tessface if we are creating tessfaces or copying from mesh with only tessfaces. */
|
||||
const bool do_tessface = (tessface_len || ((me_src->totface != 0) && (me_src->totpoly == 0)));
|
||||
|
||||
Mesh *me_dst = (Mesh *)BKE_id_new_nomain(ID_ME, nullptr);
|
||||
|
||||
me_dst->mselect = (MSelect *)MEM_dupallocN(me_src->mselect);
|
||||
|
||||
me_dst->totvert = verts_len;
|
||||
me_dst->totedge = edges_len;
|
||||
me_dst->totface = 0;
|
||||
me_dst->totface = tessface_len;
|
||||
me_dst->totloop = loops_len;
|
||||
me_dst->totpoly = polys_len;
|
||||
|
||||
|
@ -1074,14 +1078,22 @@ Mesh *BKE_mesh_new_nomain_from_template_ex(const Mesh *me_src,
|
|||
CustomData_copy(&me_src->edata, &me_dst->edata, mask.emask, CD_SET_DEFAULT, edges_len);
|
||||
CustomData_copy(&me_src->ldata, &me_dst->ldata, mask.lmask, CD_SET_DEFAULT, loops_len);
|
||||
CustomData_copy(&me_src->pdata, &me_dst->pdata, mask.pmask, CD_SET_DEFAULT, polys_len);
|
||||
mesh_tessface_clear_intern(me_dst, false);
|
||||
if (do_tessface) {
|
||||
CustomData_copy(&me_src->fdata, &me_dst->fdata, mask.fmask, CD_SET_DEFAULT, tessface_len);
|
||||
}
|
||||
else {
|
||||
mesh_tessface_clear_intern(me_dst, false);
|
||||
}
|
||||
|
||||
/* The destination mesh should at least have valid primary CD layers,
|
||||
* even in cases where the source mesh does not. */
|
||||
mesh_ensure_cdlayers_primary(me_dst);
|
||||
if (do_tessface && !CustomData_get_layer(&me_dst->fdata, CD_MFACE)) {
|
||||
CustomData_add_layer(&me_dst->fdata, CD_MFACE, CD_SET_DEFAULT, nullptr, me_dst->totface);
|
||||
}
|
||||
|
||||
/* Expect that normals aren't copied at all, since the destination mesh is new. */
|
||||
BLI_assert(BKE_mesh_vertex_normals_are_dirty(me_dst));
|
||||
BLI_assert(BKE_mesh_vert_normals_are_dirty(me_dst));
|
||||
|
||||
return me_dst;
|
||||
}
|
||||
|
@ -1090,7 +1102,7 @@ Mesh *BKE_mesh_new_nomain_from_template(
|
|||
const Mesh *me_src, int verts_len, int edges_len, int loops_len, int polys_len)
|
||||
{
|
||||
return BKE_mesh_new_nomain_from_template_ex(
|
||||
me_src, verts_len, edges_len, loops_len, polys_len, CD_MASK_EVERYTHING);
|
||||
me_src, verts_len, edges_len, 0, loops_len, polys_len, CD_MASK_EVERYTHING);
|
||||
}
|
||||
|
||||
void BKE_mesh_eval_delete(struct Mesh *mesh_eval)
|
||||
|
@ -1597,7 +1609,7 @@ void BKE_mesh_transform(Mesh *me, const float mat[4][4], bool do_keys)
|
|||
mul_m3_v3(m3, *lnors);
|
||||
}
|
||||
}
|
||||
BKE_mesh_tag_coords_changed(me);
|
||||
BKE_mesh_tag_positions_changed(me);
|
||||
}
|
||||
|
||||
void BKE_mesh_translate(Mesh *me, const float offset[3], const bool do_keys)
|
||||
|
@ -1616,7 +1628,7 @@ void BKE_mesh_translate(Mesh *me, const float offset[3], const bool do_keys)
|
|||
}
|
||||
}
|
||||
}
|
||||
BKE_mesh_tag_coords_changed_uniformly(me);
|
||||
BKE_mesh_tag_positions_changed_uniformly(me);
|
||||
}
|
||||
|
||||
void BKE_mesh_tessface_clear(Mesh *mesh)
|
||||
|
@ -1782,7 +1794,7 @@ void BKE_mesh_vert_coords_apply(Mesh *mesh, const float (*vert_coords)[3])
|
|||
for (const int i : positions.index_range()) {
|
||||
copy_v3_v3(positions[i], vert_coords[i]);
|
||||
}
|
||||
BKE_mesh_tag_coords_changed(mesh);
|
||||
BKE_mesh_tag_positions_changed(mesh);
|
||||
}
|
||||
|
||||
void BKE_mesh_vert_coords_apply_with_mat4(Mesh *mesh,
|
||||
|
@ -1793,7 +1805,7 @@ void BKE_mesh_vert_coords_apply_with_mat4(Mesh *mesh,
|
|||
for (const int i : positions.index_range()) {
|
||||
mul_v3_m4v3(positions[i], mat, vert_coords[i]);
|
||||
}
|
||||
BKE_mesh_tag_coords_changed(mesh);
|
||||
BKE_mesh_tag_positions_changed(mesh);
|
||||
}
|
||||
|
||||
static float (*ensure_corner_normal_layer(Mesh &mesh))[3]
|
||||
|
@ -1835,7 +1847,7 @@ void BKE_mesh_calc_normals_split_ex(Mesh *mesh,
|
|||
const Span<MLoop> loops = mesh->loops();
|
||||
|
||||
BKE_mesh_normals_loop_split(reinterpret_cast<const float(*)[3]>(positions.data()),
|
||||
BKE_mesh_vertex_normals_ensure(mesh),
|
||||
BKE_mesh_vert_normals_ensure(mesh),
|
||||
positions.size(),
|
||||
edges.data(),
|
||||
edges.size(),
|
||||
|
|
|
@ -68,7 +68,7 @@ void BKE_mesh_foreach_mapped_vert(
|
|||
const float(*positions)[3] = BKE_mesh_vert_positions(mesh);
|
||||
const int *index = static_cast<const int *>(CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX));
|
||||
const float(*vert_normals)[3] = (flag & MESH_FOREACH_USE_NORMAL) ?
|
||||
BKE_mesh_vertex_normals_ensure(mesh) :
|
||||
BKE_mesh_vert_normals_ensure(mesh) :
|
||||
nullptr;
|
||||
|
||||
if (index) {
|
||||
|
@ -311,7 +311,7 @@ void BKE_mesh_foreach_mapped_subdiv_face_center(
|
|||
const blender::Span<MPoly> polys = mesh->polys();
|
||||
const blender::Span<MLoop> loops = mesh->loops();
|
||||
const float(*vert_normals)[3] = (flag & MESH_FOREACH_USE_NORMAL) ?
|
||||
BKE_mesh_vertex_normals_ensure(mesh) :
|
||||
BKE_mesh_vert_normals_ensure(mesh) :
|
||||
nullptr;
|
||||
const int *index = static_cast<const int *>(CustomData_get_layer(&mesh->pdata, CD_ORIGINDEX));
|
||||
const blender::BitSpan facedot_tags = mesh->runtime->subsurf_face_dot_tags;
|
||||
|
|
|
@ -400,7 +400,7 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
|
|||
const bool *sharp_edges = static_cast<const bool *>(
|
||||
CustomData_get_layer_named(&mesh->edata, CD_PROP_BOOL, "sharp_edge"));
|
||||
BKE_mesh_normals_loop_split(BKE_mesh_vert_positions(result),
|
||||
BKE_mesh_vertex_normals_ensure(result),
|
||||
BKE_mesh_vert_normals_ensure(result),
|
||||
result->totvert,
|
||||
result->edges().data(),
|
||||
result->totedge,
|
||||
|
|
|
@ -106,7 +106,7 @@ void BKE_mesh_normals_tag_dirty(Mesh *mesh)
|
|||
mesh->runtime->poly_normals_dirty = true;
|
||||
}
|
||||
|
||||
float (*BKE_mesh_vertex_normals_for_write(Mesh *mesh))[3]
|
||||
float (*BKE_mesh_vert_normals_for_write(Mesh *mesh))[3]
|
||||
{
|
||||
if (mesh->runtime->vert_normals == nullptr) {
|
||||
mesh->runtime->vert_normals = (float(*)[3])MEM_malloc_arrayN(
|
||||
|
@ -130,7 +130,7 @@ float (*BKE_mesh_poly_normals_for_write(Mesh *mesh))[3]
|
|||
return mesh->runtime->poly_normals;
|
||||
}
|
||||
|
||||
void BKE_mesh_vertex_normals_clear_dirty(Mesh *mesh)
|
||||
void BKE_mesh_vert_normals_clear_dirty(Mesh *mesh)
|
||||
{
|
||||
mesh->runtime->vert_normals_dirty = false;
|
||||
BLI_assert(mesh->runtime->vert_normals || mesh->totvert == 0);
|
||||
|
@ -142,7 +142,7 @@ void BKE_mesh_poly_normals_clear_dirty(Mesh *mesh)
|
|||
BLI_assert(mesh->runtime->poly_normals || mesh->totpoly == 0);
|
||||
}
|
||||
|
||||
bool BKE_mesh_vertex_normals_are_dirty(const Mesh *mesh)
|
||||
bool BKE_mesh_vert_normals_are_dirty(const Mesh *mesh)
|
||||
{
|
||||
return mesh->runtime->vert_normals_dirty;
|
||||
}
|
||||
|
@ -368,9 +368,9 @@ void BKE_mesh_calc_normals_poly_and_vertex(const float (*vert_positions)[3],
|
|||
/** \name Mesh Normal Calculation
|
||||
* \{ */
|
||||
|
||||
const float (*BKE_mesh_vertex_normals_ensure(const Mesh *mesh))[3]
|
||||
const float (*BKE_mesh_vert_normals_ensure(const Mesh *mesh))[3]
|
||||
{
|
||||
if (!BKE_mesh_vertex_normals_are_dirty(mesh)) {
|
||||
if (!BKE_mesh_vert_normals_are_dirty(mesh)) {
|
||||
BLI_assert(mesh->runtime->vert_normals != nullptr || mesh->totvert == 0);
|
||||
return mesh->runtime->vert_normals;
|
||||
}
|
||||
|
@ -380,7 +380,7 @@ const float (*BKE_mesh_vertex_normals_ensure(const Mesh *mesh))[3]
|
|||
}
|
||||
|
||||
std::lock_guard lock{mesh->runtime->normals_mutex};
|
||||
if (!BKE_mesh_vertex_normals_are_dirty(mesh)) {
|
||||
if (!BKE_mesh_vert_normals_are_dirty(mesh)) {
|
||||
BLI_assert(mesh->runtime->vert_normals != nullptr);
|
||||
return mesh->runtime->vert_normals;
|
||||
}
|
||||
|
@ -395,7 +395,7 @@ const float (*BKE_mesh_vertex_normals_ensure(const Mesh *mesh))[3]
|
|||
const Span<MPoly> polys = mesh_mutable.polys();
|
||||
const Span<MLoop> loops = mesh_mutable.loops();
|
||||
|
||||
vert_normals = BKE_mesh_vertex_normals_for_write(&mesh_mutable);
|
||||
vert_normals = BKE_mesh_vert_normals_for_write(&mesh_mutable);
|
||||
poly_normals = BKE_mesh_poly_normals_for_write(&mesh_mutable);
|
||||
|
||||
BKE_mesh_calc_normals_poly_and_vertex(reinterpret_cast<const float(*)[3]>(positions.data()),
|
||||
|
@ -407,7 +407,7 @@ const float (*BKE_mesh_vertex_normals_ensure(const Mesh *mesh))[3]
|
|||
poly_normals,
|
||||
vert_normals);
|
||||
|
||||
BKE_mesh_vertex_normals_clear_dirty(&mesh_mutable);
|
||||
BKE_mesh_vert_normals_clear_dirty(&mesh_mutable);
|
||||
BKE_mesh_poly_normals_clear_dirty(&mesh_mutable);
|
||||
});
|
||||
|
||||
|
@ -461,7 +461,7 @@ void BKE_mesh_ensure_normals_for_display(Mesh *mesh)
|
|||
switch (mesh->runtime->wrapper_type) {
|
||||
case ME_WRAPPER_TYPE_SUBD:
|
||||
case ME_WRAPPER_TYPE_MDATA:
|
||||
BKE_mesh_vertex_normals_ensure(mesh);
|
||||
BKE_mesh_vert_normals_ensure(mesh);
|
||||
BKE_mesh_poly_normals_ensure(mesh);
|
||||
break;
|
||||
case ME_WRAPPER_TYPE_BMESH: {
|
||||
|
@ -481,7 +481,7 @@ void BKE_mesh_calc_normals(Mesh *mesh)
|
|||
#ifdef DEBUG_TIME
|
||||
SCOPED_TIMER_AVERAGED(__func__);
|
||||
#endif
|
||||
BKE_mesh_vertex_normals_ensure(mesh);
|
||||
BKE_mesh_vert_normals_ensure(mesh);
|
||||
}
|
||||
|
||||
void BKE_lnor_spacearr_init(MLoopNorSpaceArray *lnors_spacearr,
|
||||
|
@ -1932,7 +1932,7 @@ static void mesh_set_custom_normals(Mesh *mesh, float (*r_custom_nors)[3], const
|
|||
"sharp_edge", ATTR_DOMAIN_EDGE);
|
||||
|
||||
mesh_normals_loop_custom_set(reinterpret_cast<const float(*)[3]>(positions.data()),
|
||||
BKE_mesh_vertex_normals_ensure(mesh),
|
||||
BKE_mesh_vert_normals_ensure(mesh),
|
||||
positions.size(),
|
||||
edges.data(),
|
||||
edges.size(),
|
||||
|
|
|
@ -571,7 +571,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode,
|
|||
const blender::Span<MPoly> polys_src = me_src->polys();
|
||||
const blender::Span<MLoop> loops_src = me_src->loops();
|
||||
float(*vcos_src)[3] = BKE_mesh_vert_coords_alloc(me_src, nullptr);
|
||||
const float(*vert_normals_dst)[3] = BKE_mesh_vertex_normals_ensure(me_dst);
|
||||
const float(*vert_normals_dst)[3] = BKE_mesh_vert_normals_ensure(me_dst);
|
||||
|
||||
size_t tmp_buff_size = MREMAP_DEFAULT_BUFSIZE;
|
||||
float(*vcos)[3] = static_cast<float(*)[3]>(
|
||||
|
@ -937,7 +937,7 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode,
|
|||
|
||||
BKE_bvhtree_from_mesh_get(&treedata, me_src, BVHTREE_FROM_EDGES, 2);
|
||||
|
||||
const float(*vert_normals_dst)[3] = BKE_mesh_vertex_normals_ensure(me_dst);
|
||||
const float(*vert_normals_dst)[3] = BKE_mesh_vert_normals_ensure(me_dst);
|
||||
|
||||
for (i = 0; i < numedges_dst; i++) {
|
||||
/* For each dst edge, we sample some rays from it (interpolated from its vertices)
|
||||
|
@ -1252,8 +1252,6 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
|
|||
const float full_weight = 1.0f;
|
||||
const float max_dist_sq = max_dist * max_dist;
|
||||
|
||||
int i;
|
||||
|
||||
BLI_assert(mode & MREMAP_MODE_LOOP);
|
||||
BLI_assert((islands_precision_src >= 0.0f) && (islands_precision_src <= 1.0f));
|
||||
|
||||
|
@ -1262,7 +1260,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
|
|||
if (mode == MREMAP_MODE_TOPOLOGY) {
|
||||
/* In topology mapping, we assume meshes are identical, islands included! */
|
||||
BLI_assert(numloops_dst == me_src->totloop);
|
||||
for (i = 0; i < numloops_dst; i++) {
|
||||
for (int i = 0; i < numloops_dst; i++) {
|
||||
mesh_remap_item_define(r_map, i, FLT_MAX, 0, 1, &i, &full_weight);
|
||||
}
|
||||
}
|
||||
|
@ -1311,8 +1309,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
|
|||
const blender::Span<MEdge> edges_src = me_src->edges();
|
||||
const blender::Span<MPoly> polys_src = me_src->polys();
|
||||
const blender::Span<MLoop> loops_src = me_src->loops();
|
||||
const MLoopTri *looptri_src = nullptr;
|
||||
int num_looptri_src = 0;
|
||||
blender::Span<MLoopTri> looptris_src;
|
||||
|
||||
size_t buff_size_interp = MREMAP_DEFAULT_BUFSIZE;
|
||||
float(*vcos_interp)[3] = nullptr;
|
||||
|
@ -1365,7 +1362,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
|
|||
const bool *sharp_edges = static_cast<const bool *>(
|
||||
CustomData_get_layer_named(&mesh_dst->edata, CD_PROP_BOOL, "sharp_edge"));
|
||||
BKE_mesh_normals_loop_split(vert_positions_dst,
|
||||
BKE_mesh_vertex_normals_ensure(mesh_dst),
|
||||
BKE_mesh_vert_normals_ensure(mesh_dst),
|
||||
numverts_dst,
|
||||
edges_dst,
|
||||
numedges_dst,
|
||||
|
@ -1506,7 +1503,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
|
|||
MeshElemMap *isld = island_store.islands[tindex];
|
||||
int num_verts_active = 0;
|
||||
verts_active.fill(false);
|
||||
for (i = 0; i < isld->count; i++) {
|
||||
for (int i = 0; i < isld->count; i++) {
|
||||
const MPoly &poly = polys_src[isld->indices[i]];
|
||||
for (lidx_src = poly.loopstart; lidx_src < poly.loopstart + poly.totloop; lidx_src++) {
|
||||
const uint vidx_src = loops_src[lidx_src].v;
|
||||
|
@ -1533,16 +1530,14 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
|
|||
}
|
||||
else { /* We use polygons. */
|
||||
if (use_islands) {
|
||||
/* bvhtree here uses looptri faces... */
|
||||
looptri_src = BKE_mesh_runtime_looptri_ensure(me_src);
|
||||
num_looptri_src = BKE_mesh_runtime_looptri_len(me_src);
|
||||
blender::BitVector<> looptri_active(num_looptri_src);
|
||||
looptris_src = me_src->looptris();
|
||||
blender::BitVector<> looptri_active(looptris_src.size());
|
||||
|
||||
for (tindex = 0; tindex < num_trees; tindex++) {
|
||||
int num_looptri_active = 0;
|
||||
looptri_active.fill(false);
|
||||
for (i = 0; i < num_looptri_src; i++) {
|
||||
const MPoly &poly = polys_src[looptri_src[i].poly];
|
||||
for (const int64_t i : looptris_src.index_range()) {
|
||||
const MPoly &poly = polys_src[looptris_src[i].poly];
|
||||
if (island_store.items_to_islands[poly.loopstart] == tindex) {
|
||||
looptri_active[i].set();
|
||||
num_looptri_active++;
|
||||
|
@ -1551,8 +1546,8 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
|
|||
bvhtree_from_mesh_looptri_ex(&treedata[tindex],
|
||||
positions_src,
|
||||
loops_src.data(),
|
||||
looptri_src,
|
||||
num_looptri_src,
|
||||
looptris_src.data(),
|
||||
int(looptris_src.size()),
|
||||
looptri_active,
|
||||
num_looptri_active,
|
||||
0.0,
|
||||
|
@ -1636,7 +1631,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
|
|||
vert_to_refelem_map_src = vert_to_poly_map_src;
|
||||
}
|
||||
|
||||
for (i = vert_to_refelem_map_src[nearest.index].count; i--;) {
|
||||
for (int i = vert_to_refelem_map_src[nearest.index].count; i--;) {
|
||||
const int index_src = vert_to_refelem_map_src[nearest.index].indices[i];
|
||||
BLI_assert(index_src != -1);
|
||||
const float dot = dot_v3v3(nors_src[index_src], *nor_dst);
|
||||
|
@ -1881,7 +1876,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
|
|||
*/
|
||||
int last_valid_pidx_isld_src = -1;
|
||||
/* Note we go backward here, from dest to src poly. */
|
||||
for (i = as_solution.steps - 1; i--;) {
|
||||
for (int i = as_solution.steps - 1; i--;) {
|
||||
BLI_AStarGNLink *as_link = as_solution.prev_links[pidx_isld_src];
|
||||
const int eidx = POINTER_AS_INT(as_link->custom_data);
|
||||
pidx_isld_src = as_solution.prev_nodes[pidx_isld_src];
|
||||
|
@ -1973,7 +1968,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
|
|||
*/
|
||||
int last_valid_pidx_isld_src = -1;
|
||||
/* Note we go backward here, from dest to src poly. */
|
||||
for (i = as_solution.steps - 1; i--;) {
|
||||
for (int i = as_solution.steps - 1; i--;) {
|
||||
BLI_AStarGNLink *as_link = as_solution.prev_links[pidx_isld_src];
|
||||
int eidx = POINTER_AS_INT(as_link->custom_data);
|
||||
|
||||
|
@ -2008,14 +2003,14 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
|
|||
&poly_to_looptri_map_src_buff,
|
||||
polys_src.data(),
|
||||
int(polys_src.size()),
|
||||
looptri_src,
|
||||
num_looptri_src);
|
||||
looptris_src.data(),
|
||||
int(looptris_src.size()));
|
||||
}
|
||||
|
||||
for (j = poly_to_looptri_map_src[pidx_src].count; j--;) {
|
||||
float h[3];
|
||||
const MLoopTri *lt =
|
||||
&looptri_src[poly_to_looptri_map_src[pidx_src].indices[j]];
|
||||
&looptris_src[poly_to_looptri_map_src[pidx_src].indices[j]];
|
||||
float dist_sq;
|
||||
|
||||
closest_on_tri_to_point_v3(h,
|
||||
|
|
|
@ -65,15 +65,14 @@ static Mesh *remesh_quadriflow(const Mesh *input_mesh,
|
|||
{
|
||||
const Span<float3> input_positions = input_mesh->vert_positions();
|
||||
const Span<MLoop> input_loops = input_mesh->loops();
|
||||
const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(input_mesh);
|
||||
const Span<MLoopTri> looptris = input_mesh->looptris();
|
||||
|
||||
/* Gather the required data for export to the internal quadriflow mesh format. */
|
||||
MVertTri *verttri = (MVertTri *)MEM_callocN(
|
||||
sizeof(*verttri) * BKE_mesh_runtime_looptri_len(input_mesh), "remesh_looptri");
|
||||
Array<MVertTri> verttri(looptris.size());
|
||||
BKE_mesh_runtime_verttri_from_looptri(
|
||||
verttri, input_loops.data(), looptri, BKE_mesh_runtime_looptri_len(input_mesh));
|
||||
verttri.data(), input_loops.data(), looptris.data(), looptris.size());
|
||||
|
||||
const int totfaces = BKE_mesh_runtime_looptri_len(input_mesh);
|
||||
const int totfaces = looptris.size();
|
||||
const int totverts = input_mesh->totvert;
|
||||
Array<int> faces(totfaces * 3);
|
||||
|
||||
|
@ -105,8 +104,6 @@ static Mesh *remesh_quadriflow(const Mesh *input_mesh,
|
|||
/* Run the remesher */
|
||||
QFLOW_quadriflow_remesh(&qrd, update_cb, update_cb_data);
|
||||
|
||||
MEM_freeN(verttri);
|
||||
|
||||
if (qrd.out_faces == nullptr) {
|
||||
/* The remeshing was canceled */
|
||||
return nullptr;
|
||||
|
@ -335,7 +332,7 @@ void BKE_remesh_reproject_sculpt_face_sets(Mesh *target, const Mesh *source)
|
|||
const VArraySpan<int> src(src_face_sets);
|
||||
MutableSpan<int> dst = dst_face_sets.span;
|
||||
|
||||
const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(source);
|
||||
const blender::Span<MLoopTri> looptris = source->looptris();
|
||||
BVHTreeFromMesh bvhtree = {nullptr};
|
||||
BKE_bvhtree_from_mesh_get(&bvhtree, source, BVHTREE_FROM_LOOPTRI, 2);
|
||||
|
||||
|
@ -353,7 +350,7 @@ void BKE_remesh_reproject_sculpt_face_sets(Mesh *target, const Mesh *source)
|
|||
BLI_bvhtree_find_nearest(
|
||||
bvhtree.tree, from_co, &nearest, bvhtree.nearest_callback, &bvhtree);
|
||||
if (nearest.index != -1) {
|
||||
dst[i] = src[looptri[nearest.index].poly];
|
||||
dst[i] = src[looptris[nearest.index].poly];
|
||||
}
|
||||
else {
|
||||
dst[i] = 1;
|
||||
|
|
|
@ -254,7 +254,7 @@ void BKE_mesh_tag_edges_split(struct Mesh *mesh)
|
|||
}
|
||||
}
|
||||
|
||||
void BKE_mesh_tag_coords_changed(Mesh *mesh)
|
||||
void BKE_mesh_tag_positions_changed(Mesh *mesh)
|
||||
{
|
||||
BKE_mesh_normals_tag_dirty(mesh);
|
||||
free_bvh_cache(*mesh->runtime);
|
||||
|
@ -262,7 +262,7 @@ void BKE_mesh_tag_coords_changed(Mesh *mesh)
|
|||
mesh->runtime->bounds_cache.tag_dirty();
|
||||
}
|
||||
|
||||
void BKE_mesh_tag_coords_changed_uniformly(Mesh *mesh)
|
||||
void BKE_mesh_tag_positions_changed_uniformly(Mesh *mesh)
|
||||
{
|
||||
/* The normals and triangulation didn't change, since all verts moved by the same amount. */
|
||||
free_bvh_cache(*mesh->runtime);
|
||||
|
|
|
@ -574,19 +574,20 @@ void BKE_mesh_calc_loop_tangents(Mesh *me_eval,
|
|||
int tangent_names_len)
|
||||
{
|
||||
/* TODO(@ideasman42): store in Mesh.runtime to avoid recalculation. */
|
||||
const blender::Span<MLoopTri> looptris = me_eval->looptris();
|
||||
short tangent_mask = 0;
|
||||
BKE_mesh_calc_loop_tangent_ex(
|
||||
BKE_mesh_vert_positions(me_eval),
|
||||
me_eval->polys().data(),
|
||||
uint(me_eval->totpoly),
|
||||
me_eval->loops().data(),
|
||||
BKE_mesh_runtime_looptri_ensure(me_eval),
|
||||
uint(BKE_mesh_runtime_looptri_len(me_eval)),
|
||||
looptris.data(),
|
||||
uint(looptris.size()),
|
||||
&me_eval->ldata,
|
||||
calc_active_tangent,
|
||||
tangent_names,
|
||||
tangent_names_len,
|
||||
BKE_mesh_vertex_normals_ensure(me_eval),
|
||||
BKE_mesh_vert_normals_ensure(me_eval),
|
||||
BKE_mesh_poly_normals_ensure(me_eval),
|
||||
static_cast<const float(*)[3]>(CustomData_get_layer(&me_eval->ldata, CD_NORMAL)),
|
||||
/* may be nullptr */
|
||||
|
|
|
@ -298,8 +298,8 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
|
|||
}
|
||||
|
||||
const float(*vert_normals)[3] = nullptr;
|
||||
if (!BKE_mesh_vertex_normals_are_dirty(mesh)) {
|
||||
vert_normals = BKE_mesh_vertex_normals_ensure(mesh);
|
||||
if (!BKE_mesh_vert_normals_are_dirty(mesh)) {
|
||||
vert_normals = BKE_mesh_vert_normals_ensure(mesh);
|
||||
}
|
||||
|
||||
for (i = 0; i < totvert; i++) {
|
||||
|
|
|
@ -1018,7 +1018,7 @@ void BKE_modifier_deform_verts(ModifierData *md,
|
|||
}
|
||||
mti->deformVerts(md, ctx, me, vertexCos, numVerts);
|
||||
if (me) {
|
||||
BKE_mesh_tag_coords_changed(me);
|
||||
BKE_mesh_tag_positions_changed(me);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -474,14 +474,14 @@ static int get_timecode(MovieClip *clip, int flag)
|
|||
return clip->proxy.tc;
|
||||
}
|
||||
|
||||
static void get_sequence_fname(const MovieClip *clip, const int framenr, char *name)
|
||||
static void get_sequence_filepath(const MovieClip *clip, const int framenr, char *filepath)
|
||||
{
|
||||
ushort numlen;
|
||||
char head[FILE_MAX], tail[FILE_MAX];
|
||||
int offset;
|
||||
|
||||
BLI_strncpy(name, clip->filepath, sizeof(clip->filepath));
|
||||
BLI_path_sequence_decode(name, head, tail, &numlen);
|
||||
BLI_strncpy(filepath, clip->filepath, sizeof(clip->filepath));
|
||||
BLI_path_sequence_decode(filepath, head, tail, &numlen);
|
||||
|
||||
/* Movie-clips always points to first image from sequence, auto-guess offset for now.
|
||||
* Could be something smarter in the future. */
|
||||
|
@ -489,18 +489,18 @@ static void get_sequence_fname(const MovieClip *clip, const int framenr, char *n
|
|||
|
||||
if (numlen) {
|
||||
BLI_path_sequence_encode(
|
||||
name, head, tail, numlen, offset + framenr - clip->start_frame + clip->frame_offset);
|
||||
filepath, head, tail, numlen, offset + framenr - clip->start_frame + clip->frame_offset);
|
||||
}
|
||||
else {
|
||||
BLI_strncpy(name, clip->filepath, sizeof(clip->filepath));
|
||||
BLI_strncpy(filepath, clip->filepath, sizeof(clip->filepath));
|
||||
}
|
||||
|
||||
BLI_path_abs(name, ID_BLEND_PATH_FROM_GLOBAL(&clip->id));
|
||||
BLI_path_abs(filepath, ID_BLEND_PATH_FROM_GLOBAL(&clip->id));
|
||||
}
|
||||
|
||||
/* supposed to work with sequences only */
|
||||
static void get_proxy_fname(
|
||||
const MovieClip *clip, int proxy_render_size, bool undistorted, int framenr, char *name)
|
||||
static void get_proxy_filepath(
|
||||
const MovieClip *clip, int proxy_render_size, bool undistorted, int framenr, char *filepath)
|
||||
{
|
||||
int size = rendersize_to_number(proxy_render_size);
|
||||
char dir[FILE_MAX], clipdir[FILE_MAX], clipfile[FILE_MAX];
|
||||
|
@ -516,16 +516,17 @@ static void get_proxy_fname(
|
|||
}
|
||||
|
||||
if (undistorted) {
|
||||
BLI_snprintf(name, FILE_MAX, "%s/%s/proxy_%d_undistorted/%08d", dir, clipfile, size, proxynr);
|
||||
BLI_snprintf(
|
||||
filepath, FILE_MAX, "%s/%s/proxy_%d_undistorted/%08d", dir, clipfile, size, proxynr);
|
||||
}
|
||||
else {
|
||||
BLI_snprintf(name, FILE_MAX, "%s/%s/proxy_%d/%08d", dir, clipfile, size, proxynr);
|
||||
BLI_snprintf(filepath, FILE_MAX, "%s/%s/proxy_%d/%08d", dir, clipfile, size, proxynr);
|
||||
}
|
||||
|
||||
BLI_path_abs(name, BKE_main_blendfile_path_from_global());
|
||||
BLI_path_frame(name, 1, 0);
|
||||
BLI_path_abs(filepath, BKE_main_blendfile_path_from_global());
|
||||
BLI_path_frame(filepath, 1, 0);
|
||||
|
||||
strcat(name, ".jpg");
|
||||
strcat(filepath, ".jpg");
|
||||
}
|
||||
|
||||
#ifdef WITH_OPENEXR
|
||||
|
@ -610,7 +611,7 @@ static ImBuf *movieclip_load_sequence_file(MovieClip *clip,
|
|||
int flag)
|
||||
{
|
||||
struct ImBuf *ibuf;
|
||||
char name[FILE_MAX];
|
||||
char filepath[FILE_MAX];
|
||||
int loadflag;
|
||||
bool use_proxy = false;
|
||||
char *colorspace;
|
||||
|
@ -618,7 +619,7 @@ static ImBuf *movieclip_load_sequence_file(MovieClip *clip,
|
|||
use_proxy = (flag & MCLIP_USE_PROXY) && user->render_size != MCLIP_PROXY_RENDER_SIZE_FULL;
|
||||
if (use_proxy) {
|
||||
int undistort = user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT;
|
||||
get_proxy_fname(clip, user->render_size, undistort, framenr, name);
|
||||
get_proxy_filepath(clip, user->render_size, undistort, framenr, filepath);
|
||||
|
||||
/* Well, this is a bit weird, but proxies for movie sources
|
||||
* are built in the same exact color space as the input,
|
||||
|
@ -633,14 +634,14 @@ static ImBuf *movieclip_load_sequence_file(MovieClip *clip,
|
|||
}
|
||||
}
|
||||
else {
|
||||
get_sequence_fname(clip, framenr, name);
|
||||
get_sequence_filepath(clip, framenr, filepath);
|
||||
colorspace = clip->colorspace_settings.name;
|
||||
}
|
||||
|
||||
loadflag = IB_rect | IB_multilayer | IB_alphamode_detect | IB_metadata;
|
||||
|
||||
/* read ibuf */
|
||||
ibuf = IMB_loadiffname(name, loadflag, colorspace);
|
||||
ibuf = IMB_loadiffname(filepath, loadflag, colorspace);
|
||||
BKE_movieclip_convert_multilayer_ibuf(ibuf);
|
||||
|
||||
return ibuf;
|
||||
|
@ -699,7 +700,7 @@ static void movieclip_calc_length(MovieClip *clip)
|
|||
}
|
||||
else if (clip->source == MCLIP_SRC_SEQUENCE) {
|
||||
ushort numlen;
|
||||
char name[FILE_MAX], head[FILE_MAX], tail[FILE_MAX];
|
||||
char filepath[FILE_MAX], head[FILE_MAX], tail[FILE_MAX];
|
||||
|
||||
BLI_path_sequence_decode(clip->filepath, head, tail, &numlen);
|
||||
|
||||
|
@ -710,9 +711,9 @@ static void movieclip_calc_length(MovieClip *clip)
|
|||
else {
|
||||
clip->len = 0;
|
||||
for (;;) {
|
||||
get_sequence_fname(clip, clip->len + clip->start_frame, name);
|
||||
get_sequence_filepath(clip, clip->len + clip->start_frame, filepath);
|
||||
|
||||
if (BLI_exists(name)) {
|
||||
if (BLI_exists(filepath)) {
|
||||
clip->len++;
|
||||
}
|
||||
else {
|
||||
|
@ -791,7 +792,7 @@ static int user_frame_to_cache_frame(MovieClip *clip, int framenr)
|
|||
|
||||
BLI_path_sequence_decode(clip->filepath, head, tail, &numlen);
|
||||
|
||||
/* see comment in get_sequence_fname */
|
||||
/* see comment in get_sequence_filepath */
|
||||
clip->cache->sequence_offset = sequence_guess_offset(clip->filepath, strlen(head), numlen);
|
||||
}
|
||||
|
||||
|
@ -996,12 +997,12 @@ static void movieclip_load_get_size(MovieClip *clip)
|
|||
static void detect_clip_source(Main *bmain, MovieClip *clip)
|
||||
{
|
||||
ImBuf *ibuf;
|
||||
char name[FILE_MAX];
|
||||
char filepath[FILE_MAX];
|
||||
|
||||
BLI_strncpy(name, clip->filepath, sizeof(name));
|
||||
BLI_path_abs(name, BKE_main_blendfile_path(bmain));
|
||||
BLI_strncpy(filepath, clip->filepath, sizeof(filepath));
|
||||
BLI_path_abs(filepath, BKE_main_blendfile_path(bmain));
|
||||
|
||||
ibuf = IMB_testiffname(name, IB_rect | IB_multilayer);
|
||||
ibuf = IMB_testiffname(filepath, IB_rect | IB_multilayer);
|
||||
if (ibuf) {
|
||||
clip->source = MCLIP_SRC_SEQUENCE;
|
||||
IMB_freeImBuf(ibuf);
|
||||
|
@ -1011,13 +1012,13 @@ static void detect_clip_source(Main *bmain, MovieClip *clip)
|
|||
}
|
||||
}
|
||||
|
||||
MovieClip *BKE_movieclip_file_add(Main *bmain, const char *name)
|
||||
MovieClip *BKE_movieclip_file_add(Main *bmain, const char *filepath)
|
||||
{
|
||||
MovieClip *clip;
|
||||
int file;
|
||||
char str[FILE_MAX];
|
||||
|
||||
BLI_strncpy(str, name, sizeof(str));
|
||||
BLI_strncpy(str, filepath, sizeof(str));
|
||||
BLI_path_abs(str, BKE_main_blendfile_path(bmain));
|
||||
|
||||
/* exists? */
|
||||
|
@ -1030,8 +1031,8 @@ MovieClip *BKE_movieclip_file_add(Main *bmain, const char *name)
|
|||
/* ** add new movieclip ** */
|
||||
|
||||
/* create a short library name */
|
||||
clip = movieclip_alloc(bmain, BLI_path_basename(name));
|
||||
BLI_strncpy(clip->filepath, name, sizeof(clip->filepath));
|
||||
clip = movieclip_alloc(bmain, BLI_path_basename(filepath));
|
||||
BLI_strncpy(clip->filepath, filepath, sizeof(clip->filepath));
|
||||
|
||||
detect_clip_source(bmain, clip);
|
||||
|
||||
|
@ -1826,12 +1827,12 @@ void BKE_movieclip_update_scopes(MovieClip *clip,
|
|||
static void movieclip_build_proxy_ibuf(
|
||||
MovieClip *clip, ImBuf *ibuf, int cfra, int proxy_render_size, bool undistorted, bool threaded)
|
||||
{
|
||||
char name[FILE_MAX];
|
||||
char filepath[FILE_MAX];
|
||||
int quality, rectx, recty;
|
||||
int size = rendersize_to_number(proxy_render_size);
|
||||
ImBuf *scaleibuf;
|
||||
|
||||
get_proxy_fname(clip, proxy_render_size, undistorted, cfra, name);
|
||||
get_proxy_filepath(clip, proxy_render_size, undistorted, cfra, filepath);
|
||||
|
||||
rectx = ibuf->x * size / 100.0f;
|
||||
recty = ibuf->y * size / 100.0f;
|
||||
|
@ -1859,9 +1860,9 @@ static void movieclip_build_proxy_ibuf(
|
|||
*/
|
||||
BLI_thread_lock(LOCK_MOVIECLIP);
|
||||
|
||||
BLI_make_existing_file(name);
|
||||
if (IMB_saveiff(scaleibuf, name, IB_rect) == 0) {
|
||||
perror(name);
|
||||
BLI_make_existing_file(filepath);
|
||||
if (IMB_saveiff(scaleibuf, filepath, IB_rect) == 0) {
|
||||
perror(filepath);
|
||||
}
|
||||
|
||||
BLI_thread_unlock(LOCK_MOVIECLIP);
|
||||
|
@ -1955,7 +1956,7 @@ float BKE_movieclip_remap_clip_to_scene_frame(const MovieClip *clip, const float
|
|||
return framenr + (float)clip->start_frame - 1.0f;
|
||||
}
|
||||
|
||||
void BKE_movieclip_filename_for_frame(MovieClip *clip, const MovieClipUser *user, char *name)
|
||||
void BKE_movieclip_filepath_for_frame(MovieClip *clip, const MovieClipUser *user, char *filepath)
|
||||
{
|
||||
if (clip->source == MCLIP_SRC_SEQUENCE) {
|
||||
int use_proxy;
|
||||
|
@ -1965,15 +1966,15 @@ void BKE_movieclip_filename_for_frame(MovieClip *clip, const MovieClipUser *user
|
|||
|
||||
if (use_proxy) {
|
||||
int undistort = user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT;
|
||||
get_proxy_fname(clip, user->render_size, undistort, user->framenr, name);
|
||||
get_proxy_filepath(clip, user->render_size, undistort, user->framenr, filepath);
|
||||
}
|
||||
else {
|
||||
get_sequence_fname(clip, user->framenr, name);
|
||||
get_sequence_filepath(clip, user->framenr, filepath);
|
||||
}
|
||||
}
|
||||
else {
|
||||
BLI_strncpy(name, clip->filepath, FILE_MAX);
|
||||
BLI_path_abs(name, ID_BLEND_PATH_FROM_GLOBAL(&clip->id));
|
||||
BLI_strncpy(filepath, clip->filepath, FILE_MAX);
|
||||
BLI_path_abs(filepath, ID_BLEND_PATH_FROM_GLOBAL(&clip->id));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -160,7 +160,7 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape
|
|||
/* Vertices were moved around, need to update normals after all the vertices are updated
|
||||
* Probably this is possible to do in the loop above, but this is rather tricky because
|
||||
* we don't know all needed vertices' coordinates there yet. */
|
||||
BKE_mesh_tag_coords_changed(base_mesh);
|
||||
BKE_mesh_tag_positions_changed(base_mesh);
|
||||
}
|
||||
|
||||
void multires_reshape_apply_base_refine_from_base(MultiresReshapeContext *reshape_context)
|
||||
|
|
|
@ -735,7 +735,7 @@ static void make_duplis_verts(const DupliContext *ctx)
|
|||
vdd.params = vdd_params;
|
||||
vdd.totvert = me_eval->totvert;
|
||||
vdd.vert_positions = me_eval->vert_positions();
|
||||
vdd.vert_normals = BKE_mesh_vertex_normals_ensure(me_eval);
|
||||
vdd.vert_normals = BKE_mesh_vert_normals_ensure(me_eval);
|
||||
vdd.orco = (const float(*)[3])CustomData_get_layer(&me_eval->vdata, CD_ORCO);
|
||||
|
||||
make_child_duplis(ctx, &vdd, make_child_duplis_verts_from_mesh);
|
||||
|
|
|
@ -2160,7 +2160,7 @@ void psys_particle_on_dm(Mesh *mesh_final,
|
|||
}
|
||||
|
||||
orcodata = static_cast<const float(*)[3]>(CustomData_get_layer(&mesh_final->vdata, CD_ORCO));
|
||||
const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh_final);
|
||||
const float(*vert_normals)[3] = BKE_mesh_vert_normals_ensure(mesh_final);
|
||||
|
||||
if (from == PART_FROM_VERT) {
|
||||
const float(*vert_positions)[3] = BKE_mesh_vert_positions(mesh_final);
|
||||
|
|
|
@ -613,18 +613,8 @@ static void distribute_from_volume_exec(ParticleTask *thread, ParticleData *pa,
|
|||
/* experimental */
|
||||
tot = mesh->totface;
|
||||
|
||||
psys_interpolate_face(mesh,
|
||||
positions,
|
||||
BKE_mesh_vertex_normals_ensure(mesh),
|
||||
mface,
|
||||
0,
|
||||
0,
|
||||
pa->fuv,
|
||||
co,
|
||||
nor,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
psys_interpolate_face(
|
||||
mesh, positions, BKE_mesh_vert_normals_ensure(mesh), mface, 0, 0, pa->fuv, co, nor, 0, 0, 0);
|
||||
|
||||
normalize_v3(nor);
|
||||
negate_v3(nor);
|
||||
|
|
|
@ -834,8 +834,8 @@ void BKE_pbvh_build_mesh(PBVH *pbvh,
|
|||
pbvh->mloop = mloop;
|
||||
pbvh->looptri = looptri;
|
||||
pbvh->vert_positions = vert_positions;
|
||||
BKE_mesh_vertex_normals_ensure(mesh);
|
||||
pbvh->vert_normals = BKE_mesh_vertex_normals_for_write(mesh);
|
||||
BKE_mesh_vert_normals_ensure(mesh);
|
||||
pbvh->vert_normals = BKE_mesh_vert_normals_for_write(mesh);
|
||||
pbvh->hide_vert = static_cast<bool *>(CustomData_get_layer_named_for_write(
|
||||
&mesh->vdata, CD_PROP_BOOL, ".hide_vert", mesh->totvert));
|
||||
pbvh->vert_bitmap = static_cast<bool *>(
|
||||
|
|
|
@ -672,7 +672,6 @@ static bool update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image
|
|||
uv_islands::MeshData mesh_data(
|
||||
{pbvh->looptri, pbvh->totprim},
|
||||
{pbvh->mloop, mesh->totloop},
|
||||
pbvh->totvert,
|
||||
uv_map,
|
||||
{static_cast<blender::float3 *>(static_cast<void *>(pbvh->vert_positions)), pbvh->totvert});
|
||||
uv_islands::UVIslands islands(mesh_data);
|
||||
|
|
|
@ -200,15 +200,13 @@ static void mesh_data_init(MeshData &mesh_data)
|
|||
|
||||
MeshData::MeshData(const Span<MLoopTri> looptris,
|
||||
const Span<MLoop> loops,
|
||||
const int verts_num,
|
||||
const Span<float2> uv_map,
|
||||
const Span<float3> vertex_positions)
|
||||
const Span<float3> vert_positions)
|
||||
: looptris(looptris),
|
||||
verts_num(verts_num),
|
||||
loops(loops),
|
||||
uv_map(uv_map),
|
||||
vertex_positions(vertex_positions),
|
||||
vert_to_edge_map(verts_num),
|
||||
vert_positions(vert_positions),
|
||||
vert_to_edge_map(vert_positions.size()),
|
||||
edge_to_primitive_map(0),
|
||||
primitive_to_edge_map(looptris.size())
|
||||
{
|
||||
|
@ -1085,7 +1083,7 @@ void UVIsland::print_debug(const MeshData &mesh_data) const
|
|||
ss << "import mathutils\n";
|
||||
|
||||
ss << "uvisland_vertices = [\n";
|
||||
for (const float3 &vertex_position : mesh_data.vertex_positions) {
|
||||
for (const float3 &vertex_position : mesh_data.vert_positions) {
|
||||
ss << " mathutils.Vector((" << vertex_position.x << ", " << vertex_position.y << ", "
|
||||
<< vertex_position.z << ")),\n";
|
||||
}
|
||||
|
|
|
@ -119,10 +119,9 @@ class TriangleToEdgeMap {
|
|||
struct MeshData {
|
||||
public:
|
||||
const Span<MLoopTri> looptris;
|
||||
const int64_t verts_num;
|
||||
const Span<MLoop> loops;
|
||||
const Span<float2> uv_map;
|
||||
const Span<float3> vertex_positions;
|
||||
const Span<float3> vert_positions;
|
||||
|
||||
VertToEdgeMap vert_to_edge_map;
|
||||
|
||||
|
@ -142,9 +141,8 @@ struct MeshData {
|
|||
public:
|
||||
explicit MeshData(Span<MLoopTri> looptris,
|
||||
Span<MLoop> loops,
|
||||
const int verts_num,
|
||||
const Span<float2> uv_map,
|
||||
const Span<float3> vertex_positions);
|
||||
const Span<float3> vert_positions);
|
||||
};
|
||||
|
||||
struct UVVertex {
|
||||
|
|
|
@ -115,7 +115,7 @@ bool BKE_shrinkwrap_init_tree(
|
|||
|
||||
data->mesh = mesh;
|
||||
data->polys = mesh->polys().data();
|
||||
data->vert_normals = BKE_mesh_vertex_normals_ensure(mesh);
|
||||
data->vert_normals = BKE_mesh_vert_normals_ensure(mesh);
|
||||
|
||||
if (shrinkType == MOD_SHRINKWRAP_NEAREST_VERTEX) {
|
||||
data->bvh = BKE_bvhtree_from_mesh_get(&data->treeData, mesh, BVHTREE_FROM_VERTS, 2);
|
||||
|
@ -231,15 +231,14 @@ static ShrinkwrapBoundaryData *shrinkwrap_build_boundary_data(Mesh *mesh)
|
|||
data->edge_is_boundary = edge_is_boundary;
|
||||
|
||||
/* Build the boundary looptri bitmask. */
|
||||
const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(mesh);
|
||||
int totlooptri = BKE_mesh_runtime_looptri_len(mesh);
|
||||
const blender::Span<MLoopTri> looptris = mesh->looptris();
|
||||
|
||||
BLI_bitmap *looptri_has_boundary = BLI_BITMAP_NEW(totlooptri,
|
||||
BLI_bitmap *looptri_has_boundary = BLI_BITMAP_NEW(looptris.size(),
|
||||
"ShrinkwrapBoundaryData::looptri_is_boundary");
|
||||
|
||||
for (int i = 0; i < totlooptri; i++) {
|
||||
for (const int64_t i : looptris.index_range()) {
|
||||
int real_edges[3];
|
||||
BKE_mesh_looptri_get_real_edges(edges.data(), loops.data(), &mlooptri[i], real_edges);
|
||||
BKE_mesh_looptri_get_real_edges(edges.data(), loops.data(), &looptris[i], real_edges);
|
||||
|
||||
for (int j = 0; j < 3; j++) {
|
||||
if (real_edges[j] >= 0 && edge_mode[real_edges[j]]) {
|
||||
|
@ -296,7 +295,7 @@ static ShrinkwrapBoundaryData *shrinkwrap_build_boundary_data(Mesh *mesh)
|
|||
MEM_freeN(vert_status);
|
||||
|
||||
/* Finalize average direction and compute normal. */
|
||||
const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh);
|
||||
const float(*vert_normals)[3] = BKE_mesh_vert_normals_ensure(mesh);
|
||||
for (int i = 0; i < mesh->totvert; i++) {
|
||||
int bidx = vert_boundary_id[i];
|
||||
|
||||
|
@ -1408,7 +1407,7 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd,
|
|||
if (mesh != nullptr && smd->shrinkType == MOD_SHRINKWRAP_PROJECT) {
|
||||
/* Setup arrays to get vertex positions, normals and deform weights */
|
||||
calc.vert_positions = BKE_mesh_vert_positions_for_write(mesh);
|
||||
calc.vert_normals = BKE_mesh_vertex_normals_ensure(mesh);
|
||||
calc.vert_normals = BKE_mesh_vert_normals_ensure(mesh);
|
||||
|
||||
/* Using vertices positions/normals as if a subsurface was applied */
|
||||
if (smd->subsurfLevels) {
|
||||
|
@ -1569,7 +1568,7 @@ void BKE_shrinkwrap_remesh_target_project(Mesh *src_me, Mesh *target_me, Object
|
|||
calc.smd = &ssmd;
|
||||
calc.numVerts = src_me->totvert;
|
||||
calc.vertexCos = vertexCos;
|
||||
calc.vert_normals = BKE_mesh_vertex_normals_ensure(src_me);
|
||||
calc.vert_normals = BKE_mesh_vert_normals_ensure(src_me);
|
||||
calc.vgroup = -1;
|
||||
calc.target = target_me;
|
||||
calc.keepDist = ssmd.keepDist;
|
||||
|
|
|
@ -535,7 +535,7 @@ static bool subdiv_mesh_topology_info(const SubdivForeachContext *foreach_contex
|
|||
|
||||
SubdivMeshContext *subdiv_context = static_cast<SubdivMeshContext *>(foreach_context->user_data);
|
||||
subdiv_context->subdiv_mesh = BKE_mesh_new_nomain_from_template_ex(
|
||||
subdiv_context->coarse_mesh, num_vertices, num_edges, num_loops, num_polygons, mask);
|
||||
subdiv_context->coarse_mesh, num_vertices, num_edges, 0, num_loops, num_polygons, mask);
|
||||
subdiv_mesh_ctx_cache_custom_data_layers(subdiv_context);
|
||||
subdiv_mesh_prepare_accumulator(subdiv_context, num_vertices);
|
||||
subdiv_context->subdiv_mesh->runtime->subsurf_face_dot_tags.clear();
|
||||
|
@ -1226,7 +1226,7 @@ Mesh *BKE_subdiv_to_mesh(Subdiv *subdiv,
|
|||
* calculation. Since vertex normals are supposed to be a consistent cache, don't bother
|
||||
* calculating them here. The work may have been pointless anyway if the mesh is deformed or
|
||||
* changed afterwards. */
|
||||
BLI_assert(BKE_mesh_vertex_normals_are_dirty(result) || BKE_mesh_poly_normals_are_dirty(result));
|
||||
BLI_assert(BKE_mesh_vert_normals_are_dirty(result) || BKE_mesh_poly_normals_are_dirty(result));
|
||||
/* Free used memory. */
|
||||
subdiv_mesh_context_free(&subdiv_context);
|
||||
return result;
|
||||
|
|
|
@ -2124,10 +2124,8 @@ static bool txt_select_unprefix(Text *text, const char *remove, const bool requi
|
|||
return changed_any;
|
||||
}
|
||||
|
||||
void txt_comment(Text *text)
|
||||
void txt_comment(Text *text, const char *prefix)
|
||||
{
|
||||
const char *prefix = "#";
|
||||
|
||||
if (ELEM(NULL, text->curl, text->sell)) {
|
||||
return;
|
||||
}
|
||||
|
@ -2136,10 +2134,8 @@ void txt_comment(Text *text)
|
|||
txt_select_prefix(text, prefix, skip_blank_lines);
|
||||
}
|
||||
|
||||
bool txt_uncomment(Text *text)
|
||||
bool txt_uncomment(Text *text, const char *prefix)
|
||||
{
|
||||
const char *prefix = "#";
|
||||
|
||||
if (ELEM(NULL, text->curl, text->sell)) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -420,7 +420,12 @@ VFont *BKE_vfont_builtin_get(void)
|
|||
}
|
||||
}
|
||||
|
||||
return BKE_vfont_load(G_MAIN, FO_BUILTIN_NAME);
|
||||
/* Newly loaded ID's have a user by default, in this case the caller is responsible
|
||||
* for assigning a user, otherwise an additional user would be added, see: #100819. */
|
||||
vfont = BKE_vfont_load(G_MAIN, FO_BUILTIN_NAME);
|
||||
id_us_min(&vfont->id);
|
||||
BLI_assert(vfont->id.us == 0);
|
||||
return vfont;
|
||||
}
|
||||
|
||||
static VChar *find_vfont_char(VFontData *vfd, uint character)
|
||||
|
|
|
@ -302,7 +302,7 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
|
|||
|
||||
const float(*vert_normals)[3] = nullptr;
|
||||
if (params->calc_vert_normal) {
|
||||
vert_normals = BKE_mesh_vertex_normals_ensure(me);
|
||||
vert_normals = BKE_mesh_vert_normals_ensure(me);
|
||||
}
|
||||
|
||||
if (is_new) {
|
||||
|
|
|
@ -387,7 +387,7 @@ BLI_INLINE void extract_task_range_run_iter(const MeshRenderData *mr,
|
|||
int stop;
|
||||
switch (iter_type) {
|
||||
case MR_ITER_LOOPTRI:
|
||||
range_data.elems = is_mesh ? mr->mlooptri : (void *)mr->edit_bmesh->looptris;
|
||||
range_data.elems = is_mesh ? mr->looptris.data() : (void *)mr->edit_bmesh->looptris;
|
||||
func = is_mesh ? extract_range_iter_looptri_mesh : extract_range_iter_looptri_bm;
|
||||
stop = mr->tri_len;
|
||||
break;
|
||||
|
|
|
@ -339,7 +339,7 @@ void mesh_render_data_update_looptris(MeshRenderData *mr,
|
|||
if (mr->extract_type != MR_EXTRACT_BMESH) {
|
||||
/* Mesh */
|
||||
if ((iter_type & MR_ITER_LOOPTRI) || (data_flag & MR_DATA_LOOPTRI)) {
|
||||
mr->mlooptri = BKE_mesh_runtime_looptri_ensure(mr->me);
|
||||
mr->looptris = mr->me->looptris();
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -359,7 +359,7 @@ void mesh_render_data_update_normals(MeshRenderData *mr, const eMRDataType data_
|
|||
|
||||
if (mr->extract_type != MR_EXTRACT_BMESH) {
|
||||
/* Mesh */
|
||||
mr->vert_normals = BKE_mesh_vertex_normals_ensure(mr->me);
|
||||
mr->vert_normals = BKE_mesh_vert_normals_ensure(mr->me);
|
||||
if (data_flag & (MR_DATA_POLY_NOR | MR_DATA_LOOP_NOR | MR_DATA_TAN_LOOP_NOR)) {
|
||||
mr->poly_normals = BKE_mesh_poly_normals_ensure(mr->me);
|
||||
}
|
||||
|
|
|
@ -1625,7 +1625,7 @@ void draw_subdiv_accumulate_normals(const DRWSubdivCache *cache,
|
|||
GPUVertBuf *face_adjacency_offsets,
|
||||
GPUVertBuf *face_adjacency_lists,
|
||||
GPUVertBuf *vertex_loop_map,
|
||||
GPUVertBuf *vertex_normals)
|
||||
GPUVertBuf *vert_normals)
|
||||
{
|
||||
GPUShader *shader = get_subdiv_shader(SHADER_BUFFER_NORMALS_ACCUMULATE);
|
||||
GPU_shader_bind(shader);
|
||||
|
@ -1636,7 +1636,7 @@ void draw_subdiv_accumulate_normals(const DRWSubdivCache *cache,
|
|||
GPU_vertbuf_bind_as_ssbo(face_adjacency_offsets, binding_point++);
|
||||
GPU_vertbuf_bind_as_ssbo(face_adjacency_lists, binding_point++);
|
||||
GPU_vertbuf_bind_as_ssbo(vertex_loop_map, binding_point++);
|
||||
GPU_vertbuf_bind_as_ssbo(vertex_normals, binding_point++);
|
||||
GPU_vertbuf_bind_as_ssbo(vert_normals, binding_point++);
|
||||
BLI_assert(binding_point <= MAX_GPU_SUBDIV_SSBOS);
|
||||
|
||||
drw_subdiv_compute_dispatch(cache, shader, 0, 0, cache->num_subdiv_verts);
|
||||
|
@ -1651,7 +1651,7 @@ void draw_subdiv_accumulate_normals(const DRWSubdivCache *cache,
|
|||
}
|
||||
|
||||
void draw_subdiv_finalize_normals(const DRWSubdivCache *cache,
|
||||
GPUVertBuf *vertex_normals,
|
||||
GPUVertBuf *vert_normals,
|
||||
GPUVertBuf *subdiv_loop_subdiv_vert_index,
|
||||
GPUVertBuf *pos_nor)
|
||||
{
|
||||
|
@ -1659,7 +1659,7 @@ void draw_subdiv_finalize_normals(const DRWSubdivCache *cache,
|
|||
GPU_shader_bind(shader);
|
||||
|
||||
int binding_point = 0;
|
||||
GPU_vertbuf_bind_as_ssbo(vertex_normals, binding_point++);
|
||||
GPU_vertbuf_bind_as_ssbo(vert_normals, binding_point++);
|
||||
GPU_vertbuf_bind_as_ssbo(subdiv_loop_subdiv_vert_index, binding_point++);
|
||||
GPU_vertbuf_bind_as_ssbo(pos_nor, binding_point++);
|
||||
BLI_assert(binding_point <= MAX_GPU_SUBDIV_SSBOS);
|
||||
|
|
|
@ -175,8 +175,8 @@ void DRW_globals_update(void)
|
|||
max_ff(1.0f, UI_GetThemeValuef(TH_VERTEX_SIZE) * (float)M_SQRT2 / 2.0f);
|
||||
gb->size_vertex_gpencil = U.pixelsize * UI_GetThemeValuef(TH_GP_VERTEX_SIZE);
|
||||
gb->size_face_dot = U.pixelsize * UI_GetThemeValuef(TH_FACEDOT_SIZE);
|
||||
gb->size_edge = U.pixelsize * (1.0f / 2.0f); /* TODO: Theme. */
|
||||
gb->size_edge_fix = U.pixelsize * (0.5f + 2.0f * (2.0f * (gb->size_edge * (float)M_SQRT1_2)));
|
||||
gb->size_edge = U.pixelsize * max_ff(1.0f, UI_GetThemeValuef(TH_EDGE_WIDTH)) / 2.0f;
|
||||
gb->size_edge_fix = U.pixelsize * (0.5f + 2.0f * (1.0f * (gb->size_edge * (float)M_SQRT1_2)));
|
||||
|
||||
gb->pixel_fac = *DRW_viewport_pixelsize_get();
|
||||
|
||||
|
|
|
@ -229,10 +229,10 @@ void draw_subdiv_accumulate_normals(const DRWSubdivCache *cache,
|
|||
struct GPUVertBuf *face_adjacency_offsets,
|
||||
struct GPUVertBuf *face_adjacency_lists,
|
||||
struct GPUVertBuf *vertex_loop_map,
|
||||
struct GPUVertBuf *vertex_normals);
|
||||
struct GPUVertBuf *vert_normals);
|
||||
|
||||
void draw_subdiv_finalize_normals(const DRWSubdivCache *cache,
|
||||
struct GPUVertBuf *vertex_normals,
|
||||
struct GPUVertBuf *vert_normals,
|
||||
struct GPUVertBuf *subdiv_loop_subdiv_vert_index,
|
||||
struct GPUVertBuf *pos_nor);
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ struct MeshRenderData {
|
|||
BMFace *efa_act;
|
||||
BMFace *efa_act_uv;
|
||||
/* The triangulation of #Mesh polygons, owned by the mesh. */
|
||||
const MLoopTri *mlooptri;
|
||||
blender::Span<MLoopTri> looptris;
|
||||
const int *material_indices;
|
||||
const float (*vert_normals)[3];
|
||||
const float (*poly_normals)[3];
|
||||
|
|
|
@ -74,7 +74,7 @@ static void extract_tris_iter_poly_mesh(const MeshRenderData *mr,
|
|||
|
||||
int tri_len = mp->totloop - 2;
|
||||
for (int offs = 0; offs < tri_len; offs++) {
|
||||
const MLoopTri *mlt = &mr->mlooptri[tri_first_index_real + offs];
|
||||
const MLoopTri *mlt = &mr->looptris[tri_first_index_real + offs];
|
||||
int tri_index = tri_first_index + offs;
|
||||
GPU_indexbuf_set_tri_verts(elb, tri_index, mlt->tri[0], mlt->tri[1], mlt->tri[2]);
|
||||
}
|
||||
|
|
|
@ -214,12 +214,12 @@ static void statvis_calc_thickness(const MeshRenderData *mr, float *r_thickness)
|
|||
BVHTreeFromMesh treeData = {nullptr};
|
||||
|
||||
BVHTree *tree = BKE_bvhtree_from_mesh_get(&treeData, mr->me, BVHTREE_FROM_LOOPTRI, 4);
|
||||
const MLoopTri *mlooptri = mr->mlooptri;
|
||||
for (int i = 0; i < mr->tri_len; i++, mlooptri++) {
|
||||
const int index = mlooptri->poly;
|
||||
const float *cos[3] = {mr->vert_positions[mr->mloop[mlooptri->tri[0]].v],
|
||||
mr->vert_positions[mr->mloop[mlooptri->tri[1]].v],
|
||||
mr->vert_positions[mr->mloop[mlooptri->tri[2]].v]};
|
||||
const Span<MLoopTri> looptris = mr->looptris;
|
||||
for (const int i : looptris.index_range()) {
|
||||
const int index = looptris[i].poly;
|
||||
const float *cos[3] = {mr->vert_positions[mr->mloop[looptris[i].tri[0]].v],
|
||||
mr->vert_positions[mr->mloop[looptris[i].tri[1]].v],
|
||||
mr->vert_positions[mr->mloop[looptris[i].tri[2]].v]};
|
||||
float ray_co[3];
|
||||
float ray_no[3];
|
||||
|
||||
|
@ -261,7 +261,7 @@ static void statvis_calc_thickness(const MeshRenderData *mr, float *r_thickness)
|
|||
struct BVHTree_OverlapData {
|
||||
const float3 *positions;
|
||||
const MLoop *loops;
|
||||
const MLoopTri *mlooptri;
|
||||
Span<MLoopTri> looptris;
|
||||
float epsilon;
|
||||
};
|
||||
|
||||
|
@ -269,8 +269,8 @@ static bool bvh_overlap_cb(void *userdata, int index_a, int index_b, int /*threa
|
|||
{
|
||||
struct BVHTree_OverlapData *data = static_cast<struct BVHTree_OverlapData *>(userdata);
|
||||
|
||||
const MLoopTri *tri_a = &data->mlooptri[index_a];
|
||||
const MLoopTri *tri_b = &data->mlooptri[index_b];
|
||||
const MLoopTri *tri_a = &data->looptris[index_a];
|
||||
const MLoopTri *tri_b = &data->looptris[index_b];
|
||||
|
||||
if (UNLIKELY(tri_a->poly == tri_b->poly)) {
|
||||
return false;
|
||||
|
@ -344,15 +344,15 @@ static void statvis_calc_intersect(const MeshRenderData *mr, float *r_intersect)
|
|||
struct BVHTree_OverlapData data = {nullptr};
|
||||
data.positions = mr->vert_positions;
|
||||
data.loops = mr->mloop;
|
||||
data.mlooptri = mr->mlooptri;
|
||||
data.looptris = mr->looptris;
|
||||
data.epsilon = BLI_bvhtree_get_epsilon(tree);
|
||||
|
||||
BVHTreeOverlap *overlap = BLI_bvhtree_overlap_self(tree, &overlap_len, bvh_overlap_cb, &data);
|
||||
if (overlap) {
|
||||
for (int i = 0; i < overlap_len; i++) {
|
||||
const MPoly *f_hit_pair[2] = {
|
||||
&mr->mpoly[mr->mlooptri[overlap[i].indexA].poly],
|
||||
&mr->mpoly[mr->mlooptri[overlap[i].indexB].poly],
|
||||
&mr->mpoly[mr->looptris[overlap[i].indexA].poly],
|
||||
&mr->mpoly[mr->looptris[overlap[i].indexB].poly],
|
||||
};
|
||||
for (int j = 0; j < 2; j++) {
|
||||
const MPoly *f_hit = f_hit_pair[j];
|
||||
|
|
|
@ -291,20 +291,20 @@ static void extract_pos_nor_init_subdiv(const DRWSubdivCache *subdiv_cache,
|
|||
GPUVertBuf *subdiv_loop_subdiv_vert_index = draw_subdiv_build_origindex_buffer(
|
||||
subdiv_cache->subdiv_loop_subdiv_vert_index, subdiv_cache->num_subdiv_loops);
|
||||
|
||||
GPUVertBuf *vertex_normals = GPU_vertbuf_calloc();
|
||||
GPUVertBuf *vert_normals = GPU_vertbuf_calloc();
|
||||
GPU_vertbuf_init_build_on_device(
|
||||
vertex_normals, get_normals_format(), subdiv_cache->num_subdiv_verts);
|
||||
vert_normals, get_normals_format(), subdiv_cache->num_subdiv_verts);
|
||||
|
||||
draw_subdiv_accumulate_normals(subdiv_cache,
|
||||
vbo,
|
||||
subdiv_cache->subdiv_vertex_face_adjacency_offsets,
|
||||
subdiv_cache->subdiv_vertex_face_adjacency,
|
||||
subdiv_loop_subdiv_vert_index,
|
||||
vertex_normals);
|
||||
vert_normals);
|
||||
|
||||
draw_subdiv_finalize_normals(subdiv_cache, vertex_normals, subdiv_loop_subdiv_vert_index, vbo);
|
||||
draw_subdiv_finalize_normals(subdiv_cache, vert_normals, subdiv_loop_subdiv_vert_index, vbo);
|
||||
|
||||
GPU_vertbuf_discard(vertex_normals);
|
||||
GPU_vertbuf_discard(vert_normals);
|
||||
GPU_vertbuf_discard(subdiv_loop_subdiv_vert_index);
|
||||
}
|
||||
|
||||
|
|
|
@ -118,7 +118,7 @@ static void extract_tan_init_common(const MeshRenderData *mr,
|
|||
mr->mpoly,
|
||||
mr->poly_len,
|
||||
mr->mloop,
|
||||
mr->mlooptri,
|
||||
mr->looptris.data(),
|
||||
mr->tri_len,
|
||||
cd_ldata,
|
||||
calc_active_tangent,
|
||||
|
|
|
@ -198,23 +198,23 @@ static short ob_keyframes_loop(KeyframeEditData *ked,
|
|||
int filter;
|
||||
int ret = 0;
|
||||
|
||||
bAnimListElem dummychan = {NULL};
|
||||
Base dummybase = {NULL};
|
||||
bAnimListElem dummy_chan = {NULL};
|
||||
Base dummy_base = {NULL};
|
||||
|
||||
if (ob == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* create a dummy wrapper data to work with */
|
||||
dummybase.object = ob;
|
||||
dummy_base.object = ob;
|
||||
|
||||
dummychan.type = ANIMTYPE_OBJECT;
|
||||
dummychan.data = &dummybase;
|
||||
dummychan.id = &ob->id;
|
||||
dummychan.adt = ob->adt;
|
||||
dummy_chan.type = ANIMTYPE_OBJECT;
|
||||
dummy_chan.data = &dummy_base;
|
||||
dummy_chan.id = &ob->id;
|
||||
dummy_chan.adt = ob->adt;
|
||||
|
||||
ac.ads = ads;
|
||||
ac.data = &dummychan;
|
||||
ac.data = &dummy_chan;
|
||||
ac.datatype = ANIMCONT_CHANNEL;
|
||||
|
||||
/* get F-Curves to take keyframes from */
|
||||
|
@ -250,20 +250,20 @@ static short scene_keyframes_loop(KeyframeEditData *ked,
|
|||
int filter;
|
||||
int ret = 0;
|
||||
|
||||
bAnimListElem dummychan = {NULL};
|
||||
bAnimListElem dummy_chan = {NULL};
|
||||
|
||||
if (sce == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* create a dummy wrapper data to work with */
|
||||
dummychan.type = ANIMTYPE_SCENE;
|
||||
dummychan.data = sce;
|
||||
dummychan.id = &sce->id;
|
||||
dummychan.adt = sce->adt;
|
||||
dummy_chan.type = ANIMTYPE_SCENE;
|
||||
dummy_chan.data = sce;
|
||||
dummy_chan.id = &sce->id;
|
||||
dummy_chan.adt = sce->adt;
|
||||
|
||||
ac.ads = ads;
|
||||
ac.data = &dummychan;
|
||||
ac.data = &dummy_chan;
|
||||
ac.datatype = ANIMCONT_CHANNEL;
|
||||
|
||||
/* get F-Curves to take keyframes from */
|
||||
|
|
|
@ -926,20 +926,20 @@ void scene_to_keylist(bDopeSheet *ads, Scene *sce, AnimKeylist *keylist, const i
|
|||
bAnimContext ac = {nullptr};
|
||||
ListBase anim_data = {nullptr, nullptr};
|
||||
|
||||
bAnimListElem dummychan = {nullptr};
|
||||
bAnimListElem dummy_chan = {nullptr};
|
||||
|
||||
if (sce == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* create a dummy wrapper data to work with */
|
||||
dummychan.type = ANIMTYPE_SCENE;
|
||||
dummychan.data = sce;
|
||||
dummychan.id = &sce->id;
|
||||
dummychan.adt = sce->adt;
|
||||
dummy_chan.type = ANIMTYPE_SCENE;
|
||||
dummy_chan.data = sce;
|
||||
dummy_chan.id = &sce->id;
|
||||
dummy_chan.adt = sce->adt;
|
||||
|
||||
ac.ads = ads;
|
||||
ac.data = &dummychan;
|
||||
ac.data = &dummy_chan;
|
||||
ac.datatype = ANIMCONT_CHANNEL;
|
||||
|
||||
/* get F-Curves to take keyframes from */
|
||||
|
@ -961,23 +961,23 @@ void ob_to_keylist(bDopeSheet *ads, Object *ob, AnimKeylist *keylist, const int
|
|||
bAnimContext ac = {nullptr};
|
||||
ListBase anim_data = {nullptr, nullptr};
|
||||
|
||||
bAnimListElem dummychan = {nullptr};
|
||||
Base dummybase = {nullptr};
|
||||
bAnimListElem dummy_chan = {nullptr};
|
||||
Base dummy_base = {nullptr};
|
||||
|
||||
if (ob == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* create a dummy wrapper data to work with */
|
||||
dummybase.object = ob;
|
||||
dummy_base.object = ob;
|
||||
|
||||
dummychan.type = ANIMTYPE_OBJECT;
|
||||
dummychan.data = &dummybase;
|
||||
dummychan.id = &ob->id;
|
||||
dummychan.adt = ob->adt;
|
||||
dummy_chan.type = ANIMTYPE_OBJECT;
|
||||
dummy_chan.data = &dummy_base;
|
||||
dummy_chan.id = &ob->id;
|
||||
dummy_chan.adt = ob->adt;
|
||||
|
||||
ac.ads = ads;
|
||||
ac.data = &dummychan;
|
||||
ac.data = &dummy_chan;
|
||||
ac.datatype = ANIMCONT_CHANNEL;
|
||||
|
||||
/* get F-Curves to take keyframes from */
|
||||
|
@ -1003,15 +1003,15 @@ void cachefile_to_keylist(bDopeSheet *ads,
|
|||
}
|
||||
|
||||
/* create a dummy wrapper data to work with */
|
||||
bAnimListElem dummychan = {nullptr};
|
||||
dummychan.type = ANIMTYPE_DSCACHEFILE;
|
||||
dummychan.data = cache_file;
|
||||
dummychan.id = &cache_file->id;
|
||||
dummychan.adt = cache_file->adt;
|
||||
bAnimListElem dummy_chan = {nullptr};
|
||||
dummy_chan.type = ANIMTYPE_DSCACHEFILE;
|
||||
dummy_chan.data = cache_file;
|
||||
dummy_chan.id = &cache_file->id;
|
||||
dummy_chan.adt = cache_file->adt;
|
||||
|
||||
bAnimContext ac = {nullptr};
|
||||
ac.ads = ads;
|
||||
ac.data = &dummychan;
|
||||
ac.data = &dummy_chan;
|
||||
ac.datatype = ANIMCONT_CHANNEL;
|
||||
|
||||
/* get F-Curves to take keyframes from */
|
||||
|
|
|
@ -928,7 +928,7 @@ typedef struct MeshDeformBind {
|
|||
struct {
|
||||
blender::Span<MPoly> polys;
|
||||
blender::Span<MLoop> loops;
|
||||
const MLoopTri *looptri;
|
||||
blender::Span<MLoopTri> looptris;
|
||||
const float (*poly_nors)[3];
|
||||
} cagemesh_cache;
|
||||
} MeshDeformBind;
|
||||
|
@ -959,13 +959,12 @@ static void harmonic_ray_callback(void *userdata,
|
|||
MeshRayCallbackData *data = static_cast<MeshRayCallbackData *>(userdata);
|
||||
MeshDeformBind *mdb = data->mdb;
|
||||
const blender::Span<MLoop> loops = mdb->cagemesh_cache.loops;
|
||||
const MLoopTri *looptri = mdb->cagemesh_cache.looptri, *lt;
|
||||
const float(*poly_nors)[3] = mdb->cagemesh_cache.poly_nors;
|
||||
MeshDeformIsect *isec = data->isec;
|
||||
float no[3], co[3], dist;
|
||||
float *face[3];
|
||||
|
||||
lt = &looptri[index];
|
||||
const MLoopTri *lt = &mdb->cagemesh_cache.looptris[index];
|
||||
|
||||
face[0] = mdb->cagecos[loops[lt->tri[0]].v];
|
||||
face[1] = mdb->cagecos[loops[lt->tri[1]].v];
|
||||
|
@ -1034,7 +1033,7 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb,
|
|||
&data,
|
||||
BVH_RAYCAST_WATERTIGHT) != -1) {
|
||||
const blender::Span<MLoop> loops = mdb->cagemesh_cache.loops;
|
||||
const MLoopTri *lt = &mdb->cagemesh_cache.looptri[hit.index];
|
||||
const MLoopTri *lt = &mdb->cagemesh_cache.looptris[hit.index];
|
||||
const MPoly *mp = &mdb->cagemesh_cache.polys[lt->poly];
|
||||
const float(*cagecos)[3] = mdb->cagecos;
|
||||
const float len = isect_mdef.lambda;
|
||||
|
@ -1632,7 +1631,7 @@ static void harmonic_coordinates_bind(MeshDeformModifierData *mmd, MeshDeformBin
|
|||
Mesh *me = mdb->cagemesh;
|
||||
mdb->cagemesh_cache.polys = me->polys();
|
||||
mdb->cagemesh_cache.loops = me->loops();
|
||||
mdb->cagemesh_cache.looptri = BKE_mesh_runtime_looptri_ensure(me);
|
||||
mdb->cagemesh_cache.looptris = me->looptris();
|
||||
mdb->cagemesh_cache.poly_nors = BKE_mesh_poly_normals_ensure(me);
|
||||
}
|
||||
|
||||
|
|
|
@ -1174,21 +1174,30 @@ static int gizmo_cage2d_modal(bContext *C,
|
|||
}
|
||||
}
|
||||
|
||||
float scale[2] = {1.0f, 1.0f};
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (size_orig[i] == 0) {
|
||||
size_orig[i] = 1.0f;
|
||||
gz->matrix_offset[i][i] = 1.0f;
|
||||
}
|
||||
scale[i] = size_new[i] / size_orig[i];
|
||||
}
|
||||
|
||||
if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_SCALE_UNIFORM) {
|
||||
if (constrain_axis[0] == false && constrain_axis[1] == false) {
|
||||
if (draw_style == ED_GIZMO_CAGE2D_STYLE_CIRCLE) {
|
||||
/* So that the cursor lies on the circle. */
|
||||
size_new[1] = size_new[0] = len_v2(size_new);
|
||||
scale[1] = scale[0] = len_v2(scale);
|
||||
}
|
||||
else {
|
||||
size_new[1] = size_new[0] = (size_new[1] + size_new[0]) / 2.0f;
|
||||
scale[1] = scale[0] = (scale[1] + scale[0]) / 2.0f;
|
||||
}
|
||||
}
|
||||
else if (constrain_axis[0] == false) {
|
||||
size_new[1] = size_new[0];
|
||||
scale[1] = scale[0];
|
||||
}
|
||||
else if (constrain_axis[1] == false) {
|
||||
size_new[0] = size_new[1];
|
||||
scale[0] = scale[1];
|
||||
}
|
||||
else {
|
||||
BLI_assert(0);
|
||||
|
@ -1196,18 +1205,11 @@ static int gizmo_cage2d_modal(bContext *C,
|
|||
}
|
||||
|
||||
/* Scale around pivot. */
|
||||
float scale[2];
|
||||
float matrix_scale[4][4];
|
||||
unit_m4(matrix_scale);
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (size_orig[i] == 0) {
|
||||
size_orig[i] = 1.0f;
|
||||
gz->matrix_offset[i][i] = 1.0f;
|
||||
}
|
||||
scale[i] = size_new[i] / size_orig[i];
|
||||
mul_v3_fl(matrix_scale[i], scale[i]);
|
||||
}
|
||||
mul_v3_fl(matrix_scale[0], scale[0]);
|
||||
mul_v3_fl(matrix_scale[1], scale[1]);
|
||||
|
||||
transform_pivot_set_m4(matrix_scale, (const float[3]){UNPACK2(pivot), 0.0f});
|
||||
mul_m4_m4_post(gz->matrix_offset, matrix_scale);
|
||||
|
|
|
@ -223,7 +223,7 @@ typedef struct KeyingSetInfo {
|
|||
/* identifier so that user can hook this up to a KeyingSet (used as label). */
|
||||
char name[64];
|
||||
/* short help/description. */
|
||||
char description[240]; /* RNA_DYN_DESCR_MAX */
|
||||
char description[1024]; /* #RNA_DYN_DESCR_MAX */
|
||||
/* keying settings */
|
||||
short keyingflag;
|
||||
|
||||
|
|
|
@ -43,6 +43,8 @@ struct UndoStep *ED_text_undo_push_init(struct bContext *C);
|
|||
|
||||
/* text_format.c */
|
||||
|
||||
const char *ED_text_format_comment_line_prefix(struct Text *text);
|
||||
|
||||
bool ED_text_is_syntax_highlight_supported(struct Text *text);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -26,6 +26,7 @@ struct Object;
|
|||
struct Scene;
|
||||
struct SpaceImage;
|
||||
struct ToolSettings;
|
||||
struct UVPackIsland_Params;
|
||||
struct View2D;
|
||||
struct ViewLayer;
|
||||
struct bContext;
|
||||
|
@ -348,26 +349,6 @@ struct UVMapUDIM_Params {
|
|||
int grid_shape[2];
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
ED_UVPACK_MARGIN_SCALED = 0, /* Use scale of existing UVs to multiply margin. */
|
||||
ED_UVPACK_MARGIN_ADD, /* Just add the margin, ignoring any UV scale. */
|
||||
ED_UVPACK_MARGIN_FRACTION, /* Specify a precise fraction of final UV output. */
|
||||
} eUVPackIsland_MarginMethod;
|
||||
|
||||
/** See also #UnwrapOptions. */
|
||||
struct UVPackIsland_Params {
|
||||
uint rotate : 1;
|
||||
uint only_selected_uvs : 1;
|
||||
uint only_selected_faces : 1;
|
||||
uint use_seams : 1;
|
||||
uint correct_aspect : 1;
|
||||
bool ignore_pinned; /* Ignore islands which have any pinned UVs. */
|
||||
bool pin_unselected; /* Treat unselected UVs as if they were pinned. */
|
||||
eUVPackIsland_MarginMethod margin_method; /* Which formula to use when scaling island margin. */
|
||||
float margin; /* Additional space to add around each island. */
|
||||
float udim_base_offset[2]; /* Additional translation for bottom left corner. */
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if UV coordinates lie on a valid tile in UDIM grid or tiled image.
|
||||
*/
|
||||
|
|
|
@ -79,6 +79,7 @@ typedef enum ThemeColorID {
|
|||
TH_VERTEX_ACTIVE,
|
||||
TH_VERTEX_UNREFERENCED,
|
||||
TH_VERTEX_SIZE,
|
||||
TH_EDGE_WIDTH,
|
||||
TH_OUTLINE_WIDTH,
|
||||
TH_OBCENTER_DIA,
|
||||
TH_EDGE,
|
||||
|
|
|
@ -366,6 +366,9 @@ const uchar *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colorid)
|
|||
case TH_EDGE:
|
||||
cp = ts->edge;
|
||||
break;
|
||||
case TH_EDGE_WIDTH:
|
||||
cp = &ts->edge_width;
|
||||
break;
|
||||
case TH_EDGE_SELECT:
|
||||
cp = ts->edge_select;
|
||||
break;
|
||||
|
|
|
@ -685,7 +685,7 @@ static void undomesh_to_editmesh(UndoMesh *um, Object *ob, BMEditMesh *em)
|
|||
|
||||
/* Normals should not be stored in the undo mesh, so recalculate them. The edit
|
||||
* mesh is expected to have valid normals and there is no tracked dirty state. */
|
||||
BLI_assert(BKE_mesh_vertex_normals_are_dirty(&um->me));
|
||||
BLI_assert(BKE_mesh_vert_normals_are_dirty(&um->me));
|
||||
|
||||
/* Calculate face normals and tessellation at once since it's multi-threaded. */
|
||||
BKE_editmesh_looptri_and_normals_calc(em);
|
||||
|
|
|
@ -1453,7 +1453,7 @@ void recalc_emitter_field(Depsgraph *UNUSED(depsgraph), Object *UNUSED(ob), Part
|
|||
nor = vec + 3;
|
||||
|
||||
const float(*positions)[3] = BKE_mesh_vert_positions(mesh);
|
||||
const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh);
|
||||
const float(*vert_normals)[3] = BKE_mesh_vert_normals_ensure(mesh);
|
||||
const MFace *mfaces = (const MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
|
||||
for (i = 0; i < totface; i++, vec += 6, nor += 6) {
|
||||
const MFace *mface = &mfaces[i];
|
||||
|
|
|
@ -784,8 +784,8 @@ static Object *object_preview_camera_create(Main *preview_main,
|
|||
Object *camera = BKE_object_add(preview_main, scene, view_layer, OB_CAMERA, "Preview Camera");
|
||||
|
||||
float rotmat[3][3];
|
||||
float dummyscale[3];
|
||||
mat4_to_loc_rot_size(camera->loc, rotmat, dummyscale, preview_object->object_to_world);
|
||||
float dummy_scale[3];
|
||||
mat4_to_loc_rot_size(camera->loc, rotmat, dummy_scale, preview_object->object_to_world);
|
||||
|
||||
/* Camera is Y up, so needs additional rotations to obliquely face the front. */
|
||||
float drotmat[3][3];
|
||||
|
|
|
@ -419,7 +419,7 @@ struct ProjPaintState {
|
|||
blender::Span<MLoop> loops_eval;
|
||||
const bool *select_poly_eval;
|
||||
const int *material_indices;
|
||||
const MLoopTri *mlooptri_eval;
|
||||
blender::Span<MLoopTri> looptris_eval;
|
||||
|
||||
const float (*mloopuv_stencil_eval)[2];
|
||||
|
||||
|
@ -551,7 +551,7 @@ static Material *tex_get_material(const ProjPaintState *ps, int poly_i)
|
|||
|
||||
static TexPaintSlot *project_paint_face_paint_slot(const ProjPaintState *ps, int tri_index)
|
||||
{
|
||||
const int poly_i = ps->mlooptri_eval[tri_index].poly;
|
||||
const int poly_i = ps->looptris_eval[tri_index].poly;
|
||||
Material *ma = tex_get_material(ps, poly_i);
|
||||
return ma ? ma->texpaintslot + ma->paint_active_slot : nullptr;
|
||||
}
|
||||
|
@ -562,7 +562,7 @@ static Image *project_paint_face_paint_image(const ProjPaintState *ps, int tri_i
|
|||
return ps->stencil_ima;
|
||||
}
|
||||
|
||||
const int poly_i = ps->mlooptri_eval[tri_index].poly;
|
||||
const int poly_i = ps->looptris_eval[tri_index].poly;
|
||||
Material *ma = tex_get_material(ps, poly_i);
|
||||
TexPaintSlot *slot = ma ? ma->texpaintslot + ma->paint_active_slot : nullptr;
|
||||
return slot ? slot->ima : ps->canvas_ima;
|
||||
|
@ -570,14 +570,14 @@ static Image *project_paint_face_paint_image(const ProjPaintState *ps, int tri_i
|
|||
|
||||
static TexPaintSlot *project_paint_face_clone_slot(const ProjPaintState *ps, int tri_index)
|
||||
{
|
||||
const int poly_i = ps->mlooptri_eval[tri_index].poly;
|
||||
const int poly_i = ps->looptris_eval[tri_index].poly;
|
||||
Material *ma = tex_get_material(ps, poly_i);
|
||||
return ma ? ma->texpaintslot + ma->paint_clone_slot : nullptr;
|
||||
}
|
||||
|
||||
static Image *project_paint_face_clone_image(const ProjPaintState *ps, int tri_index)
|
||||
{
|
||||
const int poly_i = ps->mlooptri_eval[tri_index].poly;
|
||||
const int poly_i = ps->looptris_eval[tri_index].poly;
|
||||
Material *ma = tex_get_material(ps, poly_i);
|
||||
TexPaintSlot *slot = ma ? ma->texpaintslot + ma->paint_clone_slot : nullptr;
|
||||
return slot ? slot->ima : ps->clone_ima;
|
||||
|
@ -673,7 +673,7 @@ static int project_paint_PickFace(const ProjPaintState *ps, const float pt[2], f
|
|||
|
||||
for (node = ps->bucketFaces[bucket_index]; node; node = node->next) {
|
||||
const int tri_index = POINTER_AS_INT(node->link);
|
||||
const MLoopTri *lt = &ps->mlooptri_eval[tri_index];
|
||||
const MLoopTri *lt = &ps->looptris_eval[tri_index];
|
||||
const float *vtri_ss[3] = {
|
||||
ps->screenCoords[ps->loops_eval[lt->tri[0]].v],
|
||||
ps->screenCoords[ps->loops_eval[lt->tri[1]].v],
|
||||
|
@ -737,7 +737,7 @@ static bool project_paint_PickColor(
|
|||
return false;
|
||||
}
|
||||
|
||||
lt = &ps->mlooptri_eval[tri_index];
|
||||
lt = &ps->looptris_eval[tri_index];
|
||||
PS_LOOPTRI_ASSIGN_UV_3(lt_tri_uv, ps->poly_to_loop_uv, lt);
|
||||
|
||||
interp_v2_v2v2v2(uv, UNPACK3(lt_tri_uv), w);
|
||||
|
@ -915,7 +915,7 @@ static bool project_bucket_point_occluded(const ProjPaintState *ps,
|
|||
const int tri_index = POINTER_AS_INT(bucketFace->link);
|
||||
|
||||
if (orig_face != tri_index) {
|
||||
const MLoopTri *lt = &ps->mlooptri_eval[tri_index];
|
||||
const MLoopTri *lt = &ps->looptris_eval[tri_index];
|
||||
const float *vtri_ss[3] = {
|
||||
ps->screenCoords[ps->loops_eval[lt->tri[0]].v],
|
||||
ps->screenCoords[ps->loops_eval[lt->tri[1]].v],
|
||||
|
@ -1121,7 +1121,7 @@ static bool pixel_bounds_array(
|
|||
static void project_face_winding_init(const ProjPaintState *ps, const int tri_index)
|
||||
{
|
||||
/* detect the winding of faces in uv space */
|
||||
const MLoopTri *lt = &ps->mlooptri_eval[tri_index];
|
||||
const MLoopTri *lt = &ps->looptris_eval[tri_index];
|
||||
const float *lt_tri_uv[3] = {PS_LOOPTRI_AS_UV_3(ps->poly_to_loop_uv, lt)};
|
||||
float winding = cross_tri_v2(lt_tri_uv[0], lt_tri_uv[1], lt_tri_uv[2]);
|
||||
|
||||
|
@ -1141,7 +1141,7 @@ static bool check_seam(const ProjPaintState *ps,
|
|||
int *other_face,
|
||||
int *orig_fidx)
|
||||
{
|
||||
const MLoopTri *orig_lt = &ps->mlooptri_eval[orig_face];
|
||||
const MLoopTri *orig_lt = &ps->looptris_eval[orig_face];
|
||||
const float *orig_lt_tri_uv[3] = {PS_LOOPTRI_AS_UV_3(ps->poly_to_loop_uv, orig_lt)};
|
||||
/* vert indices from face vert order indices */
|
||||
const uint i1 = ps->loops_eval[orig_lt->tri[orig_i1_fidx]].v;
|
||||
|
@ -1154,7 +1154,7 @@ static bool check_seam(const ProjPaintState *ps,
|
|||
const int tri_index = POINTER_AS_INT(node->link);
|
||||
|
||||
if (tri_index != orig_face) {
|
||||
const MLoopTri *lt = &ps->mlooptri_eval[tri_index];
|
||||
const MLoopTri *lt = &ps->looptris_eval[tri_index];
|
||||
const int lt_vtri[3] = {PS_LOOPTRI_AS_VERT_INDEX_3(ps, lt)};
|
||||
/* could check if the 2 faces images match here,
|
||||
* but then there wouldn't be a way to return the opposite face's info */
|
||||
|
@ -1303,7 +1303,7 @@ static void uv_image_outset(const ProjPaintState *ps,
|
|||
int fidx[2];
|
||||
uint loop_index;
|
||||
uint vert[2];
|
||||
const MLoopTri *ltri = &ps->mlooptri_eval[tri_index];
|
||||
const MLoopTri *ltri = &ps->looptris_eval[tri_index];
|
||||
|
||||
float ibuf_inv[2];
|
||||
|
||||
|
@ -1386,7 +1386,7 @@ static void insert_seam_vert_array(const ProjPaintState *ps,
|
|||
const int ibuf_x,
|
||||
const int ibuf_y)
|
||||
{
|
||||
const MLoopTri *lt = &ps->mlooptri_eval[tri_index];
|
||||
const MLoopTri *lt = &ps->looptris_eval[tri_index];
|
||||
const float *lt_tri_uv[3] = {PS_LOOPTRI_AS_UV_3(ps->poly_to_loop_uv, lt)};
|
||||
const int fidx[2] = {fidx1, ((fidx1 + 1) % 3)};
|
||||
float vec[2];
|
||||
|
@ -1446,7 +1446,7 @@ static void project_face_seams_init(const ProjPaintState *ps,
|
|||
int other_face, other_fidx;
|
||||
/* next fidx in the face (0,1,2,3) -> (1,2,3,0) or (0,1,2) -> (1,2,0) for a tri */
|
||||
int fidx[2] = {2, 0};
|
||||
const MLoopTri *lt = &ps->mlooptri_eval[tri_index];
|
||||
const MLoopTri *lt = &ps->looptris_eval[tri_index];
|
||||
LinkNode *node;
|
||||
|
||||
/* initialize face winding if needed */
|
||||
|
@ -1665,7 +1665,7 @@ static float project_paint_uvpixel_mask(const ProjPaintState *ps,
|
|||
Image *other_tpage = ps->stencil_ima;
|
||||
|
||||
if (other_tpage && (ibuf_other = BKE_image_acquire_ibuf(other_tpage, nullptr, nullptr))) {
|
||||
const MLoopTri *lt_other = &ps->mlooptri_eval[tri_index];
|
||||
const MLoopTri *lt_other = &ps->looptris_eval[tri_index];
|
||||
const float *lt_other_tri_uv[3] = {ps->mloopuv_stencil_eval[lt_other->tri[0]],
|
||||
ps->mloopuv_stencil_eval[lt_other->tri[1]],
|
||||
ps->mloopuv_stencil_eval[lt_other->tri[2]]};
|
||||
|
@ -1704,7 +1704,7 @@ static float project_paint_uvpixel_mask(const ProjPaintState *ps,
|
|||
}
|
||||
|
||||
if (ps->do_mask_cavity) {
|
||||
const MLoopTri *lt = &ps->mlooptri_eval[tri_index];
|
||||
const MLoopTri *lt = &ps->looptris_eval[tri_index];
|
||||
const int lt_vtri[3] = {PS_LOOPTRI_AS_VERT_INDEX_3(ps, lt)};
|
||||
float ca1, ca2, ca3, ca_mask;
|
||||
ca1 = ps->cavities[lt_vtri[0]];
|
||||
|
@ -1719,7 +1719,7 @@ static float project_paint_uvpixel_mask(const ProjPaintState *ps,
|
|||
|
||||
/* calculate mask */
|
||||
if (ps->do_mask_normal) {
|
||||
const MLoopTri *lt = &ps->mlooptri_eval[tri_index];
|
||||
const MLoopTri *lt = &ps->looptris_eval[tri_index];
|
||||
const int lt_vtri[3] = {PS_LOOPTRI_AS_VERT_INDEX_3(ps, lt)};
|
||||
const MPoly *mp = &ps->polys_eval[lt->poly];
|
||||
float no[3], angle_cos;
|
||||
|
@ -1959,7 +1959,7 @@ static ProjPixel *project_paint_uvpixel_init(const ProjPaintState *ps,
|
|||
Image *other_tpage = project_paint_face_clone_image(ps, tri_index);
|
||||
|
||||
if (other_tpage && (ibuf_other = BKE_image_acquire_ibuf(other_tpage, nullptr, nullptr))) {
|
||||
const MLoopTri *lt_other = &ps->mlooptri_eval[tri_index];
|
||||
const MLoopTri *lt_other = &ps->looptris_eval[tri_index];
|
||||
const float *lt_other_tri_uv[3] = {
|
||||
PS_LOOPTRI_AS_UV_3(ps->poly_to_loop_uv_clone, lt_other)};
|
||||
|
||||
|
@ -2996,7 +2996,7 @@ static void project_paint_face_init(const ProjPaintState *ps,
|
|||
ps->projImages + image_index,
|
||||
};
|
||||
|
||||
const MLoopTri *lt = &ps->mlooptri_eval[tri_index];
|
||||
const MLoopTri *lt = &ps->looptris_eval[tri_index];
|
||||
const int lt_vtri[3] = {PS_LOOPTRI_AS_VERT_INDEX_3(ps, lt)};
|
||||
const float *lt_tri_uv[3] = {PS_LOOPTRI_AS_UV_3(ps->poly_to_loop_uv, lt)};
|
||||
|
||||
|
@ -3287,7 +3287,7 @@ static void project_paint_face_init(const ProjPaintState *ps,
|
|||
bucket_clip_edges[1])) {
|
||||
/* Avoid div by zero. */
|
||||
if (len_squared_v2v2(vCoSS[fidx1], vCoSS[fidx2]) > FLT_EPSILON) {
|
||||
uint loop_idx = ps->mlooptri_eval[tri_index].tri[fidx1];
|
||||
uint loop_idx = ps->looptris_eval[tri_index].tri[fidx1];
|
||||
LoopSeamData *seam_data = &ps->loopSeamData[loop_idx];
|
||||
float(*seam_uvs)[2] = seam_data->seam_uvs;
|
||||
|
||||
|
@ -3525,7 +3525,7 @@ static void project_bucket_init(const ProjPaintState *ps,
|
|||
for (node = ps->bucketFaces[bucket_index]; node; node = node->next) {
|
||||
tri_index = POINTER_AS_INT(node->link);
|
||||
|
||||
const MLoopTri *lt = &ps->mlooptri_eval[tri_index];
|
||||
const MLoopTri *lt = &ps->looptris_eval[tri_index];
|
||||
const float *lt_tri_uv[3] = {PS_LOOPTRI_AS_UV_3(ps->poly_to_loop_uv, lt)};
|
||||
|
||||
/* Image context switching */
|
||||
|
@ -4071,7 +4071,7 @@ static bool proj_paint_state_mesh_eval_init(const bContext *C, ProjPaintState *p
|
|||
ps->mat_array[totmat - 1] = nullptr;
|
||||
|
||||
ps->vert_positions_eval = BKE_mesh_vert_positions(ps->me_eval);
|
||||
ps->vert_normals = BKE_mesh_vertex_normals_ensure(ps->me_eval);
|
||||
ps->vert_normals = BKE_mesh_vert_normals_ensure(ps->me_eval);
|
||||
ps->edges_eval = ps->me_eval->edges();
|
||||
ps->polys_eval = ps->me_eval->polys();
|
||||
ps->loops_eval = ps->me_eval->loops();
|
||||
|
@ -4085,8 +4085,7 @@ static bool proj_paint_state_mesh_eval_init(const bContext *C, ProjPaintState *p
|
|||
ps->totpoly_eval = ps->me_eval->totpoly;
|
||||
ps->totloop_eval = ps->me_eval->totloop;
|
||||
|
||||
ps->mlooptri_eval = BKE_mesh_runtime_looptri_ensure(ps->me_eval);
|
||||
ps->totlooptri_eval = BKE_mesh_runtime_looptri_len(ps->me_eval);
|
||||
ps->looptris_eval = ps->me_eval->looptris();
|
||||
|
||||
ps->poly_to_loop_uv = static_cast<const float(**)[2]>(
|
||||
MEM_mallocN(ps->totpoly_eval * sizeof(float(*)[2]), "proj_paint_mtfaces"));
|
||||
|
@ -4159,7 +4158,7 @@ static bool project_paint_clone_face_skip(ProjPaintState *ps,
|
|||
}
|
||||
|
||||
/* will set multiple times for 4+ sided poly */
|
||||
ps->poly_to_loop_uv_clone[ps->mlooptri_eval[tri_index].poly] = lc->mloopuv_clone_base;
|
||||
ps->poly_to_loop_uv_clone[ps->looptris_eval[tri_index].poly] = lc->mloopuv_clone_base;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -4304,17 +4303,17 @@ static void project_paint_prepare_all_faces(ProjPaintState *ps,
|
|||
TexPaintSlot *slot_last = nullptr;
|
||||
TexPaintSlot *slot = nullptr;
|
||||
int tile_last = -1, tile;
|
||||
const MLoopTri *lt;
|
||||
int image_index = -1, tri_index;
|
||||
int prev_poly = -1;
|
||||
const blender::Span<MLoopTri> looptris = ps->looptris_eval;
|
||||
|
||||
BLI_assert(ps->image_tot == 0);
|
||||
|
||||
for (tri_index = 0, lt = ps->mlooptri_eval; tri_index < ps->totlooptri_eval; tri_index++, lt++) {
|
||||
for (tri_index = 0; tri_index < ps->totlooptri_eval; tri_index++) {
|
||||
bool is_face_sel;
|
||||
bool skip_tri = false;
|
||||
|
||||
is_face_sel = project_paint_check_face_sel(ps, face_lookup, lt);
|
||||
is_face_sel = project_paint_check_face_sel(ps, face_lookup, &looptris[tri_index]);
|
||||
|
||||
if (!ps->do_stencil_brush) {
|
||||
slot = project_paint_face_paint_slot(ps, tri_index);
|
||||
|
@ -4353,12 +4352,12 @@ static void project_paint_prepare_all_faces(ProjPaintState *ps,
|
|||
tpage = ps->stencil_ima;
|
||||
}
|
||||
|
||||
ps->poly_to_loop_uv[lt->poly] = mloopuv_base;
|
||||
ps->poly_to_loop_uv[looptris[tri_index].poly] = mloopuv_base;
|
||||
|
||||
tile = project_paint_face_paint_tile(tpage, mloopuv_base[lt->tri[0]]);
|
||||
tile = project_paint_face_paint_tile(tpage, mloopuv_base[looptris[tri_index].tri[0]]);
|
||||
|
||||
#ifndef PROJ_DEBUG_NOSEAMBLEED
|
||||
project_paint_bleed_add_face_user(ps, arena, lt, tri_index);
|
||||
project_paint_bleed_add_face_user(ps, arena, &looptris[tri_index], tri_index);
|
||||
#endif
|
||||
|
||||
if (skip_tri || project_paint_clone_face_skip(ps, layer_clone, slot, tri_index)) {
|
||||
|
@ -4369,7 +4368,7 @@ static void project_paint_prepare_all_faces(ProjPaintState *ps,
|
|||
|
||||
if (is_face_sel && tpage) {
|
||||
ProjPaintFaceCoSS coSS;
|
||||
proj_paint_face_coSS_init(ps, lt, &coSS);
|
||||
proj_paint_face_coSS_init(ps, &looptris[tri_index], &coSS);
|
||||
|
||||
if (is_multi_view == false) {
|
||||
if (project_paint_flt_max_cull(ps, &coSS)) {
|
||||
|
@ -4386,12 +4385,12 @@ static void project_paint_prepare_all_faces(ProjPaintState *ps,
|
|||
/* Back-face culls individual triangles but mask normal will use polygon. */
|
||||
if (ps->do_backfacecull) {
|
||||
if (ps->do_mask_normal) {
|
||||
if (prev_poly != lt->poly) {
|
||||
if (prev_poly != looptris[tri_index].poly) {
|
||||
int iloop;
|
||||
bool culled = true;
|
||||
const MPoly *poly = &ps->polys_eval[lt->poly];
|
||||
const MPoly *poly = &ps->polys_eval[looptris[tri_index].poly];
|
||||
int poly_loops = poly->totloop;
|
||||
prev_poly = lt->poly;
|
||||
prev_poly = looptris[tri_index].poly;
|
||||
for (iloop = 0; iloop < poly_loops; iloop++) {
|
||||
if (!(ps->vertFlags[ps->loops_eval[poly->loopstart + iloop].v] & PROJ_VERT_CULL)) {
|
||||
culled = false;
|
||||
|
@ -4404,7 +4403,6 @@ static void project_paint_prepare_all_faces(ProjPaintState *ps,
|
|||
* but counter gets incremented when continuing, so decrease by 3 */
|
||||
int poly_tri = poly_loops - 3;
|
||||
tri_index += poly_tri;
|
||||
lt += poly_tri;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -4451,7 +4449,7 @@ static void project_paint_prepare_all_faces(ProjPaintState *ps,
|
|||
if (image_index != -1) {
|
||||
/* Initialize the faces screen pixels */
|
||||
/* Add this to a list to initialize later */
|
||||
project_paint_delayed_face_init(ps, lt, tri_index);
|
||||
project_paint_delayed_face_init(ps, &looptris[tri_index], tri_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5703,7 +5701,7 @@ static bool project_paint_op(void *state, const float lastpos[2], const float po
|
|||
tri_index = project_paint_PickFace(ps, pos, w);
|
||||
|
||||
if (tri_index != -1) {
|
||||
const MLoopTri *lt = &ps->mlooptri_eval[tri_index];
|
||||
const MLoopTri *lt = &ps->looptris_eval[tri_index];
|
||||
const int lt_vtri[3] = {PS_LOOPTRI_AS_VERT_INDEX_3(ps, lt)};
|
||||
float world[3];
|
||||
UnifiedPaintSettings *ups = &ps->scene->toolsettings->unified_paint_settings;
|
||||
|
|
|
@ -5547,7 +5547,7 @@ void SCULPT_flush_update_step(bContext *C, SculptUpdateType update_flags)
|
|||
if (update_flags & SCULPT_UPDATE_COORDS && !ss->shapekey_active) {
|
||||
if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) {
|
||||
/* When sculpting and changing the positions of a mesh, tag them as changed and update. */
|
||||
BKE_mesh_tag_coords_changed(mesh);
|
||||
BKE_mesh_tag_positions_changed(mesh);
|
||||
/* Update the mesh's bounds eagerly since the PBVH already has that information. */
|
||||
mesh->runtime->bounds_cache.ensure([&](Bounds<float3> &r_bounds) {
|
||||
BKE_pbvh_bounding_box(ob->sculpt->pbvh, r_bounds.min, r_bounds.max);
|
||||
|
|
|
@ -1092,7 +1092,7 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase
|
|||
|
||||
if (tag_update) {
|
||||
Mesh *mesh = static_cast<Mesh *>(ob->data);
|
||||
BKE_mesh_tag_coords_changed(mesh);
|
||||
BKE_mesh_tag_positions_changed(mesh);
|
||||
|
||||
BKE_sculptsession_free_deformMats(ss);
|
||||
}
|
||||
|
|
|
@ -853,7 +853,7 @@ void uiTemplateMovieclipInformation(uiLayout *layout,
|
|||
const char *file;
|
||||
|
||||
if (framenr <= clip->len) {
|
||||
BKE_movieclip_filename_for_frame(clip, user, filepath);
|
||||
BKE_movieclip_filepath_for_frame(clip, user, filepath);
|
||||
file = BLI_path_slash_rfind(filepath);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -703,10 +703,10 @@ static uchar *prefetch_read_file_to_memory(
|
|||
user.render_size = render_size;
|
||||
user.render_flag = render_flag;
|
||||
|
||||
char name[FILE_MAX];
|
||||
BKE_movieclip_filename_for_frame(clip, &user, name);
|
||||
char filepath[FILE_MAX];
|
||||
BKE_movieclip_filepath_for_frame(clip, &user, filepath);
|
||||
|
||||
int file = BLI_open(name, O_BINARY | O_RDONLY, 0);
|
||||
int file = BLI_open(filepath, O_BINARY | O_RDONLY, 0);
|
||||
if (file == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -1307,15 +1307,15 @@ static uchar *proxy_thread_next_frame(ProxyQueue *queue,
|
|||
BLI_spin_lock(&queue->spin);
|
||||
if (!*queue->stop && queue->cfra <= queue->efra) {
|
||||
MovieClipUser user = *DNA_struct_default_get(MovieClipUser);
|
||||
char name[FILE_MAX];
|
||||
char filepath[FILE_MAX];
|
||||
size_t size;
|
||||
int file;
|
||||
|
||||
user.framenr = queue->cfra;
|
||||
|
||||
BKE_movieclip_filename_for_frame(clip, &user, name);
|
||||
BKE_movieclip_filepath_for_frame(clip, &user, filepath);
|
||||
|
||||
file = BLI_open(name, O_BINARY | O_RDONLY, 0);
|
||||
file = BLI_open(filepath, O_BINARY | O_RDONLY, 0);
|
||||
if (file < 0) {
|
||||
BLI_spin_unlock(&queue->spin);
|
||||
return NULL;
|
||||
|
|
|
@ -902,7 +902,7 @@ void file_draw_list(const bContext *C, ARegion *region)
|
|||
int numfiles;
|
||||
int numfiles_layout;
|
||||
int offset;
|
||||
int textwidth, textheight;
|
||||
int column_width, textheight;
|
||||
int i;
|
||||
bool is_icon;
|
||||
eFontStyle_Align align;
|
||||
|
@ -936,9 +936,9 @@ void file_draw_list(const bContext *C, ARegion *region)
|
|||
|
||||
filelist_file_cache_slidingwindow_set(files, numfiles_layout);
|
||||
|
||||
textwidth = (FILE_IMGDISPLAY == params->display) ?
|
||||
layout->tile_w :
|
||||
round_fl_to_int(layout->attribute_columns[COLUMN_NAME].width);
|
||||
column_width = (FILE_IMGDISPLAY == params->display) ?
|
||||
layout->tile_w :
|
||||
round_fl_to_int(layout->attribute_columns[COLUMN_NAME].width);
|
||||
textheight = (int)(layout->textheight * 3.0 / 2.0 + 0.5);
|
||||
|
||||
align = (FILE_IMGDISPLAY == params->display) ? UI_STYLE_TEXT_CENTER : UI_STYLE_TEXT_LEFT;
|
||||
|
@ -1053,7 +1053,7 @@ void file_draw_list(const bContext *C, ARegion *region)
|
|||
|
||||
if (file_selflag & FILE_SEL_EDITING) {
|
||||
const short width = (params->display == FILE_IMGDISPLAY) ?
|
||||
textwidth :
|
||||
column_width :
|
||||
layout->attribute_columns[COLUMN_NAME].width -
|
||||
ATTRIBUTE_COLUMN_PADDING;
|
||||
|
||||
|
@ -1099,8 +1099,8 @@ void file_draw_list(const bContext *C, ARegion *region)
|
|||
tile_draw_rect.ymin + layout->tile_border_y + layout->textheight :
|
||||
tile_draw_rect.ymax - layout->tile_border_y;
|
||||
const int twidth = (params->display == FILE_IMGDISPLAY) ?
|
||||
textwidth :
|
||||
textwidth - 1 - icon_ofs - padx - layout->tile_border_x;
|
||||
column_width :
|
||||
column_width - 1 - icon_ofs - padx - layout->tile_border_x;
|
||||
file_draw_string(txpos, typos, file->name, (float)twidth, textheight, align, text_col);
|
||||
}
|
||||
|
||||
|
|
|
@ -199,6 +199,12 @@ TextFormatType *ED_text_format_get(Text *text)
|
|||
return tft_lb.first;
|
||||
}
|
||||
|
||||
const char *ED_text_format_comment_line_prefix(Text *text)
|
||||
{
|
||||
const struct TextFormatType *format = ED_text_format_get(text);
|
||||
return format->comment_line;
|
||||
}
|
||||
|
||||
bool ED_text_is_syntax_highlight_supported(Text *text)
|
||||
{
|
||||
if (text == NULL) {
|
||||
|
|
|
@ -75,6 +75,9 @@ typedef struct TextFormatType {
|
|||
void (*format_line)(SpaceText *st, TextLine *line, bool do_next);
|
||||
|
||||
const char **ext; /* NULL terminated extensions */
|
||||
|
||||
/** The prefix of a single-line line comment (without trailing space). */
|
||||
const char *comment_line;
|
||||
} TextFormatType;
|
||||
|
||||
enum {
|
||||
|
|
|
@ -341,6 +341,7 @@ void ED_text_format_register_lua(void)
|
|||
tft.format_identifier = txtfmt_lua_format_identifier;
|
||||
tft.format_line = txtfmt_lua_format_line;
|
||||
tft.ext = ext;
|
||||
tft.comment_line = "--";
|
||||
|
||||
ED_text_format_register(&tft);
|
||||
}
|
||||
|
|
|
@ -359,6 +359,7 @@ void ED_text_format_register_osl(void)
|
|||
tft.format_identifier = txtfmt_osl_format_identifier;
|
||||
tft.format_line = txtfmt_osl_format_line;
|
||||
tft.ext = ext;
|
||||
tft.comment_line = "//";
|
||||
|
||||
ED_text_format_register(&tft);
|
||||
}
|
||||
|
|
|
@ -936,6 +936,7 @@ void ED_text_format_register_pov(void)
|
|||
tft.format_identifier = txtfmt_pov_format_identifier;
|
||||
tft.format_line = txtfmt_pov_format_line;
|
||||
tft.ext = ext;
|
||||
tft.comment_line = "//";
|
||||
|
||||
ED_text_format_register(&tft);
|
||||
}
|
||||
|
|
|
@ -512,6 +512,7 @@ void ED_text_format_register_pov_ini(void)
|
|||
tft.format_identifier = txtfmt_pov_ini_format_identifier;
|
||||
tft.format_line = txtfmt_pov_ini_format_line;
|
||||
tft.ext = ext;
|
||||
tft.comment_line = "//";
|
||||
|
||||
ED_text_format_register(&tft);
|
||||
}
|
||||
|
|
|
@ -507,6 +507,7 @@ void ED_text_format_register_py(void)
|
|||
tft.format_identifier = txtfmt_py_format_identifier;
|
||||
tft.format_line = txtfmt_py_format_line;
|
||||
tft.ext = ext;
|
||||
tft.comment_line = "#";
|
||||
|
||||
ED_text_format_register(&tft);
|
||||
}
|
||||
|
|
|
@ -1273,6 +1273,7 @@ static int text_comment_exec(bContext *C, wmOperator *op)
|
|||
{
|
||||
Text *text = CTX_data_edit_text(C);
|
||||
int type = RNA_enum_get(op->ptr, "type");
|
||||
const char *prefix = ED_text_format_comment_line_prefix(text);
|
||||
|
||||
text_drawcache_tag_update(CTX_wm_space_text(C), 0);
|
||||
|
||||
|
@ -1284,14 +1285,14 @@ static int text_comment_exec(bContext *C, wmOperator *op)
|
|||
|
||||
switch (type) {
|
||||
case 1:
|
||||
txt_comment(text);
|
||||
txt_comment(text, prefix);
|
||||
break;
|
||||
case -1:
|
||||
txt_uncomment(text);
|
||||
txt_uncomment(text, prefix);
|
||||
break;
|
||||
default:
|
||||
if (txt_uncomment(text) == false) {
|
||||
txt_comment(text);
|
||||
if (txt_uncomment(text, prefix) == false) {
|
||||
txt_comment(text, prefix);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -72,6 +72,7 @@ void ED_draw_object_facemap(Depsgraph *depsgraph,
|
|||
const float(*positions)[3] = BKE_mesh_vert_positions(me);
|
||||
const blender::Span<MPoly> polys = me->polys();
|
||||
const blender::Span<MLoop> loops = me->loops();
|
||||
const blender::Span<MLoopTri> looptris = me->looptris();
|
||||
|
||||
facemap_data = static_cast<const int *>(CustomData_get_layer(&me->pdata, CD_FACEMAP));
|
||||
|
||||
|
@ -90,46 +91,23 @@ void ED_draw_object_facemap(Depsgraph *depsgraph,
|
|||
GPUVertBufRaw pos_step;
|
||||
GPU_vertbuf_attr_get_raw_data(vbo_pos, pos_id, &pos_step);
|
||||
|
||||
if (BKE_mesh_runtime_looptri_ensure(me)) {
|
||||
const MLoopTri *mlt = BKE_mesh_runtime_looptri_ensure(me);
|
||||
for (const int i : polys.index_range()) {
|
||||
const MPoly &poly = polys[i];
|
||||
if (facemap_data[i] == facemap) {
|
||||
for (int j = 2; j < poly.totloop; j++) {
|
||||
copy_v3_v3(static_cast<float *>(GPU_vertbuf_raw_step(&pos_step)),
|
||||
positions[loops[mlt->tri[0]].v]);
|
||||
copy_v3_v3(static_cast<float *>(GPU_vertbuf_raw_step(&pos_step)),
|
||||
positions[loops[mlt->tri[1]].v]);
|
||||
copy_v3_v3(static_cast<float *>(GPU_vertbuf_raw_step(&pos_step)),
|
||||
positions[loops[mlt->tri[2]].v]);
|
||||
vbo_len_used += 3;
|
||||
mlt++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
mlt += poly.totloop - 2;
|
||||
int tri_index = 0;
|
||||
for (const int i : polys.index_range()) {
|
||||
const MPoly &poly = polys[i];
|
||||
if (facemap_data[i] == facemap) {
|
||||
for (int j = 2; j < poly.totloop; j++) {
|
||||
copy_v3_v3(static_cast<float *>(GPU_vertbuf_raw_step(&pos_step)),
|
||||
positions[loops[looptris[tri_index].tri[0]].v]);
|
||||
copy_v3_v3(static_cast<float *>(GPU_vertbuf_raw_step(&pos_step)),
|
||||
positions[loops[looptris[tri_index].tri[1]].v]);
|
||||
copy_v3_v3(static_cast<float *>(GPU_vertbuf_raw_step(&pos_step)),
|
||||
positions[loops[looptris[tri_index].tri[2]].v]);
|
||||
vbo_len_used += 3;
|
||||
tri_index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* No tessellation data, fan-fill. */
|
||||
for (const int i : polys.index_range()) {
|
||||
const MPoly &poly = polys[i];
|
||||
if (facemap_data[i] == facemap) {
|
||||
const MLoop *ml_start = &loops[poly.loopstart];
|
||||
const MLoop *ml_a = ml_start + 1;
|
||||
const MLoop *ml_b = ml_start + 2;
|
||||
for (int j = 2; j < poly.totloop; j++) {
|
||||
copy_v3_v3(static_cast<float *>(GPU_vertbuf_raw_step(&pos_step)),
|
||||
positions[ml_start->v]);
|
||||
copy_v3_v3(static_cast<float *>(GPU_vertbuf_raw_step(&pos_step)), positions[ml_a->v]);
|
||||
copy_v3_v3(static_cast<float *>(GPU_vertbuf_raw_step(&pos_step)), positions[ml_b->v]);
|
||||
vbo_len_used += 3;
|
||||
|
||||
ml_a++;
|
||||
ml_b++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
tri_index += poly.totloop - 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -55,6 +55,8 @@ set(SRC
|
|||
transform_generics.c
|
||||
transform_gizmo_2d.c
|
||||
transform_gizmo_3d.cc
|
||||
transform_gizmo_3d_cage.cc
|
||||
transform_gizmo_3d_shear.cc
|
||||
transform_gizmo_extrude_3d.c
|
||||
transform_input.c
|
||||
transform_mode.c
|
||||
|
@ -99,6 +101,7 @@ set(SRC
|
|||
transform_convert.h
|
||||
transform_data.h
|
||||
transform_draw_cursors.h
|
||||
transform_gizmo.h
|
||||
transform_mode.h
|
||||
transform_orientations.h
|
||||
transform_snap.h
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "transform_constraints.h"
|
||||
#include "transform_convert.h"
|
||||
#include "transform_draw_cursors.h"
|
||||
#include "transform_gizmo.h"
|
||||
#include "transform_mode.h"
|
||||
#include "transform_orientations.h"
|
||||
#include "transform_snap.h"
|
||||
|
|
|
@ -728,40 +728,6 @@ void transform_final_value_get(const TransInfo *t, float *value, int value_num);
|
|||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Gizmo
|
||||
* \{ */
|
||||
|
||||
/* transform_gizmo.c */
|
||||
|
||||
#define GIZMO_AXIS_LINE_WIDTH 2.0f
|
||||
|
||||
bool gimbal_axis_pose(struct Object *ob, const struct bPoseChannel *pchan, float gmat[3][3]);
|
||||
bool gimbal_axis_object(struct Object *ob, float gmat[3][3]);
|
||||
|
||||
/**
|
||||
* Set the #T_NO_GIZMO flag.
|
||||
*
|
||||
* \note This maintains the conventional behavior of not displaying the gizmo if the operator has
|
||||
* been triggered by shortcuts.
|
||||
*/
|
||||
void transform_gizmo_3d_model_from_constraint_and_mode_init(TransInfo *t);
|
||||
|
||||
/**
|
||||
* Change the gizmo and its orientation to match the transform state.
|
||||
*
|
||||
* \note This used while the modal operator is running so changes to the constraint or mode show
|
||||
* the gizmo associated with that state, as if it had been the initial gizmo dragged.
|
||||
*/
|
||||
void transform_gizmo_3d_model_from_constraint_and_mode_set(TransInfo *t);
|
||||
|
||||
/**
|
||||
* Restores the non-modal state of the gizmo.
|
||||
*/
|
||||
void transform_gizmo_3d_model_from_constraint_and_mode_restore(TransInfo *t);
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name TransData Creation and General Handling
|
||||
* \{ */
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "UI_resources.h"
|
||||
|
||||
#include "transform.h"
|
||||
#include "transform_gizmo.h"
|
||||
#include "transform_orientations.h"
|
||||
#include "transform_snap.h"
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "RNA_prototypes.h"
|
||||
|
||||
#include "transform.h"
|
||||
#include "transform_orientations.h"
|
||||
#include "transform_snap.h"
|
||||
|
||||
/* Own include. */
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
|
||||
#include "transform.h"
|
||||
#include "transform_convert.h"
|
||||
#include "transform_gizmo.h"
|
||||
#include "transform_mode.h"
|
||||
#include "transform_orientations.h"
|
||||
#include "transform_snap.h"
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2001-2002 NaN Holding BV. All rights reserved. */
|
||||
|
||||
/** \file
|
||||
* \ingroup edtransform
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Types/
|
||||
* \{ */
|
||||
|
||||
struct ARegion;
|
||||
struct bContext;
|
||||
struct bScreen;
|
||||
struct RegionView3D;
|
||||
struct Scene;
|
||||
struct ScrArea;
|
||||
struct TransformBounds;
|
||||
struct TransInfo;
|
||||
struct wmGizmoGroup;
|
||||
struct wmGizmoGroupType;
|
||||
struct wmMsgBus;
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Gizmo
|
||||
* \{ */
|
||||
|
||||
/* transform_gizmo_3d.c */
|
||||
|
||||
#define GIZMO_AXIS_LINE_WIDTH 2.0f
|
||||
|
||||
void gizmo_prepare_mat(const struct bContext *C,
|
||||
struct RegionView3D *rv3d,
|
||||
const struct TransformBounds *tbounds);
|
||||
void gizmo_xform_message_subscribe(struct wmGizmoGroup *gzgroup,
|
||||
struct wmMsgBus *mbus,
|
||||
struct Scene *scene,
|
||||
struct bScreen *screen,
|
||||
struct ScrArea *area,
|
||||
struct ARegion *region,
|
||||
void (*type_fn)(struct wmGizmoGroupType *));
|
||||
|
||||
/**
|
||||
* Set the #T_NO_GIZMO flag.
|
||||
*
|
||||
* \note This maintains the conventional behavior of not displaying the gizmo if the operator has
|
||||
* been triggered by shortcuts.
|
||||
*/
|
||||
void transform_gizmo_3d_model_from_constraint_and_mode_init(TransInfo *t);
|
||||
|
||||
/**
|
||||
* Change the gizmo and its orientation to match the transform state.
|
||||
*
|
||||
* \note This used while the modal operator is running so changes to the constraint or mode show
|
||||
* the gizmo associated with that state, as if it had been the initial gizmo dragged.
|
||||
*/
|
||||
void transform_gizmo_3d_model_from_constraint_and_mode_set(TransInfo *t);
|
||||
|
||||
/**
|
||||
* Restores the non-modal state of the gizmo.
|
||||
*/
|
||||
void transform_gizmo_3d_model_from_constraint_and_mode_restore(TransInfo *t);
|
||||
|
||||
/** \} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -42,7 +42,8 @@
|
|||
#include "SEQ_time.h"
|
||||
#include "SEQ_transform.h"
|
||||
|
||||
#include "transform.h" /* own include */
|
||||
#include "transform.h"
|
||||
#include "transform_gizmo.h"
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Shared Callback's
|
||||
|
|
|
@ -8,31 +8,15 @@
|
|||
* Used for 3D View
|
||||
*/
|
||||
|
||||
#include <cfloat>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include "DNA_armature_types.h"
|
||||
#include "DNA_curve_types.h"
|
||||
#include "DNA_gpencil_types.h"
|
||||
#include "DNA_lattice_types.h"
|
||||
#include "DNA_meta_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_view3d_types.h"
|
||||
|
||||
#include "BLI_array_utils.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_armature.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_crazyspace.hh"
|
||||
#include "BKE_curve.h"
|
||||
#include "BKE_curves.hh"
|
||||
#include "BKE_editmesh.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_gpencil.h"
|
||||
|
@ -41,12 +25,10 @@
|
|||
#include "BKE_paint.h"
|
||||
#include "BKE_pointcache.h"
|
||||
#include "BKE_scene.h"
|
||||
|
||||
#include "DEG_depsgraph.h"
|
||||
#include "BLI_array_utils.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_message.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "ED_armature.h"
|
||||
#include "ED_curves.h"
|
||||
|
@ -56,9 +38,7 @@
|
|||
#include "ED_object.h"
|
||||
#include "ED_particle.h"
|
||||
#include "ED_screen.h"
|
||||
#include "ED_view3d.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
|
@ -67,12 +47,9 @@
|
|||
/* local module include */
|
||||
#include "transform.h"
|
||||
#include "transform_convert.h"
|
||||
#include "transform_gizmo.h"
|
||||
#include "transform_snap.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "GPU_state.h"
|
||||
|
||||
static wmGizmoGroupType *g_GGT_xform_gizmo = nullptr;
|
||||
static wmGizmoGroupType *g_GGT_xform_gizmo_context = nullptr;
|
||||
|
||||
|
@ -527,101 +504,6 @@ static void protectflag_to_drawflags_ebone(RegionView3D *rv3d, const EditBone *e
|
|||
}
|
||||
}
|
||||
|
||||
/* could move into BLI_math however this is only useful for display/editing purposes */
|
||||
static void axis_angle_to_gimbal_axis(float gmat[3][3], const float axis[3], const float angle)
|
||||
{
|
||||
/* X/Y are arbitrary axes, most importantly Z is the axis of rotation. */
|
||||
|
||||
float cross_vec[3];
|
||||
float quat[4];
|
||||
|
||||
/* this is an un-scientific method to get a vector to cross with
|
||||
* XYZ intentionally YZX */
|
||||
cross_vec[0] = axis[1];
|
||||
cross_vec[1] = axis[2];
|
||||
cross_vec[2] = axis[0];
|
||||
|
||||
/* X-axis */
|
||||
cross_v3_v3v3(gmat[0], cross_vec, axis);
|
||||
normalize_v3(gmat[0]);
|
||||
axis_angle_to_quat(quat, axis, angle);
|
||||
mul_qt_v3(quat, gmat[0]);
|
||||
|
||||
/* Y-axis */
|
||||
axis_angle_to_quat(quat, axis, M_PI_2);
|
||||
copy_v3_v3(gmat[1], gmat[0]);
|
||||
mul_qt_v3(quat, gmat[1]);
|
||||
|
||||
/* Z-axis */
|
||||
copy_v3_v3(gmat[2], axis);
|
||||
|
||||
normalize_m3(gmat);
|
||||
}
|
||||
|
||||
static bool test_rotmode_euler(short rotmode)
|
||||
{
|
||||
return ELEM(rotmode, ROT_MODE_AXISANGLE, ROT_MODE_QUAT) ? 0 : 1;
|
||||
}
|
||||
|
||||
bool gimbal_axis_pose(Object *ob, const bPoseChannel *pchan, float gmat[3][3])
|
||||
{
|
||||
float mat[3][3], tmat[3][3], obmat[3][3];
|
||||
if (test_rotmode_euler(pchan->rotmode)) {
|
||||
eulO_to_gimbal_axis(mat, pchan->eul, pchan->rotmode);
|
||||
}
|
||||
else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
|
||||
axis_angle_to_gimbal_axis(mat, pchan->rotAxis, pchan->rotAngle);
|
||||
}
|
||||
else { /* quat */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* apply bone transformation */
|
||||
mul_m3_m3m3(tmat, pchan->bone->bone_mat, mat);
|
||||
|
||||
if (pchan->parent) {
|
||||
float parent_mat[3][3];
|
||||
|
||||
copy_m3_m4(parent_mat,
|
||||
(pchan->bone->flag & BONE_HINGE) ? pchan->parent->bone->arm_mat :
|
||||
pchan->parent->pose_mat);
|
||||
mul_m3_m3m3(mat, parent_mat, tmat);
|
||||
|
||||
/* needed if object transformation isn't identity */
|
||||
copy_m3_m4(obmat, ob->object_to_world);
|
||||
mul_m3_m3m3(gmat, obmat, mat);
|
||||
}
|
||||
else {
|
||||
/* needed if object transformation isn't identity */
|
||||
copy_m3_m4(obmat, ob->object_to_world);
|
||||
mul_m3_m3m3(gmat, obmat, tmat);
|
||||
}
|
||||
|
||||
normalize_m3(gmat);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool gimbal_axis_object(Object *ob, float gmat[3][3])
|
||||
{
|
||||
if (test_rotmode_euler(ob->rotmode)) {
|
||||
eulO_to_gimbal_axis(gmat, ob->rot, ob->rotmode);
|
||||
}
|
||||
else if (ob->rotmode == ROT_MODE_AXISANGLE) {
|
||||
axis_angle_to_gimbal_axis(gmat, ob->rotAxis, ob->rotAngle);
|
||||
}
|
||||
else { /* quat */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ob->parent) {
|
||||
float parent_mat[3][3];
|
||||
copy_m3_m4(parent_mat, ob->parent->object_to_world);
|
||||
normalize_m3(parent_mat);
|
||||
mul_m3_m3m3(gmat, parent_mat, gmat);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ED_transform_calc_gizmo_stats(const bContext *C,
|
||||
const TransformCalcParams *params,
|
||||
TransformBounds *tbounds)
|
||||
|
@ -1117,9 +999,7 @@ static void gizmo_get_idot(const RegionView3D *rv3d, float r_idot[3])
|
|||
}
|
||||
}
|
||||
|
||||
static void gizmo_prepare_mat(const bContext *C,
|
||||
RegionView3D *rv3d,
|
||||
const TransformBounds *tbounds)
|
||||
void gizmo_prepare_mat(const bContext *C, RegionView3D *rv3d, const TransformBounds *tbounds)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
|
@ -1197,13 +1077,13 @@ static void gizmo_line_range(const int twtype, const short axis_type, float *r_s
|
|||
}
|
||||
}
|
||||
|
||||
static void gizmo_xform_message_subscribe(wmGizmoGroup *gzgroup,
|
||||
wmMsgBus *mbus,
|
||||
Scene *scene,
|
||||
bScreen *screen,
|
||||
ScrArea *area,
|
||||
ARegion *region,
|
||||
void (*type_fn)(wmGizmoGroupType *))
|
||||
void gizmo_xform_message_subscribe(wmGizmoGroup *gzgroup,
|
||||
wmMsgBus *mbus,
|
||||
Scene *scene,
|
||||
bScreen *screen,
|
||||
ScrArea *area,
|
||||
ARegion *region,
|
||||
void (*type_fn)(wmGizmoGroupType *))
|
||||
{
|
||||
/* Subscribe to view properties */
|
||||
wmMsgSubscribeValue msg_sub_value_gz_tag_refresh{};
|
||||
|
@ -2337,437 +2217,6 @@ void VIEW3D_GGT_xform_gizmo_context(wmGizmoGroupType *gzgt)
|
|||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Scale Cage Gizmo
|
||||
* \{ */
|
||||
|
||||
struct XFormCageWidgetGroup {
|
||||
wmGizmo *gizmo;
|
||||
/* Only for view orientation. */
|
||||
struct {
|
||||
float viewinv_m3[3][3];
|
||||
} prev;
|
||||
};
|
||||
|
||||
static bool WIDGETGROUP_xform_cage_poll(const bContext *C, wmGizmoGroupType *gzgt)
|
||||
{
|
||||
if (!ED_gizmo_poll_or_unlink_delayed_from_tool(C, gzgt)) {
|
||||
return false;
|
||||
}
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
if (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_TOOL)) {
|
||||
return false;
|
||||
}
|
||||
if (G.moving & (G_TRANSFORM_OBJ | G_TRANSFORM_EDIT)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void WIDGETGROUP_xform_cage_setup(const bContext * /*C*/, wmGizmoGroup *gzgroup)
|
||||
{
|
||||
XFormCageWidgetGroup *xgzgroup = static_cast<XFormCageWidgetGroup *>(
|
||||
MEM_mallocN(sizeof(XFormCageWidgetGroup), __func__));
|
||||
const wmGizmoType *gzt_cage = WM_gizmotype_find("GIZMO_GT_cage_3d", true);
|
||||
xgzgroup->gizmo = WM_gizmo_new_ptr(gzt_cage, gzgroup, nullptr);
|
||||
wmGizmo *gz = xgzgroup->gizmo;
|
||||
|
||||
RNA_enum_set(
|
||||
gz->ptr, "transform", ED_GIZMO_CAGE_XFORM_FLAG_SCALE | ED_GIZMO_CAGE_XFORM_FLAG_TRANSLATE);
|
||||
|
||||
gz->color[0] = 1;
|
||||
gz->color_hi[0] = 1;
|
||||
|
||||
gzgroup->customdata = xgzgroup;
|
||||
|
||||
{
|
||||
wmOperatorType *ot_resize = WM_operatortype_find("TRANSFORM_OT_resize", true);
|
||||
PointerRNA *ptr;
|
||||
|
||||
/* assign operator */
|
||||
PropertyRNA *prop_release_confirm = nullptr;
|
||||
PropertyRNA *prop_constraint_axis = nullptr;
|
||||
|
||||
int i = ED_GIZMO_CAGE3D_PART_SCALE_MIN_X_MIN_Y_MIN_Z;
|
||||
for (int x = 0; x < 3; x++) {
|
||||
for (int y = 0; y < 3; y++) {
|
||||
for (int z = 0; z < 3; z++) {
|
||||
const bool constraint[3] = {x != 1, y != 1, z != 1};
|
||||
ptr = WM_gizmo_operator_set(gz, i, ot_resize, nullptr);
|
||||
if (prop_release_confirm == nullptr) {
|
||||
prop_release_confirm = RNA_struct_find_property(ptr, "release_confirm");
|
||||
prop_constraint_axis = RNA_struct_find_property(ptr, "constraint_axis");
|
||||
}
|
||||
RNA_property_boolean_set(ptr, prop_release_confirm, true);
|
||||
RNA_property_boolean_set_array(ptr, prop_constraint_axis, constraint);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void WIDGETGROUP_xform_cage_refresh(const bContext *C, wmGizmoGroup *gzgroup)
|
||||
{
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
|
||||
XFormCageWidgetGroup *xgzgroup = static_cast<XFormCageWidgetGroup *>(gzgroup->customdata);
|
||||
wmGizmo *gz = xgzgroup->gizmo;
|
||||
|
||||
TransformBounds tbounds;
|
||||
|
||||
const int orient_index = BKE_scene_orientation_get_index_from_flag(scene, SCE_ORIENT_SCALE);
|
||||
|
||||
TransformCalcParams calc_params{};
|
||||
calc_params.use_local_axis = true;
|
||||
calc_params.orientation_index = orient_index + 1;
|
||||
if ((ED_transform_calc_gizmo_stats(C, &calc_params, &tbounds) == 0) ||
|
||||
equals_v3v3(rv3d->tw_axis_min, rv3d->tw_axis_max)) {
|
||||
WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true);
|
||||
}
|
||||
else {
|
||||
if (tbounds.use_matrix_space) {
|
||||
copy_m4_m4(gz->matrix_space, tbounds.matrix_space);
|
||||
}
|
||||
else {
|
||||
unit_m4(gz->matrix_space);
|
||||
}
|
||||
|
||||
gizmo_prepare_mat(C, rv3d, &tbounds);
|
||||
|
||||
WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
|
||||
WM_gizmo_set_flag(gz, WM_GIZMO_MOVE_CURSOR, true);
|
||||
|
||||
float dims[3];
|
||||
sub_v3_v3v3(dims, rv3d->tw_axis_max, rv3d->tw_axis_min);
|
||||
RNA_float_set_array(gz->ptr, "dimensions", dims);
|
||||
mul_v3_fl(dims, 0.5f);
|
||||
|
||||
copy_m4_m3(gz->matrix_offset, rv3d->tw_axis_matrix);
|
||||
mid_v3_v3v3(gz->matrix_offset[3], rv3d->tw_axis_max, rv3d->tw_axis_min);
|
||||
mul_m3_v3(rv3d->tw_axis_matrix, gz->matrix_offset[3]);
|
||||
|
||||
float matrix_offset_global[4][4];
|
||||
mul_m4_m4m4(matrix_offset_global, gz->matrix_space, gz->matrix_offset);
|
||||
|
||||
PropertyRNA *prop_center_override = nullptr;
|
||||
float center[3];
|
||||
float center_global[3];
|
||||
int i = ED_GIZMO_CAGE3D_PART_SCALE_MIN_X_MIN_Y_MIN_Z;
|
||||
for (int x = 0; x < 3; x++) {
|
||||
center[0] = float(1 - x) * dims[0];
|
||||
for (int y = 0; y < 3; y++) {
|
||||
center[1] = float(1 - y) * dims[1];
|
||||
for (int z = 0; z < 3; z++) {
|
||||
center[2] = float(1 - z) * dims[2];
|
||||
wmGizmoOpElem *gzop = WM_gizmo_operator_get(gz, i);
|
||||
if (prop_center_override == nullptr) {
|
||||
prop_center_override = RNA_struct_find_property(&gzop->ptr, "center_override");
|
||||
}
|
||||
mul_v3_m4v3(center_global, matrix_offset_global, center);
|
||||
RNA_property_float_set_array(&gzop->ptr, prop_center_override, center_global);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Needed to test view orientation changes. */
|
||||
copy_m3_m4(xgzgroup->prev.viewinv_m3, rv3d->viewinv);
|
||||
}
|
||||
|
||||
static void WIDGETGROUP_xform_cage_message_subscribe(const bContext *C,
|
||||
wmGizmoGroup *gzgroup,
|
||||
wmMsgBus *mbus)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
bScreen *screen = CTX_wm_screen(C);
|
||||
ScrArea *area = CTX_wm_area(C);
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
gizmo_xform_message_subscribe(gzgroup, mbus, scene, screen, area, region, VIEW3D_GGT_xform_cage);
|
||||
}
|
||||
|
||||
static void WIDGETGROUP_xform_cage_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
|
||||
{
|
||||
XFormCageWidgetGroup *xgzgroup = static_cast<XFormCageWidgetGroup *>(gzgroup->customdata);
|
||||
|
||||
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
const TransformOrientationSlot *orient_slot = BKE_scene_orientation_slot_get(scene,
|
||||
SCE_ORIENT_SCALE);
|
||||
switch (orient_slot->type) {
|
||||
case V3D_ORIENT_VIEW: {
|
||||
float viewinv_m3[3][3];
|
||||
copy_m3_m4(viewinv_m3, rv3d->viewinv);
|
||||
if (!equals_m3m3(viewinv_m3, xgzgroup->prev.viewinv_m3)) {
|
||||
/* Take care calling refresh from draw_prepare,
|
||||
* this should be OK because it's only adjusting the cage orientation. */
|
||||
WIDGETGROUP_xform_cage_refresh(C, gzgroup);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VIEW3D_GGT_xform_cage(wmGizmoGroupType *gzgt)
|
||||
{
|
||||
gzgt->name = "Transform Cage";
|
||||
gzgt->idname = "VIEW3D_GGT_xform_cage";
|
||||
|
||||
gzgt->flag |= WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_DRAW_MODAL_EXCLUDE |
|
||||
WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP | WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK;
|
||||
|
||||
gzgt->gzmap_params.spaceid = SPACE_VIEW3D;
|
||||
gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;
|
||||
|
||||
gzgt->poll = WIDGETGROUP_xform_cage_poll;
|
||||
gzgt->setup = WIDGETGROUP_xform_cage_setup;
|
||||
gzgt->setup_keymap = WM_gizmogroup_setup_keymap_generic_maybe_drag;
|
||||
gzgt->refresh = WIDGETGROUP_xform_cage_refresh;
|
||||
gzgt->message_subscribe = WIDGETGROUP_xform_cage_message_subscribe;
|
||||
gzgt->draw_prepare = WIDGETGROUP_xform_cage_draw_prepare;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Transform Shear Gizmo
|
||||
* \{ */
|
||||
|
||||
struct XFormShearWidgetGroup {
|
||||
wmGizmo *gizmo[3][2];
|
||||
/** View aligned gizmos. */
|
||||
wmGizmo *gizmo_view[4];
|
||||
|
||||
/* Only for view orientation. */
|
||||
struct {
|
||||
float viewinv_m3[3][3];
|
||||
} prev;
|
||||
};
|
||||
|
||||
static bool WIDGETGROUP_xform_shear_poll(const bContext *C, wmGizmoGroupType *gzgt)
|
||||
{
|
||||
if (!ED_gizmo_poll_or_unlink_delayed_from_tool(C, gzgt)) {
|
||||
return false;
|
||||
}
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
if (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_TOOL)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void WIDGETGROUP_xform_shear_setup(const bContext * /*C*/, wmGizmoGroup *gzgroup)
|
||||
{
|
||||
XFormShearWidgetGroup *xgzgroup = static_cast<XFormShearWidgetGroup *>(
|
||||
MEM_mallocN(sizeof(XFormShearWidgetGroup), __func__));
|
||||
const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_3d", true);
|
||||
wmOperatorType *ot_shear = WM_operatortype_find("TRANSFORM_OT_shear", true);
|
||||
|
||||
float axis_color[3][3];
|
||||
for (int i = 0; i < 3; i++) {
|
||||
UI_GetThemeColor3fv(TH_AXIS_X + i, axis_color[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 2; j++) {
|
||||
wmGizmo *gz = WM_gizmo_new_ptr(gzt_arrow, gzgroup, nullptr);
|
||||
RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_BOX);
|
||||
const int i_ortho_a = (i + j + 1) % 3;
|
||||
const int i_ortho_b = (i + (1 - j) + 1) % 3;
|
||||
interp_v3_v3v3(gz->color, axis_color[i_ortho_a], axis_color[i_ortho_b], 0.75f);
|
||||
gz->color[3] = 0.5f;
|
||||
PointerRNA *ptr = WM_gizmo_operator_set(gz, 0, ot_shear, nullptr);
|
||||
RNA_boolean_set(ptr, "release_confirm", 1);
|
||||
xgzgroup->gizmo[i][j] = gz;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
wmGizmo *gz = WM_gizmo_new_ptr(gzt_arrow, gzgroup, nullptr);
|
||||
RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_BOX);
|
||||
RNA_enum_set(gz->ptr, "draw_options", 0); /* No stem. */
|
||||
copy_v3_fl(gz->color, 1.0f);
|
||||
gz->color[3] = 0.5f;
|
||||
WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_OFFSET_SCALE, true);
|
||||
PointerRNA *ptr = WM_gizmo_operator_set(gz, 0, ot_shear, nullptr);
|
||||
RNA_boolean_set(ptr, "release_confirm", 1);
|
||||
xgzgroup->gizmo_view[i] = gz;
|
||||
|
||||
/* Unlike the other gizmos, this never changes so can be set on setup. */
|
||||
wmGizmoOpElem *gzop = WM_gizmo_operator_get(gz, 0);
|
||||
RNA_enum_set(&gzop->ptr, "orient_type", V3D_ORIENT_VIEW);
|
||||
|
||||
RNA_enum_set(&gzop->ptr, "orient_axis", 2);
|
||||
RNA_enum_set(&gzop->ptr, "orient_axis_ortho", ((i % 2) ? 0 : 1));
|
||||
}
|
||||
|
||||
gzgroup->customdata = xgzgroup;
|
||||
}
|
||||
|
||||
static void WIDGETGROUP_xform_shear_refresh(const bContext *C, wmGizmoGroup *gzgroup)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
|
||||
|
||||
XFormShearWidgetGroup *xgzgroup = static_cast<XFormShearWidgetGroup *>(gzgroup->customdata);
|
||||
TransformBounds tbounds;
|
||||
|
||||
/* Needed to test view orientation changes. */
|
||||
copy_m3_m4(xgzgroup->prev.viewinv_m3, rv3d->viewinv);
|
||||
|
||||
TransformOrientationSlot *orient_slot = BKE_scene_orientation_slot_get_from_flag(
|
||||
scene, SCE_ORIENT_ROTATE);
|
||||
const int orient_index = BKE_scene_orientation_slot_get_index(orient_slot);
|
||||
|
||||
TransformCalcParams calc_params{};
|
||||
calc_params.use_local_axis = false;
|
||||
calc_params.orientation_index = orient_index + 1;
|
||||
if (ED_transform_calc_gizmo_stats(C, &calc_params, &tbounds) == 0) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 2; j++) {
|
||||
wmGizmo *gz = xgzgroup->gizmo[i][j];
|
||||
WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
wmGizmo *gz = xgzgroup->gizmo_view[i];
|
||||
WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
gizmo_prepare_mat(C, rv3d, &tbounds);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 2; j++) {
|
||||
wmGizmo *gz = xgzgroup->gizmo[i][j];
|
||||
WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
|
||||
WM_gizmo_set_flag(gz, WM_GIZMO_MOVE_CURSOR, true);
|
||||
|
||||
wmGizmoOpElem *gzop = WM_gizmo_operator_get(gz, 0);
|
||||
const int i_ortho_a = (i + j + 1) % 3;
|
||||
const int i_ortho_b = (i + (1 - j) + 1) % 3;
|
||||
WM_gizmo_set_matrix_rotation_from_yz_axis(gz, rv3d->twmat[i_ortho_a], rv3d->twmat[i]);
|
||||
WM_gizmo_set_matrix_location(gz, rv3d->twmat[3]);
|
||||
|
||||
RNA_float_set_array(&gzop->ptr, "orient_matrix", &tbounds.axis[0][0]);
|
||||
RNA_enum_set(&gzop->ptr, "orient_type", orient_slot->type);
|
||||
|
||||
RNA_enum_set(&gzop->ptr, "orient_axis", i_ortho_b);
|
||||
RNA_enum_set(&gzop->ptr, "orient_axis_ortho", i_ortho_a);
|
||||
|
||||
mul_v3_fl(gz->matrix_basis[0], 0.5f);
|
||||
mul_v3_fl(gz->matrix_basis[1], 6.0f);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
wmGizmo *gz = xgzgroup->gizmo_view[i];
|
||||
WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void WIDGETGROUP_xform_shear_message_subscribe(const bContext *C,
|
||||
wmGizmoGroup *gzgroup,
|
||||
wmMsgBus *mbus)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
bScreen *screen = CTX_wm_screen(C);
|
||||
ScrArea *area = CTX_wm_area(C);
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
gizmo_xform_message_subscribe(
|
||||
gzgroup, mbus, scene, screen, area, region, VIEW3D_GGT_xform_shear);
|
||||
}
|
||||
|
||||
static void WIDGETGROUP_xform_shear_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
|
||||
{
|
||||
XFormShearWidgetGroup *xgzgroup = static_cast<XFormShearWidgetGroup *>(gzgroup->customdata);
|
||||
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
/* Shear is like rotate, use the rotate setting. */
|
||||
const TransformOrientationSlot *orient_slot = BKE_scene_orientation_slot_get(
|
||||
scene, SCE_ORIENT_ROTATE);
|
||||
switch (orient_slot->type) {
|
||||
case V3D_ORIENT_VIEW: {
|
||||
float viewinv_m3[3][3];
|
||||
copy_m3_m4(viewinv_m3, rv3d->viewinv);
|
||||
if (!equals_m3m3(viewinv_m3, xgzgroup->prev.viewinv_m3)) {
|
||||
/* Take care calling refresh from draw_prepare,
|
||||
* this should be OK because it's only adjusting the cage orientation. */
|
||||
WIDGETGROUP_xform_shear_refresh(C, gzgroup);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
const float outer_thin = 0.3f;
|
||||
const float outer_offset = 1.0f / 0.3f;
|
||||
wmGizmo *gz = xgzgroup->gizmo_view[i];
|
||||
WM_gizmo_set_matrix_rotation_from_yz_axis(
|
||||
gz, rv3d->viewinv[(i + 1) % 2], rv3d->viewinv[i % 2]);
|
||||
if (i >= 2) {
|
||||
negate_v3(gz->matrix_basis[1]);
|
||||
negate_v3(gz->matrix_basis[2]);
|
||||
}
|
||||
|
||||
/* No need for depth with view aligned gizmos. */
|
||||
mul_v3_fl(gz->matrix_basis[0], 0.0f);
|
||||
mul_v3_fl(gz->matrix_basis[1], 20.0f + ((1.0f / outer_thin) * 1.8f));
|
||||
mul_v3_fl(gz->matrix_basis[2], outer_thin);
|
||||
WM_gizmo_set_matrix_location(gz, rv3d->twmat[3]);
|
||||
gz->matrix_offset[3][2] = outer_offset;
|
||||
}
|
||||
|
||||
/* Basic ordering for drawing only. */
|
||||
{
|
||||
LISTBASE_FOREACH (wmGizmo *, gz, &gzgroup->gizmos) {
|
||||
/* Since we have two pairs of each axis,
|
||||
* bias the values so gizmos that are orthogonal to the view get priority.
|
||||
* This means we never default to shearing along
|
||||
* the view axis in the case of an overlap. */
|
||||
float axis_order[3], axis_bias[3];
|
||||
copy_v3_v3(axis_order, gz->matrix_basis[2]);
|
||||
copy_v3_v3(axis_bias, gz->matrix_basis[1]);
|
||||
if (dot_v3v3(axis_bias, rv3d->viewinv[2]) < 0.0f) {
|
||||
negate_v3(axis_bias);
|
||||
}
|
||||
madd_v3_v3fl(axis_order, axis_bias, 0.01f);
|
||||
gz->temp.f = dot_v3v3(rv3d->viewinv[2], axis_order);
|
||||
}
|
||||
BLI_listbase_sort(&gzgroup->gizmos, WM_gizmo_cmp_temp_fl_reverse);
|
||||
}
|
||||
}
|
||||
|
||||
void VIEW3D_GGT_xform_shear(wmGizmoGroupType *gzgt)
|
||||
{
|
||||
gzgt->name = "Transform Shear";
|
||||
gzgt->idname = "VIEW3D_GGT_xform_shear";
|
||||
|
||||
gzgt->flag |= WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_DRAW_MODAL_EXCLUDE |
|
||||
WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP | WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK;
|
||||
|
||||
gzgt->gzmap_params.spaceid = SPACE_VIEW3D;
|
||||
gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;
|
||||
|
||||
gzgt->poll = WIDGETGROUP_xform_shear_poll;
|
||||
gzgt->setup = WIDGETGROUP_xform_shear_setup;
|
||||
gzgt->setup_keymap = WM_gizmogroup_setup_keymap_generic_maybe_drag;
|
||||
gzgt->refresh = WIDGETGROUP_xform_shear_refresh;
|
||||
gzgt->message_subscribe = WIDGETGROUP_xform_shear_message_subscribe;
|
||||
gzgt->draw_prepare = WIDGETGROUP_xform_shear_draw_prepare;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
static wmGizmoGroup *gizmogroup_xform_find(TransInfo *t)
|
||||
{
|
||||
wmGizmo *gizmo_modal_current = WM_gizmomap_get_modal(t->region->gizmo_map);
|
||||
|
|
|
@ -0,0 +1,223 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup edtransform
|
||||
*
|
||||
* \name 3D Transform Gizmo
|
||||
*
|
||||
* Used for 3D View
|
||||
*/
|
||||
|
||||
#include "BLI_math.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_scene.h"
|
||||
|
||||
#include "ED_gizmo_library.h"
|
||||
#include "ED_gizmo_utils.h"
|
||||
#include "ED_screen.h"
|
||||
#include "WM_api.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
|
||||
/* local module include */
|
||||
#include "transform.h"
|
||||
#include "transform_gizmo.h"
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Scale Cage Gizmo
|
||||
* \{ */
|
||||
|
||||
struct XFormCageWidgetGroup {
|
||||
wmGizmo *gizmo;
|
||||
/* Only for view orientation. */
|
||||
struct {
|
||||
float viewinv_m3[3][3];
|
||||
} prev;
|
||||
};
|
||||
|
||||
static bool WIDGETGROUP_xform_cage_poll(const bContext *C, wmGizmoGroupType *gzgt)
|
||||
{
|
||||
if (!ED_gizmo_poll_or_unlink_delayed_from_tool(C, gzgt)) {
|
||||
return false;
|
||||
}
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
if (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_TOOL)) {
|
||||
return false;
|
||||
}
|
||||
if (G.moving & (G_TRANSFORM_OBJ | G_TRANSFORM_EDIT)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void WIDGETGROUP_xform_cage_setup(const bContext * /*C*/, wmGizmoGroup *gzgroup)
|
||||
{
|
||||
XFormCageWidgetGroup *xgzgroup = static_cast<XFormCageWidgetGroup *>(
|
||||
MEM_mallocN(sizeof(XFormCageWidgetGroup), __func__));
|
||||
const wmGizmoType *gzt_cage = WM_gizmotype_find("GIZMO_GT_cage_3d", true);
|
||||
xgzgroup->gizmo = WM_gizmo_new_ptr(gzt_cage, gzgroup, nullptr);
|
||||
wmGizmo *gz = xgzgroup->gizmo;
|
||||
|
||||
RNA_enum_set(
|
||||
gz->ptr, "transform", ED_GIZMO_CAGE_XFORM_FLAG_SCALE | ED_GIZMO_CAGE_XFORM_FLAG_TRANSLATE);
|
||||
|
||||
gz->color[0] = 1;
|
||||
gz->color_hi[0] = 1;
|
||||
|
||||
gzgroup->customdata = xgzgroup;
|
||||
|
||||
{
|
||||
wmOperatorType *ot_resize = WM_operatortype_find("TRANSFORM_OT_resize", true);
|
||||
PointerRNA *ptr;
|
||||
|
||||
/* assign operator */
|
||||
PropertyRNA *prop_release_confirm = nullptr;
|
||||
PropertyRNA *prop_constraint_axis = nullptr;
|
||||
|
||||
int i = ED_GIZMO_CAGE3D_PART_SCALE_MIN_X_MIN_Y_MIN_Z;
|
||||
for (int x = 0; x < 3; x++) {
|
||||
for (int y = 0; y < 3; y++) {
|
||||
for (int z = 0; z < 3; z++) {
|
||||
const bool constraint[3] = {x != 1, y != 1, z != 1};
|
||||
ptr = WM_gizmo_operator_set(gz, i, ot_resize, nullptr);
|
||||
if (prop_release_confirm == nullptr) {
|
||||
prop_release_confirm = RNA_struct_find_property(ptr, "release_confirm");
|
||||
prop_constraint_axis = RNA_struct_find_property(ptr, "constraint_axis");
|
||||
}
|
||||
RNA_property_boolean_set(ptr, prop_release_confirm, true);
|
||||
RNA_property_boolean_set_array(ptr, prop_constraint_axis, constraint);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void WIDGETGROUP_xform_cage_refresh(const bContext *C, wmGizmoGroup *gzgroup)
|
||||
{
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
|
||||
XFormCageWidgetGroup *xgzgroup = static_cast<XFormCageWidgetGroup *>(gzgroup->customdata);
|
||||
wmGizmo *gz = xgzgroup->gizmo;
|
||||
|
||||
TransformBounds tbounds;
|
||||
|
||||
const int orient_index = BKE_scene_orientation_get_index_from_flag(scene, SCE_ORIENT_SCALE);
|
||||
|
||||
TransformCalcParams calc_params{};
|
||||
calc_params.use_local_axis = true;
|
||||
calc_params.orientation_index = orient_index + 1;
|
||||
if ((ED_transform_calc_gizmo_stats(C, &calc_params, &tbounds) == 0) ||
|
||||
equals_v3v3(rv3d->tw_axis_min, rv3d->tw_axis_max)) {
|
||||
WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true);
|
||||
}
|
||||
else {
|
||||
if (tbounds.use_matrix_space) {
|
||||
copy_m4_m4(gz->matrix_space, tbounds.matrix_space);
|
||||
}
|
||||
else {
|
||||
unit_m4(gz->matrix_space);
|
||||
}
|
||||
|
||||
gizmo_prepare_mat(C, rv3d, &tbounds);
|
||||
|
||||
WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
|
||||
WM_gizmo_set_flag(gz, WM_GIZMO_MOVE_CURSOR, true);
|
||||
|
||||
float dims[3];
|
||||
sub_v3_v3v3(dims, rv3d->tw_axis_max, rv3d->tw_axis_min);
|
||||
RNA_float_set_array(gz->ptr, "dimensions", dims);
|
||||
mul_v3_fl(dims, 0.5f);
|
||||
|
||||
copy_m4_m3(gz->matrix_offset, rv3d->tw_axis_matrix);
|
||||
mid_v3_v3v3(gz->matrix_offset[3], rv3d->tw_axis_max, rv3d->tw_axis_min);
|
||||
mul_m3_v3(rv3d->tw_axis_matrix, gz->matrix_offset[3]);
|
||||
|
||||
float matrix_offset_global[4][4];
|
||||
mul_m4_m4m4(matrix_offset_global, gz->matrix_space, gz->matrix_offset);
|
||||
|
||||
PropertyRNA *prop_center_override = nullptr;
|
||||
float center[3];
|
||||
float center_global[3];
|
||||
int i = ED_GIZMO_CAGE3D_PART_SCALE_MIN_X_MIN_Y_MIN_Z;
|
||||
for (int x = 0; x < 3; x++) {
|
||||
center[0] = float(1 - x) * dims[0];
|
||||
for (int y = 0; y < 3; y++) {
|
||||
center[1] = float(1 - y) * dims[1];
|
||||
for (int z = 0; z < 3; z++) {
|
||||
center[2] = float(1 - z) * dims[2];
|
||||
wmGizmoOpElem *gzop = WM_gizmo_operator_get(gz, i);
|
||||
if (prop_center_override == nullptr) {
|
||||
prop_center_override = RNA_struct_find_property(&gzop->ptr, "center_override");
|
||||
}
|
||||
mul_v3_m4v3(center_global, matrix_offset_global, center);
|
||||
RNA_property_float_set_array(&gzop->ptr, prop_center_override, center_global);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Needed to test view orientation changes. */
|
||||
copy_m3_m4(xgzgroup->prev.viewinv_m3, rv3d->viewinv);
|
||||
}
|
||||
|
||||
static void WIDGETGROUP_xform_cage_message_subscribe(const bContext *C,
|
||||
wmGizmoGroup *gzgroup,
|
||||
wmMsgBus *mbus)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
bScreen *screen = CTX_wm_screen(C);
|
||||
ScrArea *area = CTX_wm_area(C);
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
gizmo_xform_message_subscribe(gzgroup, mbus, scene, screen, area, region, VIEW3D_GGT_xform_cage);
|
||||
}
|
||||
|
||||
static void WIDGETGROUP_xform_cage_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
|
||||
{
|
||||
XFormCageWidgetGroup *xgzgroup = static_cast<XFormCageWidgetGroup *>(gzgroup->customdata);
|
||||
|
||||
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
const TransformOrientationSlot *orient_slot = BKE_scene_orientation_slot_get(scene,
|
||||
SCE_ORIENT_SCALE);
|
||||
switch (orient_slot->type) {
|
||||
case V3D_ORIENT_VIEW: {
|
||||
float viewinv_m3[3][3];
|
||||
copy_m3_m4(viewinv_m3, rv3d->viewinv);
|
||||
if (!equals_m3m3(viewinv_m3, xgzgroup->prev.viewinv_m3)) {
|
||||
/* Take care calling refresh from draw_prepare,
|
||||
* this should be OK because it's only adjusting the cage orientation. */
|
||||
WIDGETGROUP_xform_cage_refresh(C, gzgroup);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VIEW3D_GGT_xform_cage(wmGizmoGroupType *gzgt)
|
||||
{
|
||||
gzgt->name = "Transform Cage";
|
||||
gzgt->idname = "VIEW3D_GGT_xform_cage";
|
||||
|
||||
gzgt->flag |= WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_DRAW_MODAL_EXCLUDE |
|
||||
WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP | WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK;
|
||||
|
||||
gzgt->gzmap_params.spaceid = SPACE_VIEW3D;
|
||||
gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;
|
||||
|
||||
gzgt->poll = WIDGETGROUP_xform_cage_poll;
|
||||
gzgt->setup = WIDGETGROUP_xform_cage_setup;
|
||||
gzgt->setup_keymap = WM_gizmogroup_setup_keymap_generic_maybe_drag;
|
||||
gzgt->refresh = WIDGETGROUP_xform_cage_refresh;
|
||||
gzgt->message_subscribe = WIDGETGROUP_xform_cage_message_subscribe;
|
||||
gzgt->draw_prepare = WIDGETGROUP_xform_cage_draw_prepare;
|
||||
}
|
||||
|
||||
/** \} */
|
|
@ -0,0 +1,261 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup edtransform
|
||||
*
|
||||
* \name 3D Transform Gizmo
|
||||
*
|
||||
* Used for 3D View
|
||||
*/
|
||||
|
||||
#include "BLI_math.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_scene.h"
|
||||
|
||||
#include "ED_gizmo_library.h"
|
||||
#include "ED_gizmo_utils.h"
|
||||
#include "ED_screen.h"
|
||||
#include "WM_api.h"
|
||||
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
|
||||
/* local module include */
|
||||
#include "transform.h"
|
||||
#include "transform_gizmo.h"
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Transform Shear Gizmo
|
||||
* \{ */
|
||||
|
||||
struct XFormShearWidgetGroup {
|
||||
wmGizmo *gizmo[3][2];
|
||||
/** View aligned gizmos. */
|
||||
wmGizmo *gizmo_view[4];
|
||||
|
||||
/* Only for view orientation. */
|
||||
struct {
|
||||
float viewinv_m3[3][3];
|
||||
} prev;
|
||||
};
|
||||
|
||||
static bool WIDGETGROUP_xform_shear_poll(const bContext *C, wmGizmoGroupType *gzgt)
|
||||
{
|
||||
if (!ED_gizmo_poll_or_unlink_delayed_from_tool(C, gzgt)) {
|
||||
return false;
|
||||
}
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
if (v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_TOOL)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void WIDGETGROUP_xform_shear_setup(const bContext * /*C*/, wmGizmoGroup *gzgroup)
|
||||
{
|
||||
XFormShearWidgetGroup *xgzgroup = static_cast<XFormShearWidgetGroup *>(
|
||||
MEM_mallocN(sizeof(XFormShearWidgetGroup), __func__));
|
||||
const wmGizmoType *gzt_arrow = WM_gizmotype_find("GIZMO_GT_arrow_3d", true);
|
||||
wmOperatorType *ot_shear = WM_operatortype_find("TRANSFORM_OT_shear", true);
|
||||
|
||||
float axis_color[3][3];
|
||||
for (int i = 0; i < 3; i++) {
|
||||
UI_GetThemeColor3fv(TH_AXIS_X + i, axis_color[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 2; j++) {
|
||||
wmGizmo *gz = WM_gizmo_new_ptr(gzt_arrow, gzgroup, nullptr);
|
||||
RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_BOX);
|
||||
const int i_ortho_a = (i + j + 1) % 3;
|
||||
const int i_ortho_b = (i + (1 - j) + 1) % 3;
|
||||
interp_v3_v3v3(gz->color, axis_color[i_ortho_a], axis_color[i_ortho_b], 0.75f);
|
||||
gz->color[3] = 0.5f;
|
||||
PointerRNA *ptr = WM_gizmo_operator_set(gz, 0, ot_shear, nullptr);
|
||||
RNA_boolean_set(ptr, "release_confirm", 1);
|
||||
xgzgroup->gizmo[i][j] = gz;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
wmGizmo *gz = WM_gizmo_new_ptr(gzt_arrow, gzgroup, nullptr);
|
||||
RNA_enum_set(gz->ptr, "draw_style", ED_GIZMO_ARROW_STYLE_BOX);
|
||||
RNA_enum_set(gz->ptr, "draw_options", 0); /* No stem. */
|
||||
copy_v3_fl(gz->color, 1.0f);
|
||||
gz->color[3] = 0.5f;
|
||||
WM_gizmo_set_flag(gz, WM_GIZMO_DRAW_OFFSET_SCALE, true);
|
||||
PointerRNA *ptr = WM_gizmo_operator_set(gz, 0, ot_shear, nullptr);
|
||||
RNA_boolean_set(ptr, "release_confirm", 1);
|
||||
xgzgroup->gizmo_view[i] = gz;
|
||||
|
||||
/* Unlike the other gizmos, this never changes so can be set on setup. */
|
||||
wmGizmoOpElem *gzop = WM_gizmo_operator_get(gz, 0);
|
||||
RNA_enum_set(&gzop->ptr, "orient_type", V3D_ORIENT_VIEW);
|
||||
|
||||
RNA_enum_set(&gzop->ptr, "orient_axis", 2);
|
||||
RNA_enum_set(&gzop->ptr, "orient_axis_ortho", ((i % 2) ? 0 : 1));
|
||||
}
|
||||
|
||||
gzgroup->customdata = xgzgroup;
|
||||
}
|
||||
|
||||
static void WIDGETGROUP_xform_shear_refresh(const bContext *C, wmGizmoGroup *gzgroup)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
|
||||
|
||||
XFormShearWidgetGroup *xgzgroup = static_cast<XFormShearWidgetGroup *>(gzgroup->customdata);
|
||||
TransformBounds tbounds;
|
||||
|
||||
/* Needed to test view orientation changes. */
|
||||
copy_m3_m4(xgzgroup->prev.viewinv_m3, rv3d->viewinv);
|
||||
|
||||
TransformOrientationSlot *orient_slot = BKE_scene_orientation_slot_get_from_flag(
|
||||
scene, SCE_ORIENT_ROTATE);
|
||||
const int orient_index = BKE_scene_orientation_slot_get_index(orient_slot);
|
||||
|
||||
TransformCalcParams calc_params{};
|
||||
calc_params.use_local_axis = false;
|
||||
calc_params.orientation_index = orient_index + 1;
|
||||
if (ED_transform_calc_gizmo_stats(C, &calc_params, &tbounds) == 0) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 2; j++) {
|
||||
wmGizmo *gz = xgzgroup->gizmo[i][j];
|
||||
WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
wmGizmo *gz = xgzgroup->gizmo_view[i];
|
||||
WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
gizmo_prepare_mat(C, rv3d, &tbounds);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 2; j++) {
|
||||
wmGizmo *gz = xgzgroup->gizmo[i][j];
|
||||
WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
|
||||
WM_gizmo_set_flag(gz, WM_GIZMO_MOVE_CURSOR, true);
|
||||
|
||||
wmGizmoOpElem *gzop = WM_gizmo_operator_get(gz, 0);
|
||||
const int i_ortho_a = (i + j + 1) % 3;
|
||||
const int i_ortho_b = (i + (1 - j) + 1) % 3;
|
||||
WM_gizmo_set_matrix_rotation_from_yz_axis(gz, rv3d->twmat[i_ortho_a], rv3d->twmat[i]);
|
||||
WM_gizmo_set_matrix_location(gz, rv3d->twmat[3]);
|
||||
|
||||
RNA_float_set_array(&gzop->ptr, "orient_matrix", &tbounds.axis[0][0]);
|
||||
RNA_enum_set(&gzop->ptr, "orient_type", orient_slot->type);
|
||||
|
||||
RNA_enum_set(&gzop->ptr, "orient_axis", i_ortho_b);
|
||||
RNA_enum_set(&gzop->ptr, "orient_axis_ortho", i_ortho_a);
|
||||
|
||||
mul_v3_fl(gz->matrix_basis[0], 0.5f);
|
||||
mul_v3_fl(gz->matrix_basis[1], 6.0f);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
wmGizmo *gz = xgzgroup->gizmo_view[i];
|
||||
WM_gizmo_set_flag(gz, WM_GIZMO_HIDDEN, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void WIDGETGROUP_xform_shear_message_subscribe(const bContext *C,
|
||||
wmGizmoGroup *gzgroup,
|
||||
wmMsgBus *mbus)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
bScreen *screen = CTX_wm_screen(C);
|
||||
ScrArea *area = CTX_wm_area(C);
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
gizmo_xform_message_subscribe(
|
||||
gzgroup, mbus, scene, screen, area, region, VIEW3D_GGT_xform_shear);
|
||||
}
|
||||
|
||||
static void WIDGETGROUP_xform_shear_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
|
||||
{
|
||||
XFormShearWidgetGroup *xgzgroup = static_cast<XFormShearWidgetGroup *>(gzgroup->customdata);
|
||||
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
/* Shear is like rotate, use the rotate setting. */
|
||||
const TransformOrientationSlot *orient_slot = BKE_scene_orientation_slot_get(
|
||||
scene, SCE_ORIENT_ROTATE);
|
||||
switch (orient_slot->type) {
|
||||
case V3D_ORIENT_VIEW: {
|
||||
float viewinv_m3[3][3];
|
||||
copy_m3_m4(viewinv_m3, rv3d->viewinv);
|
||||
if (!equals_m3m3(viewinv_m3, xgzgroup->prev.viewinv_m3)) {
|
||||
/* Take care calling refresh from draw_prepare,
|
||||
* this should be OK because it's only adjusting the cage orientation. */
|
||||
WIDGETGROUP_xform_shear_refresh(C, gzgroup);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
const float outer_thin = 0.3f;
|
||||
const float outer_offset = 1.0f / 0.3f;
|
||||
wmGizmo *gz = xgzgroup->gizmo_view[i];
|
||||
WM_gizmo_set_matrix_rotation_from_yz_axis(
|
||||
gz, rv3d->viewinv[(i + 1) % 2], rv3d->viewinv[i % 2]);
|
||||
if (i >= 2) {
|
||||
negate_v3(gz->matrix_basis[1]);
|
||||
negate_v3(gz->matrix_basis[2]);
|
||||
}
|
||||
|
||||
/* No need for depth with view aligned gizmos. */
|
||||
mul_v3_fl(gz->matrix_basis[0], 0.0f);
|
||||
mul_v3_fl(gz->matrix_basis[1], 20.0f + ((1.0f / outer_thin) * 1.8f));
|
||||
mul_v3_fl(gz->matrix_basis[2], outer_thin);
|
||||
WM_gizmo_set_matrix_location(gz, rv3d->twmat[3]);
|
||||
gz->matrix_offset[3][2] = outer_offset;
|
||||
}
|
||||
|
||||
/* Basic ordering for drawing only. */
|
||||
{
|
||||
LISTBASE_FOREACH (wmGizmo *, gz, &gzgroup->gizmos) {
|
||||
/* Since we have two pairs of each axis,
|
||||
* bias the values so gizmos that are orthogonal to the view get priority.
|
||||
* This means we never default to shearing along
|
||||
* the view axis in the case of an overlap. */
|
||||
float axis_order[3], axis_bias[3];
|
||||
copy_v3_v3(axis_order, gz->matrix_basis[2]);
|
||||
copy_v3_v3(axis_bias, gz->matrix_basis[1]);
|
||||
if (dot_v3v3(axis_bias, rv3d->viewinv[2]) < 0.0f) {
|
||||
negate_v3(axis_bias);
|
||||
}
|
||||
madd_v3_v3fl(axis_order, axis_bias, 0.01f);
|
||||
gz->temp.f = dot_v3v3(rv3d->viewinv[2], axis_order);
|
||||
}
|
||||
BLI_listbase_sort(&gzgroup->gizmos, WM_gizmo_cmp_temp_fl_reverse);
|
||||
}
|
||||
}
|
||||
|
||||
void VIEW3D_GGT_xform_shear(wmGizmoGroupType *gzgt)
|
||||
{
|
||||
gzgt->name = "Transform Shear";
|
||||
gzgt->idname = "VIEW3D_GGT_xform_shear";
|
||||
|
||||
gzgt->flag |= WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_DRAW_MODAL_EXCLUDE |
|
||||
WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP | WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK;
|
||||
|
||||
gzgt->gzmap_params.spaceid = SPACE_VIEW3D;
|
||||
gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;
|
||||
|
||||
gzgt->poll = WIDGETGROUP_xform_shear_poll;
|
||||
gzgt->setup = WIDGETGROUP_xform_shear_setup;
|
||||
gzgt->setup_keymap = WM_gizmogroup_setup_keymap_generic_maybe_drag;
|
||||
gzgt->refresh = WIDGETGROUP_xform_shear_refresh;
|
||||
gzgt->message_subscribe = WIDGETGROUP_xform_shear_message_subscribe;
|
||||
gzgt->draw_prepare = WIDGETGROUP_xform_shear_draw_prepare;
|
||||
}
|
||||
|
||||
/** \} */
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include "transform.h"
|
||||
#include "transform_convert.h"
|
||||
#include "transform_gizmo.h"
|
||||
#include "transform_orientations.h"
|
||||
#include "transform_snap.h"
|
||||
|
||||
|
|
|
@ -230,6 +230,101 @@ static TransformOrientation *createMeshSpace(bContext *C,
|
|||
return addMatrixSpace(C, mat, name, overwrite);
|
||||
}
|
||||
|
||||
static bool test_rotmode_euler(short rotmode)
|
||||
{
|
||||
return ELEM(rotmode, ROT_MODE_AXISANGLE, ROT_MODE_QUAT) ? 0 : 1;
|
||||
}
|
||||
|
||||
/* could move into BLI_math however this is only useful for display/editing purposes */
|
||||
static void axis_angle_to_gimbal_axis(float gmat[3][3], const float axis[3], const float angle)
|
||||
{
|
||||
/* X/Y are arbitrary axes, most importantly Z is the axis of rotation. */
|
||||
|
||||
float cross_vec[3];
|
||||
float quat[4];
|
||||
|
||||
/* this is an un-scientific method to get a vector to cross with
|
||||
* XYZ intentionally YZX */
|
||||
cross_vec[0] = axis[1];
|
||||
cross_vec[1] = axis[2];
|
||||
cross_vec[2] = axis[0];
|
||||
|
||||
/* X-axis */
|
||||
cross_v3_v3v3(gmat[0], cross_vec, axis);
|
||||
normalize_v3(gmat[0]);
|
||||
axis_angle_to_quat(quat, axis, angle);
|
||||
mul_qt_v3(quat, gmat[0]);
|
||||
|
||||
/* Y-axis */
|
||||
axis_angle_to_quat(quat, axis, M_PI_2);
|
||||
copy_v3_v3(gmat[1], gmat[0]);
|
||||
mul_qt_v3(quat, gmat[1]);
|
||||
|
||||
/* Z-axis */
|
||||
copy_v3_v3(gmat[2], axis);
|
||||
|
||||
normalize_m3(gmat);
|
||||
}
|
||||
|
||||
bool gimbal_axis_pose(Object *ob, const bPoseChannel *pchan, float gmat[3][3])
|
||||
{
|
||||
float mat[3][3], tmat[3][3], obmat[3][3];
|
||||
if (test_rotmode_euler(pchan->rotmode)) {
|
||||
eulO_to_gimbal_axis(mat, pchan->eul, pchan->rotmode);
|
||||
}
|
||||
else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
|
||||
axis_angle_to_gimbal_axis(mat, pchan->rotAxis, pchan->rotAngle);
|
||||
}
|
||||
else { /* quat */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* apply bone transformation */
|
||||
mul_m3_m3m3(tmat, pchan->bone->bone_mat, mat);
|
||||
|
||||
if (pchan->parent) {
|
||||
float parent_mat[3][3];
|
||||
|
||||
copy_m3_m4(parent_mat,
|
||||
(pchan->bone->flag & BONE_HINGE) ? pchan->parent->bone->arm_mat :
|
||||
pchan->parent->pose_mat);
|
||||
mul_m3_m3m3(mat, parent_mat, tmat);
|
||||
|
||||
/* needed if object transformation isn't identity */
|
||||
copy_m3_m4(obmat, ob->object_to_world);
|
||||
mul_m3_m3m3(gmat, obmat, mat);
|
||||
}
|
||||
else {
|
||||
/* needed if object transformation isn't identity */
|
||||
copy_m3_m4(obmat, ob->object_to_world);
|
||||
mul_m3_m3m3(gmat, obmat, tmat);
|
||||
}
|
||||
|
||||
normalize_m3(gmat);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool gimbal_axis_object(Object *ob, float gmat[3][3])
|
||||
{
|
||||
if (test_rotmode_euler(ob->rotmode)) {
|
||||
eulO_to_gimbal_axis(gmat, ob->rot, ob->rotmode);
|
||||
}
|
||||
else if (ob->rotmode == ROT_MODE_AXISANGLE) {
|
||||
axis_angle_to_gimbal_axis(gmat, ob->rotAxis, ob->rotAngle);
|
||||
}
|
||||
else { /* quat */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ob->parent) {
|
||||
float parent_mat[3][3];
|
||||
copy_m3_m4(parent_mat, ob->parent->object_to_world);
|
||||
normalize_m3(parent_mat);
|
||||
mul_m3_m3m3(gmat, parent_mat, gmat);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool transform_orientations_create_from_axis(float mat[3][3],
|
||||
const float x[3],
|
||||
const float y[3],
|
||||
|
|
|
@ -9,8 +9,13 @@
|
|||
|
||||
#include "RE_engine.h"
|
||||
|
||||
struct bPoseChannel;
|
||||
struct Object;
|
||||
struct TransInfo;
|
||||
|
||||
bool gimbal_axis_pose(struct Object *ob, const struct bPoseChannel *pchan, float gmat[3][3]);
|
||||
bool gimbal_axis_object(struct Object *ob, float gmat[3][3]);
|
||||
|
||||
/**
|
||||
* Sets the matrix of the specified space orientation.
|
||||
* If the matrix cannot be obtained, an orientation different from the one informed is returned.
|
||||
|
|
|
@ -1430,7 +1430,7 @@ struct Nearest2dUserData {
|
|||
const float (*vert_normals)[3];
|
||||
const MEdge *edge; /* only used for #BVHTreeFromMeshEdges */
|
||||
const MLoop *loop;
|
||||
const MLoopTri *looptri;
|
||||
const MLoopTri *looptris;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -1481,7 +1481,7 @@ static void cb_mlooptri_edges_get(const int index, const Nearest2dUserData *data
|
|||
{
|
||||
const MEdge *medge = data->edge;
|
||||
const MLoop *mloop = data->loop;
|
||||
const MLoopTri *lt = &data->looptri[index];
|
||||
const MLoopTri *lt = &data->looptris[index];
|
||||
for (int j = 2, j_next = 0; j_next < 3; j = j_next++) {
|
||||
const MEdge *ed = &medge[mloop[lt->tri[j]].e];
|
||||
const uint tri_edge[2] = {mloop[lt->tri[j]].v, mloop[lt->tri[j_next]].v};
|
||||
|
@ -1498,7 +1498,7 @@ static void cb_mlooptri_edges_get(const int index, const Nearest2dUserData *data
|
|||
static void cb_mlooptri_verts_get(const int index, const Nearest2dUserData *data, int r_v_index[3])
|
||||
{
|
||||
const MLoop *loop = data->loop;
|
||||
const MLoopTri *looptri = &data->looptri[index];
|
||||
const MLoopTri *looptri = &data->looptris[index];
|
||||
|
||||
r_v_index[0] = loop[looptri->tri[0]].v;
|
||||
r_v_index[1] = loop[looptri->tri[1]].v;
|
||||
|
@ -1716,10 +1716,10 @@ static void nearest2d_data_init_mesh(const Mesh *mesh,
|
|||
r_nearest2d->get_tri_edges_index = cb_mlooptri_edges_get;
|
||||
|
||||
r_nearest2d->vert_positions = BKE_mesh_vert_positions(mesh);
|
||||
r_nearest2d->vert_normals = BKE_mesh_vertex_normals_ensure(mesh);
|
||||
r_nearest2d->vert_normals = BKE_mesh_vert_normals_ensure(mesh);
|
||||
r_nearest2d->edge = mesh->edges().data();
|
||||
r_nearest2d->loop = mesh->loops().data();
|
||||
r_nearest2d->looptri = BKE_mesh_runtime_looptri_ensure(mesh);
|
||||
r_nearest2d->looptris = mesh->looptris().data();
|
||||
|
||||
r_nearest2d->is_persp = is_persp;
|
||||
r_nearest2d->use_backface_culling = use_backface_culling;
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
|
||||
#include "ED_uvedit.h" /* Own include. */
|
||||
|
||||
#include "GEO_uv_pack.hh"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
|
@ -435,199 +437,6 @@ int bm_mesh_calc_uv_islands(const Scene *scene,
|
|||
|
||||
/** \} */
|
||||
|
||||
static float pack_islands_scale_margin(const blender::Vector<FaceIsland *> &island_vector,
|
||||
BoxPack *box_array,
|
||||
const float scale,
|
||||
const float margin)
|
||||
{
|
||||
for (const int index : island_vector.index_range()) {
|
||||
FaceIsland *island = island_vector[index];
|
||||
BoxPack *box = &box_array[index];
|
||||
box->index = index;
|
||||
box->w = BLI_rctf_size_x(&island->bounds_rect) * scale + 2 * margin;
|
||||
box->h = BLI_rctf_size_y(&island->bounds_rect) * scale + 2 * margin;
|
||||
}
|
||||
float max_u, max_v;
|
||||
BLI_box_pack_2d(box_array, island_vector.size(), &max_u, &max_v);
|
||||
return max_ff(max_u, max_v);
|
||||
}
|
||||
|
||||
static float pack_islands_margin_fraction(const blender::Vector<FaceIsland *> &island_vector,
|
||||
BoxPack *box_array,
|
||||
const float margin_fraction)
|
||||
{
|
||||
/*
|
||||
* Root finding using a combined search / modified-secant method.
|
||||
* First, use a robust search procedure to bracket the root within a factor of 10.
|
||||
* Then, use a modified-secant method to converge.
|
||||
*
|
||||
* This is a specialized solver using domain knowledge to accelerate convergence. */
|
||||
|
||||
float scale_low = 0.0f;
|
||||
float value_low = 0.0f;
|
||||
float scale_high = 0.0f;
|
||||
float value_high = 0.0f;
|
||||
float scale_last = 0.0f;
|
||||
|
||||
/* Scaling smaller than `min_scale_roundoff` is unlikely to fit and
|
||||
* will destroy information in existing UVs. */
|
||||
float min_scale_roundoff = 1e-5f;
|
||||
|
||||
/* Certain inputs might have poor convergence properties.
|
||||
* Use `max_iteration` to prevent an infinite loop. */
|
||||
int max_iteration = 25;
|
||||
for (int iteration = 0; iteration < max_iteration; iteration++) {
|
||||
float scale = 1.0f;
|
||||
|
||||
if (iteration == 0) {
|
||||
BLI_assert(iteration == 0);
|
||||
BLI_assert(scale == 1.0f);
|
||||
BLI_assert(scale_low == 0.0f);
|
||||
BLI_assert(scale_high == 0.0f);
|
||||
}
|
||||
else if (scale_low == 0.0f) {
|
||||
BLI_assert(scale_high > 0.0f);
|
||||
/* Search mode, shrink layout until we can find a scale that fits. */
|
||||
scale = scale_high * 0.1f;
|
||||
}
|
||||
else if (scale_high == 0.0f) {
|
||||
BLI_assert(scale_low > 0.0f);
|
||||
/* Search mode, grow layout until we can find a scale that doesn't fit. */
|
||||
scale = scale_low * 10.0f;
|
||||
}
|
||||
else {
|
||||
/* Bracket mode, use modified secant method to find root. */
|
||||
BLI_assert(scale_low > 0.0f);
|
||||
BLI_assert(scale_high > 0.0f);
|
||||
BLI_assert(value_low <= 0.0f);
|
||||
BLI_assert(value_high >= 0.0f);
|
||||
if (scale_high < scale_low * 1.0001f) {
|
||||
/* Convergence. */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Secant method for area. */
|
||||
scale = (sqrtf(scale_low) * value_high - sqrtf(scale_high) * value_low) /
|
||||
(value_high - value_low);
|
||||
scale = scale * scale;
|
||||
|
||||
if (iteration & 1) {
|
||||
/* Modified binary-search to improve robustness. */
|
||||
scale = sqrtf(scale * sqrtf(scale_low * scale_high));
|
||||
}
|
||||
}
|
||||
|
||||
scale = max_ff(scale, min_scale_roundoff);
|
||||
|
||||
/* Evaluate our `f`. */
|
||||
scale_last = scale;
|
||||
float max_uv = pack_islands_scale_margin(
|
||||
island_vector, box_array, scale_last, margin_fraction);
|
||||
float value = sqrtf(max_uv) - 1.0f;
|
||||
|
||||
if (value <= 0.0f) {
|
||||
scale_low = scale;
|
||||
value_low = value;
|
||||
}
|
||||
else {
|
||||
scale_high = scale;
|
||||
value_high = value;
|
||||
if (scale == min_scale_roundoff) {
|
||||
/* Unable to pack without damaging UVs. */
|
||||
scale_low = scale;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const bool flush = true;
|
||||
if (flush) {
|
||||
/* Write back best pack as a side-effect. First get best pack. */
|
||||
if (scale_last != scale_low) {
|
||||
scale_last = scale_low;
|
||||
float max_uv = pack_islands_scale_margin(
|
||||
island_vector, box_array, scale_last, margin_fraction);
|
||||
UNUSED_VARS(max_uv);
|
||||
/* TODO (?): `if (max_uv < 1.0f) { scale_last /= max_uv; }` */
|
||||
}
|
||||
|
||||
/* Then expand FaceIslands by the correct amount. */
|
||||
for (const int index : island_vector.index_range()) {
|
||||
BoxPack *box = &box_array[index];
|
||||
box->x /= scale_last;
|
||||
box->y /= scale_last;
|
||||
FaceIsland *island = island_vector[index];
|
||||
BLI_rctf_pad(
|
||||
&island->bounds_rect, margin_fraction / scale_last, margin_fraction / scale_last);
|
||||
}
|
||||
}
|
||||
return scale_last;
|
||||
}
|
||||
|
||||
static float calc_margin_from_aabb_length_sum(const blender::Vector<FaceIsland *> &island_vector,
|
||||
const struct UVPackIsland_Params ¶ms)
|
||||
{
|
||||
/* Logic matches behavior from #GEO_uv_parametrizer_pack.
|
||||
* Attempt to give predictable results not dependent on current UV scale by using
|
||||
* `aabb_length_sum` (was "`area`") to multiply the margin by the length (was "area"). */
|
||||
double aabb_length_sum = 0.0f;
|
||||
for (FaceIsland *island : island_vector) {
|
||||
float w = BLI_rctf_size_x(&island->bounds_rect);
|
||||
float h = BLI_rctf_size_y(&island->bounds_rect);
|
||||
aabb_length_sum += sqrtf(w * h);
|
||||
}
|
||||
return params.margin * aabb_length_sum * 0.1f;
|
||||
}
|
||||
|
||||
static BoxPack *pack_islands_params(const blender::Vector<FaceIsland *> &island_vector,
|
||||
const struct UVPackIsland_Params ¶ms,
|
||||
float r_scale[2])
|
||||
{
|
||||
BoxPack *box_array = static_cast<BoxPack *>(
|
||||
MEM_mallocN(sizeof(*box_array) * island_vector.size(), __func__));
|
||||
|
||||
if (params.margin == 0.0f) {
|
||||
/* Special case for zero margin. Margin_method is ignored as all formulas give same result. */
|
||||
const float max_uv = pack_islands_scale_margin(island_vector, box_array, 1.0f, 0.0f);
|
||||
r_scale[0] = 1.0f / max_uv;
|
||||
r_scale[1] = r_scale[0];
|
||||
return box_array;
|
||||
}
|
||||
|
||||
if (params.margin_method == ED_UVPACK_MARGIN_FRACTION) {
|
||||
/* Uses a line search on scale. ~10x slower than other method. */
|
||||
const float scale = pack_islands_margin_fraction(island_vector, box_array, params.margin);
|
||||
r_scale[0] = scale;
|
||||
r_scale[1] = scale;
|
||||
/* pack_islands_margin_fraction will pad FaceIslands, return early. */
|
||||
return box_array;
|
||||
}
|
||||
|
||||
float margin = params.margin;
|
||||
switch (params.margin_method) {
|
||||
case ED_UVPACK_MARGIN_ADD: /* Default for Blender 2.8 and earlier. */
|
||||
break; /* Nothing to do. */
|
||||
case ED_UVPACK_MARGIN_SCALED: /* Default for Blender 3.3 and later. */
|
||||
margin = calc_margin_from_aabb_length_sum(island_vector, params);
|
||||
break;
|
||||
case ED_UVPACK_MARGIN_FRACTION: /* Added as an option in Blender 3.4. */
|
||||
BLI_assert_unreachable(); /* Handled above. */
|
||||
break;
|
||||
default:
|
||||
BLI_assert_unreachable();
|
||||
}
|
||||
|
||||
const float max_uv = pack_islands_scale_margin(island_vector, box_array, 1.0f, margin);
|
||||
r_scale[0] = 1.0f / max_uv;
|
||||
r_scale[1] = r_scale[0];
|
||||
|
||||
for (int index = 0; index < island_vector.size(); index++) {
|
||||
FaceIsland *island = island_vector[index];
|
||||
BLI_rctf_pad(&island->bounds_rect, margin, margin);
|
||||
}
|
||||
return box_array;
|
||||
}
|
||||
|
||||
static bool island_has_pins(const Scene *scene,
|
||||
FaceIsland *island,
|
||||
const UVPackIsland_Params *params)
|
||||
|
@ -664,8 +473,8 @@ void ED_uvedit_pack_islands_multi(const Scene *scene,
|
|||
Object **objects,
|
||||
const uint objects_len,
|
||||
BMesh **bmesh_override,
|
||||
const struct UVMapUDIM_Params *closest_udim,
|
||||
const struct UVPackIsland_Params *params)
|
||||
const UVMapUDIM_Params *closest_udim,
|
||||
const UVPackIsland_Params *params)
|
||||
{
|
||||
blender::Vector<FaceIsland *> island_vector;
|
||||
|
||||
|
@ -751,7 +560,14 @@ void ED_uvedit_pack_islands_multi(const Scene *scene,
|
|||
}
|
||||
|
||||
float scale[2] = {1.0f, 1.0f};
|
||||
BoxPack *box_array = pack_islands_params(island_vector, *params, scale);
|
||||
blender::Vector<blender::geometry::PackIsland *> pack_island_vector;
|
||||
for (int i = 0; i < island_vector.size(); i++) {
|
||||
FaceIsland *face_island = island_vector[i];
|
||||
blender::geometry::PackIsland *pack_island = new blender::geometry::PackIsland();
|
||||
pack_island->bounds_rect = face_island->bounds_rect;
|
||||
pack_island_vector.append(pack_island);
|
||||
}
|
||||
BoxPack *box_array = pack_islands(pack_island_vector, *params, scale);
|
||||
|
||||
float base_offset[2] = {0.0f, 0.0f};
|
||||
copy_v2_v2(base_offset, params->udim_base_offset);
|
||||
|
@ -818,6 +634,12 @@ void ED_uvedit_pack_islands_multi(const Scene *scene,
|
|||
MEM_freeN(island);
|
||||
}
|
||||
|
||||
for (int i = 0; i < pack_island_vector.size(); i++) {
|
||||
blender::geometry::PackIsland *pack_island = pack_island_vector[i];
|
||||
pack_island_vector[i] = nullptr;
|
||||
delete pack_island;
|
||||
}
|
||||
|
||||
MEM_freeN(box_array);
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
|
||||
#include "DEG_depsgraph.h"
|
||||
|
||||
#include "GEO_uv_pack.hh"
|
||||
#include "GEO_uv_parametrizer.h"
|
||||
|
||||
#include "PIL_time.h"
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue