{"push_id":1154130417,"size":3,"distinct_size":1,"ref":"refs/heads/lg-texerror","head":"6f2d6675c9e96a2b7d9eec5894a4a5fad6bbe7b9","before":"a7fe757b7c01dfb03de5a7165ee5113c49747e27","commits":[{"sha":"d92a7c206378627482f49b5b4940d4603e718120","author":{"name":"Larry Gritz","email":"e3c4aae4c6bce9f7c9606fdddd16a46f7061620e@larrygritz.com"},"message":"UDIM support for textures. (#1426)\n\nBackground: \"UDIM\" refers to an emergent convention in VFX for texture\r\natlases, where separate painted textures are applied to different parts\r\n(faces or face sets) of a complex object. Instead of needing an\r\nelaborate mapping of face IDs to arbitrary filenames, you simply use a\r\nuv range extending beyond [0,1], with each unit square of texture space\r\ncorresponding to a different physical texture and a simple mapping of\r\ntile indices to filenames based on a pattern.  In practice, there are a\r\nfew competing and subtly different conventions, and we try to support\r\nthe common ones.\r\n\r\nThis patch allows TextureSystem::texture() calls to reference \"virtual\"\r\nfilenames that get expanded to concrete files based on the specific\r\nlookup coordinates.  These virtual filenames are identified on the basis\r\nof (a) there not being a real file that exists in the filesystem with\r\nthat name, and (b) the filename containing one or more of the following\r\nliteral substrings: \"<UDIM>\", \"<U>\", \"<V>\", \"<u>\", \"<v>\".\r\n(The angle brackets are part of the substring being searched, but the\r\ndouble quotes are not.)\r\n\r\nThe coordinate transformation is as follows:\r\n\r\n    utile = floor(u)\r\n    vtile = floor(v)\r\n    u = fmod (u, 1)\r\n    v = fmod (v, 1)\r\n\r\nAnd then the concrete filename is constructed using the following\r\nsubstitutions of strings with decimal numbers:\r\n\r\n    <U> -->  utile+1\r\n    <V> -->  vtile+1\r\n    <u> -->  utile\r\n    <v> -->  vtile\r\n    <UDIM> --> 1001 + utile + vtile+10\r\n\r\nAs an example, a texture lookup to \"paint.<UDIM>.tif\" at coordinates\r\n(1.4, 3.8) will, under the covers, be translated into a lookup from\r\n\"paint.1032.tif\" at coordinates (0.4, 0.8).  (The UDIM convention\r\nis 1001+utile+vtile*10 == 1032 in this case.)\r\n\r\nIf this seems strange, suffice it to say that it's derived from widely\r\nused conventions in texture painting systems used in VFX production.\r\n\r\nThis is done with minimal expense, the substitutions and decoding do not\r\nneed to be performed for each texture lookup. The basic strategy is:\r\n\r\n* When the file is first opened, the name is checked for inclusion of\r\n  any of the special tokens, and if found (and the filename doesn't\r\n  really exist on the filesystem), then it's marked as one of these UDIM\r\n  virtual textures.\r\n\r\n* Internally, the virtual texture's ImageCacheFile record holds an\r\n  associative array mapping tile ids (specifically: (vtile<<32) + utile)\r\n  to the ImageCacheFile* of the concrete file for that section.\r\n\r\n* The texture() call, if the file is a virtual UDIM texture, will look\r\n  up the concrete texture handle. Only if this atlas tile has not yet\r\n  been accessed (thus, establishing the mapping for the first time),\r\n  does it do the string searching and formatting to construct the\r\n  concrete filename, thus this expense is negligible in a render, rather\r\n  than being part of the per-texture-lookup expense.\r\n\r\n* This id->handle associative map for each virtual texture is\r\n  implemented as a boost::flat_map, which is a sorted vector whose\r\n  performance for small records (such as this) usually outperforms that\r\n  of an unordered_map because of superior memory locality.\r\n\r\n* The associative maps are kept thread-safe by a pool of reader/writer\r\n  locks. Since it only needs to write the first time an atlas tile is\r\n  used, it's almost always in \"read\" mode, and thus threads tend not to\r\n  lock against each other. Even if multiple threads are trying to write\r\n  simultaneously, the fact that it's a mutex_pool ensures that they are\r\n  usually not accessing the same lock and therefore rarely block each\r\n  other.","distinct":false,"url":"https://api.github.com/repos/lgritz/oiio/commits/d92a7c206378627482f49b5b4940d4603e718120"},{"sha":"c855deab4323fed65d494fbb652645cb26256ef6","author":{"name":"Larry Gritz","email":"e3c4aae4c6bce9f7c9606fdddd16a46f7061620e@larrygritz.com"},"message":"Travis improvements","distinct":false,"url":"https://api.github.com/repos/lgritz/oiio/commits/c855deab4323fed65d494fbb652645cb26256ef6"},{"sha":"6f2d6675c9e96a2b7d9eec5894a4a5fad6bbe7b9","author":{"name":"Larry Gritz","email":"e3c4aae4c6bce9f7c9606fdddd16a46f7061620e@larrygritz.com"},"message":"Improvements to IC/TS error reporting\n\n* Avoid needless verbosity for broken texture error messages\n* New IC/TS attribute: \"max_errors_per_file\" puts a limit on how many\n  error messages will be printed for each file. More than the first few\n  almost certainly will not provide any useful additional information,\n  but will clutter your logs and harm performance.\n* Suppress printing of empty error messages.\n* In testtex, make sure error printouts lock against each other to keep\n  from making unintelligible console output when many errors are issued\n  simultaneously from different threads.","distinct":true,"url":"https://api.github.com/repos/lgritz/oiio/commits/6f2d6675c9e96a2b7d9eec5894a4a5fad6bbe7b9"}]}
{"actor":{"display_login":"lgritz"}}