or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-objects.mdindex.mdufo-tools.md

core-objects.mddocs/

0

# Core Objects

1

2

Foundation classes for multi-dimensional interpolation that work with any arithmetic objects. These objects form the mathematical core of MutatorMath and can be used independently of UFO-specific functionality.

3

4

## Capabilities

5

6

### Location Objects

7

8

N-dimensional coordinate representation with full arithmetic support. Location objects behave like numbers and can be added, subtracted, multiplied, and divided. They store axis names as keys and coordinate values as values.

9

10

```python { .api }

11

class Location(dict):

12

"""

13

N-dimensional location object subclassed from dict.

14

15

- key is dimension or axis name

16

- value is the coordinate

17

- Location objects behave like numbers

18

- If a dimension is missing, assume it is zero

19

"""

20

def __init__(self, **kwargs):

21

"""Create location with axis=value pairs."""

22

23

def isOrigin(self) -> bool:

24

"""Check if location is at origin (all values are 0)."""

25

26

def isOnAxis(self) -> bool:

27

"""Check if location is on-axis (only one dimension != 0)."""

28

29

def isAmbivalent(self, dim=None) -> bool:

30

"""Check if location has both positive and negative values."""

31

32

def expand(self, axisNames):

33

"""Expand location with zero values for all axes in axisNames not already present."""

34

35

def copy(self) -> Location:

36

"""Return a copy of this location."""

37

38

def getActiveAxes(self) -> list:

39

"""Return list of axis names which are not zero."""

40

41

def getType(self, short=False) -> str:

42

"""Return string describing location type: origin, on-axis, off-axis, etc."""

43

44

def asString(self, strict=False) -> str:

45

"""Return location as formatted string."""

46

47

def asDict(self) -> dict:

48

"""Return location as plain dictionary."""

49

50

def asSortedStringDict(self, roundValue=False) -> dict:

51

"""Return location as sorted string dictionary."""

52

53

def asTuple(self) -> tuple:

54

"""Return location as tuple of (axis, value) pairs, sorted alphabetically."""

55

56

def fromTuple(self, locationTuple):

57

"""Read coordinates from tuple of (axis, value) pairs."""

58

59

def strip(self):

60

"""Remove axes with zero values."""

61

62

def common(self, other) -> Location:

63

"""Return location with axes common to both locations."""

64

65

def split(self) -> tuple:

66

"""Return (x, y) tuple for ambivalent locations."""

67

68

def spliceX(self) -> Location:

69

"""Return location with X values from split coordinates."""

70

71

def spliceY(self) -> Location:

72

"""Return location with Y values from split coordinates."""

73

74

def distance(self, other=None) -> float:

75

"""Calculate distance to other location or origin."""

76

77

def sameAs(self, other) -> bool:

78

"""Check if location is same as other location."""

79

80

def transform(self, transformDict):

81

"""Transform location using transformation dictionary."""

82

```

83

84

#### Location Arithmetic Operations

85

86

```python { .api }

87

def __add__(self, other) -> Location:

88

"""Add two locations or location and number."""

89

90

def __sub__(self, other) -> Location:

91

"""Subtract two locations or location and number."""

92

93

def __mul__(self, other) -> Location:

94

"""Multiply location by number or another location."""

95

96

def __truediv__(self, other) -> Location:

97

"""Divide location by number or another location (Python 3 division)."""

98

99

def __lt__(self, other) -> bool:

100

"""Compare locations for sorting."""

101

```

102

103

#### Location Usage Examples

104

105

```python

106

# Create locations

107

loc1 = Location(weight=100, width=75)

108

loc2 = Location(weight=900, width=125)

109

110

# Arithmetic operations

111

middle = (loc1 + loc2) / 2 # Location(weight=500, width=100)

112

offset = loc2 - loc1 # Location(weight=800, width=50)

113

114

# Check properties

115

print(loc1.isOrigin()) # False

116

print(loc1.onAxis()) # False (has multiple non-zero dimensions)

117

118

# Expand to include new dimensions

119

loc1.expand(Location(contrast=0)) # Adds contrast dimension

120

```

121

122

### Mutator Objects

123

124

Core interpolation engine that calculates instances from masters using piecewise linear interpolation. Mutator objects store master data and provide instance generation capabilities.

125

126

```python { .api }

127

class Mutator(dict):

128

"""

129

Main interpolation class for calculating instances from masters.

130

Subclassed from dict to store master data.

131

"""

132

def __init__(self, neutral=None):

133

"""Create mutator with optional neutral master."""

134

135

def makeInstance(self, location, bend=True) -> any:

136

"""

137

Calculate interpolated instance at given location.

138

139

Parameters:

140

- location: Location object specifying coordinates

141

- bend: bool, whether to apply bending transformations

142

143

Returns:

144

- Interpolated object of same type as masters

145

"""

146

147

def getInstance(self, aLocation, axisOnly=False, getFactors=False):

148

"""

149

Get instance with optional factor information.

150

151

Parameters:

152

- aLocation: Location object

153

- axisOnly: bool, use only on-axis masters

154

- getFactors: bool, return factors along with instance

155

156

Returns:

157

- Instance object or (instance, factors) tuple

158

"""

159

160

def setNeutral(self, aMathObject, deltaName="origin"):

161

"""Set the neutral master object with optional delta name."""

162

163

def getNeutral(self) -> any:

164

"""Get the neutral master object."""

165

166

def setBias(self, location):

167

"""Set the bias location for interpolation."""

168

169

def getBias(self) -> Location:

170

"""Get the bias location."""

171

172

def setBender(self, bender):

173

"""Set bender object for non-linear transformations."""

174

175

def addDelta(self, location, aMathObject, deltaName=None, punch=False, axisOnly=True):

176

"""

177

Add a delta master at specified location.

178

179

Parameters:

180

- location: Location object for this master

181

- aMathObject: Master object (must support math operations)

182

- deltaName: Optional name for this delta

183

- punch: bool, force addition even if location exists

184

- axisOnly: bool, restrict to on-axis deltas

185

"""

186

187

def getAxisNames(self) -> list:

188

"""Get list of all axis names used in this mutator."""

189

190

def collectLocations(self) -> list:

191

"""Collect all locations from masters."""

192

193

def getFactors(self, aLocation, axisOnly=False, allFactors=False) -> dict:

194

"""

195

Get interpolation factors for given location.

196

197

Parameters:

198

- aLocation: Location object

199

- axisOnly: bool, use only on-axis masters

200

- allFactors: bool, return all factors including zero

201

202

Returns:

203

- dict: Mapping of delta names to factors

204

"""

205

```

206

207

#### Mutator Builder Function

208

209

```python { .api }

210

def buildMutator(items, axes=None, bias=None) -> tuple[Location, Mutator]:

211

"""

212

Build a mutator with (location, obj) pairs.

213

214

Parameters:

215

- items: List of (Location, object) tuples defining masters

216

- axes: Optional axis definitions for bending

217

- bias: Optional bias location (auto-calculated if None)

218

219

Returns:

220

- Tuple of (bias_location, mutator) ready for interpolation

221

"""

222

```

223

224

#### Mutator Usage Examples

225

226

```python

227

from mutatorMath.objects.mutator import buildMutator

228

from mutatorMath.objects.location import Location

229

230

# Define masters with (location, value) pairs

231

masters = [

232

(Location(weight=100), 10), # thin master

233

(Location(weight=900), 100), # bold master

234

(Location(weight=100, width=75), 8), # thin condensed

235

(Location(weight=900, width=125), 120) # bold extended

236

]

237

238

# Build mutator

239

bias, mutator = buildMutator(masters)

240

241

# Generate instances

242

thin_normal = mutator.makeInstance(Location(weight=200, width=100))

243

bold_condensed = mutator.makeInstance(Location(weight=800, width=80))

244

```

245

246

### Bender Objects

247

248

Non-linear transformation objects that apply warpmaps to locations before interpolation. Benders enable custom axis mappings and non-linear behavior in design spaces.

249

250

```python { .api }

251

class Bender(object):

252

"""

253

Object for non-linear transformation of locations using warpmaps.

254

"""

255

def __init__(self, axes):

256

"""

257

Create bender with axis definitions.

258

259

Parameters:

260

- axes: Dict of axis definitions with 'map' arrays for warping

261

Format: {axisName: {'map': [(input, output), ...], ...}}

262

"""

263

264

def __call__(self, location) -> Location:

265

"""

266

Transform location using configured warpmaps.

267

268

Parameters:

269

- location: Location object to transform

270

271

Returns:

272

- Transformed Location object

273

"""

274

```

275

276

#### Bender Usage Examples

277

278

```python

279

from mutatorMath.objects.bender import Bender

280

from mutatorMath.objects.location import Location

281

282

# Define warp map for non-linear weight axis

283

axes = {

284

'weight': {

285

'map': [(0, 0), (500, 200), (1000, 1000)], # Non-linear mapping

286

'minimum': 0,

287

'maximum': 1000,

288

'default': 0

289

}

290

}

291

292

# Create bender

293

bender = Bender(axes)

294

295

# Transform locations

296

original = Location(weight=250)

297

transformed = bender(original) # Location(weight=100) - mapped via warp

298

```

299

300

### Utility Functions

301

302

Helper functions for location processing and analysis.

303

304

```python { .api }

305

def numberToString(value) -> str:

306

"""

307

Return nicely formatted string representation of numeric value.

308

309

Parameters:

310

- value: Number, tuple, or None to format

311

312

Returns:

313

- Formatted string representation

314

"""

315

316

def sortLocations(locations) -> list:

317

"""

318

Sort locations for optimal processing order.

319

320

Parameters:

321

- locations: List of Location objects

322

323

Returns:

324

- Sorted list of Location objects

325

"""

326

327

def biasFromLocations(locs, preferOrigin=True) -> Location:

328

"""

329

Calculate bias location from a set of locations.

330

331

Parameters:

332

- locs: List of Location objects

333

- preferOrigin: Whether to prefer origin as bias

334

335

Returns:

336

- Calculated bias Location

337

"""

338

339

def getLimits(locations, current, sortResults=True, verbose=False) -> list:

340

"""

341

Get limits for locations relative to current position.

342

343

Parameters:

344

- locations: List of Location objects

345

- current: Current Location

346

- sortResults: Whether to sort results

347

- verbose: Enable verbose output

348

349

Returns:

350

- List of limit information

351

"""

352

353

def noBend(loc) -> Location:

354

"""

355

Identity function for bending - returns location unchanged.

356

357

Parameters:

358

- loc: Location object

359

360

Returns:

361

- Same location object

362

"""

363

```