Skip to content

Commit 6939eda

Browse files
author
Roberto De Ioris
committed
added support for automagic graph nodes placement
1 parent f5f4587 commit 6939eda

4 files changed

Lines changed: 112 additions & 12 deletions

File tree

‎Source/UnrealEnginePython/Private/UEPyEdGraph.cpp‎

Lines changed: 68 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,74 @@ PyObject *py_ue_graph_add_node_custom_event(ue_PyUObject * self, PyObject * args
110110

111111
}
112112

113+
PyObject *py_ue_graph_get_good_place_for_new_node(ue_PyUObject * self, PyObject * args) {
114+
115+
ue_py_check(self);
116+
117+
if (!self->ue_object->IsA<UEdGraph>()) {
118+
return PyErr_Format(PyExc_Exception, "uobject is not a UEdGraph");
119+
}
120+
121+
UEdGraph *graph = (UEdGraph *)self->ue_object;
122+
FVector2D pos = graph->GetGoodPlaceForNewNode();
123+
124+
PyObject *ret = PyTuple_New(2);
125+
PyTuple_SetItem(ret, 0, PyLong_FromDouble(pos.X));
126+
PyTuple_SetItem(ret, 1, PyLong_FromDouble(pos.Y));
127+
return ret;
128+
}
129+
130+
PyObject *py_ue_graph_add_node_event(ue_PyUObject * self, PyObject * args) {
131+
132+
ue_py_check(self);
133+
134+
PyObject *py_class = nullptr;
135+
char *name = nullptr;
136+
int x = 0;
137+
int y = 0;
138+
139+
if (!PyArg_ParseTuple(args, "Os|ii:graph_add_node_event", &py_class, &name, &x, &y)) {
140+
return NULL;
141+
}
142+
143+
if (!self->ue_object->IsA<UEdGraph>()) {
144+
return PyErr_Format(PyExc_Exception, "uobject is not a UEdGraph");
145+
}
146+
147+
UEdGraph *graph = (UEdGraph *)self->ue_object;
148+
149+
if (!ue_is_pyuobject(py_class)) {
150+
return PyErr_Format(PyExc_Exception, "argument is not a UObject");
151+
}
152+
153+
ue_PyUObject *py_obj = (ue_PyUObject *)py_class;
154+
if (!py_obj->ue_object->IsA<UClass>()) {
155+
return PyErr_Format(PyExc_Exception, "argument is not a UClass");
156+
}
157+
158+
UClass *u_class = (UClass *)py_obj->ue_object;
159+
UBlueprint *bp = (UBlueprint *)graph->GetOuter();
160+
161+
UK2Node_Event *node = FBlueprintEditorUtils::FindOverrideForFunction(bp, u_class, UTF8_TO_TCHAR(name));
162+
if (!node) {
163+
node = NewObject<UK2Node_Event>(graph);
164+
165+
UEdGraphSchema_K2::SetNodeMetaData(node, FNodeMetadata::DefaultGraphNode);
166+
node->EventReference.SetExternalMember(UTF8_TO_TCHAR(name), u_class);
167+
FEdGraphSchemaAction_K2NewNode::SpawnNodeFromTemplate<UK2Node_Event>(graph, node, FVector2D(x, y));
168+
//graph->AddNode(node);
169+
}
170+
171+
FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified(bp);
172+
173+
PyObject *ret = (PyObject *)ue_get_python_wrapper(node);
174+
if (!ret)
175+
return PyErr_Format(PyExc_Exception, "uobject is in invalid state");
176+
Py_INCREF(ret);
177+
return ret;
178+
179+
}
180+
113181
PyObject *py_ue_graph_add_node_variable_get(ue_PyUObject * self, PyObject * args) {
114182

115183
ue_py_check(self);
@@ -142,12 +210,6 @@ PyObject *py_ue_graph_add_node_variable_get(ue_PyUObject * self, PyObject * args
142210

143211
UK2Node_VariableGet *node = NewObject<UK2Node_VariableGet>(graph);
144212

145-
node->CreateNewGuid();
146-
node->PostPlacedNewNode();
147-
node->SetFlags(RF_Transactional);
148-
node->AllocateDefaultPins();
149-
node->NodePosX = x;
150-
node->NodePosY = y;
151213
UEdGraphSchema_K2::ConfigureVarNode(node, FName(UTF8_TO_TCHAR(name)), u_struct, FBlueprintEditorUtils::FindBlueprintForGraph(graph));
152214
UEdGraphSchema_K2::SetNodeMetaData(node, FNodeMetadata::DefaultGraphNode);
153215
FEdGraphSchemaAction_K2NewNode::SpawnNodeFromTemplate<UK2Node_VariableGet>(graph, node, FVector2D(x, y));
@@ -196,12 +258,6 @@ PyObject *py_ue_graph_add_node_variable_set(ue_PyUObject * self, PyObject * args
196258

197259
UK2Node_VariableSet *node = NewObject<UK2Node_VariableSet>(graph);
198260

199-
node->CreateNewGuid();
200-
node->PostPlacedNewNode();
201-
node->SetFlags(RF_Transactional);
202-
node->AllocateDefaultPins();
203-
node->NodePosX = x;
204-
node->NodePosY = y;
205261
UEdGraphSchema_K2::ConfigureVarNode(node, FName(UTF8_TO_TCHAR(name)), u_struct, FBlueprintEditorUtils::FindBlueprintForGraph(graph));
206262
UEdGraphSchema_K2::SetNodeMetaData(node, FNodeMetadata::DefaultGraphNode);
207263
FEdGraphSchemaAction_K2NewNode::SpawnNodeFromTemplate<UK2Node_VariableSet>(graph, node, FVector2D(x, y));

‎Source/UnrealEnginePython/Private/UEPyEdGraph.h‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ PyObject *py_ue_graph_add_node_custom_event(ue_PyUObject *, PyObject *);
1010
PyObject *py_ue_graph_add_node_variable_get(ue_PyUObject *, PyObject *);
1111
PyObject *py_ue_graph_add_node_variable_set(ue_PyUObject *, PyObject *);
1212
PyObject *py_ue_graph_add_node(ue_PyUObject *, PyObject *);
13+
PyObject *py_ue_graph_add_node_event(ue_PyUObject *, PyObject *);
14+
15+
PyObject *py_ue_graph_get_good_place_for_new_node(ue_PyUObject *, PyObject *);
1316

1417
PyObject *py_ue_node_pins(ue_PyUObject *, PyObject *);
1518
PyObject *py_ue_node_find_pin(ue_PyUObject *, PyObject *);

‎Source/UnrealEnginePython/Private/UEPyEdGraphPin.cpp‎

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,49 @@ static PyObject *py_ue_edgraphpin_get_sub_category(ue_PyEdGraphPin *self, void *
6464
return PyUnicode_FromString(TCHAR_TO_UTF8(*(self->pin->PinType.PinSubCategory)));
6565
}
6666

67+
static PyObject *py_ue_edgraphpin_get_default_value(ue_PyEdGraphPin *self, void *closure) {
68+
return PyUnicode_FromString(TCHAR_TO_UTF8(*(self->pin->DefaultValue)));
69+
}
70+
71+
static int py_ue_edgraphpin_set_default_value(ue_PyEdGraphPin *self, PyObject *value, void *closure) {
72+
if (value && PyUnicode_Check(value)) {
73+
char *str = PyUnicode_AsUTF8(value);
74+
self->pin->DefaultValue = UTF8_TO_TCHAR(str);
75+
return 0;
76+
}
77+
PyErr_SetString(PyExc_TypeError, "value is not a string");
78+
return -1;
79+
}
80+
81+
static PyObject *py_ue_edgraphpin_get_default_object(ue_PyEdGraphPin *self, void *closure) {
82+
UObject *u_object = self->pin->DefaultObject;
83+
if (!u_object) {
84+
Py_INCREF(Py_None);
85+
return Py_None;
86+
}
87+
PyObject *ret = (PyObject *)ue_get_python_wrapper(u_object);
88+
if (!ret)
89+
return PyErr_Format(PyExc_Exception, "uobject is in invalid state");
90+
Py_INCREF(ret);
91+
return ret;
92+
}
93+
94+
static int py_ue_edgraphpin_set_default_object(ue_PyEdGraphPin *self, PyObject *value, void *closure) {
95+
if (value && ue_is_pyuobject(value)) {
96+
ue_PyUObject *py_obj = (ue_PyUObject *)value;
97+
self->pin->DefaultObject = py_obj->ue_object;
98+
return 0;
99+
}
100+
PyErr_SetString(PyExc_TypeError, "value is not a string");
101+
return -1;
102+
}
103+
67104
static PyGetSetDef ue_PyEdGraphPin_getseters[] = {
68105
{ (char*)"name", (getter)py_ue_edgraphpin_get_name, NULL, (char *)"", NULL },
69106
{ (char*)"category", (getter)py_ue_edgraphpin_get_category, NULL, (char *)"", NULL },
70107
{ (char*)"sub_category", (getter)py_ue_edgraphpin_get_sub_category, NULL, (char *)"", NULL },
108+
{ (char*)"default_value", (getter)py_ue_edgraphpin_get_default_value, (setter)py_ue_edgraphpin_set_default_value, (char *)"", NULL },
109+
{ (char*)"default_object", (getter)py_ue_edgraphpin_get_default_object, (setter)py_ue_edgraphpin_set_default_object, (char *)"", NULL },
71110
{ NULL } /* Sentinel */
72111
};
73112

‎Source/UnrealEnginePython/Private/UEPyModule.cpp‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,8 @@ static PyMethodDef ue_PyUObject_methods[] = {
314314
{ "graph_add_node_variable_set", (PyCFunction)py_ue_graph_add_node_variable_set, METH_VARARGS, "" },
315315

316316
{ "graph_add_node", (PyCFunction)py_ue_graph_add_node, METH_VARARGS, "" },
317+
{ "graph_add_node_event", (PyCFunction)py_ue_graph_add_node_event, METH_VARARGS, "" },
318+
{ "graph_get_good_place_for_new_node", (PyCFunction)py_ue_graph_get_good_place_for_new_node, METH_VARARGS, "" },
317319

318320
{ "node_pins", (PyCFunction)py_ue_node_pins, METH_VARARGS, "" },
319321
{ "node_find_pin", (PyCFunction)py_ue_node_find_pin, METH_VARARGS, "" },

0 commit comments

Comments
 (0)