Geometry Node: Multi-input socket tooltip #104468
|
@ -929,27 +929,26 @@ Mesh *BKE_mesh_new_from_object_to_bmain(Main *bmain,
|
||||||
return mesh_in_bmain;
|
return mesh_in_bmain;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure mesh only points original data-blocks, also increase users of materials and other
|
/* Make sure mesh only points to original data-blocks. Also increase user count of materials and
|
||||||
* possibly referenced data-blocks.
|
* other possibly referenced data-blocks.
|
||||||
*
|
*
|
||||||
* Going to original data-blocks is required to have bmain in a consistent state, where
|
* Changing to original data-blocks is required to have bmain in a consistent state, where
|
||||||
* everything is only allowed to reference original data-blocks.
|
* everything is only allowed to reference original data-blocks.
|
||||||
*
|
*
|
||||||
* Note that user-count updates has to be done *after* mesh has been transferred to Main database
|
* Note that user-count updates have to be done *after* the mesh has been transferred to Main
|
||||||
* (since doing reference-counting on non-Main IDs is forbidden). */
|
* database (since doing reference-counting on non-Main IDs is forbidden). */
|
||||||
BKE_library_foreach_ID_link(
|
BKE_library_foreach_ID_link(
|
||||||
nullptr, &mesh->id, foreach_libblock_make_original_callback, nullptr, IDWALK_NOP);
|
nullptr, &mesh->id, foreach_libblock_make_original_callback, nullptr, IDWALK_NOP);
|
||||||
|
|
||||||
/* Append the mesh to 'bmain'.
|
/* Add the mesh to 'bmain'. We do it in a bit longer way since there is no simple and clear way
|
||||||
* We do it a bit longer way since there is no simple and clear way of adding existing data-block
|
* of adding existing data-blocks to the 'bmain'. So we create new empty mesh (which guarantees
|
||||||
* to the 'bmain'. So we allocate new empty mesh in the 'bmain' (which guarantees all the naming
|
* all the naming and order and flags) and move the temporary mesh in place there. */
|
||||||
* and orders and flags) and move the temporary mesh in place there. */
|
|
||||||
Mesh *mesh_in_bmain = BKE_mesh_add(bmain, mesh->id.name + 2);
|
Mesh *mesh_in_bmain = BKE_mesh_add(bmain, mesh->id.name + 2);
|
||||||
|
|
||||||
/* NOTE: BKE_mesh_nomain_to_mesh() does not copy materials and instead it preserves them in the
|
/* NOTE: BKE_mesh_nomain_to_mesh() does not copy materials and instead preserves them in the
|
||||||
* destination mesh. So we "steal" materials before calling it.
|
* destination mesh. So we "steal" materials before calling it.
|
||||||
*
|
*
|
||||||
* TODO(sergey): We really better have a function which gets and ID and accepts it for the bmain.
|
* TODO(sergey): We really ought to have a function which gets an ID and accepts it into #Main.
|
||||||
*/
|
*/
|
||||||
mesh_in_bmain->mat = mesh->mat;
|
mesh_in_bmain->mat = mesh->mat;
|
||||||
mesh_in_bmain->totcol = mesh->totcol;
|
mesh_in_bmain->totcol = mesh->totcol;
|
||||||
|
|
|
@ -1480,7 +1480,8 @@ static void create_inspection_string_for_geometry_info(const geo_log::GeometryIn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void create_inspection_string_for_geometry_socket(std::stringstream &ss, const nodes::decl::Geometry *socket_decl)
|
static void create_inspection_string_for_geometry_socket(std::stringstream &ss,
|
||||||
|
const nodes::decl::Geometry *socket_decl)
|
||||||
{
|
{
|
||||||
/* If the geometry declaration is null, as is the case for input to group output,
|
/* If the geometry declaration is null, as is the case for input to group output,
|
||||||
* or it is an output socket don't show supported types. */
|
* or it is an output socket don't show supported types. */
|
||||||
|
@ -1531,29 +1532,6 @@ static void create_inspection_string_for_geometry_socket(std::stringstream &ss,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void create_inspection_string_for_default_socket_value(const bNodeSocket &socket, std::stringstream &ss)
|
|
||||||
{
|
|
||||||
if (!socket.is_input()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (socket.is_directly_linked()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (socket.flag & SOCK_HIDE_VALUE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (socket.typeinfo->base_cpp_type == nullptr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const CPPType &value_type = *socket.typeinfo->base_cpp_type;
|
|
||||||
BUFFER_FOR_CPP_TYPE_VALUE(value_type, socket_value);
|
|
||||||
socket.typeinfo->get_base_cpp_value(socket.default_value, socket_value);
|
|
||||||
create_inspection_string_for_generic_value(socket, GPointer(value_type, socket_value), ss);
|
|
||||||
value_type.destruct(socket_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::optional<std::string> create_description_inspection_string(const bNodeSocket &socket)
|
static std::optional<std::string> create_description_inspection_string(const bNodeSocket &socket)
|
||||||
{
|
{
|
||||||
if (socket.runtime->declaration == nullptr) {
|
if (socket.runtime->declaration == nullptr) {
|
||||||
|
@ -1564,11 +1542,12 @@ static std::optional<std::string> create_description_inspection_string(const bNo
|
||||||
if (description.is_empty()) {
|
if (description.is_empty()) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TIP_(description.data());
|
return TIP_(description.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::optional<std::string> create_log_inspection_string(geo_log::GeoTreeLog *geo_tree_log, const bNodeSocket &socket)
|
static std::optional<std::string> create_log_inspection_string(geo_log::GeoTreeLog *geo_tree_log,
|
||||||
|
const bNodeSocket &socket)
|
||||||
{
|
{
|
||||||
using namespace blender::nodes::geo_eval_log;
|
using namespace blender::nodes::geo_eval_log;
|
||||||
|
|
||||||
|
@ -1582,15 +1561,18 @@ static std::optional<std::string> create_log_inspection_string(geo_log::GeoTreeL
|
||||||
geo_tree_log->ensure_socket_values();
|
geo_tree_log->ensure_socket_values();
|
||||||
ValueLog *value_log = geo_tree_log->find_socket_value_log(socket);
|
ValueLog *value_log = geo_tree_log->find_socket_value_log(socket);
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
if (const geo_log::GenericValueLog *generic_value_log = dynamic_cast<const geo_log::GenericValueLog *>(value_log))
|
if (const geo_log::GenericValueLog *generic_value_log =
|
||||||
|
dynamic_cast<const geo_log::GenericValueLog *>(value_log))
|
||||||
{
|
{
|
||||||
create_inspection_string_for_generic_value(socket, generic_value_log->value, ss);
|
create_inspection_string_for_generic_value(socket, generic_value_log->value, ss);
|
||||||
}
|
}
|
||||||
else if (const geo_log::FieldInfoLog *gfield_value_log = dynamic_cast<const geo_log::FieldInfoLog *>(value_log))
|
else if (const geo_log::FieldInfoLog *gfield_value_log =
|
||||||
|
dynamic_cast<const geo_log::FieldInfoLog *>(value_log))
|
||||||
{
|
{
|
||||||
create_inspection_string_for_field_info(socket, *gfield_value_log, ss);
|
create_inspection_string_for_field_info(socket, *gfield_value_log, ss);
|
||||||
}
|
}
|
||||||
else if (const geo_log::GeometryInfoLog *geo_value_log = dynamic_cast<const geo_log::GeometryInfoLog *>(value_log))
|
else if (const geo_log::GeometryInfoLog *geo_value_log =
|
||||||
|
dynamic_cast<const geo_log::GeometryInfoLog *>(value_log))
|
||||||
{
|
{
|
||||||
create_inspection_string_for_geometry_info(*geo_value_log, ss);
|
create_inspection_string_for_geometry_info(*geo_value_log, ss);
|
||||||
}
|
}
|
||||||
|
@ -1605,12 +1587,13 @@ static std::optional<std::string> create_log_inspection_string(geo_log::GeoTreeL
|
||||||
static std::optional<std::string> create_declaration_inspection_string(const bNodeSocket &socket)
|
static std::optional<std::string> create_declaration_inspection_string(const bNodeSocket &socket)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
if (const nodes::decl::Geometry *socket_decl = dynamic_cast<const nodes::decl::Geometry *>(socket.runtime->declaration))
|
if (const nodes::decl::Geometry *socket_decl = dynamic_cast<const nodes::decl::Geometry *>(
|
||||||
|
socket.runtime->declaration))
|
||||||
{
|
{
|
||||||
create_inspection_string_for_geometry_socket(ss, socket_decl);
|
create_inspection_string_for_geometry_socket(ss, socket_decl);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (const const nodes::SocketDeclaration * socket_decl = socket.runtime->declaration) {
|
if (const nodes::SocketDeclaration *socket_decl = socket.runtime->declaration) {
|
||||||
if (socket_decl->input_field_type == nodes::InputSocketFieldType::Implicit) {
|
if (socket_decl->input_field_type == nodes::InputSocketFieldType::Implicit) {
|
||||||
if (!ss.str().empty()) {
|
if (!ss.str().empty()) {
|
||||||
ss << ".\n\n";
|
ss << ".\n\n";
|
||||||
|
@ -1626,23 +1609,6 @@ static std::optional<std::string> create_declaration_inspection_string(const bNo
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::optional<std::string> create_default_value_inspection_string(const bNodeSocket &socket)
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
create_inspection_string_for_default_socket_value(socket, ss);
|
|
||||||
|
|
||||||
std::string str = ss.str();
|
|
||||||
if (str.empty()) {
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool node_socket_has_tooltip(const bNodeTree &ntree, const bNodeSocket &socket)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string node_socket_get_tooltip(const SpaceNode *snode,
|
static std::string node_socket_get_tooltip(const SpaceNode *snode,
|
||||||
const bNodeTree &ntree,
|
const bNodeTree &ntree,
|
||||||
const bNodeSocket &socket)
|
const bNodeSocket &socket)
|
||||||
|
@ -1650,11 +1616,11 @@ static std::string node_socket_get_tooltip(const SpaceNode *snode,
|
||||||
TreeDrawContext tree_draw_ctx;
|
TreeDrawContext tree_draw_ctx;
|
||||||
if (snode != nullptr) {
|
if (snode != nullptr) {
|
||||||
if (ntree.type == NTREE_GEOMETRY) {
|
if (ntree.type == NTREE_GEOMETRY) {
|
||||||
tree_draw_ctx.geo_log_by_zone = geo_log::GeoModifierLog::get_tree_log_by_zone_for_node_editor(*snode);
|
tree_draw_ctx.geo_log_by_zone =
|
||||||
|
geo_log::GeoModifierLog::get_tree_log_by_zone_for_node_editor(*snode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool value_is_mentioned = false;
|
|
||||||
Vector<std::string> inspection_strings;
|
Vector<std::string> inspection_strings;
|
||||||
|
|
||||||
geo_log::GeoTreeLog *geo_tree_log = [&]() -> geo_log::GeoTreeLog * {
|
geo_log::GeoTreeLog *geo_tree_log = [&]() -> geo_log::GeoTreeLog * {
|
||||||
|
@ -1671,16 +1637,10 @@ static std::string node_socket_get_tooltip(const SpaceNode *snode,
|
||||||
}
|
}
|
||||||
if (std::optional<std::string> info = create_log_inspection_string(geo_tree_log, socket)) {
|
if (std::optional<std::string> info = create_log_inspection_string(geo_tree_log, socket)) {
|
||||||
inspection_strings.append(std::move(*info));
|
inspection_strings.append(std::move(*info));
|
||||||
value_is_mentioned = true;
|
|
||||||
}
|
}
|
||||||
if (std::optional<std::string> info = create_declaration_inspection_string(socket)) {
|
if (std::optional<std::string> info = create_declaration_inspection_string(socket)) {
|
||||||
inspection_strings.append(std::move(*info));
|
inspection_strings.append(std::move(*info));
|
||||||
}
|
}
|
||||||
if (!value_is_mentioned) {
|
|
||||||
if (std::optional<std::string> info = create_default_value_inspection_string(socket)) {
|
|
||||||
inspection_strings.append(std::move(*info));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::stringstream output;
|
std::stringstream output;
|
||||||
for (const std::string &info : inspection_strings) {
|
for (const std::string &info : inspection_strings) {
|
||||||
|
@ -1695,7 +1655,9 @@ static std::string node_socket_get_tooltip(const SpaceNode *snode,
|
||||||
|
|
||||||
if (ntree.type == NTREE_GEOMETRY) {
|
if (ntree.type == NTREE_GEOMETRY) {
|
||||||
output << ".\n\n";
|
output << ".\n\n";
|
||||||
output << TIP_("Unknown socket value. Either the socket was not used or its value was not logged during the last evaluation");
|
output << TIP_(
|
||||||
|
"Unknown socket value. Either the socket was not used or its value was not logged "
|
||||||
|
"during the last evaluation");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1706,9 +1668,6 @@ static void node_socket_add_tooltip_in_node_editor(const bNodeTree &ntree,
|
||||||
const bNodeSocket &sock,
|
const bNodeSocket &sock,
|
||||||
uiLayout &layout)
|
uiLayout &layout)
|
||||||
{
|
{
|
||||||
if (!node_socket_has_tooltip(ntree, sock)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
uiLayoutSetTooltipFunc(
|
uiLayoutSetTooltipFunc(
|
||||||
&layout,
|
&layout,
|
||||||
[](bContext *C, void *argN, const char * /*tip*/) {
|
[](bContext *C, void *argN, const char * /*tip*/) {
|
||||||
|
@ -1725,10 +1684,6 @@ static void node_socket_add_tooltip_in_node_editor(const bNodeTree &ntree,
|
||||||
|
|
||||||
void node_socket_add_tooltip(const bNodeTree &ntree, const bNodeSocket &sock, uiLayout &layout)
|
void node_socket_add_tooltip(const bNodeTree &ntree, const bNodeSocket &sock, uiLayout &layout)
|
||||||
{
|
{
|
||||||
if (!node_socket_has_tooltip(ntree, sock)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SocketTooltipData {
|
struct SocketTooltipData {
|
||||||
const bNodeTree *ntree;
|
const bNodeTree *ntree;
|
||||||
const bNodeSocket *socket;
|
const bNodeSocket *socket;
|
||||||
|
@ -1782,10 +1737,6 @@ static void node_socket_draw_nested(const bContext &C,
|
||||||
size_id,
|
size_id,
|
||||||
outline_col_id);
|
outline_col_id);
|
||||||
|
|
||||||
if (!node_socket_has_tooltip(ntree, sock)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ideally sockets themselves should be buttons, but they aren't currently. So add an invisible
|
/* Ideally sockets themselves should be buttons, but they aren't currently. So add an invisible
|
||||||
* button on top of them for the tooltip. */
|
* button on top of them for the tooltip. */
|
||||||
const eUIEmbossType old_emboss = UI_block_emboss_get(&block);
|
const eUIEmbossType old_emboss = UI_block_emboss_get(&block);
|
||||||
|
|
Loading…
Reference in New Issue