648 lines
15 KiB
Plaintext
648 lines
15 KiB
Plaintext
import json
|
|
import copy
|
|
import math
|
|
import numpy
|
|
|
|
numpy.set_printoptions(suppress=True)
|
|
|
|
def gen_id():
|
|
new_id = 42
|
|
while True:
|
|
yield new_id
|
|
new_id += 1
|
|
|
|
|
|
def gen_y():
|
|
y = 7
|
|
while True:
|
|
yield y
|
|
y += 3
|
|
|
|
new_id = gen_id()
|
|
y_position = gen_y()
|
|
new_nodes = {}
|
|
shift_left = 32
|
|
|
|
def set_transform(node, transform):
|
|
x_axis = transform[0]
|
|
y_axis = transform[1]
|
|
|
|
# Assuming there is no vertical shear
|
|
angle = math.atan2( x_axis[1], x_axis[0])
|
|
(sin, cos) = math.sin(angle), math.cos(angle)
|
|
scale_x = x_axis[0] / cos if math.fabs(cos) > 1e-10 else x_axis[1] / sin
|
|
|
|
shear_x = (sin * y_axis[1] + cos * y_axis[0]) / (sin * sin * scale_x + cos * cos * scale_x);
|
|
if not numpy.isfinite(shear_x):
|
|
shear_x = 0.;
|
|
|
|
scale_y = (y_axis[1] - scale_x * sin * shear_x) / cos if math.fabs(cos) > 1e-10 else (scale_x * cos * shear_x - y_axis[0]) / sin
|
|
|
|
translation = transform[2][:2]
|
|
node["inputs"][1] = {"Value": { "tagged_value": { "DVec2": [translation[0], translation[1]] }, "exposed": False}}
|
|
node["inputs"][2] = {"Value": { "tagged_value": { "F32": angle }, "exposed": False}}
|
|
node["inputs"][3] = {"Value": { "tagged_value": { "DVec2": [scale_x, scale_y] }, "exposed": False}}
|
|
node["inputs"][4] = {"Value": { "tagged_value": { "DVec2": [shear_x, 0] }, "exposed": False}}
|
|
node["inputs"][5] = {"Value": { "tagged_value": { "DVec2": [0,0] }, "exposed": False}}
|
|
|
|
def to_transform(transform):
|
|
mat = transform["matrix2"]
|
|
translation = transform["translation"]
|
|
return numpy.array([[mat[0], mat[1], 0], [mat[2], mat[3], 0], [translation[0], translation[1], 1]])
|
|
|
|
def update_layer(layer, indent, layer_node_id, next_id, opacity):
|
|
data = layer["data"]
|
|
|
|
opacity = opacity * layer["opacity"]
|
|
|
|
y = next(y_position)
|
|
output = None
|
|
if "Folder" in data:
|
|
new_layer_ids = list(map(lambda x, _: x, new_id, data["Folder"]["layers"]))
|
|
output = new_layer_ids[0]
|
|
insert_transform = "transform" in layer and (numpy.identity(3) != to_transform(layer["transform"])).any()
|
|
if insert_transform:
|
|
node = {
|
|
"name": "Transform",
|
|
"implementation": {"Unresolved":{"name": "graphene_core::transform::TransformNode<_, _, _, _, _, _>"}},
|
|
"manual_composition":{"Concrete":{"name":"graphene_core::transform::Footprint","size":72,"align":8}},
|
|
"metadata": {"position": [-indent-8,y]},
|
|
"skip_deduplication": False,
|
|
"path": None,
|
|
"manual_composition": {"Concrete": {"name": "graphene_core::transform::Footprint","size": 72,"align": 8}},
|
|
"inputs":[{"Node":{"node_id":output,"output_index":0,"lambda":False}}, None, None, None, None, None]
|
|
}
|
|
transform_id = next(new_id)
|
|
new_nodes[str(transform_id)] = node
|
|
output = transform_id
|
|
set_transform(node, to_transform(layer["transform"]))
|
|
indent += 8
|
|
|
|
|
|
|
|
for index, layer in enumerate(reversed(data["Folder"]["layers"])):
|
|
next_index = None
|
|
if index +1 < len(new_layer_ids):
|
|
next_index = new_layer_ids[index+1]
|
|
update_layer(layer, indent + 5, new_layer_ids[index], next_index, opacity)
|
|
|
|
if insert_transform:
|
|
indent -= 8
|
|
|
|
if "Layer" in data:
|
|
network = data["Layer"]["network"]
|
|
|
|
nodes = set(filter(lambda old_id: network["nodes"][old_id]["name"] != "Output", set(network["nodes"])))
|
|
|
|
new_ids = dict(zip(map(lambda id: int(id), nodes), new_id))
|
|
|
|
output_node = network["nodes"][str(network["outputs"][0]["node_id"])]
|
|
shift_left = output_node["metadata"]["position"][0]
|
|
output = new_ids[int(output_node["inputs"][0]["Node"]["node_id"])]
|
|
|
|
for old_id in nodes:
|
|
node = network["nodes"][old_id]
|
|
for node_input in node["inputs"]:
|
|
if "Node" in node_input:
|
|
node_input["Node"]["node_id"] = new_ids[node_input["Node"]["node_id"]]
|
|
if node["name"] == "Transform":
|
|
node["implementation"]={"Unresolved":{"name": "graphene_core::transform::TransformNode<_, _, _, _, _, _>"}}
|
|
node["manual_composition"]={"Concrete":{"name":"graphene_core::transform::Footprint","size":72,"align":8}}
|
|
|
|
if node["name"] == "Shape":
|
|
if not any(map(lambda x: network["nodes"][x]["name"] == "Cull", nodes)):
|
|
node["metadata"]["position"][1] = y
|
|
node["metadata"]["position"][0] -= shift_left + 8 + indent
|
|
if opacity != 1:
|
|
node["metadata"]["position"][0] -= 8
|
|
shape = next(new_id)
|
|
cull = next(new_id)
|
|
|
|
new_nodes[str(shape)] = copy.deepcopy(node)
|
|
|
|
node["name"] = "Cull"
|
|
node["inputs"] = [{"Node":{"node_id":shape,"output_index":0,"lambda":False}}]
|
|
node["manual_composition"] = {"Concrete":{"name":"graphene_core::transform::Footprint","size":72,"align":8}}
|
|
node["has_primary_output"] = True
|
|
node["implementation"] = {"Unresolved":{"name":"graphene_core::transform::CullNode<_>"}}
|
|
|
|
if opacity != 1:
|
|
node["metadata"]["position"][0] += 8
|
|
new_nodes[str(cull)] = copy.deepcopy(node)
|
|
|
|
node["name"] = "Opacity"
|
|
node["inputs"] = [{"Node":{"node_id":cull,"output_index":0,"lambda":False}}, {"Value":{"tagged_value":{"F32":opacity * 100},"exposed":False}}]
|
|
node["manual_composition"] = None
|
|
node["has_primary_output"] = True
|
|
node["implementation"] = {"Unresolved":{"name":"graphene_core::raster::OpacityNode<_>"}}
|
|
node["metadata"]["position"][0] += 8 + shift_left + indent
|
|
|
|
node["metadata"]["position"][1] = y
|
|
node["metadata"]["position"][0] -= shift_left + indent
|
|
|
|
new_nodes[str(new_ids[int(old_id)])] = node
|
|
|
|
|
|
|
|
assert(output == None or str(output) in new_nodes)
|
|
|
|
node_to_input = lambda node_id: {"Node": {"node_id": node_id,"output_index": 0,"lambda": False}} if node_id else {"Value":{"tagged_value":{"GraphicGroup":{"elements":[],"opacity":1.0,"transform":[1.0,0.0,0.0,1.0,0.0,0.0]}},"exposed":True}}
|
|
|
|
node = {
|
|
"name": "Layer",
|
|
"inputs": [
|
|
node_to_input(output),
|
|
{
|
|
"Value": {
|
|
"tagged_value": {
|
|
"String": layer["name"] or "Untitled"
|
|
},
|
|
"exposed": False
|
|
}
|
|
},
|
|
{
|
|
"Value": {
|
|
"tagged_value": {
|
|
"BlendMode": layer["blend_mode"]
|
|
},
|
|
"exposed": False
|
|
}
|
|
},
|
|
{
|
|
"Value": {
|
|
"tagged_value": {
|
|
"F32": 100.0
|
|
},
|
|
"exposed": False
|
|
}
|
|
},
|
|
{
|
|
"Value": {
|
|
"tagged_value": {
|
|
"Bool": True
|
|
},
|
|
"exposed": False
|
|
}
|
|
},
|
|
{
|
|
"Value": {
|
|
"tagged_value": {
|
|
"Bool": False
|
|
},
|
|
"exposed": False
|
|
}
|
|
},
|
|
{
|
|
"Value": {
|
|
"tagged_value": {
|
|
"Bool": False
|
|
},
|
|
"exposed": False
|
|
}
|
|
},
|
|
node_to_input(next_id)
|
|
],
|
|
"manual_composition": None,
|
|
"has_primary_output": True,
|
|
"implementation": {
|
|
"Network": {
|
|
"inputs": [
|
|
0,
|
|
2,
|
|
2,
|
|
2,
|
|
2,
|
|
2,
|
|
2,
|
|
2
|
|
],
|
|
"outputs": [
|
|
{
|
|
"node_id": 2,
|
|
"node_output_index": 0
|
|
}
|
|
],
|
|
"nodes": {
|
|
"1": {
|
|
"name": "Monitor",
|
|
"inputs": [
|
|
{
|
|
"Node": {
|
|
"node_id": 0,
|
|
"output_index": 0,
|
|
"lambda": False
|
|
}
|
|
}
|
|
],
|
|
"manual_composition": {
|
|
"Concrete": {
|
|
"name": "graphene_core::transform::Footprint",
|
|
"size": 72,
|
|
"align": 8
|
|
}
|
|
},
|
|
"has_primary_output": True,
|
|
"implementation": {
|
|
"Unresolved": {
|
|
"name": "graphene_core::memo::MonitorNode<_, _, _>"
|
|
}
|
|
},
|
|
"metadata": {
|
|
"position": [
|
|
0,
|
|
0
|
|
]
|
|
},
|
|
"skip_deduplication": True,
|
|
"world_state_hash": 0,
|
|
"path": None
|
|
},
|
|
"2": {
|
|
"name": "ConstructLayer",
|
|
"inputs": [
|
|
{
|
|
"Node": {
|
|
"node_id": 1,
|
|
"output_index": 0,
|
|
"lambda": False
|
|
}
|
|
},
|
|
{
|
|
"Network": {
|
|
"Fn": [
|
|
{
|
|
"Concrete": {
|
|
"name": "graphene_core::transform::Footprint",
|
|
"size": 72,
|
|
"align": 8
|
|
}
|
|
},
|
|
{
|
|
"Concrete": {
|
|
"name": "graphene_core::graphic_element::GraphicGroup",
|
|
"size": 12,
|
|
"align": 4
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
],
|
|
"manual_composition": {
|
|
"Concrete": {
|
|
"name": "graphene_core::transform::Footprint",
|
|
"size": 72,
|
|
"align": 8
|
|
}
|
|
},
|
|
"has_primary_output": True,
|
|
"implementation": {
|
|
"Unresolved": {
|
|
"name": "graphene_core::ConstructLayerNode<_, _, _, _, _, _, _, _>"
|
|
}
|
|
},
|
|
"metadata": {
|
|
"position": [
|
|
0,
|
|
0
|
|
]
|
|
},
|
|
"skip_deduplication": False,
|
|
"world_state_hash": 0,
|
|
"path": None
|
|
},
|
|
"0": {
|
|
"name": "To Graphic Element",
|
|
"inputs": [
|
|
{
|
|
"Network": {
|
|
"Generic": "T"
|
|
}
|
|
}
|
|
],
|
|
"manual_composition": None,
|
|
"has_primary_output": True,
|
|
"implementation": {
|
|
"Unresolved": {
|
|
"name": "graphene_core::ToGraphicElementNode"
|
|
}
|
|
},
|
|
"metadata": {
|
|
"position": [
|
|
0,
|
|
0
|
|
]
|
|
},
|
|
"skip_deduplication": False,
|
|
"world_state_hash": 0,
|
|
"path": None
|
|
}
|
|
},
|
|
"disabled": [],
|
|
"previous_outputs": None
|
|
}
|
|
},
|
|
"metadata": {
|
|
"position": [
|
|
-indent,
|
|
y
|
|
]
|
|
},
|
|
"skip_deduplication": False,
|
|
"world_state_hash": 0,
|
|
"path": None
|
|
}
|
|
new_nodes[str(layer_node_id)] = node
|
|
|
|
def migrate(name, new_name):
|
|
global new_id, new_id ,y_position, new_nodes
|
|
new_id = gen_id()
|
|
y_position = gen_y()
|
|
new_nodes = {}
|
|
|
|
with open(name) as f:
|
|
document = json.load(f)
|
|
layer = document["document_legacy"]["root"]
|
|
data = layer["data"]
|
|
new_layer_ids = list(map(lambda x, _: x, new_id, data["Folder"]["layers"]))
|
|
for index, layer in enumerate(reversed(data["Folder"]["layers"])):
|
|
next_index = None
|
|
if index + 1 < len(new_layer_ids):
|
|
next_index = new_layer_ids[index+1]
|
|
update_layer(layer, 5, new_layer_ids[index], next_index, 1)
|
|
|
|
new_nodes["0"] = {
|
|
"name": "Output",
|
|
"inputs": [
|
|
{
|
|
"Node": {
|
|
"node_id": 42,
|
|
"output_index": 0,
|
|
"lambda": False
|
|
}
|
|
},
|
|
{
|
|
"Network": {
|
|
"Concrete": {
|
|
"name": "graphene_core::application_io::EditorApi<graphene_std::wasm_application_io::WasmApplicationIo>",
|
|
"size": 176,
|
|
"align": 8
|
|
}
|
|
}
|
|
}
|
|
],
|
|
"manual_composition": None,
|
|
"has_primary_output": True,
|
|
"implementation": {
|
|
"Network": {
|
|
"inputs": [
|
|
3,
|
|
0
|
|
],
|
|
"outputs": [
|
|
{
|
|
"node_id": 3,
|
|
"node_output_index": 0
|
|
}
|
|
],
|
|
"nodes": {
|
|
"1": {
|
|
"name": "Create Canvas",
|
|
"inputs": [
|
|
{
|
|
"Node": {
|
|
"node_id": 0,
|
|
"output_index": 0,
|
|
"lambda": False
|
|
}
|
|
}
|
|
],
|
|
"manual_composition": None,
|
|
"has_primary_output": True,
|
|
"implementation": {
|
|
"Unresolved": {
|
|
"name": "graphene_std::wasm_application_io::CreateSurfaceNode"
|
|
}
|
|
},
|
|
"metadata": {
|
|
"position": [
|
|
0,
|
|
0
|
|
]
|
|
},
|
|
"skip_deduplication": True,
|
|
"world_state_hash": 0,
|
|
"path": None
|
|
},
|
|
"3": {
|
|
"name": "RenderNode",
|
|
"inputs": [
|
|
{
|
|
"Node": {
|
|
"node_id": 0,
|
|
"output_index": 0,
|
|
"lambda": False
|
|
}
|
|
},
|
|
{
|
|
"Network": {
|
|
"Fn": [
|
|
{
|
|
"Concrete": {
|
|
"name": "graphene_core::transform::Footprint",
|
|
"size": 72,
|
|
"align": 8
|
|
}
|
|
},
|
|
{
|
|
"Generic": "T"
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"Node": {
|
|
"node_id": 2,
|
|
"output_index": 0,
|
|
"lambda": False
|
|
}
|
|
}
|
|
],
|
|
"manual_composition": None,
|
|
"has_primary_output": True,
|
|
"implementation": {
|
|
"Unresolved": {
|
|
"name": "graphene_std::wasm_application_io::RenderNode<_, _, _>"
|
|
}
|
|
},
|
|
"metadata": {
|
|
"position": [
|
|
0,
|
|
0
|
|
]
|
|
},
|
|
"skip_deduplication": False,
|
|
"world_state_hash": 0,
|
|
"path": None
|
|
},
|
|
"2": {
|
|
"name": "Cache",
|
|
"inputs": [
|
|
{
|
|
"Node": {
|
|
"node_id": 1,
|
|
"output_index": 0,
|
|
"lambda": False
|
|
}
|
|
}
|
|
],
|
|
"manual_composition": {
|
|
"Concrete": {
|
|
"name": "()",
|
|
"size": 0,
|
|
"align": 1
|
|
}
|
|
},
|
|
"has_primary_output": True,
|
|
"implementation": {
|
|
"Unresolved": {
|
|
"name": "graphene_core::memo::MemoNode<_, _>"
|
|
}
|
|
},
|
|
"metadata": {
|
|
"position": [
|
|
0,
|
|
0
|
|
]
|
|
},
|
|
"skip_deduplication": False,
|
|
"world_state_hash": 0,
|
|
"path": None
|
|
},
|
|
"0": {
|
|
"name": "EditorApi",
|
|
"inputs": [
|
|
{
|
|
"Network": {
|
|
"Concrete": {
|
|
"name": "graphene_core::application_io::EditorApi<graphene_std::wasm_application_io::WasmApplicationIo>",
|
|
"size": 176,
|
|
"align": 8
|
|
}
|
|
}
|
|
}
|
|
],
|
|
"manual_composition": None,
|
|
"has_primary_output": True,
|
|
"implementation": {
|
|
"Unresolved": {
|
|
"name": "graphene_core::ops::IdentityNode"
|
|
}
|
|
},
|
|
"metadata": {
|
|
"position": [
|
|
0,
|
|
0
|
|
]
|
|
},
|
|
"skip_deduplication": False,
|
|
"world_state_hash": 0,
|
|
"path": None
|
|
}
|
|
},
|
|
"disabled": [],
|
|
"previous_outputs": None
|
|
}
|
|
},
|
|
"metadata": {
|
|
"position": [
|
|
8,
|
|
4
|
|
]
|
|
},
|
|
"skip_deduplication": False,
|
|
"world_state_hash": 0,
|
|
"path": None
|
|
}
|
|
|
|
document = {
|
|
"document_legacy": {
|
|
"root": {
|
|
"visible": True,
|
|
"name": None,
|
|
"data": {
|
|
"Folder": {
|
|
"next_assignment_id": 0,
|
|
"layer_ids": [],
|
|
"layers": []
|
|
}
|
|
},
|
|
"transform": {
|
|
"matrix2": [
|
|
1.0,
|
|
0.0,
|
|
0.0,
|
|
1.0
|
|
],
|
|
"translation": [
|
|
0.0,
|
|
0.0
|
|
]
|
|
},
|
|
"preserve_aspect": True,
|
|
"pivot": [
|
|
0.5,
|
|
0.5
|
|
],
|
|
"blend_mode": "Normal",
|
|
"opacity": 1.0
|
|
},
|
|
"document_network": {
|
|
"inputs": [],
|
|
"outputs": [
|
|
{
|
|
"node_id": 0,
|
|
"node_output_index": 0
|
|
}
|
|
],
|
|
"nodes": new_nodes,
|
|
"disabled": [],
|
|
"previous_outputs": None
|
|
},
|
|
"commit_hash": "ef46080400bc6c4e069765dd2127306abbc9a94b"
|
|
},
|
|
"saved_document_identifier": 0,
|
|
"auto_saved_document_identifier": 0,
|
|
"name": "Untitled Document 10",
|
|
"version": "0.0.18",
|
|
"document_mode": "DesignMode",
|
|
"view_mode": "Normal",
|
|
"overlays_visible": True,
|
|
"layer_metadata": [],
|
|
"layer_range_selection_reference": None,
|
|
"navigation_handler": {
|
|
"pan": [
|
|
82.0,
|
|
84.0
|
|
],
|
|
"tilt": 0.0,
|
|
"zoom": 1.0,
|
|
"transform_operation": "None",
|
|
"mouse_position": [
|
|
389.0,
|
|
507.0
|
|
],
|
|
"finish_operation_with_click": False
|
|
},
|
|
"properties_panel_message_handler": {
|
|
"active_selection": None
|
|
}
|
|
}
|
|
|
|
|
|
with open(new_name, "w+") as f:
|
|
json.dump(document, f, indent="\t")
|
|
|
|
migrate("just-a-potted-cactus.graphite","migrated_just_a_potted_cactus.graphite")
|
|
migrate("valley-of-spires.graphite","migrated_valley_of_spires.graphite")
|