1 /** 2 Utility functions. 3 4 Copyright: 5 Copyright © 2020-2026, Inochi2D Project 6 7 License: 8 $(LINK2 https://github.com/Inochi2D/inochi2d/blob/main/LICENSE, BSD 2-clause License) 9 10 Authors: 11 Luna Nielsen 12 */ 13 module inochi2d.param.utils; 14 import inochi2d.core.vector2d; 15 import inochi2d.core.serde; 16 import inochi2d.common; 17 import inochi2d.param; 18 import numath; 19 import nulib; 20 import numem; 21 22 /** 23 Deserializes a legacy 0.8 style nested array to the new flat format. 24 25 Params: 26 object = The DataNode to extract the data from. 27 target = The target to store the data within. 28 state = The state of the deserializer. 29 dims = The dimensionality expected. 30 */ 31 void deserialize08NestedArrays(T)(ref DataNode object, ref T target, ref ModelState state, vec2u dims) @nogc 32 if (is(T == vector2d!U, U)) { 33 import inochi2d.core.math.deform : Deformation; 34 35 // Invalid array. 36 if (!object.isArray) { 37 state.error(nstring("expected array, got ", object.type.toTypeName, "!")); 38 return; 39 } 40 41 target.resize(dims.x, dims.y); 42 43 // The Y axis is shorter than expected. 44 if (object.length < dims.y) { 45 state.error("fewer elements were found in the y axis than were expected!"); 46 return; 47 } 48 49 // Iterate through all elements, adding them to the given index in the 50 // target. 51 size_t px = 0; 52 size_t py = 0; 53 foreach (ref DataNode elem; object.array) { 54 55 // Not nested?? 56 if (!elem.isArray) { 57 state.error(nstring("expected nested array, got ", elem.type.toTypeName, "!")); 58 return; 59 } 60 61 // Too short? 62 if (elem.length < dims.x) { 63 state.error("fewer elements were found in the x axis than were expected!"); 64 return; 65 } 66 67 foreach (ref value; elem.array) { 68 target[px, py] = value.deserialize!(T.DT)(state); 69 px++; 70 } 71 py++; 72 px = 0; 73 } 74 } 75 76 /** 77 Resizes the given vector2d to fit the element counts 78 of the given parameter. 79 80 Params: 81 vec2d = The target vector2d. 82 param = The parameter. 83 */ 84 void resizeToParam(T)(ref T vec2d, Parameter param) { 85 if (param.dimensions == 1) { 86 vec2d.resize(1, param.elementCounts[0]); 87 } else if (param.dimensions == 2) { 88 vec2d.resize(param.elementCounts[0], param.elementCounts[1]); 89 } 90 } 91 92 /** 93 Interpolates between keypoints. 94 */ 95 T interpolateKeypoint(T)(ref vector2d!T values, vec2u index, vec2 norm) @nogc { 96 return T.init; 97 }