Spaces:
Runtime error
Runtime error
import os | |
import tensorflow as tf | |
import diffvg | |
import pydiffvg_tensorflow as pydiffvg | |
import time | |
from enum import IntEnum | |
import warnings | |
print_timing = False | |
__EMPTY_TENSOR = tf.constant([]) | |
def is_empty_tensor(tensor): | |
return tf.equal(tf.size(tensor), 0) | |
def set_print_timing(val): | |
global print_timing | |
print_timing=val | |
class OutputType(IntEnum): | |
color = 1 | |
sdf = 2 | |
class ShapeType: | |
__shapetypes = [ | |
diffvg.ShapeType.circle, | |
diffvg.ShapeType.ellipse, | |
diffvg.ShapeType.path, | |
diffvg.ShapeType.rect | |
] | |
def asTensor(type): | |
for i in range(len(ShapeType.__shapetypes)): | |
if ShapeType.__shapetypes[i] == type: | |
return tf.constant(i) | |
def asShapeType(index: tf.Tensor): | |
if is_empty_tensor(index): | |
return None | |
try: | |
type = ShapeType.__shapetypes[index] | |
except IndexError: | |
print(f'{index} is out of range: [0, {len(ShapeType.__shapetypes)})') | |
import sys | |
sys.exit() | |
else: | |
return type | |
class ColorType: | |
__colortypes = [ | |
diffvg.ColorType.constant, | |
diffvg.ColorType.linear_gradient, | |
diffvg.ColorType.radial_gradient | |
] | |
def asTensor(type): | |
for i in range(len(ColorType.__colortypes)): | |
if ColorType.__colortypes[i] == type: | |
return tf.constant(i) | |
def asColorType(index: tf.Tensor): | |
if is_empty_tensor(index): | |
return None | |
try: | |
type = ColorType.__colortypes[index] | |
except IndexError: | |
print(f'{index} is out of range: [0, {len(ColorType.__colortypes)})') | |
import sys | |
sys.exit() | |
else: | |
return type | |
class FilterType: | |
__filtertypes = [ | |
diffvg.FilterType.box, | |
diffvg.FilterType.tent, | |
diffvg.FilterType.hann | |
] | |
def asTensor(type): | |
for i in range(len(FilterType.__filtertypes)): | |
if FilterType.__filtertypes[i] == type: | |
return tf.constant(i) | |
def asFilterType(index: tf.Tensor): | |
if is_empty_tensor(index): | |
return None | |
try: | |
type = FilterType.__filtertypes[index] | |
except IndexError: | |
print(f'{index} is out of range: [0, {len(FilterType.__filtertypes)})') | |
import sys | |
sys.exit() | |
else: | |
return type | |
def serialize_scene(canvas_width, | |
canvas_height, | |
shapes, | |
shape_groups, | |
filter = pydiffvg.PixelFilter(type = diffvg.FilterType.box, | |
radius = tf.constant(0.5)), | |
output_type = OutputType.color, | |
use_prefiltering = False): | |
""" | |
Given a list of shapes, convert them to a linear list of argument, | |
so that we can use it in TF. | |
""" | |
with tf.device('/device:cpu:' + str(pydiffvg.get_cpu_device_id())): | |
num_shapes = len(shapes) | |
num_shape_groups = len(shape_groups) | |
args = [] | |
args.append(tf.constant(canvas_width)) | |
args.append(tf.constant(canvas_height)) | |
args.append(tf.constant(num_shapes)) | |
args.append(tf.constant(num_shape_groups)) | |
args.append(tf.constant(output_type)) | |
args.append(tf.constant(use_prefiltering)) | |
for shape in shapes: | |
if isinstance(shape, pydiffvg.Circle): | |
args.append(ShapeType.asTensor(diffvg.ShapeType.circle)) | |
args.append(tf.identity(shape.radius)) | |
args.append(tf.identity(shape.center)) | |
elif isinstance(shape, pydiffvg.Ellipse): | |
args.append(ShapeType.asTensor(diffvg.ShapeType.ellipse)) | |
args.append(tf.identity(shape.radius)) | |
args.append(tf.identity(shape.center)) | |
elif isinstance(shape, pydiffvg.Path): | |
assert(shape.points.shape[1] == 2) | |
args.append(ShapeType.asTensor(diffvg.ShapeType.path)) | |
args.append(tf.identity(shape.num_control_points)) | |
args.append(tf.identity(shape.points)) | |
args.append(tf.constant(shape.is_closed)) | |
args.append(tf.constant(shape.use_distance_approx)) | |
elif isinstance(shape, pydiffvg.Polygon): | |
assert(shape.points.shape[1] == 2) | |
args.append(ShapeType.asTensor(diffvg.ShapeType.path)) | |
if shape.is_closed: | |
args.append(tf.zeros(shape.points.shape[0], dtype = tf.int32)) | |
else: | |
args.append(tf.zeros(shape.points.shape[0] - 1, dtype = tf.int32)) | |
args.append(tf.identity(shape.points)) | |
args.append(tf.constant(shape.is_closed)) | |
elif isinstance(shape, pydiffvg.Rect): | |
args.append(ShapeType.asTensor(diffvg.ShapeType.rect)) | |
args.append(tf.identity(shape.p_min)) | |
args.append(tf.identity(shape.p_max)) | |
else: | |
assert(False) | |
args.append(tf.identity(shape.stroke_width)) | |
for shape_group in shape_groups: | |
args.append(tf.identity(shape_group.shape_ids)) | |
# Fill color | |
if shape_group.fill_color is None: | |
args.append(__EMPTY_TENSOR) | |
elif tf.is_tensor(shape_group.fill_color): | |
args.append(ColorType.asTensor(diffvg.ColorType.constant)) | |
args.append(tf.identity(shape_group.fill_color)) | |
elif isinstance(shape_group.fill_color, pydiffvg.LinearGradient): | |
args.append(ColorType.asTensor(diffvg.ColorType.linear_gradient)) | |
args.append(tf.identity(shape_group.fill_color.begin)) | |
args.append(tf.identity(shape_group.fill_color.end)) | |
args.append(tf.identity(shape_group.fill_color.offsets)) | |
args.append(tf.identity(shape_group.fill_color.stop_colors)) | |
elif isinstance(shape_group.fill_color, pydiffvg.RadialGradient): | |
args.append(ColorType.asTensor(diffvg.ColorType.radial_gradient)) | |
args.append(tf.identity(shape_group.fill_color.center)) | |
args.append(tf.identity(shape_group.fill_color.radius)) | |
args.append(tf.identity(shape_group.fill_color.offsets)) | |
args.append(tf.identity(shape_group.fill_color.stop_colors)) | |
if shape_group.fill_color is not None: | |
# go through the underlying shapes and check if they are all closed | |
for shape_id in shape_group.shape_ids: | |
if isinstance(shapes[shape_id], pydiffvg.Path): | |
if not shapes[shape_id].is_closed: | |
warnings.warn("Detected non-closed paths with fill color. This might causes unexpected results.", Warning) | |
# Stroke color | |
if shape_group.stroke_color is None: | |
args.append(__EMPTY_TENSOR) | |
elif tf.is_tensor(shape_group.stroke_color): | |
args.append(tf.constant(0)) | |
args.append(tf.identity(shape_group.stroke_color)) | |
elif isinstance(shape_group.stroke_color, pydiffvg.LinearGradient): | |
args.append(ColorType.asTensor(diffvg.ColorType.linear_gradient)) | |
args.append(tf.identity(shape_group.stroke_color.begin)) | |
args.append(tf.identity(shape_group.stroke_color.end)) | |
args.append(tf.identity(shape_group.stroke_color.offsets)) | |
args.append(tf.identity(shape_group.stroke_color.stop_colors)) | |
elif isinstance(shape_group.stroke_color, pydiffvg.RadialGradient): | |
args.append(ColorType.asTensor(diffvg.ColorType.radial_gradient)) | |
args.append(tf.identity(shape_group.stroke_color.center)) | |
args.append(tf.identity(shape_group.stroke_color.radius)) | |
args.append(tf.identity(shape_group.stroke_color.offsets)) | |
args.append(tf.identity(shape_group.stroke_color.stop_colors)) | |
args.append(tf.constant(shape_group.use_even_odd_rule)) | |
# Transformation | |
args.append(tf.identity(shape_group.shape_to_canvas)) | |
args.append(FilterType.asTensor(filter.type)) | |
args.append(tf.constant(filter.radius)) | |
return args | |
class Context: pass | |
def forward(width, | |
height, | |
num_samples_x, | |
num_samples_y, | |
seed, | |
*args): | |
""" | |
Forward rendering pass: given a serialized scene and output an image. | |
""" | |
# Unpack arguments | |
with tf.device('/device:cpu:' + str(pydiffvg.get_cpu_device_id())): | |
current_index = 0 | |
canvas_width = int(args[current_index]) | |
current_index += 1 | |
canvas_height = int(args[current_index]) | |
current_index += 1 | |
num_shapes = int(args[current_index]) | |
current_index += 1 | |
num_shape_groups = int(args[current_index]) | |
current_index += 1 | |
output_type = OutputType(int(args[current_index])) | |
current_index += 1 | |
use_prefiltering = bool(args[current_index]) | |
current_index += 1 | |
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 = ShapeType.asShapeType(args[current_index]) | |
current_index += 1 | |
if shape_type == diffvg.ShapeType.circle: | |
radius = args[current_index] | |
current_index += 1 | |
center = args[current_index] | |
current_index += 1 | |
shape = diffvg.Circle(float(radius), | |
diffvg.Vector2f(float(center[0]), float(center[1]))) | |
elif shape_type == diffvg.ShapeType.ellipse: | |
radius = args[current_index] | |
current_index += 1 | |
center = args[current_index] | |
current_index += 1 | |
shape = diffvg.Ellipse(diffvg.Vector2f(float(radius[0]), float(radius[1])), | |
diffvg.Vector2f(float(center[0]), float(center[1]))) | |
elif shape_type == diffvg.ShapeType.path: | |
num_control_points = args[current_index] | |
current_index += 1 | |
points = 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(pydiffvg.data_ptr(num_control_points)), | |
diffvg.float_ptr(pydiffvg.data_ptr(points)), | |
diffvg.float_ptr(0), # thickness | |
num_control_points.shape[0], | |
points.shape[0], | |
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 | |
shape = diffvg.Rect(diffvg.Vector2f(float(p_min[0]), float(p_min[1])), | |
diffvg.Vector2f(float(p_max[0]), float(p_max[1]))) | |
else: | |
assert(False) | |
stroke_width = args[current_index] | |
current_index += 1 | |
shapes.append(diffvg.Shape(\ | |
shape_type, shape.get_ptr(), float(stroke_width))) | |
shape_contents.append(shape) | |
for shape_group_id in range(num_shape_groups): | |
shape_ids = args[current_index] | |
current_index += 1 | |
fill_color_type = ColorType.asColorType(args[current_index]) | |
current_index += 1 | |
if fill_color_type == diffvg.ColorType.constant: | |
color = args[current_index] | |
current_index += 1 | |
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]) | |
fill_color = diffvg.LinearGradient(diffvg.Vector2f(float(beg[0]), float(beg[1])), | |
diffvg.Vector2f(float(end[0]), float(end[1])), | |
offsets.shape[0], | |
diffvg.float_ptr(pydiffvg.data_ptr(offsets)), | |
diffvg.float_ptr(pydiffvg.data_ptr(stop_colors))) | |
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]) | |
fill_color = diffvg.RadialGradient(diffvg.Vector2f(float(center[0]), float(center[1])), | |
diffvg.Vector2f(float(radius[0]), float(radius[1])), | |
offsets.shape[0], | |
diffvg.float_ptr(pydiffvg.data_ptr(offsets)), | |
diffvg.float_ptr(pydiffvg.data_ptr(stop_colors))) | |
elif fill_color_type is None: | |
fill_color = None | |
else: | |
assert(False) | |
stroke_color_type = ColorType.asColorType(args[current_index]) | |
current_index += 1 | |
if stroke_color_type == diffvg.ColorType.constant: | |
color = args[current_index] | |
current_index += 1 | |
stroke_color = diffvg.Constant(\ | |
diffvg.Vector4f(float(color[0]), | |
float(color[1]), | |
float(color[2]), | |
float(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]) | |
stroke_color = diffvg.LinearGradient(\ | |
diffvg.Vector2f(float(beg[0]), float(beg[1])), | |
diffvg.Vector2f(float(end[0]), float(end[1])), | |
offsets.shape[0], | |
diffvg.float_ptr(pydiffvg.data_ptr(offsets)), | |
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]) | |
stroke_color = diffvg.RadialGradient(\ | |
diffvg.Vector2f(float(center[0]), float(center[1])), | |
diffvg.Vector2f(float(radius[0]), float(radius[1])), | |
offsets.shape[0], | |
diffvg.float_ptr(pydiffvg.data_ptr(offsets)), | |
diffvg.float_ptr(pydiffvg.data_ptr(stop_colors))) | |
elif stroke_color_type is None: | |
stroke_color = None | |
else: | |
assert(False) | |
use_even_odd_rule = bool(args[current_index]) | |
current_index += 1 | |
shape_to_canvas = args[current_index] | |
current_index += 1 | |
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(pydiffvg.data_ptr(shape_ids)), | |
shape_ids.shape[0], | |
diffvg.ColorType.constant if fill_color_type is None else fill_color_type, | |
diffvg.void_ptr(0) if fill_color is None else fill_color.get_ptr(), | |
diffvg.ColorType.constant if stroke_color_type is None else stroke_color_type, | |
diffvg.void_ptr(0) if stroke_color is None else stroke_color.get_ptr(), | |
use_even_odd_rule, | |
diffvg.float_ptr(pydiffvg.data_ptr(shape_to_canvas)))) | |
filter_type = FilterType.asFilterType(args[current_index]) | |
current_index += 1 | |
filter_radius = args[current_index] | |
current_index += 1 | |
filt = diffvg.Filter(filter_type, filter_radius) | |
device_name = pydiffvg.get_device_name() | |
device_spec = tf.DeviceSpec.from_string(device_name) | |
use_gpu = device_spec.device_type == 'GPU' | |
gpu_index = device_spec.device_index if device_spec.device_index is not None else 0 | |
start = time.time() | |
scene = diffvg.Scene(canvas_width, | |
canvas_height, | |
shapes, | |
shape_groups, | |
filt, | |
use_gpu, | |
gpu_index) | |
time_elapsed = time.time() - start | |
global print_timing | |
if print_timing: | |
print('Scene construction, time: %.5f s' % time_elapsed) | |
with tf.device(device_name): | |
if output_type == OutputType.color: | |
rendered_image = tf.zeros((int(height), int(width), 4), dtype = tf.float32) | |
else: | |
assert(output_type == OutputType.sdf) | |
rendered_image = tf.zeros((int(height), int(width), 1), dtype = tf.float32) | |
start = time.time() | |
diffvg.render(scene, | |
diffvg.float_ptr(0), # background image | |
diffvg.float_ptr(pydiffvg.data_ptr(rendered_image) if output_type == OutputType.color else 0), | |
diffvg.float_ptr(pydiffvg.data_ptr(rendered_image) if output_type == OutputType.sdf else 0), | |
width, | |
height, | |
int(num_samples_x), | |
int(num_samples_y), | |
seed, | |
diffvg.float_ptr(0), # d_background_image | |
diffvg.float_ptr(0), # d_render_image | |
diffvg.float_ptr(0), # d_render_sdf | |
diffvg.float_ptr(0), # d_translation | |
use_prefiltering, | |
diffvg.float_ptr(0), # eval_positions | |
0 ) # num_eval_positions (automatically set to entire raster) | |
time_elapsed = time.time() - start | |
if print_timing: | |
print('Forward pass, time: %.5f s' % time_elapsed) | |
ctx = Context() | |
ctx.scene = scene | |
ctx.shape_contents = shape_contents | |
ctx.color_contents = color_contents | |
ctx.filter = filt | |
ctx.width = width | |
ctx.height = height | |
ctx.num_samples_x = num_samples_x | |
ctx.num_samples_y = num_samples_y | |
ctx.seed = seed | |
ctx.output_type = output_type | |
ctx.use_prefiltering = use_prefiltering | |
return rendered_image, ctx | |
def render(*x): | |
""" | |
The main TensorFlow interface of C++ diffvg. | |
""" | |
assert(tf.executing_eagerly()) | |
if pydiffvg.get_use_gpu() and os.environ.get('TF_FORCE_GPU_ALLOW_GROWTH') != 'true': | |
print('******************** WARNING ********************') | |
print('Tensorflow by default allocates all GPU memory,') | |
print('causing huge amount of page faults when rendering.') | |
print('Please set the environment variable TF_FORCE_GPU_ALLOW_GROWTH to true,') | |
print('so that Tensorflow allocates memory on demand.') | |
print('*************************************************') | |
width = x[0] | |
height = x[1] | |
num_samples_x = x[2] | |
num_samples_y = x[3] | |
seed = x[4] | |
args = x[5:] | |
img, ctx = forward(width, height, num_samples_x, num_samples_y, seed, *args) | |
def backward(grad_img): | |
scene = ctx.scene | |
width = ctx.width | |
height = ctx.height | |
num_samples_x = ctx.num_samples_x | |
num_samples_y = ctx.num_samples_y | |
seed = ctx.seed | |
output_type = ctx.output_type | |
use_prefiltering = ctx.use_prefiltering | |
start = time.time() | |
with tf.device(pydiffvg.get_device_name()): | |
diffvg.render(scene, | |
diffvg.float_ptr(0), # background_image | |
diffvg.float_ptr(0), # render_image | |
diffvg.float_ptr(0), # render_sdf | |
width, | |
height, | |
num_samples_x, | |
num_samples_y, | |
seed, | |
diffvg.float_ptr(0), # d_background_image | |
diffvg.float_ptr(pydiffvg.data_ptr(grad_img) if output_type == OutputType.color else 0), | |
diffvg.float_ptr(pydiffvg.data_ptr(grad_img) if output_type == OutputType.sdf else 0), | |
diffvg.float_ptr(0), # d_translation | |
use_prefiltering, | |
diffvg.float_ptr(0), # eval_positions | |
0 ) # num_eval_positions (automatically set to entire raster)) | |
time_elapsed = time.time() - start | |
global print_timing | |
if print_timing: | |
print('Backward pass, time: %.5f s' % time_elapsed) | |
with tf.device('/device:cpu:' + str(pydiffvg.get_cpu_device_id())): | |
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(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 | |
for shape_id in range(scene.num_shapes): | |
d_args.append(None) # type | |
d_shape = scene.get_d_shape(shape_id) | |
if d_shape.type == diffvg.ShapeType.circle: | |
d_circle = d_shape.as_circle() | |
radius = tf.constant(d_circle.radius) | |
d_args.append(radius) | |
c = d_circle.center | |
c = tf.constant((c.x, c.y)) | |
d_args.append(c) | |
elif d_shape.type == diffvg.ShapeType.ellipse: | |
d_ellipse = d_shape.as_ellipse() | |
r = d_ellipse.radius | |
r = tf.constant((d_ellipse.radius.x, d_ellipse.radius.y)) | |
d_args.append(r) | |
c = d_ellipse.center | |
c = tf.constant((c.x, c.y)) | |
d_args.append(c) | |
elif d_shape.type == diffvg.ShapeType.path: | |
d_path = d_shape.as_path() | |
points = tf.zeros((d_path.num_points, 2), dtype=tf.float32) | |
d_path.copy_to(diffvg.float_ptr(pydiffvg.data_ptr(points)),diffvg.float_ptr(0)) | |
d_args.append(None) # num_control_points | |
d_args.append(points) | |
d_args.append(None) # is_closed | |
d_args.append(None) # use_distance_approx | |
elif d_shape.type == diffvg.ShapeType.rect: | |
d_rect = d_shape.as_rect() | |
p_min = tf.constant((d_rect.p_min.x, d_rect.p_min.y)) | |
p_max = tf.constant((d_rect.p_max.x, d_rect.p_max.y)) | |
d_args.append(p_min) | |
d_args.append(p_max) | |
else: | |
assert(False) | |
w = tf.constant((d_shape.stroke_width)) | |
d_args.append(w) | |
for group_id in range(scene.num_shape_groups): | |
d_shape_group = scene.get_d_shape_group(group_id) | |
d_args.append(None) # shape_ids | |
d_args.append(None) # fill_color_type | |
if d_shape_group.has_fill_color(): | |
if d_shape_group.fill_color_type == diffvg.ColorType.constant: | |
d_constant = d_shape_group.fill_color_as_constant() | |
c = d_constant.color | |
d_args.append(tf.constant((c.x, c.y, c.z, c.w))) | |
elif d_shape_group.fill_color_type == diffvg.ColorType.linear_gradient: | |
d_linear_gradient = d_shape_group.fill_color_as_linear_gradient() | |
beg = d_linear_gradient.begin | |
d_args.append(tf.constant((beg.x, beg.y))) | |
end = d_linear_gradient.end | |
d_args.append(tf.constant((end.x, end.y))) | |
offsets = tf.zeros((d_linear_gradient.num_stops), dtype=tf.float32) | |
stop_colors = tf.zeros((d_linear_gradient.num_stops, 4), dtype=tf.float32) | |
# HACK: tensorflow's eager mode uses a cache to store scalar | |
# constants to avoid memory copy. If we pass scalar tensors | |
# into the C++ code and modify them, we would corrupt the | |
# cache, causing incorrect result in future scalar constant | |
# creations. Thus we force tensorflow to copy by plusing a zero. | |
# (also see https://github.com/tensorflow/tensorflow/issues/11186 | |
# for more discussion regarding copying tensors) | |
if offsets.shape.num_elements() == 1: | |
offsets = offsets + 0 | |
d_linear_gradient.copy_to(\ | |
diffvg.float_ptr(pydiffvg.data_ptr(offsets)), | |
diffvg.float_ptr(pydiffvg.data_ptr(stop_colors))) | |
d_args.append(offsets) | |
d_args.append(stop_colors) | |
elif d_shape_group.fill_color_type == diffvg.ColorType.radial_gradient: | |
d_radial_gradient = d_shape_group.fill_color_as_radial_gradient() | |
center = d_radial_gradient.center | |
d_args.append(tf.constant((center.x, center.y))) | |
radius = d_radial_gradient.radius | |
d_args.append(tf.constant((radius.x, radius.y))) | |
offsets = tf.zeros((d_radial_gradient.num_stops)) | |
if offsets.shape.num_elements() == 1: | |
offsets = offsets + 0 | |
stop_colors = tf.zeros((d_radial_gradient.num_stops, 4)) | |
d_radial_gradient.copy_to(\ | |
diffvg.float_ptr(pydiffvg.data_ptr(offsets)), | |
diffvg.float_ptr(pydiffvg.data_ptr(stop_colors))) | |
d_args.append(offsets) | |
d_args.append(stop_colors) | |
else: | |
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: | |
d_constant = d_shape_group.stroke_color_as_constant() | |
c = d_constant.color | |
d_args.append(tf.constant((c.x, c.y, c.z, c.w))) | |
elif d_shape_group.stroke_color_type == diffvg.ColorType.linear_gradient: | |
d_linear_gradient = d_shape_group.stroke_color_as_linear_gradient() | |
beg = d_linear_gradient.begin | |
d_args.append(tf.constant((beg.x, beg.y))) | |
end = d_linear_gradient.end | |
d_args.append(tf.constant((end.x, end.y))) | |
offsets = tf.zeros((d_linear_gradient.num_stops)) | |
stop_colors = tf.zeros((d_linear_gradient.num_stops, 4)) | |
if offsets.shape.num_elements() == 1: | |
offsets = offsets + 0 | |
d_linear_gradient.copy_to(\ | |
diffvg.float_ptr(pydiffvg.data_ptr(offsets)), | |
diffvg.float_ptr(pydiffvg.data_ptr(stop_colors))) | |
d_args.append(offsets) | |
d_args.append(stop_colors) | |
elif d_shape_group.fill_color_type == diffvg.ColorType.radial_gradient: | |
d_radial_gradient = d_shape_group.stroke_color_as_radial_gradient() | |
center = d_radial_gradient.center | |
d_args.append(tf.constant((center.x, center.y))) | |
radius = d_radial_gradient.radius | |
d_args.append(tf.constant((radius.x, radius.y))) | |
offsets = tf.zeros((d_radial_gradient.num_stops)) | |
stop_colors = tf.zeros((d_radial_gradient.num_stops, 4)) | |
if offsets.shape.num_elements() == 1: | |
offsets = offsets + 0 | |
d_radial_gradient.copy_to(\ | |
diffvg.float_ptr(pydiffvg.data_ptr(offsets)), | |
diffvg.float_ptr(pydiffvg.data_ptr(stop_colors))) | |
d_args.append(offsets) | |
d_args.append(stop_colors) | |
else: | |
assert(False) | |
d_args.append(None) # use_even_odd_rule | |
d_shape_to_canvas = tf.zeros((3, 3), dtype = tf.float32) | |
d_shape_group.copy_to(diffvg.float_ptr(pydiffvg.data_ptr(d_shape_to_canvas))) | |
d_args.append(d_shape_to_canvas) | |
d_args.append(None) # filter_type | |
d_args.append(tf.constant(scene.get_d_filter_radius())) | |
return d_args | |
return img, backward | |