Skip to content

Commit 28d2f35

Browse files
author
Roberto De Ioris
committed
added landscape api, improved world and level apis
1 parent 6e98885 commit 28d2f35

8 files changed

Lines changed: 287 additions & 118 deletions

File tree

‎Source/UnrealEnginePython/Private/UEPyEditor.cpp‎

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1867,30 +1867,26 @@ PyObject *py_unreal_engine_add_level_to_world(PyObject *self, PyObject * args)
18671867
return NULL;
18681868
}
18691869

1870-
if (!ue_is_pyuobject(py_world))
1871-
return PyErr_Format(PyExc_Exception, "argument is not a UWorld");
1872-
1873-
ue_PyUObject *py_obj_world = (ue_PyUObject *)py_world;
1874-
1875-
if (!py_obj_world->ue_object->IsA<UWorld>())
1870+
UWorld *u_world = ue_py_check_type<UWorld>(py_world);
1871+
if (!u_world)
18761872
{
18771873
return PyErr_Format(PyExc_Exception, "argument is not a UWorld");
18781874
}
18791875

1880-
UWorld *u_world = (UWorld *)py_obj_world->ue_object;
1881-
18821876
UClass *streaming_mode_class = ULevelStreamingKismet::StaticClass();
18831877
if (py_bool && PyObject_IsTrue(py_bool))
18841878
{
18851879
streaming_mode_class = ULevelStreamingAlwaysLoaded::StaticClass();
18861880
}
18871881

18881882
ULevel *level = (ULevel *)EditorLevelUtils::AddLevelToWorld(u_world, UTF8_TO_TCHAR(name), streaming_mode_class);
1889-
if (level)
1883+
if (!level)
18901884
{
1891-
// TODO: update levels list
1885+
return PyErr_Format(PyExc_Exception, "unable to add \"%s\" to the world", name);
18921886
}
18931887

1888+
FEditorDelegates::RefreshLevelBrowser.Broadcast();
1889+
18941890
ue_PyUObject *ret = ue_get_python_wrapper(level);
18951891
if (!ret)
18961892
return PyErr_Format(PyExc_Exception, "uobject is in invalid state");
@@ -1908,22 +1904,41 @@ PyObject *py_unreal_engine_move_selected_actors_to_level(PyObject *self, PyObjec
19081904
return NULL;
19091905
}
19101906

1911-
if (!ue_is_pyuobject(py_level))
1912-
return PyErr_Format(PyExc_Exception, "argument is not a ULevelStreaming");
1907+
ULevel *level = ue_py_check_type<ULevel>(py_level);
1908+
if (!level)
1909+
return PyErr_Format(PyExc_Exception, "argument is not a ULevel");
19131910

1914-
ue_PyUObject *py_obj_level = (ue_PyUObject *)py_level;
1911+
GEditor->MoveSelectedActorsToLevel(level);
19151912

1916-
if (!py_obj_level->ue_object->IsA<ULevel>())
1913+
Py_RETURN_NONE;
1914+
}
1915+
1916+
PyObject *py_unreal_engine_move_actor_to_level(PyObject *self, PyObject * args)
1917+
{
1918+
PyObject *py_actor;
1919+
PyObject *py_level;
1920+
if (!PyArg_ParseTuple(args, "OO:move_actor_to_level", &py_actor, &py_level))
19171921
{
1918-
return PyErr_Format(PyExc_Exception, "argument is not a ULevelStreaming");
1922+
return NULL;
19191923
}
19201924

1921-
ULevel *level = (ULevel *)py_obj_level->ue_object;
1925+
AActor *actor = ue_py_check_type<AActor>(py_actor);
1926+
if (!actor)
1927+
return PyErr_Format(PyExc_Exception, "argument is not an Actor");
19221928

1923-
GEditor->MoveSelectedActorsToLevel(level);
1929+
ULevel *level = ue_py_check_type<ULevel>(py_level);
1930+
if (!level)
1931+
return PyErr_Format(PyExc_Exception, "argument is not a ULevel");
19241932

1925-
Py_INCREF(Py_None);
1926-
return Py_None;
1933+
TArray<AActor *> actors;
1934+
actors.Add(actor);
1935+
1936+
if (UEditorLevelUtils::MoveActorsToLevel(actors, level) != 1)
1937+
{
1938+
return PyErr_Format(PyExc_Exception, "unable to move actor to level");
1939+
}
1940+
1941+
Py_RETURN_NONE;
19271942
}
19281943

19291944
PyObject *py_unreal_engine_editor_take_high_res_screen_shots(PyObject * self, PyObject * args)

‎Source/UnrealEnginePython/Private/UEPyEditor.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ PyObject *py_unreal_engine_editor_save_all(PyObject *, PyObject *);
6464

6565
PyObject *py_unreal_engine_add_level_to_world(PyObject *, PyObject *);
6666
PyObject *py_unreal_engine_move_selected_actors_to_level(PyObject *, PyObject *);
67-
67+
PyObject *py_unreal_engine_move_actor_to_level(PyObject *, PyObject *);
6868

6969
PyObject *py_ue_factory_create_new(ue_PyUObject *, PyObject *);
7070
PyObject *py_ue_factory_import_object(ue_PyUObject *, PyObject *);

‎Source/UnrealEnginePython/Private/UEPyModule.cpp‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "UObject/UEPyHUD.h"
3434
#include "UObject/UEPyAnimSequence.h"
3535
#include "UObject/UEPyCapture.h"
36+
#include "UObject/UEPyLandscape.h"
3637

3738

3839
#include "UEPyAssetUserData.h"
@@ -279,6 +280,7 @@ static PyMethodDef unreal_engine_methods[] = {
279280

280281
{ "add_level_to_world", py_unreal_engine_add_level_to_world, METH_VARARGS, "" },
281282
{ "move_selected_actors_to_level", py_unreal_engine_move_selected_actors_to_level, METH_VARARGS, "" },
283+
{ "move_actor_to_level", py_unreal_engine_move_actor_to_level, METH_VARARGS, "" },
282284

283285
{ "editor_on_asset_post_import", py_unreal_engine_editor_on_asset_post_import, METH_VARARGS, "" },
284286

@@ -642,6 +644,8 @@ static PyMethodDef ue_PyUObject_methods[] = {
642644
{ "get_world_delta_seconds", (PyCFunction)py_ue_get_world_delta_seconds, METH_VARARGS, "" },
643645

644646
{ "get_levels", (PyCFunction)py_ue_get_levels, METH_VARARGS, "" },
647+
{ "get_current_level", (PyCFunction)py_ue_get_current_level, METH_VARARGS, "" },
648+
{ "set_current_level", (PyCFunction)py_ue_set_current_level, METH_VARARGS, "" },
645649

646650
{ "add_actor_component", (PyCFunction)py_ue_add_actor_component, METH_VARARGS, "" },
647651
{ "add_actor_root_component", (PyCFunction)py_ue_add_actor_root_component, METH_VARARGS, "" },
@@ -692,6 +696,12 @@ static PyMethodDef ue_PyUObject_methods[] = {
692696

693697
{ "conditional_begin_destroy", (PyCFunction)py_ue_conditional_begin_destroy, METH_VARARGS, "" },
694698

699+
// Landscape
700+
#if WITH_EDITOR
701+
{ "create_landscape_info", (PyCFunction)py_ue_create_landscape_info, METH_VARARGS, "" },
702+
{ "get_landscape_info", (PyCFunction)py_ue_get_landscape_info, METH_VARARGS, "" },
703+
{ "landscape_import", (PyCFunction)py_ue_landscape_import, METH_VARARGS, "" },
704+
#endif
695705

696706
// Player
697707

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#include "UnrealEnginePythonPrivatePCH.h"
2+
#include "Runtime/Landscape/Classes/LandscapeProxy.h"
3+
#include "Runtime/Landscape/Classes/LandscapeInfo.h"
4+
5+
#if WITH_EDITOR
6+
PyObject *py_ue_create_landscape_info(ue_PyUObject *self, PyObject * args)
7+
{
8+
9+
ue_py_check(self);
10+
11+
ALandscapeProxy *landscape = ue_py_check_type<ALandscapeProxy>(self);
12+
if (!landscape)
13+
return PyErr_Format(PyExc_Exception, "uobject is not a ULandscapeProxy");
14+
15+
ue_PyUObject *ret = ue_get_python_wrapper(landscape->CreateLandscapeInfo());
16+
if (!ret)
17+
return PyErr_Format(PyExc_Exception, "uobject is in invalid state");
18+
Py_INCREF(ret);
19+
return (PyObject *)ret;
20+
}
21+
22+
PyObject *py_ue_get_landscape_info(ue_PyUObject *self, PyObject * args)
23+
{
24+
25+
ue_py_check(self);
26+
27+
ALandscapeProxy *landscape = ue_py_check_type<ALandscapeProxy>(self);
28+
if (!landscape)
29+
return PyErr_Format(PyExc_Exception, "uobject is not a ULandscapeProxy");
30+
31+
ULandscapeInfo *info = landscape->GetLandscapeInfo();
32+
if (!info)
33+
Py_RETURN_NONE;
34+
35+
ue_PyUObject *ret = ue_get_python_wrapper(info);
36+
if (!ret)
37+
return PyErr_Format(PyExc_Exception, "uobject is in invalid state");
38+
Py_INCREF(ret);
39+
return (PyObject *)ret;
40+
}
41+
42+
PyObject *py_ue_landscape_import(ue_PyUObject *self, PyObject * args)
43+
{
44+
45+
ue_py_check(self);
46+
47+
int section_size;
48+
int sections_per_component;
49+
int component_x;
50+
int component_y;
51+
Py_buffer heightmap_buffer;
52+
int layer_type = (int)ELandscapeImportAlphamapType::Additive;
53+
54+
if (!PyArg_ParseTuple(args, "iiiiy*|i:landscape_import", &section_size, &sections_per_component, &component_x, &component_y, &heightmap_buffer, &layer_type))
55+
return nullptr;
56+
57+
ALandscapeProxy *landscape = ue_py_check_type<ALandscapeProxy>(self);
58+
if (!landscape)
59+
return PyErr_Format(PyExc_Exception, "uobject is not a ULandscapeProxy");
60+
61+
int quads_per_component = sections_per_component * section_size;
62+
int size_x = component_x * quads_per_component + 1;
63+
int size_y = component_y * quads_per_component + 1;
64+
65+
if (heightmap_buffer.len < (Py_ssize_t)(size_x * size_y * sizeof(uint16)))
66+
return PyErr_Format(PyExc_Exception, "not enough heightmap data, expecting %d bytes", size_x * size_y * sizeof(uint16));
67+
68+
uint16 *data = (uint16 *)heightmap_buffer.buf;
69+
70+
TArray<FLandscapeImportLayerInfo> infos;
71+
72+
landscape->Import(FGuid::NewGuid(), 0, 0, size_x-1, size_y-1, sections_per_component, section_size, data, nullptr, infos, (ELandscapeImportAlphamapType)layer_type);
73+
74+
Py_RETURN_NONE;
75+
}
76+
#endif
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#pragma once
2+
3+
4+
5+
#include "UnrealEnginePython.h"
6+
7+
#if WITH_EDITOR
8+
PyObject *py_ue_create_landscape_info(ue_PyUObject *self, PyObject *);
9+
PyObject *py_ue_get_landscape_info(ue_PyUObject *self, PyObject *);
10+
PyObject *py_ue_landscape_import(ue_PyUObject *self, PyObject *);
11+
#endif

0 commit comments

Comments
 (0)