Forum: Poser Python Scripting


Subject: Morphs: copying and mirroring

unrealblue opened this issue on Mar 04, 2020 ยท 30 posts


adp001 posted Wed, 11 March 2020 at 5:38 PM

I wrote a whole class now. Looks long and complicated, resulting in low speed. But it isn't. It's very fast. My desktop machine needs 0.08 seconds to build 100.000 entries in a standard list with random coordinates.

(No special characters in there, so i can post it here):

from array import array
X, Y, Z = 0, 1, 2


class IndexedVertex(object):
    __slots__ = "ar", "idx"

    def __init__(self, *args, **kwargs):
        self.ar = array("f", args[:3]) if args 
            else array("f", (0,0,0))
        if len(args) >= 4:
            self.idx = args[3]
        else:
            kwargs.get("idx", None)

    def __getitem__(self, item):
        return self.ar.__getitem__(item)

    def __eq__(self, other):
        return self.ar == other.ar

    def __gt__(self, other):
        return self.ar > other.ar

    def __lt__(self, other):
        return self.ar < other.ar

    def __ge__(self, other):
        return self.ar >= other.ar

    def __le__(self, other):
        return self.ar >= other.ar

    def __add__(self, other):
        return self.__class__((a + b for a, b in zip(self.ar, other.ar)), idx=self.idx)

    def __radd__(self, other):
        return self.__class__((a + other for a in self.ar), idx=self.idx)

    def __sub__(self, other):
        return self.__class__((a - b for a, b in zip(self.ar, other.ar)), idx=self.idx)

    def __rsub__(self, other):
        return self.__class__((a - other for a in self.ar), idx=self.idx)

    def __mul__(self, other):
        return self.__class__((a * b for a, b in zip(self.ar, other.ar)), idx=self.idx)

    def __rmul__(self, other):
        return self.__class__((a * other for a in self.ar), idx=self.idx)

    def __div__(self, other):
        return self.__class__((a / b for a, b in zip(self.ar, other.ar)), idx=self.idx)

    def __rdiv__(self, other):
        return self.__class__((a / other for a in self.ar), idx=self.idx)

    def __pow__(self, other):
        return self.__class__((a ** b for a, b in zip(self.ar, other.ar)), idx=self.idx)

    def __rpow__(self, other):
        return self.__class__((a ** other for a in self.ar), idx=self.idx)

    def __abs__(self):
        return self.__class__((abs(a) for a in self.ar), idx=self.idx)

    def __repr__(self):
        ar = ", ".join(map(str, self.ar))
        return "{}([{}], idx={})".format(self.__class__.__name__, ar, self.idx)

    def __str__(self):
        return "(X={}, Y={}, Z={}, idx={})".format(round(self.X, 5),
                                                   round(self.Y, 5),
                                                   round(self.Z, 5),
                                                   self.idx
                                                   )

    def __getstate__(self):
        return [self.X, self.Y, self.Z, self.idx]

    def __setstate__(self, state):
        self.ar = array("f", state[:3])
        self.idx = state[3] if len(state)>3 else None

    @property
    def X(self): return self.ar[X]

    @X.setter
    def X(self, v):
        self.ar[X] = v

    @property
    def Y(self): return self.ar[Y]

    @Y.setter
    def Y(self, v):
        self.ar[Y] = v

    @property
    def Z(self): return self.ar[Z]

    @Z.setter
    def Z(self, v):
        self.ar[Z] = v

    def set_index(self, value=None):
        if value is not None:
            self.idx = value
        return self

    def rounded(self, precision):
        return self.__class__(round(self.X, precision),
                              round(self.Y, precision),
                              round(self.Z, precision),
                              self.idx
                              )
    def round(self, precision):
        for i in range(len(self.ar)):
            self.ar[i] = round(self.ar[i], precision)
        return self