Files
diffvg/gradientmesh/gmtypes2.py

73 lines
2.3 KiB
Python

#!/usr/bin/env python3
from __future__ import annotations
from typing import TypeAlias
from random import uniform
import torch
Point: TypeAlias = torch.FloatTensor
Vector: TypeAlias = Point
Color: TypeAlias = torch.FloatTensor
def indexize_tensor(tensor, eps=1e-5):
"""Take tensor of quads to flat list of points plus index map."""
tensor_shape = tensor.shape
tensor = tensor.view(-1, tensor_shape[-1])
# Round tensor elements to handle floating point precision errors
tensor = torch.round(tensor / eps) * eps
# Compute unique rows and their indices
tensor, inverse_indices = tensor.unique(dim=0, return_inverse=True)
# Compute index tensor
index_tensor = inverse_indices.view(tensor_shape[:-1])
return tensor, index_tensor
def ferguson_to_bezier(corner_points, tangent_vectors):
"""Take Ferguson patch to Bezier representation"""
# Assume corner_points is a list of 4 points [P0, P1, P2, P3] and
# tangent_vectors is a list of 4 vectors [V0, V1, V2, V3]
# Bezier control points
bezier_points = [None]*12
# Use tangent vectors to determine interior points and place them in the order
for i in range(4):
bezier_points[3*i] = corner_points[i]
bezier_points[3*i + 1] = corner_points[i] + tangent_vectors[i]/3
bezier_points[3*i + 2] = corner_points[i] + 2*tangent_vectors[i]/3
return bezier_points
class Mesh:
def __init__(self, points, tangents, colors):
self.fpoints, self.ipoints = indexize_tensor(points)
self.ftangents, self.itangents = indexize_tensor(tangents)
self.colors = colors
@classmethod
def grid(cls, width, height):
dx = 1.0 / width
dy = 1.0 / height
points = []
tangents = []
colors = []
for i in range(width):
for j in range(height):
x1, y1 = i * dx, j * dy
x2, y2 = (i+1) * dx, (j+1) * dy
# Clockwise order: bottom left, bottom right, top right, top left
square = [[x1, y1], [x2, y1], [x2, y2], [x1, y2]]
points.append(square)
tangents.append([[0.0, 0.0] for _ in range(4)])
colors.append([uniform(0, 1) for _ in range(3)] + [1.0])
return cls(torch.tensor(points),
torch.tensor(tangents),
torch.tensor(colors))