Files
test2/scripts/freestyle/modules/freestyle/functions.py
2023-06-15 13:35:34 +10:00

314 lines
9.2 KiB
Python

# SPDX-FileCopyrightText: 2014-2023 Blender Foundation
#
# SPDX-License-Identifier: GPL-2.0-or-later
"""
This module contains functions operating on vertices (0D elements) and
polylines (1D elements). The module is also intended to be a
collection of examples for function definition in Python.
User-defined functions inherit one of the following base classes,
depending on the object type (0D or 1D) to operate on and the return
value type:
- :class:`freestyle.types.UnaryFunction0DDouble`
- :class:`freestyle.types.UnaryFunction0DEdgeNature`
- :class:`freestyle.types.UnaryFunction0DFloat`
- :class:`freestyle.types.UnaryFunction0DId`
- :class:`freestyle.types.UnaryFunction0DMaterial`
- :class:`freestyle.types.UnaryFunction0DUnsigned`
- :class:`freestyle.types.UnaryFunction0DVec2f`
- :class:`freestyle.types.UnaryFunction0DVec3f`
- :class:`freestyle.types.UnaryFunction0DVectorViewShape`
- :class:`freestyle.types.UnaryFunction0DViewShape`
- :class:`freestyle.types.UnaryFunction1DDouble`
- :class:`freestyle.types.UnaryFunction1DEdgeNature`
- :class:`freestyle.types.UnaryFunction1DFloat`
- :class:`freestyle.types.UnaryFunction1DUnsigned`
- :class:`freestyle.types.UnaryFunction1DVec2f`
- :class:`freestyle.types.UnaryFunction1DVec3f`
- :class:`freestyle.types.UnaryFunction1DVectorViewShape`
- :class:`freestyle.types.UnaryFunction1DVoid`
"""
__all__ = (
"ChainingTimeStampF1D",
"Curvature2DAngleF0D",
"Curvature2DAngleF1D",
"CurveMaterialF0D",
"CurveNatureF0D",
"CurveNatureF1D",
"DensityF0D",
"DensityF1D",
"GetCompleteViewMapDensityF1D",
"GetCurvilinearAbscissaF0D",
"GetDirectionalViewMapDensityF1D",
"GetOccludeeF0D",
"GetOccludeeF1D",
"GetOccludersF0D",
"GetOccludersF1D",
"GetParameterF0D",
"GetProjectedXF0D",
"GetProjectedXF1D",
"GetProjectedYF0D",
"GetProjectedYF1D",
"GetProjectedZF0D",
"GetProjectedZF1D",
"GetShapeF0D",
"GetShapeF1D",
"GetSteerableViewMapDensityF1D",
"GetViewMapGradientNormF0D",
"GetViewMapGradientNormF1D",
"GetXF0D",
"GetXF1D",
"GetYF0D",
"GetYF1D",
"GetZF0D",
"GetZF1D",
"IncrementChainingTimeStampF1D",
"LocalAverageDepthF0D",
"LocalAverageDepthF1D",
"MaterialF0D",
"Normal2DF0D",
"Normal2DF1D",
"Orientation2DF1D",
"Orientation3DF1D",
"QuantitativeInvisibilityF0D",
"QuantitativeInvisibilityF1D",
"ReadCompleteViewMapPixelF0D",
"ReadMapPixelF0D",
"ReadSteerableViewMapPixelF0D",
"ShapeIdF0D",
"TimeStampF1D",
"VertexOrientation2DF0D",
"VertexOrientation3DF0D",
"ZDiscontinuityF0D",
"ZDiscontinuityF1D",
"pyCurvilinearLengthF0D",
"pyDensityAnisotropyF0D",
"pyDensityAnisotropyF1D",
"pyGetInverseProjectedZF1D",
"pyGetSquareInverseProjectedZF1D",
"pyInverseCurvature2DAngleF0D",
"pyViewMapGradientNormF0D",
"pyViewMapGradientNormF1D",
"pyViewMapGradientVectorF0D",
)
# module members
from _freestyle import (
ChainingTimeStampF1D,
Curvature2DAngleF0D,
Curvature2DAngleF1D,
CurveNatureF0D,
CurveNatureF1D,
DensityF0D,
DensityF1D,
GetCompleteViewMapDensityF1D,
GetCurvilinearAbscissaF0D,
GetDirectionalViewMapDensityF1D,
GetOccludeeF0D,
GetOccludeeF1D,
GetOccludersF0D,
GetOccludersF1D,
GetParameterF0D,
GetProjectedXF0D,
GetProjectedXF1D,
GetProjectedYF0D,
GetProjectedYF1D,
GetProjectedZF0D,
GetProjectedZF1D,
GetShapeF0D,
GetShapeF1D,
GetSteerableViewMapDensityF1D,
GetViewMapGradientNormF0D,
GetViewMapGradientNormF1D,
GetXF0D,
GetXF1D,
GetYF0D,
GetYF1D,
GetZF0D,
GetZF1D,
IncrementChainingTimeStampF1D,
LocalAverageDepthF0D,
LocalAverageDepthF1D,
MaterialF0D,
Normal2DF0D,
Normal2DF1D,
Orientation2DF1D,
Orientation3DF1D,
QuantitativeInvisibilityF0D,
QuantitativeInvisibilityF1D,
ReadCompleteViewMapPixelF0D,
ReadMapPixelF0D,
ReadSteerableViewMapPixelF0D,
ShapeIdF0D,
TimeStampF1D,
VertexOrientation2DF0D,
VertexOrientation3DF0D,
ZDiscontinuityF0D,
ZDiscontinuityF1D,
)
# constructs for function definition in Python
from freestyle.types import (
CurvePoint,
IntegrationType,
UnaryFunction0DDouble,
UnaryFunction0DMaterial,
UnaryFunction0DVec2f,
UnaryFunction1DDouble,
)
from freestyle.utils import ContextFunctions as CF
from freestyle.utils import integrate
from mathutils import Vector
# -- Functions for 0D elements (vertices) -- #
class CurveMaterialF0D(UnaryFunction0DMaterial):
"""
A replacement of the built-in MaterialF0D for stroke creation.
MaterialF0D does not work with Curves and Strokes. Line color
priority is used to pick one of the two materials at material
boundaries.
Notes: expects instances of CurvePoint to be iterated over
can return None if no fedge can be found
"""
def __call__(self, inter):
fe = inter.object.fedge
if fe is None:
return None
if fe.is_smooth:
return fe.material
else:
right, left = fe.material_right, fe.material_left
return right if (right.priority > left.priority) else left
class pyInverseCurvature2DAngleF0D(UnaryFunction0DDouble):
def __call__(self, inter):
func = Curvature2DAngleF0D()
c = func(inter)
return (3.1415 - c)
class pyCurvilinearLengthF0D(UnaryFunction0DDouble):
def __call__(self, inter):
cp = inter.object
assert isinstance(cp, CurvePoint)
return cp.t2d
class pyDensityAnisotropyF0D(UnaryFunction0DDouble):
"""Estimates the anisotropy of density."""
def __init__(self, level):
UnaryFunction0DDouble.__init__(self)
self.IsoDensity = ReadCompleteViewMapPixelF0D(level)
self.d0Density = ReadSteerableViewMapPixelF0D(0, level)
self.d1Density = ReadSteerableViewMapPixelF0D(1, level)
self.d2Density = ReadSteerableViewMapPixelF0D(2, level)
self.d3Density = ReadSteerableViewMapPixelF0D(3, level)
def __call__(self, inter):
c_iso = self.IsoDensity(inter)
c_0 = self.d0Density(inter)
c_1 = self.d1Density(inter)
c_2 = self.d2Density(inter)
c_3 = self.d3Density(inter)
cMax = max(max(c_0, c_1), max(c_2, c_3))
cMin = min(min(c_0, c_1), min(c_2, c_3))
return 0 if (c_iso == 0) else (cMax - cMin) / c_iso
class pyViewMapGradientVectorF0D(UnaryFunction0DVec2f):
"""
Returns the gradient vector for a pixel.
.. method:: __init__(self, level)
Builds a pyViewMapGradientVectorF0D object.
:arg level: the level at which to compute the gradient
:type level: int
"""
def __init__(self, level):
UnaryFunction0DVec2f.__init__(self)
self._l = level
self._step = pow(2, self._l)
def __call__(self, iter):
p = iter.object.point_2d
gx = CF.read_complete_view_map_pixel(self._l, int(p.x + self._step), int(p.y)) - \
CF.read_complete_view_map_pixel(self._l, int(p.x), int(p.y))
gy = CF.read_complete_view_map_pixel(self._l, int(p.x), int(p.y + self._step)) - \
CF.read_complete_view_map_pixel(self._l, int(p.x), int(p.y))
return Vector((gx, gy))
class pyViewMapGradientNormF0D(UnaryFunction0DDouble):
def __init__(self, l):
UnaryFunction0DDouble.__init__(self)
self._l = l
self._step = pow(2, self._l)
def __call__(self, iter):
p = iter.object.point_2d
gx = CF.read_complete_view_map_pixel(self._l, int(p.x + self._step), int(p.y)) - \
CF.read_complete_view_map_pixel(self._l, int(p.x), int(p.y))
gy = CF.read_complete_view_map_pixel(self._l, int(p.x), int(p.y + self._step)) - \
CF.read_complete_view_map_pixel(self._l, int(p.x), int(p.y))
return Vector((gx, gy)).length
# -- Functions for 1D elements (curves) -- #
class pyGetInverseProjectedZF1D(UnaryFunction1DDouble):
def __call__(self, inter):
func = GetProjectedZF1D()
z = func(inter)
return (1.0 - z)
class pyGetSquareInverseProjectedZF1D(UnaryFunction1DDouble):
def __call__(self, inter):
func = GetProjectedZF1D()
z = func(inter)
return (1.0 - pow(z, 2))
class pyDensityAnisotropyF1D(UnaryFunction1DDouble):
def __init__(self, level, integrationType=IntegrationType.MEAN, sampling=2.0):
UnaryFunction1DDouble.__init__(self, integrationType)
self._func = pyDensityAnisotropyF0D(level)
self._integration = integrationType
self._sampling = sampling
def __call__(self, inter):
v = integrate(
self._func, inter.points_begin(
self._sampling), inter.points_end(
self._sampling), self._integration)
return v
class pyViewMapGradientNormF1D(UnaryFunction1DDouble):
def __init__(self, l, integrationType, sampling=2.0):
UnaryFunction1DDouble.__init__(self, integrationType)
self._func = pyViewMapGradientNormF0D(l)
self._integration = integrationType
self._sampling = sampling
def __call__(self, inter):
v = integrate(
self._func, inter.points_begin(
self._sampling), inter.points_end(
self._sampling), self._integration)
return v