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