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 shape = diffvg.Path( diffvg.int_ptr(pydiffvg.data_ptr(num_control_points)), diffvg.float_ptr(pydiffvg.data_ptr(points)), num_control_points.shape[0], points.shape[0], is_closed) 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_grad(grad_img, width, height, num_samples_x, num_samples_y, seed, background_image, *args): if not grad_img.is_contiguous(): grad_img = grad_img.contiguous() assert(torch.isfinite(grad_img).all()) # Unpack arguments current_index = 0 canvas_width = args[current_index] current_index += 1 canvas_height = args[current_index] current_index += 1 num_shapes = args[current_index] current_index += 1 num_shape_groups = args[current_index] current_index += 1 output_type = args[current_index] current_index += 1 use_prefiltering = args[current_index] current_index += 1 eval_positions = args[current_index] current_index += 1 shapes = [] shape_groups = [] shape_contents = [] # Important to avoid GC deleting the shapes color_contents = [] # Same as above for shape_id in range(num_shapes): shape_type = args[current_index] current_index += 1 if shape_type == diffvg.ShapeType.circle: radius = args[current_index] current_index += 1 center = args[current_index] current_index += 1 shape = diffvg.Circle(radius, diffvg.Vector2f(center[0], center[1])) elif shape_type == diffvg.ShapeType.ellipse: radius = args[current_index] current_index += 1 center = args[current_index] current_index += 1 shape = diffvg.Ellipse(diffvg.Vector2f(radius[0], radius[1]), diffvg.Vector2f(center[0], center[1])) elif shape_type == diffvg.ShapeType.path: num_control_points = args[current_index] current_index += 1 points = args[current_index] current_index += 1 thickness = args[current_index] current_index += 1 is_closed = args[current_index] current_index += 1 use_distance_approx = args[current_index] current_index += 1 shape = diffvg.Path(diffvg.int_ptr(num_control_points.data_ptr()), diffvg.float_ptr(points.data_ptr()), diffvg.float_ptr(thickness.data_ptr() if thickness is not None else 0), 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(p_min[0], p_min[1]), diffvg.Vector2f(p_max[0], p_max[1])) else: assert(False) stroke_width = args[current_index] current_index += 1 shapes.append(diffvg.Shape( shape_type, shape.get_ptr(), stroke_width.item())) shape_contents.append(shape) for shape_group_id in range(num_shape_groups): shape_ids = args[current_index] current_index += 1 fill_color_type = args[current_index] current_index += 1 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(beg[0], beg[1]), diffvg.Vector2f(end[0], end[1]), offsets.shape[0], diffvg.float_ptr(offsets.data_ptr()), diffvg.float_ptr(stop_colors.data_ptr())) elif fill_color_type == diffvg.ColorType.radial_gradient: center = args[current_index] current_index += 1 radius = args[current_index] current_index += 1 offsets = args[current_index] current_index += 1 stop_colors = args[current_index] current_index += 1 assert(offsets.shape[0] == stop_colors.shape[0]) fill_color = diffvg.RadialGradient(diffvg.Vector2f(center[0], center[1]), diffvg.Vector2f(radius[0], radius[1]), offsets.shape[0], diffvg.float_ptr(offsets.data_ptr()), diffvg.float_ptr(stop_colors.data_ptr())) elif fill_color_type is None: fill_color = None else: assert(False) stroke_color_type = args[current_index] current_index += 1 if stroke_color_type == diffvg.ColorType.constant: color = args[current_index] current_index += 1 stroke_color = diffvg.Constant( diffvg.Vector4f(color[0], color[1], color[2], color[3])) elif stroke_color_type == diffvg.ColorType.linear_gradient: beg = args[current_index] current_index += 1 end = args[current_index] current_index += 1 offsets = args[current_index] current_index += 1 stop_colors = args[current_index] current_index += 1 assert(offsets.shape[0] == stop_colors.shape[0]) stroke_color = diffvg.LinearGradient(diffvg.Vector2f(beg[0], beg[1]), diffvg.Vector2f(end[0], end[1]), offsets.shape[0], diffvg.float_ptr(offsets.data_ptr()), diffvg.float_ptr(stop_colors.data_ptr())) elif stroke_color_type == diffvg.ColorType.radial_gradient: center = args[current_index] current_index += 1 radius = args[current_index] current_index += 1 offsets = args[current_index] current_index += 1 stop_colors = args[current_index] current_index += 1 assert(offsets.shape[0] == stop_colors.shape[0]) stroke_color = diffvg.RadialGradient(diffvg.Vector2f(center[0], center[1]), diffvg.Vector2f(radius[0], radius[1]), offsets.shape[0], diffvg.float_ptr(offsets.data_ptr()), diffvg.float_ptr(stop_colors.data_ptr())) elif stroke_color_type is None: stroke_color = None else: assert(False) use_even_odd_rule = args[current_index] current_index += 1 shape_to_canvas = args[current_index] current_index += 1 if fill_color is not None: color_contents.append(fill_color) if stroke_color is not None: color_contents.append(stroke_color) shape_groups.append(diffvg.ShapeGroup( diffvg.int_ptr(shape_ids.data_ptr()), shape_ids.shape[0], 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(shape_to_canvas.data_ptr()))) filter_type = args[current_index] current_index += 1 filter_radius = args[current_index] current_index += 1 filt = diffvg.Filter(filter_type, filter_radius) scene = diffvg.Scene(canvas_width, canvas_height, shapes, shape_groups, filt, pydiffvg.get_use_gpu(), pydiffvg.get_device().index if pydiffvg.get_device().index is not None else -1) if output_type == OutputType.color: assert(grad_img.shape[2] == 4) else: assert(grad_img.shape[2] == 1) if background_image is not None: background_image = background_image.to(pydiffvg.get_device()) if background_image.shape[2] == 3: background_image = torch.cat(( background_image, torch.ones(background_image.shape[0], background_image.shape[1], 1, device=background_image.device)), dim=2) background_image = background_image.contiguous() # assert(background_image.shape[0] == rendered_image.shape[0]) # assert(background_image.shape[1] == rendered_image.shape[1]) assert(background_image.shape[2] == 4) translation_grad_image = \ torch.zeros(height, width, 2, device=pydiffvg.get_device()) start = time.time() diffvg.render(scene, diffvg.float_ptr(background_image.data_ptr() if background_image is not None else 0), 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(grad_img.data_ptr() if output_type == OutputType.color else 0), diffvg.float_ptr(grad_img.data_ptr() if output_type == OutputType.sdf else 0), diffvg.float_ptr(translation_grad_image.data_ptr()), use_prefiltering, diffvg.float_ptr(eval_positions.data_ptr()), eval_positions.shape[0]) time_elapsed = time.time() - start if print_timing: print('Gradient pass, time: %.5f s' % time_elapsed) assert(torch.isfinite(translation_grad_image).all()) return translation_grad_image