45 if (frame_end <= frame_start) {
59 if (frame_start < scene->r.sfra) {
67 if (frame_end > scene->r.efra) {
73 C, op, 250,
IFACE_(
"Bake Object Transform to Grease Pencil"),
IFACE_(
"Bake"));
82 bake_targets.
append(active_object);
91 bake_targets.
append(duplicate_object->ob);
97 if (
object == active_object) {
102 bake_targets.
append(
object);
104 else if (object->type ==
OB_EMPTY) {
111 bake_targets.
append(duplicate_object->ob);
123 for (
Object *bake_target : bake_targets) {
126 for (
const int i :
IndexRange(fcurve->totvert)) {
129 keyframes.
add(
int(bezt.
vec[1][0]));
140 using namespace bke::greasepencil;
148 const int frame_start = (scene.r.sfra >
RNA_int_get(op->
ptr,
"frame_start")) ?
152 const int frame_end = (scene.r.efra <
RNA_int_get(op->
ptr,
"frame_end")) ?
157 const int frame_offset =
RNA_int_get(op->
ptr,
"frame_target") - frame_start;
176 std::optional<Set<int>> keyframes;
183 for (
int frame = frame_start; frame <= frame_end; frame++) {
184 if ((frame - frame_start) % step != 0 && frame != frame_end) {
188 if (keyframes && keyframes->contains(frame)) {
192 scene.r.cfra = frame;
195 for (
Object *source_object : bake_targets) {
198 source_object_eval->
data);
199 const float4x4 to_target = source_object_eval->object_to_world() * target_imat;
201 for (
const Layer *source_layer : source_eval_grease_pencil.layers()) {
202 std::string layer_name = fmt::format(
203 "{}_{}", source_object->id.name + 2, source_layer->name());
204 TreeNode *node = target.find_node_by_name(layer_name);
205 if (node ==
nullptr) {
206 Layer &new_layer = target.add_layer(layer_name);
207 target.set_active_layer(&new_layer);
210 Layer &target_layer = target.find_node_by_name(layer_name)->as_layer();
211 std::optional<DrawingPlacement> drawing_placement;
214 scene, *region, *v3d, *target_object_eval, &target_layer, reproject_mode);
218 if (source_frame ==
nullptr) {
222 const int target_frame_num = scene.r.cfra + frame_offset;
223 Drawing &source_drawing = *source_eval_grease_pencil.get_drawing_at(*source_layer,
225 Drawing &target_drawing = *target.insert_frame(target_layer, target_frame_num);
233 target_strokes.attributes_for_write().lookup_or_add_for_write_span<
int>(
238 source_material_indices[i] + 1);
244 if (source_material == target_material) {
263 target_material_indices.
finish();
266 for (const int i : range) {
267 positions[i] = math::transform_point(to_target, positions[i]);
270 if (drawing_placement) {
272 for (const int i : range) {
273 positions[i] = drawing_placement->reproject(positions[i]);
280 scene.r.cfra = prior_frame;
306 return (area && area->spacetype);
311 ot->
name =
"Bake Object Transform to Grease Pencil";
312 ot->
idname =
"GREASE_PENCIL_OT_bake_grease_pencil_animation";
313 ot->
description =
"Bake grease pencil object transform to grease pencil keyframes";
321 RNA_def_int(
ot->
srna,
"frame_start", 1, 1, 100000,
"Start Frame",
"The start frame", 1, 100000);
324 ot->
srna,
"frame_end", 250, 1, 100000,
"End Frame",
"The end frame of animation", 1, 100000);
327 RNA_def_int(
ot->
srna,
"step", 1, 1, 100,
"Step",
"Step between generated frames", 1, 100);
332 "Only Selected Keyframes",
333 "Convert only selected keyframes");
335 ot->
srna,
"frame_target", 1, 1, 100000,
"Target Frame",
"Destination frame", 1, 100000);
338 {
int(ReprojectMode::Keep),
"KEEP", 0,
"No Reproject",
""},
339 {
int(ReprojectMode::Front),
343 "Reproject the strokes using the X-Z plane"},
344 {
int(ReprojectMode::Side),
"SIDE", 0,
"Side",
"Reproject the strokes using the Y-Z plane"},
345 {
int(ReprojectMode::Top),
"TOP", 0,
"Top",
"Reproject the strokes using the X-Y plane"},
346 {
int(ReprojectMode::View),
350 "Reproject the strokes to end up on the same plane, as if drawn from the current "
352 "using 'Cursor' Stroke Placement"},
353 {
int(ReprojectMode::Cursor),
357 "Reproject the strokes using the orientation of 3D cursor"},
358 {0,
nullptr, 0,
nullptr,
nullptr},
363 rna_grease_pencil_reproject_type_items,
364 int(ReprojectMode::Keep),
Functions for backward compatibility with the legacy Action API.
AnimData * BKE_animdata_from_id(const ID *id)
#define CTX_DATA_BEGIN(C, Type, instance, member)
Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
ScrArea * CTX_wm_area(const bContext *C)
Object * CTX_data_active_object(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Main * CTX_data_main(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
View3D * CTX_wm_view3d(const bContext *C)
Low-level operations for curves.
ListBase * object_duplilist(Depsgraph *depsgraph, Scene *sce, Object *ob)
void free_object_duplilist(ListBase *lb)
General operations, lookup, etc. for materials.
struct Material * BKE_object_material_get(struct Object *ob, short act)
void BKE_object_material_assign(struct Main *bmain, struct Object *ob, struct Material *ma, short act, int assign_type)
@ BKE_MAT_ASSIGN_USERPREF
bool BKE_object_material_slot_add(struct Main *bmain, struct Object *ob)
int BKE_object_material_index_get(Object *ob, const Material *ma)
void BKE_scene_graph_update_for_newframe(Depsgraph *depsgraph)
#define LISTBASE_FOREACH(type, var, list)
void DEG_id_tag_update(ID *id, unsigned int flags)
void DEG_relations_tag_update(Main *bmain)
float DEG_get_ctime(const Depsgraph *graph)
Object * DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
void append(const T &value)
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const void *default_value=nullptr) const
IndexRange curves_range() const
AttributeAccessor attributes() const
bke::CurvesGeometry & strokes_for_write()
const bke::CurvesGeometry & strokes() const
const Depsgraph * depsgraph
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
void ED_operatortypes_grease_pencil_bake_animation()
Vector< FCurve * > fcurves_for_assigned_action(AnimData *adt)
static Vector< Object * > get_bake_targets(bContext &C, Depsgraph &depsgraph, Scene &scene)
static int bake_grease_pencil_animation_exec(bContext *C, wmOperator *op)
static int bake_grease_pencil_animation_invoke(bContext *C, wmOperator *op, const wmEvent *)
static Set< int > get_selected_object_keyframes(Span< Object * > bake_targets)
static bool bake_grease_pencil_animation_poll(bContext *C)
static void GREASE_PENCIL_OT_bake_grease_pencil_animation(wmOperatorType *ot)
static void ensure_valid_frame_end(Main *, Scene *, PointerRNA *ptr)
Object * add_type(bContext *C, int type, const char *name, const float loc[3], const float rot[3], bool enter_editmode, unsigned short local_view_bits) ATTR_NONNULL(1) ATTR_RETURNS_NONNULL
CartesianBasis invert(const CartesianBasis &basis)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
void RNA_int_set(PointerRNA *ptr, const char *name, int value)
int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
int RNA_int_get(PointerRNA *ptr, const char *name)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
int RNA_enum_get(PointerRNA *ptr, const char *name)
void RNA_def_property_update_runtime(PropertyRNA *prop, RNAPropertyUpdateFunc func)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, const int default_value, const int hardmin, const int hardmax, const char *ui_name, const char *ui_description, const int softmin, const int softmax)
unsigned short local_view_uid
MutableVArraySpan< T > span
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
int(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
int(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
void WM_cursor_wait(bool val)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
void WM_operatortype_append(void(*opfunc)(wmOperatorType *))
int WM_operator_props_dialog_popup(bContext *C, wmOperator *op, int width, std::optional< std::string > title, std::optional< std::string > confirm_text, const bool cancel_default)