Files
test/source/blender/editors/object/object_light_linking_ops.cc
Campbell Barton b3dfde88f3 Cleanup: spelling in comments (check_spelling_* target)
Also uppercase acronyms: API, UTF & ASCII.
2025-05-17 10:17:37 +10:00

278 lines
8.3 KiB
C++

/* SPDX-FileCopyrightText: 2001-2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup edobj
*/
#include "object_intern.hh"
#include "BKE_context.hh"
#include "BKE_light_linking.h"
#include "ED_object.hh"
#include "ED_screen.hh"
#include "WM_api.hh"
#include "WM_types.hh"
#include "UI_resources.hh"
#include "DNA_collection_types.h"
#include "RNA_access.hh"
#include "RNA_define.hh"
#include "RNA_prototypes.hh"
namespace blender::ed::object {
/* -------------------------------------------------------------------- */
/** \name Create New Light Linking Receiver/Blocker Collection Operators
* \{ */
template<LightLinkingType link_type>
static wmOperatorStatus light_linking_collection_new_exec(bContext *C, wmOperator * /*op*/)
{
Main *bmain = CTX_data_main(C);
Object *object = context_active_object(C);
BKE_light_linking_collection_new(bmain, object, link_type);
return OPERATOR_FINISHED;
}
void OBJECT_OT_light_linking_receiver_collection_new(wmOperatorType *ot)
{
/* identifiers */
ot->name = "New Light Linking Collection";
ot->description = "Create new light linking collection used by the active emitter";
ot->idname = "OBJECT_OT_light_linking_receiver_collection_new";
/* API callbacks. */
ot->exec = light_linking_collection_new_exec<LIGHT_LINKING_RECEIVER>;
ot->poll = ED_operator_object_active_editable;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
void OBJECT_OT_light_linking_blocker_collection_new(wmOperatorType *ot)
{
/* identifiers */
ot->name = "New Light Linking Collection";
ot->description = "Create new light linking collection used by the active emitter";
ot->idname = "OBJECT_OT_light_linking_blocker_collection_new";
/* API callbacks. */
ot->exec = light_linking_collection_new_exec<LIGHT_LINKING_BLOCKER>;
ot->poll = ED_operator_object_active_editable;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Select Light Linking Receivers/Blockers Operator
* \{ */
template<LightLinkingType link_type>
static wmOperatorStatus light_linking_select_exec(bContext *C, wmOperator * /*op*/)
{
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *emitter = context_active_object(C);
BKE_light_linking_select_receivers_of_emitter(scene, view_layer, emitter, link_type);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
return OPERATOR_FINISHED;
}
void OBJECT_OT_light_linking_receivers_select(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Select Light Linking Receivers";
ot->description = "Select all objects which receive light from this emitter";
ot->idname = "OBJECT_OT_light_linking_receivers_select";
/* API callbacks. */
ot->exec = light_linking_select_exec<LIGHT_LINKING_RECEIVER>;
ot->poll = ED_operator_object_active;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
void OBJECT_OT_light_linking_blockers_select(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Select Light Linking Blockers";
ot->description = "Select all objects which block light from this emitter";
ot->idname = "OBJECT_OT_light_linking_blockers_select";
/* API callbacks. */
ot->exec = light_linking_select_exec<LIGHT_LINKING_BLOCKER>;
ot->poll = ED_operator_object_active;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Link Receivers/Blockers to Emitter Operator
* \{ */
template<LightLinkingType link_type>
static wmOperatorStatus light_linking_link_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
Object *emitter = context_active_object(C);
const eCollectionLightLinkingState link_state = eCollectionLightLinkingState(
RNA_enum_get(op->ptr, "link_state"));
CTX_DATA_BEGIN (C, Object *, receiver, selected_objects) {
if (receiver == emitter) {
continue;
}
BKE_light_linking_link_receiver_to_emitter(bmain, emitter, receiver, link_type, link_state);
}
CTX_DATA_END;
/* It is possible that the receiver collection is also used by the view layer.
* For this case send a notifier so that the UI is updated for the changes in the collection
* content. */
WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene);
return OPERATOR_FINISHED;
}
void OBJECT_OT_light_linking_receivers_link(wmOperatorType *ot)
{
static const EnumPropertyItem link_state_items[] = {
{COLLECTION_LIGHT_LINKING_STATE_INCLUDE,
"INCLUDE",
ICON_NONE,
"Include",
"Include selected receivers to receive light from the active emitter"},
{COLLECTION_LIGHT_LINKING_STATE_EXCLUDE,
"EXCLUDE",
ICON_NONE,
"Exclude",
"Exclude selected receivers from receiving light from the active emitter"},
{0, nullptr, 0, nullptr, nullptr},
};
/* identifiers */
ot->name = "Link Receivers to Emitter";
ot->description = "Light link selected receivers to the active emitter object";
ot->idname = "OBJECT_OT_light_linking_receivers_link";
/* API callbacks. */
ot->exec = light_linking_link_exec<LIGHT_LINKING_RECEIVER>;
ot->poll = ED_operator_object_active_editable;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
ot->prop = RNA_def_enum(ot->srna,
"link_state",
link_state_items,
COLLECTION_LIGHT_LINKING_STATE_INCLUDE,
"Link State",
"State of the light linking");
}
void OBJECT_OT_light_linking_blockers_link(wmOperatorType *ot)
{
static const EnumPropertyItem link_state_items[] = {
{COLLECTION_LIGHT_LINKING_STATE_INCLUDE,
"INCLUDE",
ICON_NONE,
"Include",
"Include selected blockers to cast shadows from the active emitter"},
{COLLECTION_LIGHT_LINKING_STATE_EXCLUDE,
"EXCLUDE",
ICON_NONE,
"Exclude",
"Exclude selected blockers from casting shadows from the active emitter"},
{0, nullptr, 0, nullptr, nullptr},
};
/* identifiers */
ot->name = "Link Blockers to Emitter";
ot->description = "Light link selected blockers to the active emitter object";
ot->idname = "OBJECT_OT_light_linking_blockers_link";
/* API callbacks. */
ot->exec = light_linking_link_exec<LIGHT_LINKING_BLOCKER>;
ot->poll = ED_operator_object_active_editable;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
ot->prop = RNA_def_enum(ot->srna,
"link_state",
link_state_items,
COLLECTION_LIGHT_LINKING_STATE_INCLUDE,
"Link State",
"State of the shadow linking");
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Unlink from the Light Linking Collection Operator
* \{ */
static wmOperatorStatus light_linking_unlink_from_collection_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
ID *id = static_cast<ID *>(CTX_data_pointer_get_type(C, "id", &RNA_ID).data);
Collection *collection = static_cast<Collection *>(
CTX_data_pointer_get_type(C, "collection", &RNA_Collection).data);
if (!id || !collection) {
return OPERATOR_PASS_THROUGH;
}
if (!BKE_light_linking_unlink_id_from_collection(bmain, collection, id, op->reports)) {
return OPERATOR_CANCELLED;
}
/* Copy notifiers from the Outliner's "Unlink" operation for objects and collections. */
WM_event_add_notifier(C, NC_SCENE | ND_LAYER, nullptr);
WM_event_add_notifier(C, NC_ID | NA_EDITED, nullptr);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_OUTLINER, nullptr);
return OPERATOR_FINISHED;
}
void OBJECT_OT_light_linking_unlink_from_collection(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Remove From Light Linking Collection";
ot->description = "Remove this object or collection from the light linking collection";
ot->idname = "OBJECT_OT_light_linking_unlink_from_collection";
/* API callbacks. */
ot->exec = light_linking_unlink_from_collection_exec;
ot->poll = ED_operator_object_active_editable;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/** \} */
} // namespace blender::ed::object