Skip to content

Commit 3ce911a

Browse files
author
Roberto De Ioris
committed
another round of sequencer improvements
1 parent 38e0079 commit 3ce911a

6 files changed

Lines changed: 130 additions & 42 deletions

File tree

‎Source/UnrealEnginePython/Private/UEPyEngine.cpp‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,22 @@ PyObject *py_unreal_engine_load_object(PyObject * self, PyObject * args) {
304304

305305
}
306306

307+
PyObject *py_unreal_engine_string_to_guid(PyObject * self, PyObject * args) {
308+
char *str;
309+
if (!PyArg_ParseTuple(args, "s:string_to_guid", &str)) {
310+
return NULL;
311+
}
312+
313+
FGuid guid;
314+
315+
if (FGuid::Parse(FString(str), guid)) {
316+
return py_ue_new_uscriptstruct(FindObject<UScriptStruct>(ANY_PACKAGE, UTF8_TO_TCHAR((char *)"Guid")), (uint8 *)&guid);
317+
}
318+
319+
return PyErr_Format(PyExc_Exception, "unable to build FGuid");
320+
321+
}
322+
307323

308324
PyObject *py_unreal_engine_find_object(PyObject * self, PyObject * args) {
309325
char *name;

‎Source/UnrealEnginePython/Private/UEPyEngine.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ PyObject *py_unreal_engine_load_class(PyObject *, PyObject *);
2525
PyObject *py_unreal_engine_load_struct(PyObject *, PyObject *);
2626
PyObject *py_unreal_engine_load_enum(PyObject *, PyObject *);
2727

28+
PyObject *py_unreal_engine_string_to_guid(PyObject *, PyObject *);
29+
2830
PyObject *py_unreal_engine_find_object(PyObject *, PyObject *);
2931

3032
PyObject *py_unreal_engine_all_classes(PyObject *, PyObject *);

‎Source/UnrealEnginePython/Private/UEPyModule.cpp‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,8 @@ static PyMethodDef unreal_engine_methods[] = {
174174
{ "get_discovered_plugins", py_unreal_engine_get_discovered_plugins, METH_VARARGS, "" },
175175
{ "get_enabled_plugins", py_unreal_engine_get_enabled_plugins, METH_VARARGS, "" },
176176
{ "find_plugin", py_unreal_engine_find_plugin, METH_VARARGS, "" },
177+
178+
{ "string_to_guid", py_unreal_engine_string_to_guid, METH_VARARGS, "" },
177179
#pragma warning(suppress: 4191)
178180
{ "get_assets_by_filter", (PyCFunction)py_unreal_engine_get_assets_by_filter, METH_VARARGS | METH_KEYWORDS, "" },
179181
{ "create_blueprint", py_unreal_engine_create_blueprint, METH_VARARGS, "" },
@@ -559,12 +561,15 @@ static PyMethodDef ue_PyUObject_methods[] = {
559561
{ "sequencer_folders", (PyCFunction)py_ue_sequencer_folders, METH_VARARGS, "" },
560562
{ "sequencer_set_display_name", (PyCFunction)py_ue_sequencer_set_display_name, METH_VARARGS, "" },
561563
{ "sequencer_get_display_name", (PyCFunction)py_ue_sequencer_get_display_name, METH_VARARGS, "" },
564+
{ "sequencer_changed", (PyCFunction)py_ue_sequencer_changed, METH_VARARGS, "" },
562565
#endif
563566
{ "sequencer_sections", (PyCFunction)py_ue_sequencer_sections, METH_VARARGS, "" },
564567
{ "sequencer_track_sections", (PyCFunction)py_ue_sequencer_track_sections, METH_VARARGS, "" },
565568
{ "sequencer_possessables", (PyCFunction)py_ue_sequencer_possessables, METH_VARARGS, "" },
569+
{ "sequencer_possessables_guid", (PyCFunction)py_ue_sequencer_possessables_guid, METH_VARARGS, "" },
566570
{ "sequencer_find_possessable", (PyCFunction)py_ue_sequencer_find_possessable, METH_VARARGS, "" },
567571
{ "sequencer_add_master_track", (PyCFunction)py_ue_sequencer_add_master_track, METH_VARARGS, "" },
572+
{ "sequencer_add_camera_cut_track", (PyCFunction)py_ue_sequencer_add_camera_cut_track, METH_VARARGS, "" },
568573

569574
{ "sequencer_add_track", (PyCFunction)py_ue_sequencer_add_track, METH_VARARGS, "" },
570575
{ "sequencer_add_actor", (PyCFunction)py_ue_sequencer_add_actor, METH_VARARGS, "" },

‎Source/UnrealEnginePython/Private/UEPySequencer.cpp‎

Lines changed: 96 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,44 @@
1010
#if WITH_EDITOR
1111
#include "Editor/Sequencer/Public/ISequencer.h"
1212
#include "Editor/Sequencer/Public/ISequencerModule.h"
13+
#include "Editor/UnrealEd/Public/Toolkits/AssetEditorManager.h"
14+
#include "Private/LevelSequenceEditorToolkit.h"
15+
#include "Tracks/MovieSceneCameraCutTrack.h"
1316
#endif
1417

15-
static void movie_update(UMovieSceneSequence *movie) {
1618
#if WITH_EDITOR
17-
ISequencerModule& sequencer_module = FModuleManager::LoadModuleChecked<ISequencerModule>("Sequencer");
18-
FSequencerInitParams sequencer_params;
19-
sequencer_params.RootSequence = movie;
20-
TSharedRef<ISequencer> sequencer = sequencer_module.CreateSequencer(sequencer_params);
21-
sequencer->NotifyMovieSceneDataChanged(EMovieSceneDataChangeType::Unknown);
22-
#endif
19+
PyObject *py_ue_sequencer_changed(ue_PyUObject *self, PyObject * args) {
20+
21+
ue_py_check(self);
22+
23+
PyObject *py_bool = nullptr;
24+
if (!PyArg_ParseTuple(args, "|O:sequencer_changed", &py_bool)) {
25+
return NULL;
26+
}
27+
28+
bool force_open = false;
29+
30+
if (!self->ue_object->IsA<ULevelSequence>())
31+
return PyErr_Format(PyExc_Exception, "uobject is not a LevelSequence");
32+
33+
ULevelSequence *seq = (ULevelSequence *)self->ue_object;
34+
35+
if (py_bool && PyObject_IsTrue(py_bool)) {
36+
// try to open the editor for the asset
37+
FAssetEditorManager::Get().OpenEditorForAsset(seq);
38+
}
39+
40+
IAssetEditorInstance *editor = FAssetEditorManager::Get().FindEditorForAsset(seq, true);
41+
if (editor) {
42+
FLevelSequenceEditorToolkit *toolkit = (FLevelSequenceEditorToolkit *)editor;
43+
ISequencer *sequencer = toolkit->GetSequencer().Get();
44+
sequencer->NotifyMovieSceneDataChanged(EMovieSceneDataChangeType::Unknown);
45+
}
46+
47+
Py_INCREF(Py_None);
48+
return Py_None;
2349
}
50+
#endif
2451

2552
PyObject *py_ue_sequencer_possessable_tracks(ue_PyUObject *self, PyObject * args) {
2653

@@ -127,8 +154,6 @@ PyObject *py_ue_sequencer_add_possessable(ue_PyUObject *self, PyObject * args) {
127154

128155
seq->BindPossessableObject(new_guid, *(py_ue_obj->ue_object), py_ue_obj->ue_object->GetWorld());
129156

130-
movie_update(seq);
131-
132157
return PyUnicode_FromString(TCHAR_TO_UTF8(*new_guid.ToString()));
133158
}
134159

@@ -156,22 +181,27 @@ PyObject *py_ue_sequencer_add_actor(ue_PyUObject *self, PyObject * args) {
156181
TArray<TWeakObjectPtr<AActor>> actors;
157182
actors.Add((AActor *)py_ue_obj->ue_object);
158183

159-
ISequencerModule& sequencer_module = FModuleManager::LoadModuleChecked<ISequencerModule>("Sequencer");
160-
FSequencerInitParams sequencer_params;
161-
sequencer_params.RootSequence = seq;
162-
sequencer_params.bEditWithinLevelEditor = false;
163-
sequencer_params.ToolkitHost = nullptr;
184+
// try to open the editor for the asset
185+
FAssetEditorManager::Get().OpenEditorForAsset(seq);
164186

165-
FSequencerViewParams view_params;
166-
view_params.InitialScrubPosition = 0;
167-
sequencer_params.ViewParams = view_params;
187+
IAssetEditorInstance *editor = FAssetEditorManager::Get().FindEditorForAsset(seq, true);
188+
if (editor) {
189+
FLevelSequenceEditorToolkit *toolkit = (FLevelSequenceEditorToolkit *)editor;
190+
ISequencer *sequencer = toolkit->GetSequencer().Get();
191+
sequencer->AddActors(actors);
192+
}
193+
else {
194+
return PyErr_Format(PyExc_Exception, "unable to access sequencer");
195+
}
168196

169-
TSharedRef<ISequencer> sequencer = sequencer_module.CreateSequencer(sequencer_params);
197+
UObject& u_obj = *actors[0];
170198

171-
sequencer->AddActors(actors);
199+
FGuid new_guid = seq->FindPossessableObjectId(u_obj, u_obj.GetWorld());
200+
if (!new_guid.IsValid()) {
201+
return PyErr_Format(PyExc_Exception, "unable to find guid");
202+
}
172203

173-
Py_INCREF(Py_None);
174-
return Py_None;
204+
return PyUnicode_FromString(TCHAR_TO_UTF8(*new_guid.ToString()));
175205
}
176206

177207
PyObject *py_ue_sequencer_master_tracks(ue_PyUObject *self, PyObject * args) {
@@ -220,6 +250,26 @@ PyObject *py_ue_sequencer_possessables(ue_PyUObject *self, PyObject * args) {
220250
return py_possessables;
221251
}
222252

253+
PyObject *py_ue_sequencer_possessables_guid(ue_PyUObject *self, PyObject * args) {
254+
255+
ue_py_check(self);
256+
257+
if (!self->ue_object->IsA<ULevelSequence>())
258+
return PyErr_Format(PyExc_Exception, "uobject is not a LevelSequence");
259+
260+
ULevelSequence *seq = (ULevelSequence *)self->ue_object;
261+
UMovieScene *scene = seq->GetMovieScene();
262+
263+
PyObject *py_possessables = PyList_New(0);
264+
for (int32 i = 0; i < scene->GetPossessableCount(); i++) {
265+
FMovieScenePossessable possessable = scene->GetPossessable(i);
266+
PyObject *py_possessable = PyUnicode_FromString(TCHAR_TO_UTF8(*possessable.GetGuid().ToString()));
267+
PyList_Append(py_possessables, py_possessable);
268+
}
269+
270+
return py_possessables;
271+
}
272+
223273
#if WITH_EDITOR
224274
PyObject *py_ue_sequencer_folders(ue_PyUObject *self, PyObject * args) {
225275

@@ -303,31 +353,21 @@ PyObject *py_ue_sequencer_track_add_section(ue_PyUObject *self, PyObject * args)
303353

304354
ue_py_check(self);
305355

306-
PyObject *obj;
307-
if (!PyArg_ParseTuple(args, "O:sequencer_track_add_section", &obj)) {
308-
return NULL;
309-
}
310-
311356
if (!self->ue_object->IsA<UMovieSceneTrack>())
312357
return PyErr_Format(PyExc_Exception, "uobject is not a UMovieSceneTrack");
313358

314359
UMovieSceneTrack *track = (UMovieSceneTrack *)self->ue_object;
315360

316-
ue_PyUObject *py_obj = ue_is_pyuobject(obj);
317-
if (!py_obj)
318-
return PyErr_Format(PyExc_Exception, "argument is not a uobject");
319-
320-
if (!py_obj->ue_object->IsA<UMovieSceneSection>())
321-
return PyErr_Format(PyExc_Exception, "uobject is not a UMovieSceneSection");
322-
323-
UMovieSceneSection *new_section = (UMovieSceneSection *)py_obj->ue_object;
361+
UMovieSceneSection *new_section = track->CreateNewSection();
324362

325363
track->AddSection(*new_section);
326364

327-
movie_update((UMovieSceneSequence *)track->GetOuter());
365+
PyObject *ret = (PyObject *)ue_get_python_wrapper(new_section);
366+
if (!ret)
367+
return PyErr_Format(PyExc_Exception, "PyUObject is in invalid state");
328368

329-
Py_INCREF(Py_None);
330-
return Py_None;
369+
Py_INCREF(ret);
370+
return ret;
331371
}
332372

333373
PyObject *py_ue_sequencer_add_master_track(ue_PyUObject *self, PyObject * args) {
@@ -365,7 +405,25 @@ PyObject *py_ue_sequencer_add_master_track(ue_PyUObject *self, PyObject * args)
365405
if (!ret)
366406
return PyErr_Format(PyExc_Exception, "PyUObject is in invalid state");
367407

368-
movie_update(seq);
408+
Py_INCREF(ret);
409+
return ret;
410+
}
411+
412+
PyObject *py_ue_sequencer_add_camera_cut_track(ue_PyUObject *self, PyObject * args) {
413+
414+
ue_py_check(self);
415+
416+
if (!self->ue_object->IsA<ULevelSequence>())
417+
return PyErr_Format(PyExc_Exception, "uobject is not a LevelSequence");
418+
419+
ULevelSequence *seq = (ULevelSequence *)self->ue_object;
420+
UMovieScene *scene = seq->GetMovieScene();
421+
422+
UMovieSceneTrack *track = scene->AddCameraCutTrack(UMovieSceneCameraCutTrack::StaticClass());
423+
424+
PyObject *ret = (PyObject *)ue_get_python_wrapper(track);
425+
if (!ret)
426+
return PyErr_Format(PyExc_Exception, "PyUObject is in invalid state");
369427

370428
Py_INCREF(ret);
371429
return ret;
@@ -411,8 +469,6 @@ PyObject *py_ue_sequencer_add_track(ue_PyUObject *self, PyObject * args) {
411469
if (!ret)
412470
return PyErr_Format(PyExc_Exception, "PyUObject is in invalid state");
413471

414-
movie_update(seq);
415-
416472
Py_INCREF(ret);
417473
return ret;
418474
}
@@ -436,8 +492,6 @@ PyObject *py_ue_sequencer_set_display_name(ue_PyUObject *self, PyObject * args)
436492
return PyErr_Format(PyExc_Exception, "the uobject does not expose the SetDisplayName() method");
437493
}
438494

439-
//movie_update((UMovieSceneSequence *)track->GetOuter());
440-
441495
Py_INCREF(Py_None);
442496
return Py_None;
443497
}

‎Source/UnrealEnginePython/Private/UEPySequencer.h‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,18 @@ PyObject *py_ue_sequencer_track_sections(ue_PyUObject *, PyObject *);
1111
PyObject *py_ue_sequencer_folders(ue_PyUObject *, PyObject *);
1212
PyObject *py_ue_sequencer_set_display_name(ue_PyUObject *, PyObject *);
1313
PyObject *py_ue_sequencer_get_display_name(ue_PyUObject *, PyObject *);
14+
PyObject *py_ue_sequencer_changed(ue_PyUObject *, PyObject *);
1415
#endif
1516
PyObject *py_ue_sequencer_sections(ue_PyUObject *, PyObject *);
1617
PyObject *py_ue_sequencer_possessables(ue_PyUObject *, PyObject *);
18+
PyObject *py_ue_sequencer_possessables_guid(ue_PyUObject *, PyObject *);
1719
PyObject *py_ue_sequencer_find_possessable(ue_PyUObject *, PyObject *);
1820

1921
PyObject *py_ue_sequencer_add_master_track(ue_PyUObject *, PyObject *);
2022

23+
24+
PyObject *py_ue_sequencer_add_camera_cut_track(ue_PyUObject *, PyObject *);
25+
2126
PyObject *py_ue_sequencer_add_possessable(ue_PyUObject *, PyObject *);
2227

2328
PyObject *py_ue_sequencer_track_add_section(ue_PyUObject *, PyObject *);

‎Source/UnrealEnginePython/UnrealEnginePython.Build.cs‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,12 @@ public UnrealEnginePython(TargetInfo Target)
9292
"Projects",
9393
"Sequencer",
9494
"SequencerWidgets",
95+
"AssetTools",
96+
"LevelSequenceEditor",
97+
"MovieSceneTools",
98+
"MovieSceneTracks",
99+
"CinematicCamera",
100+
"EditorStyle",
95101
"UMGEditor",
96102
});
97103
}

0 commit comments

Comments
 (0)