import pydiffvg import torch # import skimage # import numpy as np # Use GPU if available pydiffvg.set_use_gpu(torch.cuda.is_available()) canvas_width = 256 canvas_height = 256 circle = pydiffvg.Circle(radius=torch.tensor(40.0), center=torch.tensor([128.0, 128.0])) shapes = [circle] circle_group = pydiffvg.ShapeGroup(shape_ids=torch.tensor([0]), fill_color=torch.tensor( [0.3, 0.6, 0.3, 1.0])) shape_groups = [circle_group] scene_args = pydiffvg.RenderFunction.serialize_scene( canvas_width, canvas_height, shapes, shape_groups, output_type=pydiffvg.OutputType.sdf) render = pydiffvg.RenderFunction.apply img = render( 256, # width 256, # height 2, # num_samples_x 2, # num_samples_y 0, # seed
def save(self, all_points, save_dir, name, verbose=False, white_background=True): # note that this if for a single shape and bs dimension should have multiple curves # print('1:', process.memory_info().rss*1e-6) render_size = self.imsize bs = all_points.shape[0] if verbose: render_size = render_size * 2 all_points = all_points * render_size num_ctrl_pts = torch.zeros(self.curves, dtype=torch.int32) + 2 shapes = [] shape_groups = [] for k in range(bs): # Get point parameters from network color = make_tensor(color[k]) points = all_points[k].cpu().contiguous() #[self.sort_idx[k]] if verbose: np.random.seed(0) colors = np.random.rand(self.curves, 4) high = np.array((0.565, 0.392, 0.173, 1)) low = np.array((0.094, 0.310, 0.635, 1)) diff = (high - low) / (self.curves) colors[:, 3] = 1 for i in range(self.curves): scale = diff * i color = low + scale color[3] = 1 color = torch.tensor(color) num_ctrl_pts = torch.zeros(1, dtype=torch.int32) + 2 if i * 3 + 4 > self.curves * 3: curve_points = torch.stack([ points[i * 3], points[i * 3 + 1], points[i * 3 + 2], points[0] ]) else: curve_points = points[i * 3:i * 3 + 4] path = pydiffvg.Path(num_control_points=num_ctrl_pts, points=curve_points, is_closed=False, stroke_width=torch.tensor(4)) path_group = pydiffvg.ShapeGroup(shape_ids=torch.tensor( [i]), fill_color=None, stroke_color=color) shapes.append(path) shape_groups.append(path_group) for i in range(self.curves * 3): scale = diff * (i // 3) color = low + scale color[3] = 1 color = torch.tensor(color) if i % 3 == 0: # color = torch.tensor(colors[i//3]) #green shape = pydiffvg.Rect(p_min=points[i] - 8, p_max=points[i] + 8) group = pydiffvg.ShapeGroup(shape_ids=torch.tensor( [self.curves + i]), fill_color=color) else: # color = torch.tensor(colors[i//3]) #purple shape = pydiffvg.Circle(radius=torch.tensor(8.0), center=points[i]) group = pydiffvg.ShapeGroup(shape_ids=torch.tensor( [self.curves + i]), fill_color=color) shapes.append(shape) shape_groups.append(group) else: path = pydiffvg.Path(num_control_points=num_ctrl_pts, points=points, is_closed=True) shapes.append(path) path_group = pydiffvg.ShapeGroup(shape_ids=torch.tensor( [len(shapes) - 1]), fill_color=color, stroke_color=color) shape_groups.append(path_group) pydiffvg.save_svg(f"{save_dir}{name}/{name}.svg", self.imsize, self.imsize, shapes, shape_groups)
def parse_shape(node, transform, fill_color, shapes, shape_groups, defs): tag = remove_namespaces(node.tag) new_transform, new_fill_color, stroke_color, stroke_width, use_even_odd_rule = \ parse_common_attrib(node, transform, fill_color, defs) if tag == 'path': d = node.attrib['d'] name = '' if 'id' in node.attrib: name = node.attrib['id'] force_closing = new_fill_color is not None paths = pydiffvg.from_svg_path(d, new_transform, force_closing) for idx, path in enumerate(paths): assert (path.points.shape[1] == 2) path.stroke_width = stroke_width path.source_id = name path.id = "{}-{}".format(name, idx) if len(paths) > 1 else name prev_shapes_size = len(shapes) shapes = shapes + paths shape_ids = torch.tensor(list(range(prev_shapes_size, len(shapes)))) shape_groups.append(pydiffvg.ShapeGroup(\ shape_ids = shape_ids, fill_color = new_fill_color, stroke_color = stroke_color, use_even_odd_rule = use_even_odd_rule, id = name)) elif tag == 'polygon': name = '' if 'id' in node.attrib: name = node.attrib['id'] force_closing = new_fill_color is not None pts = node.attrib['points'].strip() pts = pts.split(' ') # import ipdb; ipdb.set_trace() pts = [[float(y) for y in re.split(',| ', x)] for x in pts if x] pts = torch.tensor(pts, dtype=torch.float32).view(-1, 2) polygon = pydiffvg.Polygon(pts, force_closing) polygon.stroke_width = stroke_width shape_ids = torch.tensor([len(shapes)]) shapes.append(polygon) shape_groups.append(pydiffvg.ShapeGroup(\ shape_ids = shape_ids, fill_color = new_fill_color, stroke_color = stroke_color, use_even_odd_rule = use_even_odd_rule, shape_to_canvas = new_transform, id = name)) elif tag == 'line': x1 = float(node.attrib['x1']) y1 = float(node.attrib['y1']) x2 = float(node.attrib['x2']) y2 = float(node.attrib['y2']) p1 = torch.tensor([x1, y1]) p2 = torch.tensor([x2, y2]) points = torch.stack((p1, p2)) line = pydiffvg.Polygon(points, False) line.stroke_width = stroke_width shape_ids = torch.tensor([len(shapes)]) shapes.append(line) shape_groups.append(pydiffvg.ShapeGroup(\ shape_ids = shape_ids, fill_color = new_fill_color, stroke_color = stroke_color, use_even_odd_rule = use_even_odd_rule, shape_to_canvas = new_transform)) elif tag == 'circle': radius = float(node.attrib['r']) cx = float(node.attrib['cx']) cy = float(node.attrib['cy']) name = '' if 'id' in node.attrib: name = node.attrib['id'] center = torch.tensor([cx, cy]) circle = pydiffvg.Circle(radius=torch.tensor(radius), center=center) circle.stroke_width = stroke_width shape_ids = torch.tensor([len(shapes)]) shapes.append(circle) shape_groups.append(pydiffvg.ShapeGroup(\ shape_ids = shape_ids, fill_color = new_fill_color, stroke_color = stroke_color, use_even_odd_rule = use_even_odd_rule, shape_to_canvas = new_transform)) elif tag == 'ellipse': rx = float(node.attrib['rx']) ry = float(node.attrib['ry']) cx = float(node.attrib['cx']) cy = float(node.attrib['cy']) name = '' if 'id' in node.attrib: name = node.attrib['id'] center = torch.tensor([cx, cy]) circle = pydiffvg.Circle(radius=torch.tensor(radius), center=center) circle.stroke_width = stroke_width shape_ids = torch.tensor([len(shapes)]) shapes.append(circle) shape_groups.append(pydiffvg.ShapeGroup(\ shape_ids = shape_ids, fill_color = new_fill_color, stroke_color = stroke_color, use_even_odd_rule = use_even_odd_rule, shape_to_canvas = new_transform)) elif tag == 'rect': x = 0.0 y = 0.0 if x in node.attrib: x = float(node.attrib['x']) if y in node.attrib: y = float(node.attrib['y']) w = float(node.attrib['width']) h = float(node.attrib['height']) p_min = torch.tensor([x, y]) p_max = torch.tensor([x + w, x + h]) rect = pydiffvg.Rect(p_min=p_min, p_max=p_max) rect.stroke_width = stroke_width shape_ids = torch.tensor([len(shapes)]) shapes.append(rect) shape_groups.append(pydiffvg.ShapeGroup(\ shape_ids = shape_ids, fill_color = new_fill_color, stroke_color = stroke_color, use_even_odd_rule = use_even_odd_rule, shape_to_canvas = new_transform)) return shapes, shape_groups
def my_render(curve_points, curve_widths, curve_alphas, circle_centers, circle_radiuses, circle_widths, circle_alphas, canvas_size=32, colors=None): dev = curve_points.device curve_points = 0.5*(curve_points + 1.0) * canvas_size circle_centers = 0.5*(circle_centers + 1.0) * canvas_size circle_radiuses = circle_radiuses * canvas_size / 2 eps = 1e-4 curve_points = curve_points + eps*torch.randn_like(curve_points) bs, num_strokes, num_pts, _ = curve_points.shape num_segments = (num_pts - 1) // 3 num_circles = circle_centers.shape[1] n_out = 3 if colors is not None else 1 output = torch.zeros(bs, n_out, canvas_size, canvas_size, device=curve_points.device) scenes = [] for k in range(bs): shapes = [] shape_groups = [] for p in range(num_strokes): points = curve_points[k, p].contiguous().cuda() # bezier num_ctrl_pts = torch.zeros(num_segments, dtype=torch.int32) + 2 width = curve_widths[k, p].cuda() alpha = curve_alphas[k, p].cuda() if colors is not None: color = colors[k, p] else: color = torch.ones(3, device=alpha.device) color = torch.cat([color, alpha.view(1,)]) path = pydiffvg.Path( num_control_points=num_ctrl_pts, points=points, stroke_width=width, is_closed=False) shapes.append(path) path_group = pydiffvg.ShapeGroup( shape_ids=torch.tensor([len(shapes) - 1]), fill_color=None, stroke_color=color) shape_groups.append(path_group) for c in range(num_circles): center = circle_centers[k, c] radius = circle_radiuses[k, c] width = circle_widths[k, c] alpha = circle_alphas[k, c] circle = pydiffvg.Circle(radius=radius, center=center, stroke_width=width) shapes.append(circle) if colors is not None: color = colors[k, p] else: color = torch.ones(3, device=alpha.device) color = torch.cat([color, alpha.view(1,)]) circle_group = pydiffvg.ShapeGroup(shape_ids=torch.tensor([len(shapes) - 1]), fill_color=torch.tensor([0, 0, 0, 0.0]), stroke_color=color, ) shape_groups.append(circle_group) # Rasterize scenes.append((canvas_size, canvas_size, shapes, shape_groups)) raster = render(canvas_size, canvas_size, shapes, shape_groups, samples=2) raster = raster.permute(2, 0, 1).view(4, canvas_size, canvas_size) alpha = raster[3:4] if colors is not None: # color output image = raster[:3] alpha = alpha.repeat(3, 1, 1) else: image = raster[:1] # alpha compositing image = image*alpha output[k] = image output = output.to(dev) return output, scenes
def raster(all_points, color=[0, 0, 0, 1], verbose=False, white_background=True): assert len(color) == 4 # print('1:', process.memory_info().rss*1e-6) render_size = 512 paths = int(all_points.shape[0] / 3) bs = 1 #all_points.shape[0] outputs = [] scaling = torch.zeros([1, 2]) scaling[:, 0] = 512 / 24 scaling[:, 1] = 512 / 24 print(scaling) all_points = all_points * scaling num_ctrl_pts = torch.zeros(paths, dtype=torch.int32) + 2 color = make_tensor(color) for k in range(bs): # Get point parameters from network shapes = [] shape_groups = [] points = all_points.cpu().contiguous() # [self.sort_idx[k]] if verbose: np.random.seed(0) colors = np.random.rand(paths, 4) high = np.array((0.565, 0.392, 0.173, 1)) low = np.array((0.094, 0.310, 0.635, 1)) diff = (high - low) / (paths) colors[:, 3] = 1 for i in range(paths): scale = diff * i color = low + scale color[3] = 1 color = torch.tensor(color) num_ctrl_pts = torch.zeros(1, dtype=torch.int32) + 2 if i * 3 + 4 > paths * 3: curve_points = torch.stack([ points[i * 3], points[i * 3 + 1], points[i * 3 + 2], points[0] ]) else: curve_points = points[i * 3:i * 3 + 4] path = pydiffvg.Path(num_control_points=num_ctrl_pts, points=curve_points, is_closed=False, stroke_width=torch.tensor(4)) path_group = pydiffvg.ShapeGroup(shape_ids=torch.tensor([i]), fill_color=None, stroke_color=color) shapes.append(path) shape_groups.append(path_group) for i in range(paths * 3): scale = diff * (i // 3) color = low + scale color[3] = 1 color = torch.tensor(color) if i % 3 == 0: # color = torch.tensor(colors[i//3]) #green shape = pydiffvg.Rect(p_min=points[i] - 8, p_max=points[i] + 8) group = pydiffvg.ShapeGroup(shape_ids=torch.tensor( [paths + i]), fill_color=color) else: # color = torch.tensor(colors[i//3]) #purple shape = pydiffvg.Circle(radius=torch.tensor(8.0), center=points[i]) group = pydiffvg.ShapeGroup(shape_ids=torch.tensor( [paths + i]), fill_color=color) shapes.append(shape) shape_groups.append(group) else: path = pydiffvg.Path(num_control_points=num_ctrl_pts, points=points, is_closed=True) shapes.append(path) path_group = pydiffvg.ShapeGroup(shape_ids=torch.tensor( [len(shapes) - 1]), fill_color=color, stroke_color=color) shape_groups.append(path_group) scene_args = pydiffvg.RenderFunction.serialize_scene( render_size, render_size, shapes, shape_groups) out = render( render_size, # width render_size, # height 2, # num_samples_x 2, # num_samples_y 102, # seed None, *scene_args) out = out.permute(2, 0, 1).view(4, render_size, render_size) # [:3]#.mean(0, keepdim=True) outputs.append(out) output = torch.stack(outputs).to(all_points.device) alpha = output[:, 3:4, :, :] # map to [-1, 1] if white_background: output_white_bg = output[:, :3, :, :] * alpha + (1 - alpha) output = torch.cat([output_white_bg, alpha], dim=1) del num_ctrl_pts, color return output
import pydiffvg import torch import skimage import numpy as np # Use GPU if available pydiffvg.set_use_gpu(torch.cuda.is_available()) canvas_width, canvas_height = 256, 256 circle = pydiffvg.Circle(radius=torch.tensor(40.0), center=torch.tensor([128.0, 128.0]), stroke_width=torch.tensor(5.0)) shapes = [circle] circle_group = pydiffvg.ShapeGroup( shape_ids=torch.tensor([0]), fill_color=torch.tensor([0.3, 0.6, 0.3, 1.0]), stroke_color=torch.tensor([0.6, 0.3, 0.6, 0.8])) shape_groups = [circle_group] scene_args = pydiffvg.RenderFunction.serialize_scene(\ canvas_width, canvas_height, shapes, shape_groups) render = pydiffvg.RenderFunction.apply img = render( 256, # width 256, # height 2, # num_samples_x 2, # num_samples_y 0, # seed None, *scene_args) # The output image is in linear RGB space. Do Gamma correction before saving the image.