178 lines
4.8 KiB
Python
178 lines
4.8 KiB
Python
from __future__ import annotations
|
|
|
|
from time import sleep
|
|
|
|
import pydiffvg
|
|
import torch
|
|
import random
|
|
from random import uniform
|
|
|
|
from gmtypes import GradientMesh, Quad, Patch, Point, join_quads
|
|
|
|
|
|
def quads():
|
|
return [
|
|
Quad.random(),
|
|
Quad.random(),
|
|
Quad.random(),
|
|
Quad.random(),
|
|
]
|
|
|
|
|
|
def rand_quad_test(filename='random_quad.png', width=256, height=256,
|
|
degree=4, num_control_points=2):
|
|
pydiffvg.set_use_gpu(torch.cuda.is_available())
|
|
render = pydiffvg.RenderFunction.apply
|
|
|
|
patch = Patch.random()
|
|
|
|
shape_groups = [patch.as_shape_group()]
|
|
shapes = [patch.as_path(width, height)]
|
|
|
|
scene_args = pydiffvg.RenderFunction.serialize_scene(width, height,
|
|
shapes, shape_groups)
|
|
|
|
img = render(width, height, 2, 2, 0, None, *scene_args)
|
|
pydiffvg.imwrite(img.cpu(), f"test_data/{filename}", gamma=2.2)
|
|
|
|
return img
|
|
|
|
|
|
def mult_quad_test(filename='multiple_quads.png', width=1024,
|
|
height=1024, num_control_points=None, mask=None, seed=None):
|
|
random.seed(seed)
|
|
mask = mask or [1, 1, 1, 1]
|
|
pydiffvg.set_use_gpu(torch.cuda.is_available())
|
|
render = pydiffvg.RenderFunction.apply
|
|
|
|
a, b, c, d = quads()
|
|
join_quads(a, b, c, d)
|
|
|
|
to_render = [a, b, c, d]
|
|
to_render = [x for x in to_render if mask[to_render.index(x)]]
|
|
|
|
shape_groups = [patch.as_shape_group(color=(
|
|
uniform(0, 1),
|
|
uniform(0, 1),
|
|
uniform(0, 1),
|
|
0.8
|
|
)) for patch in to_render]
|
|
|
|
for i in range(len(to_render)):
|
|
shape_groups[i].shape_ids = torch.tensor([i])
|
|
shapes = [patch.as_path(width, height) for patch in to_render]
|
|
|
|
scene_args = pydiffvg.RenderFunction.serialize_scene(width, height,
|
|
shapes, shape_groups)
|
|
|
|
img = render(width, height, 2, 2, 0, None, *scene_args)
|
|
pydiffvg.imwrite(img.cpu(), f"test_data/{filename}", gamma=2.2)
|
|
return img.clone()
|
|
|
|
|
|
def om():
|
|
filename = 'optimize_test.png'
|
|
pydiffvg.set_use_gpu(torch.cuda.is_available())
|
|
render = pydiffvg.RenderFunction.apply
|
|
|
|
target = mult_quad_test(width=256, height=256)
|
|
|
|
squad = quads()
|
|
|
|
join_quads(*squad)
|
|
|
|
gm = GradientMesh(*squad)
|
|
|
|
points_n = []
|
|
for s in squad:
|
|
out = []
|
|
for pt in s.points:
|
|
out.append([pt.x, pt.y])
|
|
for cpt in pt.controls:
|
|
out.append([cpt.x, cpt.y])
|
|
points_n.append(out)
|
|
|
|
points_n = torch.tensor(points_n, requires_grad=True)
|
|
color = torch.tensor([s.color for s in squad], requires_grad=True)
|
|
|
|
paths = [s.as_path() for s in squad]
|
|
path_groups = [pydiffvg.ShapeGroup(shape_ids=torch.tensor([i]),
|
|
fill_color=torch.tensor(squad[i].color))
|
|
for i in range(len(squad))]
|
|
scene_args = pydiffvg.RenderFunction.serialize_scene(
|
|
256, 256, paths, path_groups
|
|
)
|
|
img = render(256, # width
|
|
256, # height
|
|
2, # num_samples_x
|
|
2, # num_samples_y
|
|
1, # seed
|
|
None,
|
|
*scene_args)
|
|
|
|
points, controls, color = [torch.tensor(x, requires_grad=True)
|
|
for x in gm.to_numbers()]
|
|
|
|
optimizer = torch.optim.Adam([points, color, points_n], lr=1e-2)
|
|
|
|
for t in range(180):
|
|
print(f"iteration {t}")
|
|
optimizer.zero_grad()
|
|
|
|
points_n.data = torch.tensor(
|
|
GradientMesh.from_path_points(points_n, color).to_path_points()
|
|
)
|
|
|
|
for i in range(len(paths)):
|
|
paths[i].points = points_n[i] * 256
|
|
|
|
for i in range(len(path_groups)):
|
|
path_groups[i].fill_color = color[i]
|
|
|
|
scene_args = pydiffvg.RenderFunction.serialize_scene(
|
|
256, 256, paths, path_groups)
|
|
|
|
img = render(256, # width
|
|
256, # height
|
|
2, # num_samples_x
|
|
2, # num_samples_y
|
|
t+1, # seed
|
|
None,
|
|
*scene_args)
|
|
|
|
pydiffvg.imwrite(img.cpu(),
|
|
f'test_data/test_curve/iter_{filename}_'
|
|
f'{str(t).zfill(5)}.png',
|
|
gamma=2.2)
|
|
|
|
loss = (img - target).pow(2).sum()
|
|
|
|
loss.backward()
|
|
|
|
print(f'loss: {loss}')
|
|
print(f'points.grad {points.grad}')
|
|
print(f'color.grad {color.grad}')
|
|
|
|
optimizer.step()
|
|
|
|
|
|
def slideshow(n=30, s=1, do_mask=False):
|
|
mask = None
|
|
for i in range(n):
|
|
if do_mask:
|
|
mask = [1] * 4
|
|
print(i % n)
|
|
mask[i % 4] = 0
|
|
print(mask)
|
|
|
|
mult_quad_test(mask=mask)
|
|
sleep(s)
|
|
|
|
|
|
def get_mesh():
|
|
a, b, c, d = quads()
|
|
join_quads(a,b,c,d)
|
|
|
|
gm = GradientMesh(a, b, c, d)
|
|
return gm
|