* Set the items of this vector using a swizzle. * - If value is a vector or list this operates like an array copy, except that * the destination is effectively re-ordered as defined by the swizzle. At * most `min(len(source), len(destination))` values will be copied. * - If the value is scalar, it is copied to all axes listed in the swizzle. * - If an axis appears more than once in the sw
| 2855 | * \return 0 on success and -1 on failure. On failure, the vector will be unchanged. |
| 2856 | */ |
| 2857 | static int Vector_swizzle_set(VectorObject *self, PyObject *value, void *closure) |
| 2858 | { |
| 2859 | size_t size_from; |
| 2860 | float scalarVal; |
| 2861 | |
| 2862 | size_t axis_from; |
| 2863 | size_t axis_to; |
| 2864 | |
| 2865 | uint swizzleClosure; |
| 2866 | |
| 2867 | float tvec[MAX_DIMENSIONS]; |
| 2868 | float vec_assign[MAX_DIMENSIONS]; |
| 2869 | |
| 2870 | if (BaseMath_ReadCallback_ForWrite(self) == -1) { |
| 2871 | return -1; |
| 2872 | } |
| 2873 | |
| 2874 | /* Check that the closure can be used with this vector: even 2D vectors have |
| 2875 | * swizzles defined for axes z and w, but they would be invalid. */ |
| 2876 | swizzleClosure = POINTER_AS_INT(closure); |
| 2877 | axis_from = 0; |
| 2878 | |
| 2879 | while (swizzleClosure & SWIZZLE_VALID_AXIS) { |
| 2880 | axis_to = swizzleClosure & SWIZZLE_AXIS; |
| 2881 | if (axis_to >= self->vec_num) { |
| 2882 | PyErr_SetString(PyExc_AttributeError, |
| 2883 | "Vector swizzle: " |
| 2884 | "specified axis not present"); |
| 2885 | return -1; |
| 2886 | } |
| 2887 | swizzleClosure = swizzleClosure >> SWIZZLE_BITS_PER_AXIS; |
| 2888 | axis_from++; |
| 2889 | } |
| 2890 | |
| 2891 | if (((scalarVal = PyFloat_AsDouble(value)) == -1 && PyErr_Occurred()) == 0) { |
| 2892 | int i; |
| 2893 | |
| 2894 | for (i = 0; i < MAX_DIMENSIONS; i++) { |
| 2895 | vec_assign[i] = scalarVal; |
| 2896 | } |
| 2897 | |
| 2898 | size_from = axis_from; |
| 2899 | } |
| 2900 | else if (PyErr_Clear(), /* run but ignore the result */ |
| 2901 | (size_from = size_t(mathutils_array_parse( |
| 2902 | vec_assign, 2, 4, value, "Vector.**** = swizzle assignment"))) == size_t(-1)) |
| 2903 | { |
| 2904 | return -1; |
| 2905 | } |
| 2906 | |
| 2907 | if (axis_from != size_from) { |
| 2908 | PyErr_SetString(PyExc_AttributeError, "Vector swizzle: size does not match swizzle"); |
| 2909 | return -1; |
| 2910 | } |
| 2911 | |
| 2912 | /* Copy vector contents onto swizzled axes. */ |
| 2913 | axis_from = 0; |
| 2914 | swizzleClosure = POINTER_AS_INT(closure); |
nothing calls this directly
no test coverage detected