erge branch 'master' of http://git.nakadashi.lol/akko/diffvg
@@ -1,5 +0,0 @@
|
||||
v 100 150
|
||||
v 42.3 50
|
||||
v 157.7 50
|
||||
|
||||
f 1 2 3
|
@@ -3,140 +3,146 @@ import torch
|
||||
import skimage
|
||||
import numpy as np
|
||||
|
||||
# Use GPU if available
|
||||
pydiffvg.set_use_gpu(torch.cuda.is_available())
|
||||
def run():
|
||||
|
||||
canvas_width, canvas_height = 256, 256
|
||||
num_control_points = torch.tensor([2, 2, 2])
|
||||
points = torch.tensor([[20.0, 30.0], # base
|
||||
[50.0, 60.0], # control point
|
||||
[ 90.0, 198.0], # control point
|
||||
[ 60.0, 218.0], # base
|
||||
[ 90.0, 180.0], # control point
|
||||
[200.0, 85.0], # control point
|
||||
[230.0, 90.0], # base
|
||||
[220.0, 70.0], # control point
|
||||
[130.0, 55.0]]) # control point
|
||||
path = pydiffvg.Path(num_control_points = num_control_points,
|
||||
points = points,
|
||||
is_closed = True)
|
||||
shapes = [path]
|
||||
path_group = pydiffvg.ShapeGroup(shape_ids = torch.tensor([0]),
|
||||
fill_color = torch.tensor([0.3, 0.6, 0.3, 1.0]))
|
||||
shape_groups = [path_group]
|
||||
scene_args = pydiffvg.RenderFunction.serialize_scene(\
|
||||
canvas_width, canvas_height, shapes, shape_groups)
|
||||
# Use GPU if available
|
||||
pydiffvg.set_use_gpu(torch.cuda.is_available())
|
||||
|
||||
render = pydiffvg.RenderFunction.apply
|
||||
img = render(256, # width
|
||||
256, # height
|
||||
2, # num_samples_x
|
||||
2, # num_samples_y
|
||||
0, # seed
|
||||
None,
|
||||
*scene_args)
|
||||
# The output image is in linear RGB space. Do Gamma correction before saving the image.
|
||||
pydiffvg.imwrite(img.cpu(), 'results/test_curve/target.png', gamma=2.2)
|
||||
target = img.clone()
|
||||
canvas_width, canvas_height = 256, 256
|
||||
num_control_points = torch.tensor([2, 2, 2])
|
||||
points = torch.tensor([[20.0, 30.0], # base
|
||||
[50.0, 60.0], # control point
|
||||
[ 90.0, 198.0], # control point
|
||||
[ 60.0, 218.0], # base
|
||||
[ 90.0, 180.0], # control point
|
||||
[200.0, 85.0], # control point
|
||||
[230.0, 90.0], # base
|
||||
[220.0, 70.0], # control point
|
||||
[130.0, 55.0]]) # control point
|
||||
path = pydiffvg.Path(num_control_points = num_control_points,
|
||||
points = points,
|
||||
is_closed = True)
|
||||
shapes = [path]
|
||||
path_group = pydiffvg.ShapeGroup(shape_ids = torch.tensor([0]),
|
||||
fill_color = torch.tensor([0.3, 0.6, 0.3, 1.0]))
|
||||
shape_groups = [path_group]
|
||||
scene_args = pydiffvg.RenderFunction.serialize_scene(\
|
||||
canvas_width, canvas_height, shapes, shape_groups)
|
||||
|
||||
# Load the obj file, get the vertices/control points
|
||||
obj = "imgs/Triangle.obj"
|
||||
vertices_tmp, faces_tmp = pydiffvg.obj_to_scene(obj)
|
||||
print(float(vertices_tmp[1][1]))
|
||||
print(faces_tmp)
|
||||
render = pydiffvg.RenderFunction.apply
|
||||
img = render(256, # width
|
||||
256, # height
|
||||
2, # num_samples_x
|
||||
2, # num_samples_y
|
||||
0, # seed
|
||||
None,
|
||||
*scene_args)
|
||||
# The output image is in linear RGB space. Do Gamma correction before saving the image.
|
||||
pydiffvg.imwrite(img.cpu(), 'results/test_curve/target.png', gamma=2.2)
|
||||
target = img.clone()
|
||||
|
||||
vertices = []
|
||||
faces = []
|
||||
for v in vertices_tmp:
|
||||
vertices.append([float(v[1]), float(v[2])])
|
||||
for f in faces_tmp:
|
||||
vs_count = len(f)
|
||||
tmp = []
|
||||
for v in f[1:]:
|
||||
tmp.append(int(v))
|
||||
faces.append(tmp)
|
||||
print(vertices)
|
||||
print(faces)
|
||||
# Load the obj file, get the vertices/control points
|
||||
obj = "imgs/Triangle.obj"
|
||||
vertices_tmp, faces_tmp = pydiffvg.obj_to_scene(obj)
|
||||
print(float(vertices_tmp[1][1]))
|
||||
print(faces_tmp)
|
||||
|
||||
# Ternary subdivision
|
||||
# Move the path to produce initial guess
|
||||
# normalize points for easier learning rate
|
||||
points_n = torch.tensor([[vertices[0][0]/256.0, vertices[0][1]/256.0], # base
|
||||
[70.0/256.0, 140.0/256.0], # control point
|
||||
[50.0/256.0, 100.0/256.0], # control point
|
||||
[vertices[1][0]/256.0, vertices[1][1]/256.0], # base
|
||||
[80.0/256.0, 40.0/256.0], # control point
|
||||
[120.0/256.0, 40.0/256.0], # control point
|
||||
[vertices[2][0]/256.0, vertices[2][1]/256.0], # base
|
||||
[150.0/256.0, 100.0/256.0], # control point
|
||||
[130.0/256.0, 140.0/256.0]], # control point
|
||||
requires_grad = True)
|
||||
color = torch.tensor([0.3, 0.2, 0.5, 1.0], requires_grad=True)
|
||||
path.points = points_n * 256
|
||||
path_group.fill_color = color
|
||||
scene_args = pydiffvg.RenderFunction.serialize_scene(\
|
||||
canvas_width, canvas_height, shapes, shape_groups)
|
||||
img = render(256, # width
|
||||
256, # height
|
||||
2, # num_samples_x
|
||||
2, # num_samples_y
|
||||
1, # seed
|
||||
None,
|
||||
*scene_args)
|
||||
pydiffvg.imwrite(img.cpu(), 'results/test_curve/init.png', gamma=2.2)
|
||||
vertices = []
|
||||
faces = []
|
||||
for v in vertices_tmp:
|
||||
vertices.append([float(v[1]), float(v[2])])
|
||||
for f in faces_tmp:
|
||||
vs_count = len(f)
|
||||
tmp = []
|
||||
for v in f[1:]:
|
||||
tmp.append(int(v))
|
||||
faces.append(tmp)
|
||||
print(vertices)
|
||||
print(faces)
|
||||
|
||||
# Optimize
|
||||
optimizer = torch.optim.Adam([points_n, color], lr=1e-2)
|
||||
# Run 100 Adam iterations.
|
||||
for t in range(100):
|
||||
print('iteration:', t)
|
||||
optimizer.zero_grad()
|
||||
# Forward pass: render the image.
|
||||
# Ternary subdivision
|
||||
# Move the path to produce initial guess
|
||||
# normalize points for easier learning rate
|
||||
points_n = torch.tensor([[vertices[0][0]/256.0, vertices[0][1]/256.0], # base
|
||||
[70.0/256.0, 140.0/256.0], # control point
|
||||
[50.0/256.0, 100.0/256.0], # control point
|
||||
[vertices[1][0]/256.0, vertices[1][1]/256.0], # base
|
||||
[80.0/256.0, 40.0/256.0], # control point
|
||||
[120.0/256.0, 40.0/256.0], # control point
|
||||
[vertices[2][0]/256.0, vertices[2][1]/256.0], # base
|
||||
[150.0/256.0, 100.0/256.0], # control point
|
||||
[130.0/256.0, 140.0/256.0]], # control point
|
||||
requires_grad = True)
|
||||
color = torch.tensor([0.3, 0.2, 0.5, 1.0], requires_grad=True)
|
||||
path.points = points_n * 256
|
||||
path_group.fill_color = color
|
||||
scene_args = pydiffvg.RenderFunction.serialize_scene(\
|
||||
canvas_width, canvas_height, shapes, shape_groups)
|
||||
return scene_args
|
||||
img = render(256, # width
|
||||
256, # height
|
||||
2, # num_samples_x
|
||||
2, # num_samples_y
|
||||
1, # seed
|
||||
None,
|
||||
*scene_args)
|
||||
pydiffvg.imwrite(img.cpu(), 'results/test_curve/init.png', gamma=2.2)
|
||||
|
||||
# Optimize
|
||||
optimizer = torch.optim.Adam([points_n, color], lr=1e-2)
|
||||
# Run 100 Adam iterations.
|
||||
for t in range(100):
|
||||
print('iteration:', t)
|
||||
optimizer.zero_grad()
|
||||
# Forward pass: render the image.
|
||||
path.points = points_n * 256
|
||||
path_group.fill_color = color
|
||||
scene_args = pydiffvg.RenderFunction.serialize_scene(\
|
||||
canvas_width, canvas_height, shapes, shape_groups)
|
||||
img = render(256, # width
|
||||
256, # height
|
||||
2, # num_samples_x
|
||||
2, # num_samples_y
|
||||
t+1, # seed
|
||||
None,
|
||||
*scene_args)
|
||||
# Save the intermediate render.
|
||||
pydiffvg.imwrite(img.cpu(),
|
||||
'results/test_curve/iter_{}.png'.format(t), gamma=2.2)
|
||||
# Compute the loss function. Here it is L2.
|
||||
loss = (img - target).pow(2).sum()
|
||||
print('loss:', loss.item())
|
||||
|
||||
# Backpropagate the gradients.
|
||||
loss.backward()
|
||||
# Print the gradients
|
||||
print('points_n.grad:', points_n.grad)
|
||||
print('color.grad:', color.grad)
|
||||
|
||||
# Take a gradient descent step.
|
||||
optimizer.step()
|
||||
# Print the current params.
|
||||
print('points:', path.points)
|
||||
print('color:', path_group.fill_color)
|
||||
|
||||
# Render the final result.
|
||||
scene_args = pydiffvg.RenderFunction.serialize_scene(\
|
||||
canvas_width, canvas_height, shapes, shape_groups)
|
||||
img = render(256, # width
|
||||
256, # height
|
||||
2, # num_samples_x
|
||||
2, # num_samples_y
|
||||
t+1, # seed
|
||||
None,
|
||||
*scene_args)
|
||||
# Save the intermediate render.
|
||||
pydiffvg.imwrite(img.cpu(), 'results/test_curve/iter_{}.png'.format(t), gamma=2.2)
|
||||
# Compute the loss function. Here it is L2.
|
||||
loss = (img - target).pow(2).sum()
|
||||
print('loss:', loss.item())
|
||||
256, # height
|
||||
2, # num_samples_x
|
||||
2, # num_samples_y
|
||||
102, # seed
|
||||
None,
|
||||
*scene_args)
|
||||
# Save the images and differences.
|
||||
pydiffvg.imwrite(img.cpu(), 'results/test_curve/final.png')
|
||||
|
||||
# Backpropagate the gradients.
|
||||
loss.backward()
|
||||
# Print the gradients
|
||||
print('points_n.grad:', points_n.grad)
|
||||
print('color.grad:', color.grad)
|
||||
|
||||
# Take a gradient descent step.
|
||||
optimizer.step()
|
||||
# Print the current params.
|
||||
print('points:', path.points)
|
||||
print('color:', path_group.fill_color)
|
||||
|
||||
# Render the final result.
|
||||
scene_args = pydiffvg.RenderFunction.serialize_scene(\
|
||||
canvas_width, canvas_height, shapes, shape_groups)
|
||||
img = render(256, # width
|
||||
256, # height
|
||||
2, # num_samples_x
|
||||
2, # num_samples_y
|
||||
102, # seed
|
||||
None,
|
||||
*scene_args)
|
||||
# Save the images and differences.
|
||||
pydiffvg.imwrite(img.cpu(), 'results/test_curve/final.png')
|
||||
|
||||
# Convert the intermediate renderings to a video.
|
||||
from subprocess import call
|
||||
call(["ffmpeg", "-framerate", "24", "-i",
|
||||
"results/test_curve/iter_%d.png", "-vb", "20M",
|
||||
"results/test_curve/out.mp4"])
|
||||
# Convert the intermediate renderings to a video.
|
||||
from subprocess import call
|
||||
call(["ffmpeg", "-framerate", "24", "-i",
|
||||
"results/test_curve/iter_%d.png", "-vb", "20M",
|
||||
"results/test_curve/out.mp4"])
|
||||
|
||||
if __name__ == "__main__":
|
||||
run()
|
||||
|
13
color.h
@@ -7,7 +7,8 @@
|
||||
enum class ColorType {
|
||||
Constant,
|
||||
LinearGradient,
|
||||
RadialGradient
|
||||
RadialGradient,
|
||||
PatchGradient
|
||||
};
|
||||
|
||||
struct Constant {
|
||||
@@ -61,3 +62,13 @@ struct RadialGradient {
|
||||
float *stop_offsets;
|
||||
float *stop_colors; // rgba
|
||||
};
|
||||
|
||||
/*
|
||||
struct PatchGradient {
|
||||
PatchGradient(const Vector2f &topLeft,
|
||||
const Vector2f &topRight,
|
||||
const Vector2f &bottomLeft,
|
||||
const Vector2f &bottomRight,
|
||||
const )
|
||||
}
|
||||
*/
|
||||
|
20
diffvg.cpp
@@ -1490,6 +1490,11 @@ void render(std::shared_ptr<Scene> scene,
|
||||
bool use_prefiltering,
|
||||
ptr<float> eval_positions,
|
||||
int num_eval_positions) {
|
||||
|
||||
/////////////////
|
||||
// Setup stuff //
|
||||
/////////////////
|
||||
|
||||
#ifdef __NVCC__
|
||||
int old_device_id = -1;
|
||||
if (scene->use_gpu) {
|
||||
@@ -1519,6 +1524,11 @@ void render(std::shared_ptr<Scene> scene,
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// IDK what this does but I think it relates to the prefiltering //
|
||||
// TODO //
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
if (render_image.get() != nullptr || d_render_image.get() != nullptr ||
|
||||
render_sdf.get() != nullptr || d_render_sdf.get() != nullptr) {
|
||||
if (weight_image != nullptr) {
|
||||
@@ -1533,6 +1543,11 @@ void render(std::shared_ptr<Scene> scene,
|
||||
}, width * height * num_samples_x * num_samples_y, scene->use_gpu);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// Think this relates to the actual rendering //
|
||||
////////////////////////////////////////////////
|
||||
|
||||
auto num_samples = eval_positions.get() == nullptr ?
|
||||
width * height * num_samples_x * num_samples_y : num_eval_positions;
|
||||
parallel_for(render_kernel{
|
||||
@@ -1555,6 +1570,11 @@ void render(std::shared_ptr<Scene> scene,
|
||||
}, num_samples, scene->use_gpu);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// The reason for this is described in the diffvg paper //
|
||||
// I don't think it's especially important for the gradient meshes //
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Boundary sampling
|
||||
if (!use_prefiltering && d_render_image.get() != nullptr) {
|
||||
auto num_samples = width * height * num_samples_x * num_samples_y;
|
||||
|
1104
poetry.lock
generated
@@ -586,13 +586,17 @@ def obj_to_scene(filename):
|
||||
"""
|
||||
Load from a obj file and convert to PyTorch tensors.
|
||||
"""
|
||||
f = open(filename)
|
||||
lines = f.readlines()
|
||||
with open(filename, 'r') as f:
|
||||
lines = f.readlines()
|
||||
|
||||
data_lines = []
|
||||
vertices = []
|
||||
faces = []
|
||||
for line in lines:
|
||||
l=line.split()
|
||||
# Ignore empty lines
|
||||
if not l:
|
||||
continue
|
||||
#vertex
|
||||
if(l[0] == "v"):
|
||||
vertices.append(l)
|
||||
|
@@ -7,6 +7,9 @@ import warnings
|
||||
|
||||
print_timing = False
|
||||
|
||||
def popmult(lst, n):
|
||||
return (lst[:n], lst[n:])
|
||||
|
||||
def set_print_timing(val):
|
||||
global print_timing
|
||||
print_timing=val
|
||||
@@ -35,98 +38,128 @@ class RenderFunction(torch.autograd.Function):
|
||||
"""
|
||||
num_shapes = len(shapes)
|
||||
num_shape_groups = len(shape_groups)
|
||||
args = []
|
||||
args.append(canvas_width)
|
||||
args.append(canvas_height)
|
||||
args.append(num_shapes)
|
||||
args.append(num_shape_groups)
|
||||
args.append(output_type)
|
||||
args.append(use_prefiltering)
|
||||
args.append(eval_positions.to(pydiffvg.get_device()))
|
||||
args = [canvas_width,
|
||||
canvas_height,
|
||||
num_shapes,
|
||||
num_shape_groups,
|
||||
output_type,
|
||||
use_prefiltering,
|
||||
eval_positions.to(pydiffvg.get_device())]
|
||||
|
||||
for shape in shapes:
|
||||
use_thickness = False
|
||||
if isinstance(shape, pydiffvg.Circle):
|
||||
assert(shape.center.is_contiguous())
|
||||
args.append(diffvg.ShapeType.circle)
|
||||
args.append(shape.radius.cpu())
|
||||
args.append(shape.center.cpu())
|
||||
assert shape.center.is_contiguous()
|
||||
args += [
|
||||
diffvg.ShapeType.circle,
|
||||
shape.radius.cpu(),
|
||||
shape.center.cpu()
|
||||
]
|
||||
elif isinstance(shape, pydiffvg.Ellipse):
|
||||
assert(shape.radius.is_contiguous())
|
||||
assert(shape.center.is_contiguous())
|
||||
args.append(diffvg.ShapeType.ellipse)
|
||||
args.append(shape.radius.cpu())
|
||||
args.append(shape.center.cpu())
|
||||
assert shape.radius.is_contiguous()
|
||||
assert shape.center.is_contiguous()
|
||||
args += [
|
||||
diffvg.ShapeType.ellipse,
|
||||
shape.radius.cpu(),
|
||||
shape.center.cpu()
|
||||
]
|
||||
elif isinstance(shape, pydiffvg.Path):
|
||||
assert(shape.num_control_points.is_contiguous())
|
||||
assert(shape.points.is_contiguous())
|
||||
assert(shape.points.shape[1] == 2)
|
||||
assert(torch.isfinite(shape.points).all())
|
||||
args.append(diffvg.ShapeType.path)
|
||||
args.append(shape.num_control_points.to(torch.int32).cpu())
|
||||
args.append(shape.points.cpu())
|
||||
assert shape.num_control_points.is_contiguous()
|
||||
assert shape.points.is_contiguous()
|
||||
assert shape.points.shape[1] == 2
|
||||
assert torch.isfinite(shape.points).all()
|
||||
|
||||
args += [
|
||||
diffvg.ShapeType.path,
|
||||
shape.num_control_points.to(torch.int32).cpu(),
|
||||
shape.points.cpu()
|
||||
]
|
||||
|
||||
if len(shape.stroke_width.shape) > 0 and shape.stroke_width.shape[0] > 1:
|
||||
assert(torch.isfinite(shape.stroke_width).all())
|
||||
assert torch.isfinite(shape.stroke_width).all()
|
||||
use_thickness = True
|
||||
args.append(shape.stroke_width.cpu())
|
||||
else:
|
||||
args.append(None)
|
||||
args.append(shape.is_closed)
|
||||
args.append(shape.use_distance_approx)
|
||||
|
||||
args += [shape.is_closed, shape.use_distance_approx]
|
||||
elif isinstance(shape, pydiffvg.Polygon):
|
||||
assert(shape.points.is_contiguous())
|
||||
assert(shape.points.shape[1] == 2)
|
||||
assert shape.points.is_contiguous()
|
||||
assert shape.points.shape[1] == 2
|
||||
|
||||
args.append(diffvg.ShapeType.path)
|
||||
|
||||
if shape.is_closed:
|
||||
args.append(torch.zeros(shape.points.shape[0], dtype = torch.int32))
|
||||
else:
|
||||
args.append(torch.zeros(shape.points.shape[0] - 1, dtype = torch.int32))
|
||||
args.append(shape.points.cpu())
|
||||
args.append(None)
|
||||
args.append(shape.is_closed)
|
||||
args.append(False) # use_distance_approx
|
||||
|
||||
args += [
|
||||
shape.points.cpu(),
|
||||
None,
|
||||
shape.is_closed(),
|
||||
False # use_distance_approx
|
||||
]
|
||||
|
||||
elif isinstance(shape, pydiffvg.Rect):
|
||||
assert(shape.p_min.is_contiguous())
|
||||
assert(shape.p_max.is_contiguous())
|
||||
args.append(diffvg.ShapeType.rect)
|
||||
args.append(shape.p_min.cpu())
|
||||
args.append(shape.p_max.cpu())
|
||||
assert shape.p_min.is_contiguous()
|
||||
assert shape.p_max.is_contiguous()
|
||||
|
||||
args += [
|
||||
diffvg.ShapeType.rect,
|
||||
shape.p_min.cpu(),
|
||||
shape.p_max.cpu()
|
||||
]
|
||||
else:
|
||||
assert(False)
|
||||
assert False
|
||||
|
||||
if use_thickness:
|
||||
args.append(torch.tensor(0.0))
|
||||
else:
|
||||
args.append(shape.stroke_width.cpu())
|
||||
|
||||
for shape_group in shape_groups:
|
||||
assert(shape_group.shape_ids.is_contiguous())
|
||||
assert shape_group.shape_ids.is_contiguous()
|
||||
args.append(shape_group.shape_ids.to(torch.int32).cpu())
|
||||
# Fill color
|
||||
if shape_group.fill_color is None:
|
||||
args.append(None)
|
||||
|
||||
elif isinstance(shape_group.fill_color, torch.Tensor):
|
||||
assert(shape_group.fill_color.is_contiguous())
|
||||
args.append(diffvg.ColorType.constant)
|
||||
args.append(shape_group.fill_color.cpu())
|
||||
assert shape_group.fill_color.is_contiguous()
|
||||
|
||||
args += [
|
||||
diffvg.ColorType.constant,
|
||||
shape_group.fill_color.cpu()
|
||||
]
|
||||
|
||||
elif isinstance(shape_group.fill_color, pydiffvg.LinearGradient):
|
||||
assert(shape_group.fill_color.begin.is_contiguous())
|
||||
assert(shape_group.fill_color.end.is_contiguous())
|
||||
assert(shape_group.fill_color.offsets.is_contiguous())
|
||||
assert(shape_group.fill_color.stop_colors.is_contiguous())
|
||||
args.append(diffvg.ColorType.linear_gradient)
|
||||
args.append(shape_group.fill_color.begin.cpu())
|
||||
args.append(shape_group.fill_color.end.cpu())
|
||||
args.append(shape_group.fill_color.offsets.cpu())
|
||||
args.append(shape_group.fill_color.stop_colors.cpu())
|
||||
assert shape_group.fill_color.begin.is_contiguous()
|
||||
assert shape_group.fill_color.end.is_contiguous()
|
||||
assert shape_group.fill_color.offsets.is_contiguous()
|
||||
assert shape_group.fill_color.stop_colors.is_contiguous()
|
||||
|
||||
args += [
|
||||
diffvg.ColorType.linear_gradient,
|
||||
shape_group.fill_color.begin.cpu(),
|
||||
shape_group.fill_color.end.cpu(),
|
||||
shape_group.fill_color.offsets.cpu(),
|
||||
shape_group.fill_color.stop_colors.cpu(),
|
||||
]
|
||||
|
||||
elif isinstance(shape_group.fill_color, pydiffvg.RadialGradient):
|
||||
assert(shape_group.fill_color.center.is_contiguous())
|
||||
assert(shape_group.fill_color.radius.is_contiguous())
|
||||
assert(shape_group.fill_color.offsets.is_contiguous())
|
||||
assert(shape_group.fill_color.stop_colors.is_contiguous())
|
||||
args.append(diffvg.ColorType.radial_gradient)
|
||||
args.append(shape_group.fill_color.center.cpu())
|
||||
args.append(shape_group.fill_color.radius.cpu())
|
||||
args.append(shape_group.fill_color.offsets.cpu())
|
||||
args.append(shape_group.fill_color.stop_colors.cpu())
|
||||
assert shape_group.fill_color.center.is_contiguous()
|
||||
assert shape_group.fill_color.radius.is_contiguous()
|
||||
assert shape_group.fill_color.offsets.is_contiguous()
|
||||
assert shape_group.fill_color.stop_colors.is_contiguous()
|
||||
|
||||
args += [
|
||||
diffvg.ColorType.radial_gradient,
|
||||
shape_group.fill_color.center.cpu(),
|
||||
shape_group.fill_color.radius.cpu(),
|
||||
shape_group.fill_color.offsets.cpu(),
|
||||
shape_group.fill_color.stop_colors.cpu()
|
||||
]
|
||||
|
||||
if shape_group.fill_color is not None:
|
||||
# go through the underlying shapes and check if they are all closed
|
||||
@@ -138,35 +171,44 @@ class RenderFunction(torch.autograd.Function):
|
||||
# Stroke color
|
||||
if shape_group.stroke_color is None:
|
||||
args.append(None)
|
||||
|
||||
elif isinstance(shape_group.stroke_color, torch.Tensor):
|
||||
assert(shape_group.stroke_color.is_contiguous())
|
||||
args.append(diffvg.ColorType.constant)
|
||||
args.append(shape_group.stroke_color.cpu())
|
||||
assert shape_group.stroke_color.is_contiguous()
|
||||
args += [ diffvg.ColorType.constant, shape_group.stroke_color.cpu() ]
|
||||
|
||||
elif isinstance(shape_group.stroke_color, pydiffvg.LinearGradient):
|
||||
assert(shape_group.stroke_color.begin.is_contiguous())
|
||||
assert(shape_group.stroke_color.end.is_contiguous())
|
||||
assert(shape_group.stroke_color.offsets.is_contiguous())
|
||||
assert(shape_group.stroke_color.stop_colors.is_contiguous())
|
||||
assert(torch.isfinite(shape_group.stroke_color.stop_colors).all())
|
||||
args.append(diffvg.ColorType.linear_gradient)
|
||||
args.append(shape_group.stroke_color.begin.cpu())
|
||||
args.append(shape_group.stroke_color.end.cpu())
|
||||
args.append(shape_group.stroke_color.offsets.cpu())
|
||||
args.append(shape_group.stroke_color.stop_colors.cpu())
|
||||
assert shape_group.stroke_color.begin.is_contiguous()
|
||||
assert shape_group.stroke_color.end.is_contiguous()
|
||||
assert shape_group.stroke_color.offsets.is_contiguous()
|
||||
assert shape_group.stroke_color.stop_colors.is_contiguous()
|
||||
assert torch.isfinite(shape_group.stroke_color.stop_colors).all()
|
||||
|
||||
args += [
|
||||
diffvg.ColorType.linear_gradient,
|
||||
shape_group.stroke_color.begin.cpu(),
|
||||
shape_group.stroke_color.end.cpu(),
|
||||
shape_group.stroke_color.offsets.cpu(),
|
||||
shape_group.stroke_color.stop_colors.cpu()
|
||||
]
|
||||
|
||||
elif isinstance(shape_group.stroke_color, pydiffvg.RadialGradient):
|
||||
assert(shape_group.stroke_color.center.is_contiguous())
|
||||
assert(shape_group.stroke_color.radius.is_contiguous())
|
||||
assert(shape_group.stroke_color.offsets.is_contiguous())
|
||||
assert(shape_group.stroke_color.stop_colors.is_contiguous())
|
||||
assert(torch.isfinite(shape_group.stroke_color.stop_colors).all())
|
||||
args.append(diffvg.ColorType.radial_gradient)
|
||||
args.append(shape_group.stroke_color.center.cpu())
|
||||
args.append(shape_group.stroke_color.radius.cpu())
|
||||
args.append(shape_group.stroke_color.offsets.cpu())
|
||||
args.append(shape_group.stroke_color.stop_colors.cpu())
|
||||
args.append(shape_group.use_even_odd_rule)
|
||||
# Transformation
|
||||
args.append(shape_group.shape_to_canvas.contiguous().cpu())
|
||||
assert shape_group.stroke_color.center.is_contiguous()
|
||||
assert shape_group.stroke_color.radius.is_contiguous()
|
||||
assert shape_group.stroke_color.offsets.is_contiguous()
|
||||
assert shape_group.stroke_color.stop_colors.is_contiguous()
|
||||
assert torch.isfinite(shape_group.stroke_color.stop_colors).all()
|
||||
|
||||
args += [
|
||||
diffvg.ColorType.radial_gradient,
|
||||
shape_group.stroke_color.center.cpu(),
|
||||
shape_group.stroke_color.radius.cpu(),
|
||||
shape_group.stroke_color.offsets.cpu(),
|
||||
shape_group.stroke_color.stop_colors.cpu()
|
||||
]
|
||||
|
||||
args += [ shape_group.use_even_odd_rule,
|
||||
shape_group.shape_to_canvas.contiguous().cpu() ]
|
||||
|
||||
args.append(filter.type)
|
||||
args.append(filter.radius.cpu())
|
||||
return args
|
||||
@@ -184,52 +226,31 @@ class RenderFunction(torch.autograd.Function):
|
||||
Forward rendering pass.
|
||||
"""
|
||||
# Unpack arguments
|
||||
current_index = 0
|
||||
canvas_width = args[current_index]
|
||||
current_index += 1
|
||||
canvas_height = args[current_index]
|
||||
current_index += 1
|
||||
num_shapes = args[current_index]
|
||||
current_index += 1
|
||||
num_shape_groups = args[current_index]
|
||||
current_index += 1
|
||||
output_type = args[current_index]
|
||||
current_index += 1
|
||||
use_prefiltering = args[current_index]
|
||||
current_index += 1
|
||||
eval_positions = args[current_index]
|
||||
current_index += 1
|
||||
args = list(args)
|
||||
|
||||
(canvas_width, canvas_height, num_shapes,
|
||||
num_shape_groups, output_type, use_prefiltering, eval_positions), args = popmult(args, 7)
|
||||
|
||||
shapes = []
|
||||
shape_groups = []
|
||||
shape_contents = [] # Important to avoid GC deleting the shapes
|
||||
color_contents = [] # Same as above
|
||||
for shape_id in range(num_shapes):
|
||||
shape_type = args[current_index]
|
||||
current_index += 1
|
||||
shape_type = args.pop(0)
|
||||
if shape_type == diffvg.ShapeType.circle:
|
||||
radius = args[current_index]
|
||||
current_index += 1
|
||||
center = args[current_index]
|
||||
current_index += 1
|
||||
(radius, center), args = popmult(args, 2)
|
||||
|
||||
shape = diffvg.Circle(radius, diffvg.Vector2f(center[0], center[1]))
|
||||
elif shape_type == diffvg.ShapeType.ellipse:
|
||||
radius = args[current_index]
|
||||
current_index += 1
|
||||
center = args[current_index]
|
||||
current_index += 1
|
||||
(radius, center), args = popmult(args, 2)
|
||||
|
||||
shape = diffvg.Ellipse(diffvg.Vector2f(radius[0], radius[1]),
|
||||
diffvg.Vector2f(center[0], center[1]))
|
||||
elif shape_type == diffvg.ShapeType.path:
|
||||
num_control_points = args[current_index]
|
||||
current_index += 1
|
||||
points = args[current_index]
|
||||
current_index += 1
|
||||
thickness = args[current_index]
|
||||
current_index += 1
|
||||
is_closed = args[current_index]
|
||||
current_index += 1
|
||||
use_distance_approx = args[current_index]
|
||||
current_index += 1
|
||||
|
||||
(num_control_points, points, thickness,
|
||||
is_closed, use_distance_approx), args = popmult(args, 5)
|
||||
|
||||
shape = diffvg.Path(diffvg.int_ptr(num_control_points.data_ptr()),
|
||||
diffvg.float_ptr(points.data_ptr()),
|
||||
diffvg.float_ptr(thickness.data_ptr() if thickness is not None else 0),
|
||||
@@ -238,55 +259,36 @@ class RenderFunction(torch.autograd.Function):
|
||||
is_closed,
|
||||
use_distance_approx)
|
||||
elif shape_type == diffvg.ShapeType.rect:
|
||||
p_min = args[current_index]
|
||||
current_index += 1
|
||||
p_max = args[current_index]
|
||||
current_index += 1
|
||||
(p_min, p_max), args = popmult(args, 2)
|
||||
shape = diffvg.Rect(diffvg.Vector2f(p_min[0], p_min[1]),
|
||||
diffvg.Vector2f(p_max[0], p_max[1]))
|
||||
else:
|
||||
assert(False)
|
||||
stroke_width = args[current_index]
|
||||
current_index += 1
|
||||
assert False
|
||||
|
||||
stroke_width = args.pop(0)
|
||||
shapes.append(diffvg.Shape(\
|
||||
shape_type, shape.get_ptr(), stroke_width.item()))
|
||||
shape_contents.append(shape)
|
||||
|
||||
for shape_group_id in range(num_shape_groups):
|
||||
shape_ids = args[current_index]
|
||||
current_index += 1
|
||||
fill_color_type = args[current_index]
|
||||
current_index += 1
|
||||
(shape_ids, fill_color_type), args = popmult(args, 2)
|
||||
if fill_color_type == diffvg.ColorType.constant:
|
||||
color = args[current_index]
|
||||
current_index += 1
|
||||
color = args.pop(0)
|
||||
fill_color = diffvg.Constant(\
|
||||
diffvg.Vector4f(color[0], color[1], color[2], color[3]))
|
||||
elif fill_color_type == diffvg.ColorType.linear_gradient:
|
||||
beg = args[current_index]
|
||||
current_index += 1
|
||||
end = args[current_index]
|
||||
current_index += 1
|
||||
offsets = args[current_index]
|
||||
current_index += 1
|
||||
stop_colors = args[current_index]
|
||||
current_index += 1
|
||||
assert(offsets.shape[0] == stop_colors.shape[0])
|
||||
(beg, end, offsets, stop_colors), args = popmult(args, 4)
|
||||
|
||||
assert offsets.shape[0] == stop_colors.shape[0]
|
||||
fill_color = diffvg.LinearGradient(diffvg.Vector2f(beg[0], beg[1]),
|
||||
diffvg.Vector2f(end[0], end[1]),
|
||||
offsets.shape[0],
|
||||
diffvg.float_ptr(offsets.data_ptr()),
|
||||
diffvg.float_ptr(stop_colors.data_ptr()))
|
||||
elif fill_color_type == diffvg.ColorType.radial_gradient:
|
||||
center = args[current_index]
|
||||
current_index += 1
|
||||
radius = args[current_index]
|
||||
current_index += 1
|
||||
offsets = args[current_index]
|
||||
current_index += 1
|
||||
stop_colors = args[current_index]
|
||||
current_index += 1
|
||||
assert(offsets.shape[0] == stop_colors.shape[0])
|
||||
(center, radius, offsets, stop_colors), args = popmult(args, 4)
|
||||
|
||||
assert offsets.shape[0] == stop_colors.shape[0]
|
||||
fill_color = diffvg.RadialGradient(diffvg.Vector2f(center[0], center[1]),
|
||||
diffvg.Vector2f(radius[0], radius[1]),
|
||||
offsets.shape[0],
|
||||
@@ -295,39 +297,28 @@ class RenderFunction(torch.autograd.Function):
|
||||
elif fill_color_type is None:
|
||||
fill_color = None
|
||||
else:
|
||||
assert(False)
|
||||
stroke_color_type = args[current_index]
|
||||
current_index += 1
|
||||
assert False
|
||||
|
||||
stroke_color_type = args.pop(0)
|
||||
if stroke_color_type == diffvg.ColorType.constant:
|
||||
color = args[current_index]
|
||||
current_index += 1
|
||||
color = args.pop(0)
|
||||
stroke_color = diffvg.Constant(\
|
||||
diffvg.Vector4f(color[0], color[1], color[2], color[3]))
|
||||
|
||||
elif stroke_color_type == diffvg.ColorType.linear_gradient:
|
||||
beg = args[current_index]
|
||||
current_index += 1
|
||||
end = args[current_index]
|
||||
current_index += 1
|
||||
offsets = args[current_index]
|
||||
current_index += 1
|
||||
stop_colors = args[current_index]
|
||||
current_index += 1
|
||||
assert(offsets.shape[0] == stop_colors.shape[0])
|
||||
(beg, end, offsets, stop_colors), args = popmult(args, 4)
|
||||
|
||||
assert offsets.shape[0] == stop_colors.shape[0]
|
||||
stroke_color = diffvg.LinearGradient(diffvg.Vector2f(beg[0], beg[1]),
|
||||
diffvg.Vector2f(end[0], end[1]),
|
||||
offsets.shape[0],
|
||||
diffvg.float_ptr(offsets.data_ptr()),
|
||||
diffvg.float_ptr(stop_colors.data_ptr()))
|
||||
|
||||
elif stroke_color_type == diffvg.ColorType.radial_gradient:
|
||||
center = args[current_index]
|
||||
current_index += 1
|
||||
radius = args[current_index]
|
||||
current_index += 1
|
||||
offsets = args[current_index]
|
||||
current_index += 1
|
||||
stop_colors = args[current_index]
|
||||
current_index += 1
|
||||
assert(offsets.shape[0] == stop_colors.shape[0])
|
||||
(center, radius, offsets, stop_colors), args = popmult(args, 4)
|
||||
|
||||
assert offsets.shape[0] == stop_colors.shape[0]
|
||||
stroke_color = diffvg.RadialGradient(diffvg.Vector2f(center[0], center[1]),
|
||||
diffvg.Vector2f(radius[0], radius[1]),
|
||||
offsets.shape[0],
|
||||
@@ -335,17 +326,18 @@ class RenderFunction(torch.autograd.Function):
|
||||
diffvg.float_ptr(stop_colors.data_ptr()))
|
||||
elif stroke_color_type is None:
|
||||
stroke_color = None
|
||||
|
||||
else:
|
||||
assert(False)
|
||||
use_even_odd_rule = args[current_index]
|
||||
current_index += 1
|
||||
shape_to_canvas = args[current_index]
|
||||
current_index += 1
|
||||
assert False
|
||||
|
||||
(use_even_odd_rule, shape_to_canvas), args = popmult(args, 2)
|
||||
|
||||
if fill_color is not None:
|
||||
color_contents.append(fill_color)
|
||||
|
||||
if stroke_color is not None:
|
||||
color_contents.append(stroke_color)
|
||||
|
||||
shape_groups.append(diffvg.ShapeGroup(\
|
||||
diffvg.int_ptr(shape_ids.data_ptr()),
|
||||
shape_ids.shape[0],
|
||||
@@ -356,10 +348,7 @@ class RenderFunction(torch.autograd.Function):
|
||||
use_even_odd_rule,
|
||||
diffvg.float_ptr(shape_to_canvas.data_ptr())))
|
||||
|
||||
filter_type = args[current_index]
|
||||
current_index += 1
|
||||
filter_radius = args[current_index]
|
||||
current_index += 1
|
||||
(filter_type, filter_radius), args = popmult(args, 2)
|
||||
filt = diffvg.Filter(filter_type, filter_radius)
|
||||
|
||||
start = time.time()
|
||||
@@ -367,15 +356,16 @@ class RenderFunction(torch.autograd.Function):
|
||||
shapes, shape_groups, filt, pydiffvg.get_use_gpu(),
|
||||
pydiffvg.get_device().index if pydiffvg.get_device().index is not None else -1)
|
||||
time_elapsed = time.time() - start
|
||||
|
||||
global print_timing
|
||||
if print_timing:
|
||||
print('Scene construction, time: %.5f s' % time_elapsed)
|
||||
|
||||
if output_type == OutputType.color:
|
||||
assert(eval_positions.shape[0] == 0)
|
||||
assert eval_positions.shape[0] == 0
|
||||
rendered_image = torch.zeros(height, width, 4, device = pydiffvg.get_device())
|
||||
else:
|
||||
assert(output_type == OutputType.sdf)
|
||||
assert output_type == OutputType.sdf
|
||||
if eval_positions.shape[0] == 0:
|
||||
rendered_image = torch.zeros(height, width, 1, device = pydiffvg.get_device())
|
||||
else:
|
||||
@@ -386,9 +376,10 @@ class RenderFunction(torch.autograd.Function):
|
||||
if background_image.shape[2] == 3:
|
||||
raise NotImplementedError('Background image must have 4 channels, not 3. Add a fourth channel with all ones via torch.ones().')
|
||||
background_image = background_image.contiguous()
|
||||
assert(background_image.shape[0] == rendered_image.shape[0])
|
||||
assert(background_image.shape[1] == rendered_image.shape[1])
|
||||
assert(background_image.shape[2] == 4)
|
||||
|
||||
assert background_image.shape[0] == rendered_image.shape[0]
|
||||
assert background_image.shape[1] == rendered_image.shape[1]
|
||||
assert background_image.shape[2] == 4
|
||||
|
||||
start = time.time()
|
||||
diffvg.render(scene,
|
||||
@@ -407,7 +398,7 @@ class RenderFunction(torch.autograd.Function):
|
||||
use_prefiltering,
|
||||
diffvg.float_ptr(eval_positions.data_ptr()),
|
||||
eval_positions.shape[0])
|
||||
assert(torch.isfinite(rendered_image).all())
|
||||
assert torch.isfinite(rendered_image).all()
|
||||
time_elapsed = time.time() - start
|
||||
if print_timing:
|
||||
print('Forward pass, time: %.5f s' % time_elapsed)
|
||||
@@ -438,55 +429,33 @@ class RenderFunction(torch.autograd.Function):
|
||||
*args):
|
||||
if not grad_img.is_contiguous():
|
||||
grad_img = grad_img.contiguous()
|
||||
assert(torch.isfinite(grad_img).all())
|
||||
assert torch.isfinite(grad_img).all()
|
||||
|
||||
args = list(args)
|
||||
# Unpack arguments
|
||||
current_index = 0
|
||||
canvas_width = args[current_index]
|
||||
current_index += 1
|
||||
canvas_height = args[current_index]
|
||||
current_index += 1
|
||||
num_shapes = args[current_index]
|
||||
current_index += 1
|
||||
num_shape_groups = args[current_index]
|
||||
current_index += 1
|
||||
output_type = args[current_index]
|
||||
current_index += 1
|
||||
use_prefiltering = args[current_index]
|
||||
current_index += 1
|
||||
eval_positions = args[current_index]
|
||||
current_index += 1
|
||||
(canvas_width, canvas_height, num_shapes,
|
||||
num_shape_groups, output_type, use_prefiltering,
|
||||
eval_positions), args = popmult(args, 7)
|
||||
|
||||
shapes = []
|
||||
shape_groups = []
|
||||
shape_contents = [] # Important to avoid GC deleting the shapes
|
||||
color_contents = [] # Same as above
|
||||
for shape_id in range(num_shapes):
|
||||
shape_type = args[current_index]
|
||||
current_index += 1
|
||||
shape_type = args.pop(0)
|
||||
if shape_type == diffvg.ShapeType.circle:
|
||||
radius = args[current_index]
|
||||
current_index += 1
|
||||
center = args[current_index]
|
||||
current_index += 1
|
||||
(radius, center), args = popmult(args, 2)
|
||||
|
||||
shape = diffvg.Circle(radius, diffvg.Vector2f(center[0], center[1]))
|
||||
elif shape_type == diffvg.ShapeType.ellipse:
|
||||
radius = args[current_index]
|
||||
current_index += 1
|
||||
center = args[current_index]
|
||||
current_index += 1
|
||||
(radius, center), args = popmult(args, 2)
|
||||
|
||||
shape = diffvg.Ellipse(diffvg.Vector2f(radius[0], radius[1]),
|
||||
diffvg.Vector2f(center[0], center[1]))
|
||||
elif shape_type == diffvg.ShapeType.path:
|
||||
num_control_points = args[current_index]
|
||||
current_index += 1
|
||||
points = args[current_index]
|
||||
current_index += 1
|
||||
thickness = args[current_index]
|
||||
current_index += 1
|
||||
is_closed = args[current_index]
|
||||
current_index += 1
|
||||
use_distance_approx = args[current_index]
|
||||
current_index += 1
|
||||
(num_control_points, points, thickness,
|
||||
is_closed, use_distance_approx), args = popmult(args, 5)
|
||||
|
||||
shape = diffvg.Path(diffvg.int_ptr(num_control_points.data_ptr()),
|
||||
diffvg.float_ptr(points.data_ptr()),
|
||||
diffvg.float_ptr(thickness.data_ptr() if thickness is not None else 0),
|
||||
@@ -495,114 +464,93 @@ class RenderFunction(torch.autograd.Function):
|
||||
is_closed,
|
||||
use_distance_approx)
|
||||
elif shape_type == diffvg.ShapeType.rect:
|
||||
p_min = args[current_index]
|
||||
current_index += 1
|
||||
p_max = args[current_index]
|
||||
current_index += 1
|
||||
(p_min, p_max), args = popmult(args, 2)
|
||||
|
||||
shape = diffvg.Rect(diffvg.Vector2f(p_min[0], p_min[1]),
|
||||
diffvg.Vector2f(p_max[0], p_max[1]))
|
||||
else:
|
||||
assert(False)
|
||||
stroke_width = args[current_index]
|
||||
current_index += 1
|
||||
assert False
|
||||
|
||||
stroke_width = args.pop(0)
|
||||
|
||||
shapes.append(diffvg.Shape(\
|
||||
shape_type, shape.get_ptr(), stroke_width.item()))
|
||||
shape_contents.append(shape)
|
||||
|
||||
for shape_group_id in range(num_shape_groups):
|
||||
shape_ids = args[current_index]
|
||||
current_index += 1
|
||||
fill_color_type = args[current_index]
|
||||
current_index += 1
|
||||
(shape_ids, fill_color_type), args = popmult(args, 2)
|
||||
|
||||
if fill_color_type == diffvg.ColorType.constant:
|
||||
color = args[current_index]
|
||||
current_index += 1
|
||||
color = args.pop(0)
|
||||
|
||||
fill_color = diffvg.Constant(\
|
||||
diffvg.Vector4f(color[0], color[1], color[2], color[3]))
|
||||
|
||||
elif fill_color_type == diffvg.ColorType.linear_gradient:
|
||||
beg = args[current_index]
|
||||
current_index += 1
|
||||
end = args[current_index]
|
||||
current_index += 1
|
||||
offsets = args[current_index]
|
||||
current_index += 1
|
||||
stop_colors = args[current_index]
|
||||
current_index += 1
|
||||
assert(offsets.shape[0] == stop_colors.shape[0])
|
||||
(beg, end, offsets, stop_colors), args = popmult(args, 4)
|
||||
|
||||
assert offsets.shape[0] == stop_colors.shape[0]
|
||||
fill_color = diffvg.LinearGradient(diffvg.Vector2f(beg[0], beg[1]),
|
||||
diffvg.Vector2f(end[0], end[1]),
|
||||
offsets.shape[0],
|
||||
diffvg.float_ptr(offsets.data_ptr()),
|
||||
diffvg.float_ptr(stop_colors.data_ptr()))
|
||||
|
||||
elif fill_color_type == diffvg.ColorType.radial_gradient:
|
||||
center = args[current_index]
|
||||
current_index += 1
|
||||
radius = args[current_index]
|
||||
current_index += 1
|
||||
offsets = args[current_index]
|
||||
current_index += 1
|
||||
stop_colors = args[current_index]
|
||||
current_index += 1
|
||||
assert(offsets.shape[0] == stop_colors.shape[0])
|
||||
(center, radius, offsets, stop_colors), args = popmult(args, 4)
|
||||
|
||||
assert offsets.shape[0] == stop_colors.shape[0]
|
||||
fill_color = diffvg.RadialGradient(diffvg.Vector2f(center[0], center[1]),
|
||||
diffvg.Vector2f(radius[0], radius[1]),
|
||||
offsets.shape[0],
|
||||
diffvg.float_ptr(offsets.data_ptr()),
|
||||
diffvg.float_ptr(stop_colors.data_ptr()))
|
||||
|
||||
elif fill_color_type is None:
|
||||
fill_color = None
|
||||
|
||||
else:
|
||||
assert(False)
|
||||
stroke_color_type = args[current_index]
|
||||
current_index += 1
|
||||
assert False
|
||||
|
||||
stroke_color_type = args.pop(0)
|
||||
|
||||
if stroke_color_type == diffvg.ColorType.constant:
|
||||
color = args[current_index]
|
||||
current_index += 1
|
||||
color = args.pop(0)
|
||||
stroke_color = diffvg.Constant(\
|
||||
diffvg.Vector4f(color[0], color[1], color[2], color[3]))
|
||||
elif stroke_color_type == diffvg.ColorType.linear_gradient:
|
||||
beg = args[current_index]
|
||||
current_index += 1
|
||||
end = args[current_index]
|
||||
current_index += 1
|
||||
offsets = args[current_index]
|
||||
current_index += 1
|
||||
stop_colors = args[current_index]
|
||||
current_index += 1
|
||||
assert(offsets.shape[0] == stop_colors.shape[0])
|
||||
(beg, end, offsets, stop_colors) = popmult(args, 4)
|
||||
|
||||
assert offsets.shape[0] == stop_colors.shape[0]
|
||||
stroke_color = diffvg.LinearGradient(diffvg.Vector2f(beg[0], beg[1]),
|
||||
diffvg.Vector2f(end[0], end[1]),
|
||||
offsets.shape[0],
|
||||
diffvg.float_ptr(offsets.data_ptr()),
|
||||
diffvg.float_ptr(stop_colors.data_ptr()))
|
||||
elif stroke_color_type == diffvg.ColorType.radial_gradient:
|
||||
center = args[current_index]
|
||||
current_index += 1
|
||||
radius = args[current_index]
|
||||
current_index += 1
|
||||
offsets = args[current_index]
|
||||
current_index += 1
|
||||
stop_colors = args[current_index]
|
||||
current_index += 1
|
||||
assert(offsets.shape[0] == stop_colors.shape[0])
|
||||
(center, radius, offsets, stop_colors), args = popmult(args, 4)
|
||||
|
||||
assert offsets.shape[0] == stop_colors.shape[0]
|
||||
stroke_color = diffvg.RadialGradient(diffvg.Vector2f(center[0], center[1]),
|
||||
diffvg.Vector2f(radius[0], radius[1]),
|
||||
offsets.shape[0],
|
||||
diffvg.float_ptr(offsets.data_ptr()),
|
||||
diffvg.float_ptr(stop_colors.data_ptr()))
|
||||
|
||||
elif stroke_color_type is None:
|
||||
stroke_color = None
|
||||
|
||||
else:
|
||||
assert(False)
|
||||
use_even_odd_rule = args[current_index]
|
||||
current_index += 1
|
||||
shape_to_canvas = args[current_index]
|
||||
current_index += 1
|
||||
assert False
|
||||
|
||||
(use_even_odd_rule, shape_to_canvas), args = popmult(args, 2)
|
||||
|
||||
if fill_color is not None:
|
||||
color_contents.append(fill_color)
|
||||
|
||||
if stroke_color is not None:
|
||||
color_contents.append(stroke_color)
|
||||
|
||||
shape_groups.append(diffvg.ShapeGroup(\
|
||||
diffvg.int_ptr(shape_ids.data_ptr()),
|
||||
shape_ids.shape[0],
|
||||
@@ -613,31 +561,32 @@ class RenderFunction(torch.autograd.Function):
|
||||
use_even_odd_rule,
|
||||
diffvg.float_ptr(shape_to_canvas.data_ptr())))
|
||||
|
||||
filter_type = args[current_index]
|
||||
current_index += 1
|
||||
filter_radius = args[current_index]
|
||||
current_index += 1
|
||||
(filter_type, filter_radius), args = popmult(args, 2)
|
||||
|
||||
filt = diffvg.Filter(filter_type, filter_radius)
|
||||
|
||||
scene = diffvg.Scene(canvas_width, canvas_height,
|
||||
shapes, shape_groups, filt, pydiffvg.get_use_gpu(),
|
||||
pydiffvg.get_device().index if pydiffvg.get_device().index is not None else -1)
|
||||
shapes, shape_groups, filt, pydiffvg.get_use_gpu(),
|
||||
pydiffvg.get_device().index if pydiffvg.get_device().index is not None else -1)
|
||||
|
||||
if output_type == OutputType.color:
|
||||
assert(grad_img.shape[2] == 4)
|
||||
assert grad_img.shape[2] == 4
|
||||
else:
|
||||
assert(grad_img.shape[2] == 1)
|
||||
assert grad_img.shape[2] == 1
|
||||
|
||||
if background_image is not None:
|
||||
background_image = background_image.to(pydiffvg.get_device())
|
||||
if background_image.shape[2] == 3:
|
||||
background_image = torch.cat((\
|
||||
background_image, torch.ones(background_image.shape[0], background_image.shape[1], 1,
|
||||
device = background_image.device)), dim = 2)
|
||||
background_image = torch.cat((
|
||||
background_image, torch.ones(background_image.shape[0],
|
||||
background_image.shape[1],
|
||||
1,
|
||||
device=background_image.device)),
|
||||
dim=2)
|
||||
background_image = background_image.contiguous()
|
||||
assert(background_image.shape[0] == rendered_image.shape[0])
|
||||
assert(background_image.shape[1] == rendered_image.shape[1])
|
||||
assert(background_image.shape[2] == 4)
|
||||
assert background_image.shape[0] == rendered_image.shape[0]
|
||||
assert background_image.shape[1] == rendered_image.shape[1]
|
||||
assert background_image.shape[2] == 4
|
||||
|
||||
translation_grad_image = \
|
||||
torch.zeros(height, width, 2, device = pydiffvg.get_device())
|
||||
@@ -661,7 +610,7 @@ class RenderFunction(torch.autograd.Function):
|
||||
time_elapsed = time.time() - start
|
||||
if print_timing:
|
||||
print('Gradient pass, time: %.5f s' % time_elapsed)
|
||||
assert(torch.isfinite(translation_grad_image).all())
|
||||
assert torch.isfinite(translation_grad_image).all()
|
||||
|
||||
return translation_grad_image
|
||||
|
||||
@@ -670,7 +619,7 @@ class RenderFunction(torch.autograd.Function):
|
||||
grad_img):
|
||||
if not grad_img.is_contiguous():
|
||||
grad_img = grad_img.contiguous()
|
||||
assert(torch.isfinite(grad_img).all())
|
||||
assert torch.isfinite(grad_img).all()
|
||||
|
||||
scene = ctx.scene
|
||||
width = ctx.width
|
||||
@@ -710,20 +659,11 @@ class RenderFunction(torch.autograd.Function):
|
||||
if print_timing:
|
||||
print('Backward pass, time: %.5f s' % time_elapsed)
|
||||
|
||||
d_args = []
|
||||
d_args.append(None) # width
|
||||
d_args.append(None) # height
|
||||
d_args.append(None) # num_samples_x
|
||||
d_args.append(None) # num_samples_y
|
||||
d_args.append(None) # seed
|
||||
d_args.append(d_background_image)
|
||||
d_args.append(None) # canvas_width
|
||||
d_args.append(None) # canvas_height
|
||||
d_args.append(None) # num_shapes
|
||||
d_args.append(None) # num_shape_groups
|
||||
d_args.append(None) # output_type
|
||||
d_args.append(None) # use_prefiltering
|
||||
d_args.append(None) # eval_positions
|
||||
# [width, height, num_samples_x, num_samples_y, seed,
|
||||
# d_background_image, canvas_width, canvas_height, num_shapes,
|
||||
# num_shape_groups, output_type, use_prefiltering, _eval_positions]
|
||||
d_args = [None] * 5 + [d_background_image] + [None] * 7
|
||||
|
||||
for shape_id in range(scene.num_shapes):
|
||||
d_args.append(None) # type
|
||||
d_shape = scene.get_d_shape(shape_id)
|
||||
@@ -731,21 +671,21 @@ class RenderFunction(torch.autograd.Function):
|
||||
if d_shape.type == diffvg.ShapeType.circle:
|
||||
d_circle = d_shape.as_circle()
|
||||
radius = torch.tensor(d_circle.radius)
|
||||
assert(torch.isfinite(radius).all())
|
||||
assert torch.isfinite(radius).all()
|
||||
d_args.append(radius)
|
||||
c = d_circle.center
|
||||
c = torch.tensor((c.x, c.y))
|
||||
assert(torch.isfinite(c).all())
|
||||
assert torch.isfinite(c).all()
|
||||
d_args.append(c)
|
||||
elif d_shape.type == diffvg.ShapeType.ellipse:
|
||||
d_ellipse = d_shape.as_ellipse()
|
||||
r = d_ellipse.radius
|
||||
r = torch.tensor((d_ellipse.radius.x, d_ellipse.radius.y))
|
||||
assert(torch.isfinite(r).all())
|
||||
assert torch.isfinite(r).all()
|
||||
d_args.append(r)
|
||||
c = d_ellipse.center
|
||||
c = torch.tensor((c.x, c.y))
|
||||
assert(torch.isfinite(c).all())
|
||||
assert torch.isfinite(c).all()
|
||||
d_args.append(c)
|
||||
elif d_shape.type == diffvg.ShapeType.path:
|
||||
d_path = d_shape.as_path()
|
||||
@@ -757,9 +697,9 @@ class RenderFunction(torch.autograd.Function):
|
||||
d_path.copy_to(diffvg.float_ptr(points.data_ptr()), diffvg.float_ptr(thickness.data_ptr()))
|
||||
else:
|
||||
d_path.copy_to(diffvg.float_ptr(points.data_ptr()), diffvg.float_ptr(0))
|
||||
assert(torch.isfinite(points).all())
|
||||
assert torch.isfinite(points).all()
|
||||
if thickness is not None:
|
||||
assert(torch.isfinite(thickness).all())
|
||||
assert torch.isfinite(thickness).all()
|
||||
d_args.append(None) # num_control_points
|
||||
d_args.append(points)
|
||||
d_args.append(thickness)
|
||||
@@ -769,17 +709,17 @@ class RenderFunction(torch.autograd.Function):
|
||||
d_rect = d_shape.as_rect()
|
||||
p_min = torch.tensor((d_rect.p_min.x, d_rect.p_min.y))
|
||||
p_max = torch.tensor((d_rect.p_max.x, d_rect.p_max.y))
|
||||
assert(torch.isfinite(p_min).all())
|
||||
assert(torch.isfinite(p_max).all())
|
||||
assert torch.isfinite(p_min).all()
|
||||
assert torch.isfinite(p_max).all()
|
||||
d_args.append(p_min)
|
||||
d_args.append(p_max)
|
||||
else:
|
||||
assert(False)
|
||||
assert False
|
||||
if use_thickness:
|
||||
d_args.append(None)
|
||||
else:
|
||||
w = torch.tensor((d_shape.stroke_width))
|
||||
assert(torch.isfinite(w).all())
|
||||
assert torch.isfinite(w).all()
|
||||
d_args.append(w)
|
||||
|
||||
for group_id in range(scene.num_shape_groups):
|
||||
@@ -802,7 +742,7 @@ class RenderFunction(torch.autograd.Function):
|
||||
d_linear_gradient.copy_to(\
|
||||
diffvg.float_ptr(offsets.data_ptr()),
|
||||
diffvg.float_ptr(stop_colors.data_ptr()))
|
||||
assert(torch.isfinite(stop_colors).all())
|
||||
assert torch.isfinite(stop_colors).all()
|
||||
d_args.append(offsets)
|
||||
d_args.append(stop_colors)
|
||||
elif d_shape_group.fill_color_type == diffvg.ColorType.radial_gradient:
|
||||
@@ -816,11 +756,11 @@ class RenderFunction(torch.autograd.Function):
|
||||
d_radial_gradient.copy_to(\
|
||||
diffvg.float_ptr(offsets.data_ptr()),
|
||||
diffvg.float_ptr(stop_colors.data_ptr()))
|
||||
assert(torch.isfinite(stop_colors).all())
|
||||
assert torch.isfinite(stop_colors).all()
|
||||
d_args.append(offsets)
|
||||
d_args.append(stop_colors)
|
||||
else:
|
||||
assert(False)
|
||||
assert False
|
||||
d_args.append(None) # stroke_color_type
|
||||
if d_shape_group.has_stroke_color():
|
||||
if d_shape_group.stroke_color_type == diffvg.ColorType.constant:
|
||||
@@ -838,7 +778,7 @@ class RenderFunction(torch.autograd.Function):
|
||||
d_linear_gradient.copy_to(\
|
||||
diffvg.float_ptr(offsets.data_ptr()),
|
||||
diffvg.float_ptr(stop_colors.data_ptr()))
|
||||
assert(torch.isfinite(stop_colors).all())
|
||||
assert torch.isfinite(stop_colors).all()
|
||||
d_args.append(offsets)
|
||||
d_args.append(stop_colors)
|
||||
elif d_shape_group.fill_color_type == diffvg.ColorType.radial_gradient:
|
||||
@@ -852,15 +792,15 @@ class RenderFunction(torch.autograd.Function):
|
||||
d_radial_gradient.copy_to(\
|
||||
diffvg.float_ptr(offsets.data_ptr()),
|
||||
diffvg.float_ptr(stop_colors.data_ptr()))
|
||||
assert(torch.isfinite(stop_colors).all())
|
||||
assert torch.isfinite(stop_colors).all()
|
||||
d_args.append(offsets)
|
||||
d_args.append(stop_colors)
|
||||
else:
|
||||
assert(False)
|
||||
assert False
|
||||
d_args.append(None) # use_even_odd_rule
|
||||
d_shape_to_canvas = torch.zeros((3, 3))
|
||||
d_shape_group.copy_to(diffvg.float_ptr(d_shape_to_canvas.data_ptr()))
|
||||
assert(torch.isfinite(d_shape_to_canvas).all())
|
||||
assert torch.isfinite(d_shape_to_canvas).all()
|
||||
d_args.append(d_shape_to_canvas)
|
||||
d_args.append(None) # filter_type
|
||||
d_args.append(torch.tensor(scene.get_d_filter_radius()))
|
||||
|
@@ -5,8 +5,11 @@ description = ""
|
||||
authors = ["Marco Lee <marco@goodnotesapp.com>"]
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = ">=3.8,<3.11"
|
||||
python = ">=3.9,<3.11"
|
||||
pygame = "^2.0.1"
|
||||
torch = "^2.0.1"
|
||||
ipython = "^8.13.2"
|
||||
pytest-metadata = "^2.0.4"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
torch = "^2.0.0"
|
||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |