USD: Skeleton and blend shape import #110912
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(¶llel_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,
|
||||
¶llel_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(¶llel_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,
|
||||
¶llel_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(¶llel_range_settings);
|
||||
BLI_task_parallel_range(0,
|
||||
num_effected_faces,
|
||||
&data,
|
||||
subdiv_ccg_stitch_face_inner_grids_task,
|
||||
¶llel_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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) ||
|
||||
|
|
|
@ -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*/,
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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_);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue