USD: Skeleton and blend shape import #110912

Merged
Michael Kowalski merged 38 commits from makowalski/blender:usdskel_import into main 2023-08-17 20:11:58 +02:00
32 changed files with 555 additions and 337 deletions
Showing only changes of commit 601d38639e - Show all commits

View File

@ -1514,15 +1514,17 @@ macro(windows_install_shared_manifest)
if(WINDOWS_INSTALL_RELEASE)
list(APPEND WINDOWS_SHARED_MANIFEST_RELEASE ${WINDOWS_INSTALL_FILES})
endif()
install(FILES ${WINDOWS_INSTALL_FILES}
CONFIGURATIONS ${WINDOWS_CONFIGURATIONS}
DESTINATION "./blender.shared"
install(
FILES ${WINDOWS_INSTALL_FILES}
DESTINATION "./blender.shared"
CONFIGURATIONS ${WINDOWS_CONFIGURATIONS}
)
else()
# Python module without manifest.
install(FILES ${WINDOWS_INSTALL_FILES}
CONFIGURATIONS ${WINDOWS_CONFIGURATIONS}
DESTINATION "./bpy"
install(
FILES ${WINDOWS_INSTALL_FILES}
DESTINATION "./bpy"
CONFIGURATIONS ${WINDOWS_CONFIGURATIONS}
)
endif()
endmacro()
@ -1559,7 +1561,7 @@ macro(windows_generate_shared_manifest)
)
install(
FILES ${CMAKE_BINARY_DIR}/Debug/blender.shared.manifest
DESTINATION "./blender.shared"
DESTINATION ${CMAKE_INSTALL_PREFIX}/blender.shared
CONFIGURATIONS Debug
)
endif()
@ -1571,7 +1573,7 @@ macro(windows_generate_shared_manifest)
)
install(
FILES ${CMAKE_BINARY_DIR}/Release/blender.shared.manifest
DESTINATION "./blender.shared"
DESTINATION ${CMAKE_INSTALL_PREFIX}/blender.shared
CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel
)
endif()

View File

@ -134,11 +134,19 @@ if(WITH_WINDOWS_BUNDLE_CRT)
string(FIND ${lib} "ucrtbase" pos)
if(NOT pos EQUAL -1)
list(REMOVE_ITEM CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS ${lib})
install(FILES ${lib} DESTINATION . COMPONENT Libraries)
install(
FILES ${lib}
DESTINATION ${CMAKE_INSTALL_PREFIX}
COMPONENT Libraries
)
endif()
endforeach()
# Install the CRT to the blender.crt Sub folder.
install(FILES ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} DESTINATION ./blender.crt COMPONENT Libraries)
install(
FILES ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS}
DESTINATION ${CMAKE_INSTALL_PREFIX}/blender.crt
COMPONENT Libraries
)
windows_generate_manifest(
FILES "${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS}"
@ -146,7 +154,10 @@ if(WITH_WINDOWS_BUNDLE_CRT)
NAME "blender.crt"
)
install(FILES ${CMAKE_BINARY_DIR}/blender.crt.manifest DESTINATION ./blender.crt)
install(
FILES ${CMAKE_BINARY_DIR}/blender.crt.manifest
DESTINATION ${CMAKE_INSTALL_PREFIX}/blender.crt
)
set(BUNDLECRT "<dependency><dependentAssembly><assemblyIdentity type=\"win32\" name=\"blender.crt\" version=\"1.0.0.0\" /></dependentAssembly></dependency>")
endif()
if(NOT WITH_PYTHON_MODULE)

View File

@ -217,10 +217,6 @@ bool BKE_paint_always_hide_test(Object *ob);
/* Partial visibility. */
/**
* Returns non-zero if any of the face's vertices are hidden, zero otherwise.
*/
bool paint_is_face_hidden(const int *looptri_faces, const bool *hide_poly, int tri_index);
/**
* Returns non-zero if any of the corners of the grid
* face whose inner corner is at (x, y) are hidden, zero otherwise.

View File

@ -14,7 +14,6 @@
#include "BLI_bitmap.h"
#include "BLI_compiler_compat.h"
#include "BLI_ghash.h"
#include "BLI_index_mask.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_offset_indices.hh"
#include "BLI_vector.hh"
@ -211,7 +210,7 @@ void BKE_pbvh_build_grids(PBVH *pbvh,
CCGElem **grids,
int totgrid,
CCGKey *key,
blender::Span<int> gridfaces,
void **gridfaces,
DMFlagMat *flagmats,
unsigned int **grid_hidden,
Mesh *me,
@ -444,12 +443,10 @@ void BKE_pbvh_update_vertex_data(PBVH *pbvh, int flags);
void BKE_pbvh_update_visibility(PBVH *pbvh);
void BKE_pbvh_update_normals(PBVH *pbvh, SubdivCCG *subdiv_ccg);
void BKE_pbvh_redraw_BB(PBVH *pbvh, float bb_min[3], float bb_max[3]);
blender::IndexMask BKE_pbvh_get_grid_updates(const PBVH *pbvh,
blender::Span<const PBVHNode *> nodes,
blender::IndexMaskMemory &memory);
void BKE_pbvh_get_grid_updates(PBVH *pbvh, bool clear, void ***r_gridfaces, int *r_totface);
void BKE_pbvh_grids_update(PBVH *pbvh,
CCGElem **grids,
blender::Span<int> gridfaces,
void **gridfaces,
DMFlagMat *flagmats,
unsigned int **grid_hidden,
CCGKey *key);

View File

@ -8,7 +8,6 @@
#pragma once
#include "BLI_array.hh"
#include "BLI_bitmap.h"
#include "BLI_offset_indices.hh"
#include "BLI_sys_types.h"
@ -160,7 +159,7 @@ struct SubdivCCG {
int num_faces;
SubdivCCGFace *faces;
/* Indexed by grid index, points to corresponding face from `faces`. */
blender::Array<int> grid_faces;
SubdivCCGFace **grid_faces;
/* Edges which are adjacent to faces.
* Used for faster grid stitching, in the cost of extra memory.
@ -236,14 +235,17 @@ void BKE_subdiv_ccg_key_top_level(CCGKey *key, const SubdivCCG *subdiv_ccg);
void BKE_subdiv_ccg_recalc_normals(SubdivCCG *subdiv_ccg);
/* Update normals of affected faces. */
void BKE_subdiv_ccg_update_normals(SubdivCCG *subdiv_ccg, const blender::IndexMask &face_mask);
void BKE_subdiv_ccg_update_normals(SubdivCCG *subdiv_ccg,
CCGFace **effected_faces,
int num_effected_faces);
/* Average grid coordinates and normals along the grid boundaries. */
void BKE_subdiv_ccg_average_grids(SubdivCCG *subdiv_ccg);
/* Similar to above, but only updates given faces. */
void BKE_subdiv_ccg_average_stitch_faces(SubdivCCG *subdiv_ccg,
const blender::IndexMask &face_mask);
CCGFace **effected_faces,
int num_effected_faces);
/* Get geometry counters at the current subdivision level. */
void BKE_subdiv_ccg_topology_counters(const SubdivCCG *subdiv_ccg,

View File

@ -1226,11 +1226,12 @@ void multires_stitch_grids(Object *ob)
/* NOTE: Currently CCG does not keep track of faces, making it impossible
* to use BKE_pbvh_get_grid_updates().
*/
blender::IndexMaskMemory memory;
blender::Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(pbvh, nullptr, nullptr);
const blender::IndexMask mask = BKE_pbvh_get_grid_updates(pbvh, nodes, memory);
if (!mask.is_empty()) {
BKE_subdiv_ccg_average_stitch_faces(subdiv_ccg, mask);
CCGFace **faces;
int num_faces;
BKE_pbvh_get_grid_updates(pbvh, false, (void ***)&faces, &num_faces);
if (num_faces) {
BKE_subdiv_ccg_average_stitch_faces(subdiv_ccg, faces, num_faces);
MEM_freeN(faces);
}
}

View File

@ -894,51 +894,12 @@ static void object_blend_read_lib(BlendLibReader *reader, ID *id)
/* XXX deprecated - old pose library, deprecated in Blender 3.5. */
BLO_read_id_address(reader, id, &ob->poselib);
/* 2.8x drops support for non-empty dupli instances. */
if (ob->type == OB_EMPTY) {
BLO_read_id_address(reader, id, &ob->instance_collection);
}
else {
if (ob->instance_collection != nullptr) {
ID *new_id = BLO_read_get_new_id_address(
reader, id, ID_IS_LINKED(id), &ob->instance_collection->id);
BLO_reportf_wrap(reports,
RPT_INFO,
TIP_("Non-Empty object '%s' cannot duplicate collection '%s' "
"anymore in Blender 2.80, removed instancing"),
ob->id.name + 2,
new_id->name + 2);
}
ob->instance_collection = nullptr;
ob->transflag &= ~OB_DUPLICOLLECTION;
}
BLO_read_id_address(reader, id, &ob->instance_collection);
/* XXX deprecated - old proxy system. <<< */
BLO_read_id_address(reader, id, &ob->proxy);
if (ob->proxy) {
/* paranoia check, actually a proxy_from pointer should never be written... */
if (!ID_IS_LINKED(ob->proxy)) {
ob->proxy->proxy_from = nullptr;
ob->proxy = nullptr;
if (ob->id.lib) {
BLO_reportf_wrap(reports,
RPT_INFO,
TIP_("Proxy lost from object %s lib %s\n"),
ob->id.name + 2,
ob->id.lib->filepath);
}
else {
BLO_reportf_wrap(
reports, RPT_INFO, TIP_("Proxy lost from object %s lib <NONE>\n"), ob->id.name + 2);
}
reports->count.missing_obproxies++;
}
else {
/* this triggers object_update to always use a copy */
ob->proxy->proxy_from = ob;
}
}
BLO_read_id_address(reader, id, &ob->proxy_group);
/* >>> XXX deprecated - old proxy system . */
void *poin = ob->data;
BLO_read_id_address(reader, id, &ob->data);

View File

@ -1293,14 +1293,6 @@ void BKE_paint_blend_read_lib(BlendLibReader *reader, Scene *sce, Paint *p)
}
}
bool paint_is_face_hidden(const int *looptri_faces, const bool *hide_poly, const int tri_index)
{
if (!hide_poly) {
return false;
}
return hide_poly[looptri_faces[tri_index]];
}
bool paint_is_grid_face_hidden(const uint *grid_hidden, int gridsize, int x, int y)
{
/* Skip face if any of its corners are hidden. */
@ -2260,7 +2252,7 @@ static PBVH *build_pbvh_from_ccg(Object *ob, SubdivCCG *subdiv_ccg)
subdiv_ccg->grids,
subdiv_ccg->num_grids,
&key,
subdiv_ccg->grid_faces,
(void **)subdiv_ccg->grid_faces,
subdiv_ccg->grid_flag_mats,
subdiv_ccg->grid_hidden,
base_mesh,
@ -2349,7 +2341,7 @@ void BKE_sculpt_bvh_update_from_ccg(PBVH *pbvh, SubdivCCG *subdiv_ccg)
BKE_pbvh_grids_update(pbvh,
subdiv_ccg->grids,
subdiv_ccg->grid_faces,
(void **)subdiv_ccg->grid_faces,
subdiv_ccg->grid_flag_mats,
subdiv_ccg->grid_hidden,
&key);

View File

@ -318,29 +318,20 @@ static int map_insert_vert(
/* Find vertices used by the faces in this node and update the draw buffers */
static void build_mesh_leaf_node(PBVH *pbvh, PBVHNode *node)
{
bool has_visible = false;
node->uniq_verts = node->face_verts = 0;
const int totface = node->prim_indices.size();
const Span<int> prim_indices = node->prim_indices;
/* reserve size is rough guess */
blender::Map<int, int> map;
map.reserve(totface);
map.reserve(prim_indices.size());
node->face_vert_indices.reinitialize(totface);
node->face_vert_indices.reinitialize(prim_indices.size());
for (int i = 0; i < totface; i++) {
const MLoopTri *lt = &pbvh->looptri[node->prim_indices[i]];
for (const int i : prim_indices.index_range()) {
const MLoopTri &tri = pbvh->looptri[prim_indices[i]];
for (int j = 0; j < 3; j++) {
node->face_vert_indices[i][j] = map_insert_vert(
pbvh, map, &node->face_verts, &node->uniq_verts, pbvh->corner_verts[lt->tri[j]]);
}
if (has_visible == false) {
if (!paint_is_face_hidden(
pbvh->looptri_faces.data(), pbvh->hide_poly, node->prim_indices[i])) {
has_visible = true;
}
pbvh, map, &node->face_verts, &node->uniq_verts, pbvh->corner_verts[tri.tri[j]]);
}
}
@ -356,19 +347,22 @@ static void build_mesh_leaf_node(PBVH *pbvh, PBVHNode *node)
node->vert_indices[value] = item.key;
}
for (int i = 0; i < totface; i++) {
const int sides = 3;
for (int j = 0; j < sides; j++) {
for (const int i : prim_indices.index_range()) {
for (int j = 0; j < 3; j++) {
if (node->face_vert_indices[i][j] < 0) {
node->face_vert_indices[i][j] = -node->face_vert_indices[i][j] + node->uniq_verts - 1;
}
}
}
const bool fully_hidden = pbvh->hide_poly &&
std::all_of(
prim_indices.begin(), prim_indices.end(), [&](const int tri) {
const int face = pbvh->looptri_faces[tri];
return pbvh->hide_poly[face];
});
BKE_pbvh_node_fully_hidden_set(node, fully_hidden);
BKE_pbvh_node_mark_rebuild_draw(node);
BKE_pbvh_node_fully_hidden_set(node, !has_visible);
}
static void update_vb(PBVH *pbvh, PBVHNode *node, const Span<BBC> prim_bbc, int offset, int count)
@ -927,7 +921,7 @@ void BKE_pbvh_build_grids(PBVH *pbvh,
CCGElem **grids,
int totgrid,
CCGKey *key,
blender::Span<int> gridfaces,
void **gridfaces,
DMFlagMat *flagmats,
BLI_bitmap **grid_hidden,
Mesh *me,
@ -1742,21 +1736,49 @@ void BKE_pbvh_redraw_BB(PBVH *pbvh, float bb_min[3], float bb_max[3])
copy_v3_v3(bb_max, bb.bmax);
}
blender::IndexMask BKE_pbvh_get_grid_updates(const PBVH *pbvh,
const Span<const PBVHNode *> nodes,
blender::IndexMaskMemory &memory)
void BKE_pbvh_get_grid_updates(PBVH *pbvh, bool clear, void ***r_gridfaces, int *r_totface)
{
using namespace blender;
Array<bool> faces_to_update(pbvh->faces_num, false);
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (const PBVHNode *node : nodes.slice(range)) {
GSet *face_set = BLI_gset_ptr_new(__func__);
PBVHNode *node;
PBVHIter iter;
pbvh_iter_begin(&iter, pbvh, nullptr, nullptr);
while ((node = pbvh_iter_next(&iter, PBVH_Leaf))) {
if (node->flag & PBVH_UpdateNormals) {
for (const int grid : node->prim_indices) {
const int face = pbvh->gridfaces[grid];
faces_to_update[face] = true;
void *face = pbvh->gridfaces[grid];
BLI_gset_add(face_set, face);
}
if (clear) {
node->flag &= ~PBVH_UpdateNormals;
}
}
}
});
return IndexMask::from_bools(faces_to_update, memory);
pbvh_iter_end(&iter);
const int tot = BLI_gset_len(face_set);
if (tot == 0) {
*r_totface = 0;
*r_gridfaces = nullptr;
BLI_gset_free(face_set, nullptr);
return;
}
void **faces = static_cast<void **>(MEM_mallocN(sizeof(*faces) * tot, __func__));
GSetIterator gs_iter;
int i;
GSET_ITER_INDEX (gs_iter, face_set, i) {
faces[i] = BLI_gsetIterator_getKey(&gs_iter);
}
BLI_gset_free(face_set, nullptr);
*r_totface = tot;
*r_gridfaces = faces;
}
/***************************** PBVH Access ***********************************/
@ -2280,7 +2302,7 @@ static bool pbvh_faces_node_raycast(PBVH *pbvh,
const MLoopTri *lt = &pbvh->looptri[looptri_i];
const blender::int3 face_verts = node->face_vert_indices[i];
if (paint_is_face_hidden(pbvh->looptri_faces.data(), pbvh->hide_poly, looptri_i)) {
if (pbvh->hide_poly && pbvh->hide_poly[pbvh->looptri_faces[looptri_i]]) {
continue;
}
@ -2627,7 +2649,7 @@ static bool pbvh_faces_node_nearest_to_ray(PBVH *pbvh,
const MLoopTri *lt = &pbvh->looptri[looptri_i];
const blender::int3 face_verts = node->face_vert_indices[i];
if (paint_is_face_hidden(pbvh->looptri_faces.data(), pbvh->hide_poly, looptri_i)) {
if (pbvh->hide_poly && pbvh->hide_poly[pbvh->looptri_faces[looptri_i]]) {
continue;
}
@ -2817,7 +2839,6 @@ bool BKE_pbvh_node_frustum_exclude_AABB(PBVHNode *node, void *data)
void BKE_pbvh_update_normals(PBVH *pbvh, SubdivCCG *subdiv_ccg)
{
using namespace blender;
/* Update normals */
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(
pbvh, update_search_cb, POINTER_FROM_INT(PBVH_UpdateNormals));
@ -2830,11 +2851,12 @@ void BKE_pbvh_update_normals(PBVH *pbvh, SubdivCCG *subdiv_ccg)
pbvh_faces_update_normals(pbvh, nodes);
}
else if (pbvh->header.type == PBVH_GRIDS) {
IndexMaskMemory memory;
const IndexMask faces_to_update = BKE_pbvh_get_grid_updates(pbvh, nodes, memory);
BKE_subdiv_ccg_update_normals(subdiv_ccg, faces_to_update);
for (PBVHNode *node : nodes) {
node->flag &= ~PBVH_UpdateNormals;
CCGFace **faces;
int num_faces;
BKE_pbvh_get_grid_updates(pbvh, true, (void ***)&faces, &num_faces);
if (num_faces > 0) {
BKE_subdiv_ccg_update_normals(subdiv_ccg, faces, num_faces);
MEM_freeN(faces);
}
}
}
@ -2953,7 +2975,7 @@ void BKE_pbvh_draw_debug_cb(PBVH *pbvh,
void BKE_pbvh_grids_update(PBVH *pbvh,
CCGElem **grids,
blender::Span<int> gridfaces,
void **gridfaces,
DMFlagMat *flagmats,
BLI_bitmap **grid_hidden,
CCGKey *key)

View File

@ -176,7 +176,7 @@ struct PBVH {
/* Grid Data */
CCGKey gridkey;
CCGElem **grids;
blender::Span<int> gridfaces;
void **gridfaces;
const DMFlagMat *grid_flag_mats;
int totgrid;
BLI_bitmap **grid_hidden;

View File

@ -13,7 +13,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_enumerable_thread_specific.hh"
#include "BLI_ghash.h"
#include "BLI_math_bits.h"
#include "BLI_math_geom.h"
@ -41,7 +40,8 @@ static void subdiv_ccg_average_inner_face_grids(SubdivCCG *subdiv_ccg,
void subdiv_ccg_average_faces_boundaries_and_corners(SubdivCCG *subdiv_ccg,
CCGKey *key,
const blender::IndexMask &face_mask);
CCGFace **effected_faces,
int num_effected_faces);
/** \} */
@ -152,7 +152,8 @@ static void subdiv_ccg_alloc_elements(SubdivCCG *subdiv_ccg, Subdiv *subdiv)
if (num_faces) {
subdiv_ccg->faces = static_cast<SubdivCCGFace *>(
MEM_calloc_arrayN(num_faces, sizeof(SubdivCCGFace), "Subdiv CCG faces"));
subdiv_ccg->grid_faces.reinitialize(num_grids);
subdiv_ccg->grid_faces = static_cast<SubdivCCGFace **>(
MEM_calloc_arrayN(num_grids, sizeof(SubdivCCGFace *), "Subdiv CCG grid faces"));
}
}
@ -231,7 +232,7 @@ static void subdiv_ccg_eval_regular_grid(CCGEvalGridsData *data, const int face_
const float grid_size_1_inv = 1.0f / (grid_size - 1);
const int element_size = element_size_bytes_get(subdiv_ccg);
SubdivCCGFace *faces = subdiv_ccg->faces;
blender::MutableSpan<int> grid_faces = subdiv_ccg->grid_faces;
SubdivCCGFace **grid_faces = subdiv_ccg->grid_faces;
const SubdivCCGFace *face = &faces[face_index];
for (int corner = 0; corner < face->num_grids; corner++) {
const int grid_index = face->start_grid_index + corner;
@ -248,7 +249,7 @@ static void subdiv_ccg_eval_regular_grid(CCGEvalGridsData *data, const int face_
}
}
/* Assign grid's face. */
grid_faces[grid_index] = face_index;
grid_faces[grid_index] = &faces[face_index];
/* Assign material flags. */
subdiv_ccg->grid_flag_mats[grid_index] = data->material_flags_evaluator->eval_material_flags(
data->material_flags_evaluator, face_index);
@ -262,7 +263,7 @@ static void subdiv_ccg_eval_special_grid(CCGEvalGridsData *data, const int face_
const float grid_size_1_inv = 1.0f / (grid_size - 1);
const int element_size = element_size_bytes_get(subdiv_ccg);
SubdivCCGFace *faces = subdiv_ccg->faces;
blender::MutableSpan<int> grid_faces = subdiv_ccg->grid_faces;
SubdivCCGFace **grid_faces = subdiv_ccg->grid_faces;
const SubdivCCGFace *face = &faces[face_index];
for (int corner = 0; corner < face->num_grids; corner++) {
const int grid_index = face->start_grid_index + corner;
@ -278,7 +279,7 @@ static void subdiv_ccg_eval_special_grid(CCGEvalGridsData *data, const int face_
}
}
/* Assign grid's face. */
grid_faces[grid_index] = face_index;
grid_faces[grid_index] = &faces[face_index];
/* Assign material flags. */
subdiv_ccg->grid_flag_mats[grid_index] = data->material_flags_evaluator->eval_material_flags(
data->material_flags_evaluator, face_index);
@ -572,7 +573,7 @@ SubdivCCG *BKE_subdiv_to_ccg(Subdiv *subdiv,
SubdivCCGMaterialFlagsEvaluator *material_flags_evaluator)
{
BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_CCG);
SubdivCCG *subdiv_ccg = MEM_new<SubdivCCG>(__func__);
SubdivCCG *subdiv_ccg = MEM_cnew<SubdivCCG>(__func__);
subdiv_ccg->subdiv = subdiv;
subdiv_ccg->level = bitscan_forward_i(settings->resolution - 1);
subdiv_ccg->grid_size = BKE_subdiv_grid_size_from_level(subdiv_ccg->level);
@ -639,6 +640,7 @@ void BKE_subdiv_ccg_destroy(SubdivCCG *subdiv_ccg)
BKE_subdiv_free(subdiv_ccg->subdiv);
}
MEM_SAFE_FREE(subdiv_ccg->faces);
MEM_SAFE_FREE(subdiv_ccg->grid_faces);
/* Free map of adjacent edges. */
for (int i = 0; i < subdiv_ccg->num_adjacent_edges; i++) {
SubdivCCGAdjacentEdge *adjacent_edge = &subdiv_ccg->adjacent_edges[i];
@ -655,7 +657,7 @@ void BKE_subdiv_ccg_destroy(SubdivCCG *subdiv_ccg)
}
MEM_SAFE_FREE(subdiv_ccg->adjacent_vertices);
MEM_SAFE_FREE(subdiv_ccg->cache_.start_face_grid_index);
MEM_delete(subdiv_ccg);
MEM_freeN(subdiv_ccg);
}
void BKE_subdiv_ccg_key(CCGKey *key, const SubdivCCG *subdiv_ccg, int level)
@ -684,20 +686,32 @@ void BKE_subdiv_ccg_key_top_level(CCGKey *key, const SubdivCCG *subdiv_ccg)
/** \name Normals
* \{ */
struct RecalcInnerNormalsData {
SubdivCCG *subdiv_ccg;
CCGKey *key;
};
struct RecalcInnerNormalsTLSData {
float (*face_normals)[3];
};
/* Evaluate high-res face normals, for faces which corresponds to grid elements
*
* {(x, y), {x + 1, y}, {x + 1, y + 1}, {x, y + 1}}
*
* The result is stored in normals storage from TLS. */
static void subdiv_ccg_recalc_inner_face_normals(
SubdivCCG *subdiv_ccg,
CCGKey *key,
blender::MutableSpan<blender::float3> face_normals,
const int grid_index)
static void subdiv_ccg_recalc_inner_face_normals(SubdivCCG *subdiv_ccg,
CCGKey *key,
RecalcInnerNormalsTLSData *tls,
const int grid_index)
{
const int grid_size = subdiv_ccg->grid_size;
const int grid_size_1 = grid_size - 1;
CCGElem *grid = subdiv_ccg->grids[grid_index];
if (tls->face_normals == nullptr) {
tls->face_normals = static_cast<float(*)[3]>(
MEM_malloc_arrayN(grid_size_1 * grid_size_1, sizeof(float[3]), "CCG TLS normals"));
}
for (int y = 0; y < grid_size - 1; y++) {
for (int x = 0; x < grid_size - 1; x++) {
CCGElem *grid_elements[4] = {
@ -713,22 +727,22 @@ static void subdiv_ccg_recalc_inner_face_normals(
CCG_elem_co(key, grid_elements[3]),
};
const int face_index = y * grid_size_1 + x;
float *face_normal = face_normals[face_index];
float *face_normal = tls->face_normals[face_index];
normal_quad_v3(face_normal, co[0], co[1], co[2], co[3]);
}
}
}
/* Average normals at every grid element, using adjacent faces normals. */
static void subdiv_ccg_average_inner_face_normals(
SubdivCCG *subdiv_ccg,
CCGKey *key,
const blender::Span<blender::float3> face_normals,
const int grid_index)
static void subdiv_ccg_average_inner_face_normals(SubdivCCG *subdiv_ccg,
CCGKey *key,
RecalcInnerNormalsTLSData *tls,
const int grid_index)
{
const int grid_size = subdiv_ccg->grid_size;
const int grid_size_1 = grid_size - 1;
CCGElem *grid = subdiv_ccg->grids[grid_index];
const float(*face_normals)[3] = tls->face_normals;
for (int y = 0; y < grid_size; y++) {
for (int x = 0; x < grid_size; x++) {
float normal_acc[3] = {0.0f, 0.0f, 0.0f};
@ -758,25 +772,42 @@ static void subdiv_ccg_average_inner_face_normals(
}
}
static void subdiv_ccg_recalc_inner_normal_task(void *__restrict userdata_v,
const int grid_index,
const TaskParallelTLS *__restrict tls_v)
{
RecalcInnerNormalsData *data = static_cast<RecalcInnerNormalsData *>(userdata_v);
RecalcInnerNormalsTLSData *tls = static_cast<RecalcInnerNormalsTLSData *>(tls_v->userdata_chunk);
subdiv_ccg_recalc_inner_face_normals(data->subdiv_ccg, data->key, tls, grid_index);
subdiv_ccg_average_inner_face_normals(data->subdiv_ccg, data->key, tls, grid_index);
}
static void subdiv_ccg_recalc_inner_normal_free(const void *__restrict /*userdata*/,
void *__restrict tls_v)
{
RecalcInnerNormalsTLSData *tls = static_cast<RecalcInnerNormalsTLSData *>(tls_v);
MEM_SAFE_FREE(tls->face_normals);
}
/* Recalculate normals which corresponds to non-boundaries elements of grids. */
static void subdiv_ccg_recalc_inner_grid_normals(SubdivCCG *subdiv_ccg)
{
using namespace blender;
const int grid_size_1 = subdiv_ccg->grid_size - 1;
threading::EnumerableThreadSpecific<Array<float3>> face_normals_tls(
[&]() { return Array<float3>(grid_size_1 * grid_size_1); });
CCGKey key;
BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
threading::parallel_for(IndexRange(subdiv_ccg->num_grids), 512, [&](const IndexRange range) {
MutableSpan<float3> face_normals = face_normals_tls.local();
for (const int grid_index : range) {
subdiv_ccg_recalc_inner_face_normals(subdiv_ccg, &key, face_normals, grid_index);
subdiv_ccg_average_inner_face_normals(subdiv_ccg, &key, face_normals, grid_index);
}
});
RecalcInnerNormalsData data{};
data.subdiv_ccg = subdiv_ccg;
data.key = &key;
RecalcInnerNormalsTLSData tls_data = {nullptr};
TaskParallelSettings parallel_range_settings;
BLI_parallel_range_settings_defaults(&parallel_range_settings);
parallel_range_settings.userdata_chunk = &tls_data;
parallel_range_settings.userdata_chunk_size = sizeof(tls_data);
parallel_range_settings.func_free = subdiv_ccg_recalc_inner_normal_free;
BLI_task_parallel_range(0,
subdiv_ccg->num_grids,
&data,
subdiv_ccg_recalc_inner_normal_task,
&parallel_range_settings);
}
void BKE_subdiv_ccg_recalc_normals(SubdivCCG *subdiv_ccg)
@ -789,48 +820,80 @@ void BKE_subdiv_ccg_recalc_normals(SubdivCCG *subdiv_ccg)
BKE_subdiv_ccg_average_grids(subdiv_ccg);
}
static void subdiv_ccg_recalc_modified_inner_grid_normals(SubdivCCG *subdiv_ccg,
const blender::IndexMask &face_mask)
struct RecalcModifiedInnerNormalsData {
SubdivCCG *subdiv_ccg;
CCGKey *key;
SubdivCCGFace **effected_ccg_faces;
};
static void subdiv_ccg_recalc_modified_inner_normal_task(void *__restrict userdata_v,
const int face_index,
const TaskParallelTLS *__restrict tls_v)
{
using namespace blender;
const int grid_size_1 = subdiv_ccg->grid_size - 1;
threading::EnumerableThreadSpecific<Array<float3>> face_normals_tls(
[&]() { return Array<float3>(grid_size_1 * grid_size_1); });
CCGKey key;
BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
const SubdivCCGFace *faces = subdiv_ccg->faces;
face_mask.foreach_segment(GrainSize(512), [&](const IndexMaskSegment segment) {
MutableSpan<float3> face_normals = face_normals_tls.local();
for (const int face_index : segment) {
const SubdivCCGFace &face = faces[face_index];
const int num_face_grids = face.num_grids;
for (int i = 0; i < num_face_grids; i++) {
const int grid_index = face.start_grid_index + i;
subdiv_ccg_recalc_inner_face_normals(subdiv_ccg, &key, face_normals, grid_index);
subdiv_ccg_average_inner_face_normals(subdiv_ccg, &key, face_normals, grid_index);
}
}
});
RecalcModifiedInnerNormalsData *data = static_cast<RecalcModifiedInnerNormalsData *>(userdata_v);
SubdivCCG *subdiv_ccg = data->subdiv_ccg;
CCGKey *key = data->key;
RecalcInnerNormalsTLSData *tls = static_cast<RecalcInnerNormalsTLSData *>(tls_v->userdata_chunk);
SubdivCCGFace **faces = data->effected_ccg_faces;
SubdivCCGFace *face = faces[face_index];
const int num_face_grids = face->num_grids;
for (int i = 0; i < num_face_grids; i++) {
const int grid_index = face->start_grid_index + i;
subdiv_ccg_recalc_inner_face_normals(data->subdiv_ccg, data->key, tls, grid_index);
subdiv_ccg_average_inner_face_normals(data->subdiv_ccg, data->key, tls, grid_index);
}
subdiv_ccg_average_inner_face_grids(subdiv_ccg, key, face);
}
void BKE_subdiv_ccg_update_normals(SubdivCCG *subdiv_ccg, const blender::IndexMask &face_mask)
static void subdiv_ccg_recalc_modified_inner_normal_free(const void *__restrict /*userdata*/,
void *__restrict tls_v)
{
RecalcInnerNormalsTLSData *tls = static_cast<RecalcInnerNormalsTLSData *>(tls_v);
MEM_SAFE_FREE(tls->face_normals);
}
static void subdiv_ccg_recalc_modified_inner_grid_normals(SubdivCCG *subdiv_ccg,
CCGFace **effected_faces,
int num_effected_faces)
{
CCGKey key;
BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
RecalcModifiedInnerNormalsData data{};
data.subdiv_ccg = subdiv_ccg;
data.key = &key;
data.effected_ccg_faces = (SubdivCCGFace **)effected_faces;
RecalcInnerNormalsTLSData tls_data = {nullptr};
TaskParallelSettings parallel_range_settings;
BLI_parallel_range_settings_defaults(&parallel_range_settings);
parallel_range_settings.userdata_chunk = &tls_data;
parallel_range_settings.userdata_chunk_size = sizeof(tls_data);
parallel_range_settings.func_free = subdiv_ccg_recalc_modified_inner_normal_free;
BLI_task_parallel_range(0,
num_effected_faces,
&data,
subdiv_ccg_recalc_modified_inner_normal_task,
&parallel_range_settings);
}
void BKE_subdiv_ccg_update_normals(SubdivCCG *subdiv_ccg,
CCGFace **effected_faces,
int num_effected_faces)
{
if (!subdiv_ccg->has_normal) {
/* Grids don't have normals, can do early output. */
return;
}
if (face_mask.is_empty()) {
if (num_effected_faces == 0) {
/* No faces changed, so nothing to do here. */
return;
}
subdiv_ccg_recalc_modified_inner_grid_normals(subdiv_ccg, face_mask);
subdiv_ccg_recalc_modified_inner_grid_normals(subdiv_ccg, effected_faces, num_effected_faces);
CCGKey key;
BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
subdiv_ccg_average_faces_boundaries_and_corners(subdiv_ccg, &key, face_mask);
subdiv_ccg_average_faces_boundaries_and_corners(
subdiv_ccg, &key, effected_faces, num_effected_faces);
}
/** \} */
@ -1164,7 +1227,8 @@ void BKE_subdiv_ccg_average_grids(SubdivCCG *subdiv_ccg)
}
static void subdiv_ccg_affected_face_adjacency(SubdivCCG *subdiv_ccg,
const blender::IndexMask &face_mask,
CCGFace **effected_faces,
int num_effected_faces,
GSet *r_adjacent_vertices,
GSet *r_adjacent_edges)
{
@ -1177,8 +1241,9 @@ static void subdiv_ccg_affected_face_adjacency(SubdivCCG *subdiv_ccg,
static_or_heap_storage_init(&face_vertices_storage);
static_or_heap_storage_init(&face_edges_storage);
face_mask.foreach_index([&](const int face_index) {
SubdivCCGFace *face = &subdiv_ccg->faces[face_index];
for (int i = 0; i < num_effected_faces; i++) {
SubdivCCGFace *face = (SubdivCCGFace *)effected_faces[i];
int face_index = face - subdiv_ccg->faces;
const int num_face_grids = face->num_grids;
const int num_face_edges = num_face_grids;
int *face_vertices = static_or_heap_storage_get(&face_vertices_storage, num_face_edges);
@ -1201,7 +1266,7 @@ static void subdiv_ccg_affected_face_adjacency(SubdivCCG *subdiv_ccg,
SubdivCCGAdjacentVertex *adjacent_vertex = &subdiv_ccg->adjacent_vertices[vertex_index];
BLI_gset_add(r_adjacent_vertices, adjacent_vertex);
}
});
}
static_or_heap_storage_free(&face_vertices_storage);
static_or_heap_storage_free(&face_edges_storage);
@ -1209,13 +1274,15 @@ static void subdiv_ccg_affected_face_adjacency(SubdivCCG *subdiv_ccg,
void subdiv_ccg_average_faces_boundaries_and_corners(SubdivCCG *subdiv_ccg,
CCGKey *key,
const blender::IndexMask &face_mask)
CCGFace **effected_faces,
int num_effected_faces)
{
GSet *adjacent_vertices = BLI_gset_ptr_new(__func__);
GSet *adjacent_edges = BLI_gset_ptr_new(__func__);
GSetIterator gi;
subdiv_ccg_affected_face_adjacency(subdiv_ccg, face_mask, adjacent_vertices, adjacent_edges);
subdiv_ccg_affected_face_adjacency(
subdiv_ccg, effected_faces, num_effected_faces, adjacent_vertices, adjacent_edges);
int *adjacent_vertex_index_map;
int *adjacent_edge_index_map;
@ -1253,17 +1320,42 @@ void subdiv_ccg_average_faces_boundaries_and_corners(SubdivCCG *subdiv_ccg,
static_or_heap_storage_free(&index_heap);
}
void BKE_subdiv_ccg_average_stitch_faces(SubdivCCG *subdiv_ccg,
const blender::IndexMask &face_mask)
struct StitchFacesInnerGridsData {
SubdivCCG *subdiv_ccg;
CCGKey *key;
CCGFace **effected_ccg_faces;
};
static void subdiv_ccg_stitch_face_inner_grids_task(void *__restrict userdata_v,
const int face_index,
const TaskParallelTLS *__restrict /*tls_v*/)
{
StitchFacesInnerGridsData *data = static_cast<StitchFacesInnerGridsData *>(userdata_v);
SubdivCCG *subdiv_ccg = data->subdiv_ccg;
CCGKey *key = data->key;
CCGFace **effected_ccg_faces = data->effected_ccg_faces;
CCGFace *effected_ccg_face = effected_ccg_faces[face_index];
SubdivCCGFace *face = (SubdivCCGFace *)effected_ccg_face;
subdiv_ccg_average_inner_face_grids(subdiv_ccg, key, face);
}
void BKE_subdiv_ccg_average_stitch_faces(SubdivCCG *subdiv_ccg,
CCGFace **effected_faces,
int num_effected_faces)
{
using namespace blender;
CCGKey key;
BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
face_mask.foreach_index(GrainSize(512), [&](const int face_index) {
subdiv_ccg_average_inner_face_grids(subdiv_ccg, &key, &subdiv_ccg->faces[face_index]);
});
StitchFacesInnerGridsData data{};
data.subdiv_ccg = subdiv_ccg;
data.key = &key;
data.effected_ccg_faces = effected_faces;
TaskParallelSettings parallel_range_settings;
BLI_parallel_range_settings_defaults(&parallel_range_settings);
BLI_task_parallel_range(0,
num_effected_faces,
&data,
subdiv_ccg_stitch_face_inner_grids_task,
&parallel_range_settings);
/* TODO(sergey): Only average elements which are adjacent to modified
* faces. */
subdiv_ccg_average_all_boundaries_and_corners(subdiv_ccg, &key);
@ -1421,7 +1513,7 @@ static SubdivCCGCoord coord_step_inside_from_boundary(const SubdivCCG *subdiv_cc
BLI_INLINE
int next_grid_index_from_coord(const SubdivCCG *subdiv_ccg, const SubdivCCGCoord *coord)
{
SubdivCCGFace *face = &subdiv_ccg->faces[subdiv_ccg->grid_faces[coord->grid_index]];
SubdivCCGFace *face = subdiv_ccg->grid_faces[coord->grid_index];
const int face_grid_index = coord->grid_index;
int next_face_grid_index = face_grid_index + 1 - face->start_grid_index;
if (next_face_grid_index == face->num_grids) {
@ -1431,7 +1523,7 @@ int next_grid_index_from_coord(const SubdivCCG *subdiv_ccg, const SubdivCCGCoord
}
BLI_INLINE int prev_grid_index_from_coord(const SubdivCCG *subdiv_ccg, const SubdivCCGCoord *coord)
{
SubdivCCGFace *face = &subdiv_ccg->faces[subdiv_ccg->grid_faces[coord->grid_index]];
SubdivCCGFace *face = subdiv_ccg->grid_faces[coord->grid_index];
const int face_grid_index = coord->grid_index;
int prev_face_grid_index = face_grid_index - 1 - face->start_grid_index;
if (prev_face_grid_index < 0) {
@ -1447,7 +1539,7 @@ static void neighbor_coords_corner_center_get(const SubdivCCG *subdiv_ccg,
const bool include_duplicates,
SubdivCCGNeighbors *r_neighbors)
{
const SubdivCCGFace *face = &subdiv_ccg->faces[subdiv_ccg->grid_faces[coord->grid_index]];
SubdivCCGFace *face = subdiv_ccg->grid_faces[coord->grid_index];
const int num_adjacent_grids = face->num_grids;
subdiv_ccg_neighbors_init(
@ -1475,7 +1567,7 @@ static int adjacent_vertex_index_from_coord(const SubdivCCG *subdiv_ccg,
Subdiv *subdiv = subdiv_ccg->subdiv;
OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner;
const SubdivCCGFace *face = &subdiv_ccg->faces[subdiv_ccg->grid_faces[coord->grid_index]];
const SubdivCCGFace *face = subdiv_ccg->grid_faces[coord->grid_index];
const int face_index = face - subdiv_ccg->faces;
const int face_grid_index = coord->grid_index - face->start_grid_index;
const int num_face_grids = face->num_grids;
@ -1562,7 +1654,7 @@ static int adjacent_edge_index_from_coord(const SubdivCCG *subdiv_ccg, const Sub
{
Subdiv *subdiv = subdiv_ccg->subdiv;
OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner;
const SubdivCCGFace *face = &subdiv_ccg->faces[subdiv_ccg->grid_faces[coord->grid_index]];
SubdivCCGFace *face = subdiv_ccg->grid_faces[coord->grid_index];
const int face_grid_index = coord->grid_index - face->start_grid_index;
const int face_index = face - subdiv_ccg->faces;
@ -1859,7 +1951,9 @@ void BKE_subdiv_ccg_neighbor_coords_get(const SubdivCCG *subdiv_ccg,
int BKE_subdiv_ccg_grid_to_face_index(const SubdivCCG *subdiv_ccg, const int grid_index)
{
return subdiv_ccg->grid_faces[grid_index];
const SubdivCCGFace *face = subdiv_ccg->grid_faces[grid_index];
const int face_index = face - subdiv_ccg->faces;
return face_index;
}
const int *BKE_subdiv_ccg_start_face_grid_index_ensure(SubdivCCG *subdiv_ccg)

View File

@ -4103,35 +4103,29 @@ void BLO_main_expander(BLOExpandDoitCallback expand_doit_func)
void BLO_expand_main(void *fdhandle, Main *mainvar)
{
ListBase *lbarray[INDEX_ID_MAX];
FileData *fd = static_cast<FileData *>(fdhandle);
ID *id;
int a;
bool do_it = true;
BlendExpander expander = {fd, mainvar};
while (do_it) {
for (bool do_it = true; do_it;) {
do_it = false;
ID *id_iter;
a = set_listbasepointers(mainvar, lbarray);
while (a--) {
id = static_cast<ID *>(lbarray[a]->first);
while (id) {
if (id->tag & LIB_TAG_NEED_EXPAND) {
expand_id(&expander, id);
const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(id);
if (id_type->blend_read_expand != nullptr) {
id_type->blend_read_expand(&expander, id);
}
do_it = true;
id->tag &= ~LIB_TAG_NEED_EXPAND;
}
id = static_cast<ID *>(id->next);
FOREACH_MAIN_ID_BEGIN (mainvar, id_iter) {
if ((id_iter->tag & LIB_TAG_NEED_EXPAND) == 0) {
continue;
}
expand_id(&expander, id_iter);
const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(id_iter);
if (id_type->blend_read_expand != nullptr) {
id_type->blend_read_expand(&expander, id_iter);
}
do_it = true;
id_iter->tag &= ~LIB_TAG_NEED_EXPAND;
}
FOREACH_MAIN_ID_END;
}
}

View File

@ -101,6 +101,7 @@
#include "BLT_translation.h"
#include "BLO_read_write.h"
#include "BLO_readfile.h"
#include "readfile.h"
@ -2913,6 +2914,22 @@ void do_versions_after_linking_280(FileData *fd, Main *bmain)
brush->disconnected_distance_max = 0.1f;
}
}
/* 2.8x dropped support for non-empty dupli instances. but propoer do-versionning was never
* done correctly. So added here as a 'safe' place version wise, always better than in
* readfile lib-linking code! */
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
if (ob->type != OB_EMPTY && ob->instance_collection != nullptr) {
BLO_reportf_wrap(fd->reports,
RPT_INFO,
TIP_("Non-Empty object '%s' cannot duplicate collection '%s' "
"anymore in Blender 2.80 and later, removed instancing"),
ob->id.name + 2,
ob->instance_collection->id.name + 2);
ob->instance_collection = nullptr;
ob->transflag &= ~OB_DUPLICOLLECTION;
}
}
}
/**

View File

@ -38,6 +38,9 @@
#include "BKE_scene.h"
#include "BKE_tracking.h"
#include "BLT_translation.h"
#include "BLO_read_write.h"
#include "BLO_readfile.h"
#include "readfile.h"
@ -46,7 +49,7 @@
// static CLG_LogRef LOG = {"blo.readfile.doversion"};
void do_versions_after_linking_400(FileData * /*fd*/, Main *bmain)
void do_versions_after_linking_400(FileData *fd, Main *bmain)
{
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 9)) {
/* Fix area light scaling. */
@ -56,6 +59,37 @@ void do_versions_after_linking_400(FileData * /*fd*/, Main *bmain)
light->energy *= M_PI_4;
}
}
/* Object proxies have been deprecated sine 3.x era, so their update & sanity check can now
* happen in do_versions code. */
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
if (ob->proxy) {
/* Paranoia check, actually a proxy_from pointer should never be written... */
if (!ID_IS_LINKED(ob->proxy)) {
ob->proxy->proxy_from = nullptr;
ob->proxy = nullptr;
if (ob->id.lib) {
BLO_reportf_wrap(fd->reports,
RPT_INFO,
TIP_("Proxy lost from object %s lib %s\n"),
ob->id.name + 2,
ob->id.lib->filepath);
}
else {
BLO_reportf_wrap(fd->reports,
RPT_INFO,
TIP_("Proxy lost from object %s lib <NONE>\n"),
ob->id.name + 2);
}
fd->reports->count.missing_obproxies++;
}
else {
/* This triggers object_update to always use a copy. */
ob->proxy->proxy_from = ob;
}
}
}
}
/**

View File

@ -8,7 +8,7 @@ void main()
lightprobe_vert_iface.instance = gl_VertexID / 3;
#ifdef GPU_METAL
MTLRenderTargetArrayIndex = lightprobe_vert_iface.instance;
gpu_Layer = lightprobe_vert_iface.instance;
lightprobe_geom_iface.layer = float(lightprobe_vert_iface.instance);
gl_Position = vec4(lightprobe_vert_iface.vPos, 0.0, 1.0);
#endif

View File

@ -30,6 +30,6 @@ void main()
#ifdef GPU_METAL
/* In the Metal API, gl_Layer equivalent is specified in the vertex shader for multilayered
* rendering support. */
MTLRenderTargetArrayIndex = Layer + geom_iface.fFace;
gpu_Layer = Layer + geom_iface.fFace;
#endif
}

View File

@ -29,7 +29,7 @@ void main()
#ifdef GPU_METAL
volumetric_geom_iface.slice = int(volumetric_vert_iface.vPos.z);
MTLRenderTargetArrayIndex = int(volumetric_vert_iface.vPos.z);
gpu_Layer = int(volumetric_vert_iface.vPos.z);
gl_Position = volumetric_vert_iface.vPos.xyww;
#endif
}

View File

@ -50,7 +50,8 @@ vec3 lightprobe_irradiance_grid_bias_sample_coord(IrradianceGridData grid_data,
/* NOTE(fclem): Use uint to avoid signed int modulo. */
uint vis_comp = uint(cell_start.z) % 4u;
/* Visibility is stored after the irradiance. */
ivec3 vis_coord = ivec3(brick_atlas_coord, IRRADIANCE_GRID_BRICK_SIZE * 4) + ivec3(cell_start);
ivec3 vis_coord = ivec3(ivec2(brick_atlas_coord), IRRADIANCE_GRID_BRICK_SIZE * 4) +
ivec3(cell_start);
/* Visibility is stored packed 1 cell per channel. */
vis_coord.z -= int(vis_comp);
float cell_visibility = texelFetch(irradiance_atlas_tx, vis_coord, 0)[vis_comp];

View File

@ -168,7 +168,7 @@ static bool menu_items_from_ui_create_item_from_button(MenuSearch_Data *data,
MenuSearch_Item *item = nullptr;
/* Use override if the name is empty, this can happen with popovers. */
std::string drawstr_override = nullptr;
std::string drawstr_override;
const char *drawstr_sep = (but->flag & UI_BUT_HAS_SEP_CHAR) ?
strrchr(but->drawstr, UI_SEP_CHAR) :
nullptr;

View File

@ -451,7 +451,7 @@ static int view_scrollright_exec(bContext *C, wmOperator *op)
}
/* set RNA-Props - only movement in positive x-direction */
RNA_int_set(op->ptr, "deltax", 40);
RNA_int_set(op->ptr, "deltax", 40 * UI_SCALE_FAC);
RNA_int_set(op->ptr, "deltay", 0);
/* apply movement, then we're done */
@ -491,7 +491,7 @@ static int view_scrollleft_exec(bContext *C, wmOperator *op)
}
/* set RNA-Props - only movement in negative x-direction */
RNA_int_set(op->ptr, "deltax", -40);
RNA_int_set(op->ptr, "deltax", -40 * UI_SCALE_FAC);
RNA_int_set(op->ptr, "deltay", 0);
/* apply movement, then we're done */
@ -536,7 +536,7 @@ static int view_scrolldown_exec(bContext *C, wmOperator *op)
/* set RNA-Props */
RNA_int_set(op->ptr, "deltax", 0);
RNA_int_set(op->ptr, "deltay", -40);
RNA_int_set(op->ptr, "deltay", -40 * UI_SCALE_FAC);
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "page");
const bool use_page_size = (vpd->v2d->flag & V2D_SNAP_TO_PAGESIZE_Y) ||
@ -591,7 +591,7 @@ static int view_scrollup_exec(bContext *C, wmOperator *op)
/* set RNA-Props */
RNA_int_set(op->ptr, "deltax", 0);
RNA_int_set(op->ptr, "deltay", 40);
RNA_int_set(op->ptr, "deltay", 40 * UI_SCALE_FAC);
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "page");
const bool use_page_size = (vpd->v2d->flag & V2D_SNAP_TO_PAGESIZE_Y) ||

View File

@ -120,13 +120,6 @@ extern "C" eAttrDomain BKE_id_attribute_domain(const struct ID * /*id*/,
/* -------------------------------------------------------------------- */
/** \name Stubs of BKE_paint.hh
* \{ */
bool paint_is_face_hidden(const int * /*looptri_faces*/,
const bool * /*hide_poly*/,
int /*tri_index*/)
{
BLI_assert_unreachable();
return false;
}
void BKE_paint_face_set_overlay_color_get(const int /*face_set*/,
const int /*seed*/,

View File

@ -515,10 +515,11 @@ struct MTLContextGlobalShaderPipelineState {
MTLContextDepthStencilState depth_stencil_state;
/* Viewport/Scissor Region. */
int viewport_offset_x;
int viewport_offset_y;
int viewport_width;
int viewport_height;
int num_active_viewports = 1;
int viewport_offset_x[GPU_MAX_VIEWPORTS];
int viewport_offset_y[GPU_MAX_VIEWPORTS];
int viewport_width[GPU_MAX_VIEWPORTS];
int viewport_height[GPU_MAX_VIEWPORTS];
bool scissor_enabled;
int scissor_x;
int scissor_y;
@ -862,6 +863,7 @@ class MTLContext : public Context {
/* State assignment. */
void set_viewport(int origin_x, int origin_y, int width, int height);
void set_viewports(int count, const int (&viewports)[GPU_MAX_VIEWPORTS][4]);
void set_scissor(int scissor_x, int scissor_y, int scissor_width, int scissor_height);
void set_scissor_enabled(bool scissor_enabled);

View File

@ -751,10 +751,12 @@ void MTLContext::pipeline_state_init()
this->pipeline_state.src_rgb_blend_factor = MTLBlendFactorOne;
/* Viewport and scissor. */
this->pipeline_state.viewport_offset_x = 0;
this->pipeline_state.viewport_offset_y = 0;
this->pipeline_state.viewport_width = 0;
this->pipeline_state.viewport_height = 0;
for (int v = 0; v < GPU_MAX_VIEWPORTS; v++) {
this->pipeline_state.viewport_offset_x[v] = 0;
this->pipeline_state.viewport_offset_y[v] = 0;
this->pipeline_state.viewport_width[v] = 0;
this->pipeline_state.viewport_height[v] = 0;
}
this->pipeline_state.scissor_x = 0;
this->pipeline_state.scissor_y = 0;
this->pipeline_state.scissor_width = 0;
@ -804,14 +806,46 @@ void MTLContext::set_viewport(int origin_x, int origin_y, int width, int height)
BLI_assert(height > 0);
BLI_assert(origin_x >= 0);
BLI_assert(origin_y >= 0);
bool changed = (this->pipeline_state.viewport_offset_x != origin_x) ||
(this->pipeline_state.viewport_offset_y != origin_y) ||
(this->pipeline_state.viewport_width != width) ||
(this->pipeline_state.viewport_height != height);
this->pipeline_state.viewport_offset_x = origin_x;
this->pipeline_state.viewport_offset_y = origin_y;
this->pipeline_state.viewport_width = width;
this->pipeline_state.viewport_height = height;
bool changed = (this->pipeline_state.viewport_offset_x[0] != origin_x) ||
(this->pipeline_state.viewport_offset_y[0] != origin_y) ||
(this->pipeline_state.viewport_width[0] != width) ||
(this->pipeline_state.viewport_height[0] != height) ||
(this->pipeline_state.num_active_viewports != 1);
this->pipeline_state.viewport_offset_x[0] = origin_x;
this->pipeline_state.viewport_offset_y[0] = origin_y;
this->pipeline_state.viewport_width[0] = width;
this->pipeline_state.viewport_height[0] = height;
this->pipeline_state.num_active_viewports = 1;
if (changed) {
this->pipeline_state.dirty_flags = (this->pipeline_state.dirty_flags |
MTL_PIPELINE_STATE_VIEWPORT_FLAG);
}
}
void MTLContext::set_viewports(int count, const int (&viewports)[GPU_MAX_VIEWPORTS][4])
{
BLI_assert(this);
bool changed = (this->pipeline_state.num_active_viewports != count);
for (int v = 0; v < count; v++) {
const int(&viewport_info)[4] = viewports[v];
BLI_assert(viewport_info[0] >= 0);
BLI_assert(viewport_info[1] >= 0);
BLI_assert(viewport_info[2] > 0);
BLI_assert(viewport_info[3] > 0);
changed = changed || (this->pipeline_state.viewport_offset_x[v] != viewport_info[0]) ||
(this->pipeline_state.viewport_offset_y[v] != viewport_info[1]) ||
(this->pipeline_state.viewport_width[v] != viewport_info[2]) ||
(this->pipeline_state.viewport_height[v] != viewport_info[3]);
this->pipeline_state.viewport_offset_x[v] = viewport_info[0];
this->pipeline_state.viewport_offset_y[v] = viewport_info[1];
this->pipeline_state.viewport_width[v] = viewport_info[2];
this->pipeline_state.viewport_height[v] = viewport_info[3];
}
this->pipeline_state.num_active_viewports = count;
if (changed) {
this->pipeline_state.dirty_flags = (this->pipeline_state.dirty_flags |
MTL_PIPELINE_STATE_VIEWPORT_FLAG);
@ -989,18 +1023,30 @@ bool MTLContext::ensure_render_pipeline_state(MTLPrimitiveType mtl_prim_type)
/** Dynamic Per-draw Render State on RenderCommandEncoder. */
/* State: Viewport. */
if (this->pipeline_state.dirty_flags & MTL_PIPELINE_STATE_VIEWPORT_FLAG) {
if (this->pipeline_state.num_active_viewports > 1) {
/* Multiple Viewports. */
MTLViewport viewports[GPU_MAX_VIEWPORTS];
for (int v = 0; v < this->pipeline_state.num_active_viewports; v++) {
MTLViewport &viewport = viewports[v];
viewport.originX = (double)this->pipeline_state.viewport_offset_x[v];
viewport.originY = (double)this->pipeline_state.viewport_offset_y[v];
viewport.width = (double)this->pipeline_state.viewport_width[v];
viewport.height = (double)this->pipeline_state.viewport_height[v];
viewport.znear = this->pipeline_state.depth_stencil_state.depth_range_near;
viewport.zfar = this->pipeline_state.depth_stencil_state.depth_range_far;
}
[rec setViewports:viewports count:this->pipeline_state.num_active_viewports];
}
else {
/* Single Viewport. */
MTLViewport viewport;
viewport.originX = (double)this->pipeline_state.viewport_offset_x;
viewport.originY = (double)this->pipeline_state.viewport_offset_y;
viewport.width = (double)this->pipeline_state.viewport_width;
viewport.height = (double)this->pipeline_state.viewport_height;
viewport.originX = (double)this->pipeline_state.viewport_offset_x[0];
viewport.originY = (double)this->pipeline_state.viewport_offset_y[0];
viewport.width = (double)this->pipeline_state.viewport_width[0];
viewport.height = (double)this->pipeline_state.viewport_height[0];
viewport.znear = this->pipeline_state.depth_stencil_state.depth_range_near;
viewport.zfar = this->pipeline_state.depth_stencil_state.depth_range_far;
[rec setViewport:viewport];
this->pipeline_state.dirty_flags = (this->pipeline_state.dirty_flags &
~MTL_PIPELINE_STATE_VIEWPORT_FLAG);
}
/* State: Scissor. */

View File

@ -789,7 +789,12 @@ void MTLFrameBuffer::apply_state()
}
/* Update Context State. */
mtl_ctx->set_viewport(viewport_[0][0], viewport_[0][1], viewport_w, viewport_h);
if (multi_viewport_) {
mtl_ctx->set_viewports(GPU_MAX_VIEWPORTS, viewport_);
}
else {
mtl_ctx->set_viewport(viewport_[0][0], viewport_[0][1], viewport_w, viewport_h);
}
mtl_ctx->set_scissor(scissor_[0], scissor_[1], scissor_[2], scissor_[3]);
mtl_ctx->set_scissor_enabled(scissor_test_);

View File

@ -198,7 +198,10 @@ class MTLShader : public Shader {
MTLComputePipelineStateInstance compute_pso_instance_;
/* True to enable multi-layered rendering support. */
bool uses_mtl_array_index_ = false;
bool uses_gpu_layer = false;
/* True to enable multi-viewport rendering support. */
bool uses_gpu_viewport_index = false;
/** SSBO Vertex fetch pragma options. */
/* Indicates whether to pass in VertexBuffer's as regular buffer bindings

View File

@ -806,7 +806,7 @@ MTLRenderPipelineStateInstance *MTLShader::bake_current_pipeline_state(
}
/* Primitive Type -- Primitive topology class needs to be specified for layered rendering. */
bool requires_specific_topology_class = uses_mtl_array_index_ ||
bool requires_specific_topology_class = uses_gpu_layer || uses_gpu_viewport_index ||
prim_type == MTLPrimitiveTopologyClassPoint;
pipeline_descriptor.vertex_descriptor.prim_topology_class =
(requires_specific_topology_class) ? prim_type : MTLPrimitiveTopologyClassUnspecified;

View File

@ -420,7 +420,8 @@ class MSLGeneratorInterface {
bool uses_gl_PrimitiveID;
/* Sets the output render target array index when using multilayered rendering. */
bool uses_gl_FragDepth;
bool uses_mtl_array_index_;
bool uses_gpu_layer;
bool uses_gpu_viewport_index;
bool uses_transform_feedback;
bool uses_barycentrics;
/* Compute shader global variables. */

View File

@ -973,9 +973,12 @@ bool MTLShader::generate_msl_from_glsl(const shader::ShaderCreateInfo *info)
std::string::npos;
msl_iface.uses_gl_PointSize = shd_builder_->glsl_vertex_source_.find("gl_PointSize") !=
std::string::npos;
msl_iface.uses_mtl_array_index_ = shd_builder_->glsl_vertex_source_.find(
"MTLRenderTargetArrayIndex") != std::string::npos;
msl_iface.uses_gpu_layer = bool(info->builtins_ & BuiltinBits::LAYER) ||
shd_builder_->glsl_vertex_source_.find("gpu_Layer") !=
std::string::npos;
msl_iface.uses_gpu_viewport_index = bool(info->builtins_ & BuiltinBits::VIEWPORT_INDEX) ||
shd_builder_->glsl_vertex_source_.find(
"gpu_ViewportIndex") != std::string::npos;
/** Identify usage of fragment-shader builtins. */
if (!msl_iface.uses_transform_feedback) {
std::smatch gl_special_cases;
@ -1173,8 +1176,11 @@ bool MTLShader::generate_msl_from_glsl(const shader::ShaderCreateInfo *info)
}
/* Render target array index if using multilayered rendering. */
if (msl_iface.uses_mtl_array_index_) {
ss_vertex << "int MTLRenderTargetArrayIndex = 0;" << std::endl;
if (msl_iface.uses_gpu_layer) {
ss_vertex << "int gpu_Layer = 0;" << std::endl;
}
if (msl_iface.uses_gpu_viewport_index) {
ss_vertex << "int gpu_ViewportIndex = 0;" << std::endl;
}
/* Global vertex data pointers when using SSBO vertex fetch mode.
@ -1304,6 +1310,14 @@ bool MTLShader::generate_msl_from_glsl(const shader::ShaderCreateInfo *info)
ss_fragment << "vec3 gpu_BaryCoord;\n";
}
/* Render target array index and viewport array index passed from vertex shader. */
if (msl_iface.uses_gpu_layer) {
ss_fragment << "int gpu_Layer = 0;" << std::endl;
}
if (msl_iface.uses_gpu_viewport_index) {
ss_fragment << "int gpu_ViewportIndex = 0;" << std::endl;
}
/* Add Texture members. */
for (const MSLTextureResource &tex : msl_iface.texture_samplers) {
if (bool(tex.stage & ShaderStage::FRAGMENT)) {
@ -1379,7 +1393,8 @@ bool MTLShader::generate_msl_from_glsl(const shader::ShaderCreateInfo *info)
this->set_interface(msl_iface.bake_shader_interface(this->name));
/* Update other shader properties. */
uses_mtl_array_index_ = msl_iface.uses_mtl_array_index_;
uses_gpu_layer = msl_iface.uses_gpu_layer;
uses_gpu_viewport_index = msl_iface.uses_gpu_viewport_index;
use_ssbo_vertex_fetch_mode_ = msl_iface.uses_ssbo_vertex_fetch_mode;
if (msl_iface.uses_ssbo_vertex_fetch_mode) {
ssbo_vertex_fetch_output_prim_type_ = vertex_fetch_ssbo_output_prim_type;
@ -2716,8 +2731,13 @@ std::string MSLGeneratorInterface::generate_msl_vertex_out_struct(ShaderStage sh
}
/* Add MTL render target array index for multilayered rendering support. */
if (uses_mtl_array_index_) {
out << "\tuint MTLRenderTargetArrayIndex [[render_target_array_index]];" << std::endl;
if (uses_gpu_layer) {
out << "\tuint gpu_Layer [[render_target_array_index]];" << std::endl;
}
/* Add Viewport Index output */
if (uses_gpu_viewport_index) {
out << "\tuint gpu_ViewportIndex [[viewport_array_index]];" << std::endl;
}
out << "} VertexOut;" << std::endl << std::endl;
@ -3007,10 +3027,14 @@ std::string MSLGeneratorInterface::generate_msl_vertex_output_population()
}
/* Output render target array Index. */
if (uses_mtl_array_index_) {
out << "\toutput.MTLRenderTargetArrayIndex = "
""
<< shader_stage_inst_name << ".MTLRenderTargetArrayIndex;" << std::endl;
if (uses_gpu_layer) {
out << "\toutput.gpu_Layer = " << shader_stage_inst_name << ".gpu_Layer;" << std::endl;
}
/* Output Viewport Index. */
if (uses_gpu_viewport_index) {
out << "\toutput.gpu_ViewportIndex = " << shader_stage_inst_name << ".gpu_ViewportIndex;"
<< std::endl;
}
/* Output clip-distances.
@ -3143,6 +3167,17 @@ std::string MSLGeneratorInterface::generate_msl_fragment_input_population()
<< ".gl_FragCoord.z;" << std::endl;
}
/* Input render target array index received from vertex shader. */
if (uses_gpu_layer) {
out << "\t" << shader_stage_inst_name << ".gpu_Layer = v_in.gpu_Layer;" << std::endl;
}
/* Input viewport array index received from vertex shader. */
if (uses_gpu_viewport_index) {
out << "\t" << shader_stage_inst_name << ".gpu_ViewportIndex = v_in.gpu_ViewportIndex;"
<< std::endl;
}
/* NOTE: We will only assign to the intersection of the vertex output and fragment input.
* Fragment input represents varying variables which are declared (but are not necessarily
* used). The Vertex out defines the set which is passed into the fragment shader, which

View File

@ -255,6 +255,7 @@ struct SStruct {
#define depth2D thread _mtl_combined_image_sampler_depth_2d<float>
#define sampler2DArray thread _mtl_combined_image_sampler_2d_array<float>
#define sampler2DArrayShadow thread _mtl_combined_image_sampler_depth_2d_array<float>
#define depth2DArray thread _mtl_combined_image_sampler_depth_2d_array<float>
#define depth2DArrayShadow thread _mtl_combined_image_sampler_depth_2d_array<float>
#define sampler3D thread _mtl_combined_image_sampler_3d<float>
#define samplerBuffer thread _mtl_combined_image_sampler_buffer<float, access::read>

View File

@ -43,14 +43,15 @@ class GPUOpenGLTest : public GPUTest {
public:
GPUOpenGLTest() : GPUTest(GHOST_kDrawingContextTypeOpenGL, GPU_BACKEND_OPENGL) {}
};
# define GPU_OPENGL_TEST(test_name) \
TEST_F(GPUOpenGLTest, test_name) \
{ \
test_##test_name(); \
}
#else
# define GPU_OPENGL_TEST(test_name)
#endif
#define GPU_OPENGL_TEST(test_name) \
TEST_F(GPUOpenGLTest, test_name) \
{ \
test_##test_name(); \
}
#ifdef WITH_METAL_BACKEND
class GPUMetalTest : public GPUTest {
public:

View File

@ -1485,13 +1485,10 @@ static std::string rna_operator_description_cb(bContext *C,
ot->rna_ext.call(C, &ptr, func, &list);
RNA_parameter_get_lookup(&list, "result", &ret);
const char *result = (const char *)ret;
std::string result = ret ? std::string(static_cast<const char *>(ret)) : "";
RNA_parameter_list_free(&list);
if (!result) {
return "";
}
return result;
}

View File

@ -363,9 +363,9 @@ endif()
if(UNIX AND NOT APPLE)
if(WITH_PYTHON_MODULE)
if(WITH_INSTALL_PORTABLE)
set(TARGETDIR_BPY bpy)
set(TARGETDIR_VER bpy/${BLENDER_VERSION})
set(TARGETDIR_LIB bpy/lib)
set(TARGETDIR_BPY "./bpy")
set(TARGETDIR_VER "./bpy/${BLENDER_VERSION}")
set(TARGETDIR_LIB "./bpy/lib")
else()
set(TARGETDIR_BPY ${PYTHON_SITE_PACKAGES}/bpy)
set(TARGETDIR_VER ${PYTHON_SITE_PACKAGES}/bpy/${BLENDER_VERSION})
@ -373,12 +373,12 @@ if(UNIX AND NOT APPLE)
endif()
else()
if(WITH_INSTALL_PORTABLE)
set(TARGETDIR_VER ${BLENDER_VERSION})
set(TARGETDIR_TEXT "${CMAKE_INSTALL_PREFIX}")
set(TARGETDIR_LIB lib)
set(TARGETDIR_VER "./${BLENDER_VERSION}")
set(TARGETDIR_TEXT ".")
set(TARGETDIR_LIB "./lib")
else()
set(TARGETDIR_VER share/blender/${BLENDER_VERSION})
set(TARGETDIR_TEXT share/doc/blender)
set(TARGETDIR_VER "./share/blender/${BLENDER_VERSION}")
set(TARGETDIR_TEXT "./share/doc/blender")
endif()
endif()
@ -390,17 +390,17 @@ elseif(WIN32)
set(TARGETDIR_LIB ${CMAKE_INSTALL_PREFIX_WITH_CONFIG}/bpy)
set(TARGETDIR_EXE ${CMAKE_INSTALL_PREFIX_WITH_CONFIG}/bpy)
else()
set(TARGETDIR_VER ${BLENDER_VERSION})
set(TARGETDIR_TEXT "${CMAKE_INSTALL_PREFIX}")
set(TARGETDIR_LIB "${CMAKE_INSTALL_PREFIX}/blender.shared")
set(TARGETDIR_EXE "${CMAKE_INSTALL_PREFIX}")
set(TARGETDIR_VER "./${BLENDER_VERSION}")
set(TARGETDIR_TEXT ".")
set(TARGETDIR_LIB "./blender.shared")
set(TARGETDIR_EXE ".")
endif()
elseif(APPLE)
if(WITH_PYTHON_MODULE)
if(WITH_INSTALL_PORTABLE)
set(TARGETDIR_BPY bpy)
set(TARGETDIR_VER bpy/${BLENDER_VERSION})
set(TARGETDIR_LIB bpy/lib)
set(TARGETDIR_BPY "./bpy")
set(TARGETDIR_VER "./bpy/${BLENDER_VERSION}")
set(TARGETDIR_LIB "./bpy/lib")
else()
# Paths defined in terms of site-packages since the site-packages
# directory can be a symlink (brew for example).
@ -409,9 +409,9 @@ elseif(APPLE)
set(TARGETDIR_LIB ${PYTHON_SITE_PACKAGES}/bpy/lib)
endif()
else()
set(TARGETDIR_VER Blender.app/Contents/Resources/${BLENDER_VERSION})
set(TARGETDIR_LIB Blender.app/Contents/Resources/lib)
set(TARGETDIR_TEXT Blender.app/Contents/Resources/text)
set(TARGETDIR_VER "./Blender.app/Contents/Resources/${BLENDER_VERSION}")
set(TARGETDIR_LIB "./Blender.app/Contents/Resources/lib")
set(TARGETDIR_TEXT "./Blender.app/Contents/Resources/text")
endif()
# Skip re-linking on CPACK / install.
set_target_properties(blender PROPERTIES BUILD_WITH_INSTALL_RPATH true)
@ -634,9 +634,10 @@ if(UNIX AND NOT APPLE)
# none of the other files are needed currently
elseif(WITH_INSTALL_PORTABLE)
set(BLENDER_BIN "blender")
install(
TARGETS blender
DESTINATION "${CMAKE_INSTALL_PREFIX}"
DESTINATION "."
)
install(
@ -644,13 +645,13 @@ if(UNIX AND NOT APPLE)
${CMAKE_SOURCE_DIR}/release/freedesktop/blender.desktop
${CMAKE_SOURCE_DIR}/release/freedesktop/icons/scalable/apps/blender.svg
${CMAKE_SOURCE_DIR}/release/freedesktop/icons/symbolic/apps/blender-symbolic.svg
DESTINATION "${CMAKE_INSTALL_PREFIX}"
DESTINATION "."
)
if(WITH_BLENDER_THUMBNAILER)
install(
TARGETS blender-thumbnailer
DESTINATION "${CMAKE_INSTALL_PREFIX}"
DESTINATION "."
)
endif()
@ -658,13 +659,16 @@ if(UNIX AND NOT APPLE)
if(NOT DEFINED LIBDIR)
# Pass.
elseif(EXISTS ${LIBDIR}/mesa)
install(DIRECTORY ${LIBDIR}/mesa/lib/ DESTINATION "lib/mesa/")
install(
DIRECTORY ${LIBDIR}/mesa/lib
DESTINATION "./lib/mesa"
)
install(
PROGRAMS
${CMAKE_SOURCE_DIR}/release/bin/blender-launcher
${CMAKE_SOURCE_DIR}/release/bin/blender-softwaregl
DESTINATION "${CMAKE_INSTALL_PREFIX}"
DESTINATION "."
)
# Remove from old location, so existing builds don't start with software
@ -685,28 +689,29 @@ if(UNIX AND NOT APPLE)
endif()
else()
# main blender binary
set(BLENDER_BIN "bin/blender")
install(
TARGETS blender
DESTINATION bin
DESTINATION "./bin"
)
# Misc files.
install(
FILES ${CMAKE_SOURCE_DIR}/release/freedesktop/blender.desktop
DESTINATION share/applications
DESTINATION "./share/applications"
)
install(
FILES ${CMAKE_SOURCE_DIR}/release/freedesktop/icons/scalable/apps/blender.svg
DESTINATION share/icons/hicolor/scalable/apps
DESTINATION "./share/icons/hicolor/scalable/apps"
)
install(
FILES ${CMAKE_SOURCE_DIR}/release/freedesktop/icons/symbolic/apps/blender-symbolic.svg
DESTINATION share/icons/hicolor/symbolic/apps
DESTINATION "./share/icons/hicolor/symbolic/apps"
)
if(WITH_BLENDER_THUMBNAILER)
install(
TARGETS blender-thumbnailer
DESTINATION bin
DESTINATION "./bin"
)
endif()
endif()
@ -1020,13 +1025,13 @@ elseif(WIN32)
# on the build-bot does not support this endeavor.
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/\${CMAKE_INSTALL_CONFIG_NAME}/blender_public.pdb
DESTINATION "${CMAKE_INSTALL_PREFIX}"
DESTINATION "."
RENAME blender.pdb
)
else()
install(
FILES $<TARGET_PDB_FILE:blender>
DESTINATION "${CMAKE_INSTALL_PREFIX}"
DESTINATION "."
RENAME blender.pdb
)
endif()
@ -1249,14 +1254,14 @@ elseif(WIN32)
install(
FILES
${LIBDIR}/python/${_PYTHON_VERSION_NO_DOTS}/libs/python${_PYTHON_VERSION_NO_DOTS}.pdb
DESTINATION "${CMAKE_INSTALL_PREFIX}"
DESTINATION "."
CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel
)
install(
FILES
${LIBDIR}/python/${_PYTHON_VERSION_NO_DOTS}/libs/python${_PYTHON_VERSION_NO_DOTS}_d.pdb
DESTINATION "${CMAKE_INSTALL_PREFIX}"
DESTINATION "."
CONFIGURATIONS Debug
)
endif()
@ -1354,7 +1359,7 @@ elseif(WIN32)
${LIBDIR}/audaspace/lib/audaspace.dll
${LIBDIR}/audaspace/lib/audaspace-c.dll
${LIBDIR}/audaspace/lib/audaspace-py.dll
DESTINATION "${CMAKE_INSTALL_PREFIX}"
DESTINATION "."
)
endif()
@ -1375,7 +1380,7 @@ elseif(WIN32)
if(WITH_BLENDER_THUMBNAILER)
install(
TARGETS BlendThumb
DESTINATION "${CMAKE_INSTALL_PREFIX}"
DESTINATION "."
)
endif()
@ -1434,25 +1439,26 @@ elseif(APPLE)
COMMAND SetFile -d ${SETFILE_DATE} -m ${SETFILE_DATE} ${EXECUTABLE_OUTPUT_PATH}/Blender.app
)
set(BLENDER_BIN "bin/blender")
install(
TARGETS blender
DESTINATION "${CMAKE_INSTALL_PREFIX}"
DESTINATION "."
)
install(
FILES ${OSX_APP_SOURCEDIR}/Contents/PkgInfo
DESTINATION Blender.app/Contents
DESTINATION "./Blender.app/Contents"
)
install_dir(
${OSX_APP_SOURCEDIR}/Contents/Resources
Blender.app/Contents/
"./Blender.app/Contents"
)
if(WITH_BLENDER_THUMBNAILER)
install(
TARGETS blender-thumbnailer
DESTINATION Blender.app/Contents/MacOS/
DESTINATION "./Blender.app/Contents/MacOS"
)
endif()
@ -1748,10 +1754,11 @@ endif()
# Setup launcher
if(WIN32 AND NOT WITH_PYTHON_MODULE)
set(BLENDER_BIN "blender.exe")
install(
TARGETS blender blender-launcher
COMPONENT Blender
DESTINATION "${CMAKE_INSTALL_PREFIX}"
DESTINATION "."
)
set_target_properties(
blender
@ -1777,9 +1784,12 @@ if(UNIX AND NOT APPLE)
if(WITH_DOC_MANPAGE)
# Only run the command to generate the man-page when it may be outdated.
# The `IS_NEWER_THAN` checks always run when files are missing.
# NOTE: While `${EXECUTABLE_OUTPUT_PATH}/blender` may work in some cases
# Blender's requirement of libraries mean the installation path must be used.
install(
CODE "\
set(BLENDER_BIN \"${EXECUTABLE_OUTPUT_PATH}/blender\")\n\
set(BLENDER_BIN \"${CMAKE_INSTALL_PREFIX}/${BLENDER_BIN}\")\n\
set(MANPAGE_GEN \"${CMAKE_SOURCE_DIR}/doc/manpage/blender.1.py\")\n\
set(MANPAGE_OUT \"${CMAKE_CURRENT_BINARY_DIR}/blender.1\")\n\
if(\n\
@ -1809,13 +1819,13 @@ endif()\n\
if(WITH_INSTALL_PORTABLE)
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/blender.1
DESTINATION "${CMAKE_INSTALL_PREFIX}"
DESTINATION "."
)
else()
# Manual page (only with `blender` binary).
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/blender.1
DESTINATION share/man/man1
DESTINATION "./share/man/man1"
)
endif()
endif()