Skip to content
Snippets Groups Projects
misc.py 2.93 KiB
Newer Older
  • Learn to ignore specific revisions
  • #====================== BEGIN GPL LICENSE BLOCK ======================
    #
    #  This program is free software; you can redistribute it and/or
    #  modify it under the terms of the GNU General Public License
    #  as published by the Free Software Foundation; either version 2
    #  of the License, or (at your option) any later version.
    #
    #  This program is distributed in the hope that it will be useful,
    #  but WITHOUT ANY WARRANTY; without even the implied warranty of
    #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    #  GNU General Public License for more details.
    #
    #  You should have received a copy of the GNU General Public License
    #  along with this program; if not, write to the Free Software Foundation,
    #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
    #
    #======================= END GPL LICENSE BLOCK ========================
    
    # <pep8 compliant>
    
    import math
    from mathutils import Vector, Matrix, Color
    
    #=============================================
    # Math
    #=============================================
    
    
    def angle_on_plane(plane, vec1, vec2):
        """ Return the angle between two vectors projected onto a plane.
        """
        plane.normalize()
        vec1 = vec1 - (plane * (vec1.dot(plane)))
        vec2 = vec2 - (plane * (vec2.dot(plane)))
        vec1.normalize()
        vec2.normalize()
    
        # Determine the angle
        angle = math.acos(max(-1.0, min(1.0, vec1.dot(vec2))))
    
        if angle < 0.00001:  # close enough to zero that sign doesn't matter
            return angle
    
        # Determine the sign of the angle
        vec3 = vec2.cross(vec1)
        vec3.normalize()
        sign = vec3.dot(plane)
        if sign >= 0:
            sign = 1
        else:
            sign = -1
    
        return angle * sign
    
    #=============================================
    # Color correction functions
    #=============================================
    
    
    def linsrgb_to_srgb (linsrgb):
        """Convert physically linear RGB values into sRGB ones. The transform is
        uniform in the components, so *linsrgb* can be of any shape.
    
        *linsrgb* values should range between 0 and 1, inclusively.
    
        """
        # From Wikipedia, but easy analogue to the above.
        gamma = 1.055 * linsrgb**(1./2.4) - 0.055
        scale = linsrgb * 12.92
        # return np.where (linsrgb > 0.0031308, gamma, scale)
        if linsrgb > 0.0031308:
            return gamma
        return scale
    
    
    def gamma_correct(color):
    
        corrected_color = Color()
        for i, component in enumerate(color):
            corrected_color[i] = linsrgb_to_srgb(color[i])
        return corrected_color
    
    
    #=============================================
    # Misc
    #=============================================
    
    def copy_attributes(a, b):
        keys = dir(a)
        for key in keys:
            if not key.startswith("_") \
            and not key.startswith("error_") \
            and key != "group" \
            and key != "is_valid" \
            and key != "rna_type" \
            and key != "bl_rna":
                try:
                    setattr(b, key, getattr(a, key))
                except AttributeError:
                    pass