tinyusdz.cc 154 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352
  1. /*
  2. Copyright (c) 2019 - 2020, Syoyo Fujita.
  3. All rights reserved.
  4. Redistribution and use in source and binary forms, with or without
  5. modification, are permitted provided that the following conditions are met:
  6. * Redistributions of source code must retain the above copyright
  7. notice, this list of conditions and the following disclaimer.
  8. * Redistributions in binary form must reproduce the above copyright
  9. notice, this list of conditions and the following disclaimer in the
  10. documentation and/or other materials provided with the distribution.
  11. * Neither the name of the Syoyo Fujita nor the
  12. names of its contributors may be used to endorse or promote products
  13. derived from this software without specific prior written permission.
  14. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  15. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  16. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  17. DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  18. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  19. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  20. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  21. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  23. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #include <algorithm>
  26. #include <atomic>
  27. #include <cassert>
  28. #include <cctype> // std::tolower
  29. #include <chrono>
  30. #include <fstream>
  31. #include <map>
  32. #include <sstream>
  33. #include <thread>
  34. #include <tuple>
  35. #include <unordered_map>
  36. #include <unordered_set>
  37. #include <vector>
  38. // local debug flag(now defined in tinyusdz.hh)
  39. //#define TINYUSDZ_LOCAL_DEBUG_PRINT (1)
  40. #include "integerCoding.h"
  41. #include "lz4-compression.hh"
  42. #include "stream-reader.hh"
  43. #include "tinyusdz.hh"
  44. #if defined(TINYUSDZ_SUPPORT_AUDIO)
  45. #if defined(__clang__)
  46. #pragma clang diagnostic push
  47. #pragma clang diagnostic ignored "-Weverything"
  48. #endif
  49. #define DR_WAV_IMPLEMENTATION
  50. #include "external/dr_wav.h"
  51. #define DR_MP3_IMPLEMENTATION
  52. #include "external/dr_mp3.h"
  53. #if defined(__clang__)
  54. #pragma clang diagnostic pop
  55. #endif
  56. #endif // TINYUSDZ_SUPPORT_AUDIO
  57. #if defined(TINYUSDZ_USE_OPENSUBDIV)
  58. #include "subdiv.hh"
  59. #endif
  60. #if defined(TINYUSDZ_SUPPORT_EXR)
  61. #include "external/tinyexr.h"
  62. #endif
  63. #ifndef TINYUSDZ_NO_STB_IMAGE_IMPLEMENTATION
  64. #define STB_IMAGE_IMPLEMENTATION
  65. #endif
  66. #if defined(__clang__)
  67. #pragma clang diagnostic push
  68. #pragma clang diagnostic ignored "-Weverything"
  69. #endif
  70. #include "external/stb_image.h"
  71. #if defined(__clang__)
  72. #pragma clang diagnostic pop
  73. #endif
  74. namespace tinyusdz {
  75. float half_to_float(float16 h) {
  76. static const FP32 magic = {113 << 23};
  77. static const unsigned int shifted_exp = 0x7c00
  78. << 13; // exponent mask after shift
  79. FP32 o;
  80. o.u = (h.u & 0x7fffU) << 13U; // exponent/mantissa bits
  81. unsigned int exp_ = shifted_exp & o.u; // just the exponent
  82. o.u += (127 - 15) << 23; // exponent adjust
  83. // handle exponent special cases
  84. if (exp_ == shifted_exp) // Inf/NaN?
  85. o.u += (128 - 16) << 23; // extra exp adjust
  86. else if (exp_ == 0) // Zero/Denormal?
  87. {
  88. o.u += 1 << 23; // extra exp adjust
  89. o.f -= magic.f; // renormalize
  90. }
  91. o.u |= (h.u & 0x8000U) << 16U; // sign bit
  92. return o.f;
  93. }
  94. float16 float_to_half_full(float _f) {
  95. FP32 f;
  96. f.f = _f;
  97. float16 o = {0};
  98. // Based on ISPC reference code (with minor modifications)
  99. if (f.s.Exponent == 0) // Signed zero/denormal (which will underflow)
  100. o.s.Exponent = 0;
  101. else if (f.s.Exponent == 255) // Inf or NaN (all exponent bits set)
  102. {
  103. o.s.Exponent = 31;
  104. o.s.Mantissa = f.s.Mantissa ? 0x200 : 0; // NaN->qNaN and Inf->Inf
  105. } else // Normalized number
  106. {
  107. // Exponent unbias the single, then bias the halfp
  108. int newexp = f.s.Exponent - 127 + 15;
  109. if (newexp >= 31) // Overflow, return signed infinity
  110. o.s.Exponent = 31;
  111. else if (newexp <= 0) // Underflow
  112. {
  113. if ((14 - newexp) <= 24) // Mantissa might be non-zero
  114. {
  115. unsigned int mant = f.s.Mantissa | 0x800000; // Hidden 1 bit
  116. o.s.Mantissa = mant >> (14 - newexp);
  117. if ((mant >> (13 - newexp)) & 1) // Check for rounding
  118. o.u++; // Round, might overflow into exp bit, but this is OK
  119. }
  120. } else {
  121. o.s.Exponent = static_cast<unsigned int>(newexp);
  122. o.s.Mantissa = f.s.Mantissa >> 13;
  123. if (f.s.Mantissa & 0x1000) // Check for rounding
  124. o.u++; // Round, might overflow to inf, this is OK
  125. }
  126. }
  127. o.s.Sign = f.s.Sign;
  128. return o;
  129. }
  130. namespace {
  131. constexpr size_t kMinCompressedArraySize = 16;
  132. constexpr size_t kSectionNameMaxLength = 15;
  133. // Decode image(png, jpg, ...)
  134. static bool DecodeImage(const uint8_t *bytes, const size_t size,
  135. const std::string &uri, Image *image, std::string *warn,
  136. std::string *err) {
  137. (void)warn;
  138. int w = 0, h = 0, comp = 0, req_comp = 0;
  139. unsigned char *data = nullptr;
  140. // force 32-bit textures for common Vulkan compatibility. It appears that
  141. // some GPU drivers do not support 24-bit images for Vulkan
  142. req_comp = 4;
  143. int bits = 8;
  144. // It is possible that the image we want to load is a 16bit per channel image
  145. // We are going to attempt to load it as 16bit per channel, and if it worked,
  146. // set the image data accodingly. We are casting the returned pointer into
  147. // unsigned char, because we are representing "bytes". But we are updating
  148. // the Image metadata to signal that this image uses 2 bytes (16bits) per
  149. // channel:
  150. if (stbi_is_16_bit_from_memory(bytes, int(size))) {
  151. data = reinterpret_cast<unsigned char *>(
  152. stbi_load_16_from_memory(bytes, int(size), &w, &h, &comp, req_comp));
  153. if (data) {
  154. bits = 16;
  155. }
  156. }
  157. // at this point, if data is still NULL, it means that the image wasn't
  158. // 16bit per channel, we are going to load it as a normal 8bit per channel
  159. // mage as we used to do:
  160. // if image cannot be decoded, ignore parsing and keep it by its path
  161. // don't break in this case
  162. // FIXME we should only enter this function if the image is embedded. If
  163. // `uri` references an image file, it should be left as it is. Image loading
  164. // should not be mandatory (to support other formats)
  165. if (!data)
  166. data = stbi_load_from_memory(bytes, int(size), &w, &h, &comp, req_comp);
  167. if (!data) {
  168. // NOTE: you can use `warn` instead of `err`
  169. if (err) {
  170. (*err) +=
  171. "Unknown image format. STB cannot decode image data for image: " +
  172. uri + "\".\n";
  173. }
  174. return false;
  175. }
  176. if ((w < 1) || (h < 1)) {
  177. stbi_image_free(data);
  178. if (err) {
  179. (*err) += "Invalid image data for image: " + uri + "\"\n";
  180. }
  181. return false;
  182. }
  183. image->width = w;
  184. image->height = h;
  185. image->channels = req_comp;
  186. image->bpp = bits;
  187. image->data.resize(static_cast<size_t>(w * h * req_comp) * size_t(bits / 8));
  188. std::copy(data, data + w * h * req_comp * (bits / 8), image->data.begin());
  189. stbi_image_free(data);
  190. return true;
  191. };
  192. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  193. float to_float(uint16_t h) {
  194. float16 f;
  195. f.u = h;
  196. return half_to_float(f);
  197. }
  198. #endif
  199. #ifdef __clang__
  200. #pragma clang diagnostic push
  201. #pragma clang diagnostic ignored "-Wexit-time-destructors"
  202. #endif
  203. const ValueType &GetValueType(int32_t type_id) {
  204. static std::map<uint32_t, ValueType> table;
  205. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  206. std::cout << "type_id = " << type_id << "\n";
  207. #endif
  208. if (table.size() == 0) {
  209. // Register data types
  210. // NOTE(syoyo): We can use C++11 template to create compile-time table for
  211. // data types, but this way(use std::map) is easier to read and maintain, I
  212. // think.
  213. // reference: crateDataTypes.h
  214. #define ADD_VALUE_TYPE(NAME_STR, TYPE_ID, SUPPORTS_ARRAY) \
  215. { \
  216. assert(table.count(TYPE_ID) == 0); \
  217. table[TYPE_ID] = ValueType(NAME_STR, TYPE_ID, SUPPORTS_ARRAY); \
  218. }
  219. ADD_VALUE_TYPE("InvaldOrUnsupported", 0, false)
  220. // Array types.
  221. ADD_VALUE_TYPE("Bool", VALUE_TYPE_BOOL, true)
  222. ADD_VALUE_TYPE("UChar", VALUE_TYPE_UCHAR, true)
  223. ADD_VALUE_TYPE("Int", VALUE_TYPE_INT, true)
  224. ADD_VALUE_TYPE("UInt", VALUE_TYPE_UINT, true)
  225. ADD_VALUE_TYPE("Int64", VALUE_TYPE_INT64, true)
  226. ADD_VALUE_TYPE("UInt64", VALUE_TYPE_UINT64, true)
  227. ADD_VALUE_TYPE("Half", VALUE_TYPE_HALF, true)
  228. ADD_VALUE_TYPE("Float", VALUE_TYPE_FLOAT, true)
  229. ADD_VALUE_TYPE("Double", VALUE_TYPE_DOUBLE, true)
  230. ADD_VALUE_TYPE("String", VALUE_TYPE_STRING, true)
  231. ADD_VALUE_TYPE("Token", VALUE_TYPE_TOKEN, true)
  232. ADD_VALUE_TYPE("AssetPath", VALUE_TYPE_ASSET_PATH, true)
  233. ADD_VALUE_TYPE("Quatd", VALUE_TYPE_QUATD, true)
  234. ADD_VALUE_TYPE("Quatf", VALUE_TYPE_QUATF, true)
  235. ADD_VALUE_TYPE("Quath", VALUE_TYPE_QUATH, true)
  236. ADD_VALUE_TYPE("Vec2d", VALUE_TYPE_VEC2D, true)
  237. ADD_VALUE_TYPE("Vec2f", VALUE_TYPE_VEC2F, true)
  238. ADD_VALUE_TYPE("Vec2h", VALUE_TYPE_VEC2H, true)
  239. ADD_VALUE_TYPE("Vec2i", VALUE_TYPE_VEC2I, true)
  240. ADD_VALUE_TYPE("Vec3d", VALUE_TYPE_VEC3D, true)
  241. ADD_VALUE_TYPE("Vec3f", VALUE_TYPE_VEC3F, true)
  242. ADD_VALUE_TYPE("Vec3h", VALUE_TYPE_VEC3H, true)
  243. ADD_VALUE_TYPE("Vec3i", VALUE_TYPE_VEC3I, true)
  244. ADD_VALUE_TYPE("Vec4d", VALUE_TYPE_VEC4D, true)
  245. ADD_VALUE_TYPE("Vec4f", VALUE_TYPE_VEC4F, true)
  246. ADD_VALUE_TYPE("Vec4h", VALUE_TYPE_VEC4H, true)
  247. ADD_VALUE_TYPE("Vec4i", VALUE_TYPE_VEC4I, true)
  248. ADD_VALUE_TYPE("Matrix2d", VALUE_TYPE_MATRIX2D, true)
  249. ADD_VALUE_TYPE("Matrix3d", VALUE_TYPE_MATRIX3D, true)
  250. ADD_VALUE_TYPE("Matrix4d", VALUE_TYPE_MATRIX4D, true)
  251. // Non-array types.
  252. ADD_VALUE_TYPE("Dictionary", VALUE_TYPE_DICTIONARY,
  253. false) // std::map<std::string, Value>
  254. ADD_VALUE_TYPE("TokenListOp", VALUE_TYPE_TOKEN_LIST_OP, false)
  255. ADD_VALUE_TYPE("StringListOp", VALUE_TYPE_STRING_LIST_OP, false)
  256. ADD_VALUE_TYPE("PathListOp", VALUE_TYPE_PATH_LIST_OP, false)
  257. ADD_VALUE_TYPE("ReferenceListOp", VALUE_TYPE_REFERENCE_LIST_OP, false)
  258. ADD_VALUE_TYPE("IntListOp", VALUE_TYPE_INT_LIST_OP, false)
  259. ADD_VALUE_TYPE("Int64ListOp", VALUE_TYPE_INT64_LIST_OP, false)
  260. ADD_VALUE_TYPE("UIntListOp", VALUE_TYPE_UINT_LIST_OP, false)
  261. ADD_VALUE_TYPE("UInt64ListOp", VALUE_TYPE_UINT64_LIST_OP, false)
  262. ADD_VALUE_TYPE("PathVector", VALUE_TYPE_PATH_VECTOR, false)
  263. ADD_VALUE_TYPE("TokenVector", VALUE_TYPE_TOKEN_VECTOR, false)
  264. ADD_VALUE_TYPE("Specifier", VALUE_TYPE_SPECIFIER, false)
  265. ADD_VALUE_TYPE("Permission", VALUE_TYPE_PERMISSION, false)
  266. ADD_VALUE_TYPE("Variability", VALUE_TYPE_VARIABILITY, false)
  267. ADD_VALUE_TYPE("VariantSelectionMap", VALUE_TYPE_VARIANT_SELECTION_MAP,
  268. false)
  269. ADD_VALUE_TYPE("TimeSamples", VALUE_TYPE_TIME_SAMPLES, false)
  270. ADD_VALUE_TYPE("Payload", VALUE_TYPE_PAYLOAD, false)
  271. ADD_VALUE_TYPE("DoubleVector", VALUE_TYPE_DOUBLE_VECTOR, false)
  272. ADD_VALUE_TYPE("LayerOffsetVector", VALUE_TYPE_LAYER_OFFSET_VECTOR, false)
  273. ADD_VALUE_TYPE("StringVector", VALUE_TYPE_STRING_VECTOR, false)
  274. ADD_VALUE_TYPE("ValueBlock", VALUE_TYPE_VALUE_BLOCK, false)
  275. ADD_VALUE_TYPE("Value", VALUE_TYPE_VALUE, false)
  276. ADD_VALUE_TYPE("UnregisteredValue", VALUE_TYPE_UNREGISTERED_VALUE, false)
  277. ADD_VALUE_TYPE("UnregisteredValueListOp",
  278. VALUE_TYPE_UNREGISTERED_VALUE_LIST_OP, false)
  279. ADD_VALUE_TYPE("PayloadListOp", VALUE_TYPE_PAYLOAD_LIST_OP, false)
  280. ADD_VALUE_TYPE("TimeCode", VALUE_TYPE_TIME_CODE, true)
  281. }
  282. #undef ADD_VALUE_TYPE
  283. if (type_id < 0) {
  284. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  285. std::cerr << "Unknonw type id: " << type_id << "\n";
  286. #endif
  287. return table.at(0);
  288. }
  289. if (!table.count(uint32_t(type_id))) {
  290. // Invalid or unsupported.
  291. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  292. std::cerr << "Unknonw type id: " << type_id << "\n";
  293. #endif
  294. return table.at(0);
  295. }
  296. return table.at(uint32_t(type_id));
  297. }
  298. #ifdef __clang__
  299. #pragma clang diagnostic pop
  300. #endif
  301. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  302. std::string GetValueTypeRepr(int32_t type_id) {
  303. ValueType dty = GetValueType(type_id);
  304. std::stringstream ss;
  305. ss << "ValueType: " << dty.name << "(" << dty.id
  306. << "), supports_array = " << dty.supports_array;
  307. return ss.str();
  308. }
  309. #endif
  310. std::string GetSpecTypeString(SpecType ty) {
  311. if (SpecTypeUnknown == ty) {
  312. return "SpecTypeUnknown";
  313. } else if (SpecTypeAttribute == ty) {
  314. return "SpecTypeAttribute";
  315. } else if (SpecTypeConnection == ty) {
  316. return "SpecTypeConection";
  317. } else if (SpecTypeExpression == ty) {
  318. return "SpecTypeExpression";
  319. } else if (SpecTypeMapper == ty) {
  320. return "SpecTypeMapper";
  321. } else if (SpecTypeMapperArg == ty) {
  322. return "SpecTypeMapperArg";
  323. } else if (SpecTypePrim == ty) {
  324. return "SpecTypePrim";
  325. } else if (SpecTypePseudoRoot == ty) {
  326. return "SpecTypePseudoRoot";
  327. } else if (SpecTypeRelationship == ty) {
  328. return "SpecTypeRelationship";
  329. } else if (SpecTypeRelationshipTarget == ty) {
  330. return "SpecTypeRelationshipTarget";
  331. } else if (SpecTypeVariant == ty) {
  332. return "SpecTypeVariant";
  333. } else if (SpecTypeVariantSet == ty) {
  334. return "SpecTypeVariantSet";
  335. }
  336. return "??? SpecType " + std::to_string(ty);
  337. }
  338. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  339. std::string GetSpecifierString(Specifier ty) {
  340. if (SpecifierDef == ty) {
  341. return "SpecifierDef";
  342. } else if (SpecifierOver == ty) {
  343. return "SpecifierOver";
  344. } else if (SpecifierClass == ty) {
  345. return "SpecifierClass";
  346. }
  347. return "??? Specifier " + std::to_string(ty);
  348. }
  349. std::string GetPermissionString(Permission ty) {
  350. if (PermissionPublic == ty) {
  351. return "PermissionPublic";
  352. } else if (PermissionPrivate == ty) {
  353. return "PermissionPrivate";
  354. }
  355. return "??? Permission " + std::to_string(ty);
  356. }
  357. std::string GetVariabilityString(Variability ty) {
  358. if (VariabilityVarying == ty) {
  359. return "VariabilityVarying";
  360. } else if (VariabilityUniform == ty) {
  361. return "VariabilityUniform";
  362. } else if (VariabilityConfig == ty) {
  363. return "VariabilityConfig";
  364. }
  365. return "??? Variability " + std::to_string(ty);
  366. }
  367. #endif
  368. ///
  369. /// Node represents scene graph node.
  370. /// This does not contain leaf node inormation.
  371. ///
  372. class Node {
  373. public:
  374. // -2 = initialize as invalid node
  375. Node() : _parent(-2) {}
  376. Node(int64_t parent, Path &path) : _parent(parent), _path(path) {}
  377. int64_t GetParent() const { return _parent; }
  378. const std::vector<size_t> &GetChildren() const { return _children; }
  379. ///
  380. /// child_name is used when reconstructing scene graph.
  381. ///
  382. void AddChildren(const std::string &child_name, size_t node_index) {
  383. assert(_primChildren.count(child_name) == 0);
  384. _primChildren.emplace(child_name);
  385. _children.push_back(node_index);
  386. }
  387. ///
  388. /// Get full path(e.g. `/muda/dora/bora` when the parent is `/muda/dora` and
  389. /// this node is `bora`)
  390. ///
  391. // std::string GetFullPath() const { return _path.full_path_name(); }
  392. ///
  393. /// Get local path
  394. ///
  395. std::string GetLocalPath() const { return _path.full_path_name(); }
  396. const Path &GetPath() const { return _path; }
  397. NodeType GetNodeType() const { return _node_type; }
  398. const std::unordered_set<std::string> &GetPrimChildren() const {
  399. return _primChildren;
  400. }
  401. private:
  402. int64_t
  403. _parent; // -1 = this node is the root node. -2 = invalid or leaf node
  404. std::vector<size_t> _children; // index to child nodes.
  405. std::unordered_set<std::string> _primChildren; // List of name of child nodes
  406. Path _path; // local path
  407. NodeType _node_type;
  408. };
  409. // -- from USD ----------------------------------------------------------------
  410. //
  411. // Copyright 2016 Pixar
  412. //
  413. // Licensed under the Apache License, Version 2.0 (the "Apache License")
  414. // with the following modification; you may not use this file except in
  415. // compliance with the Apache License and the following modification to it:
  416. // Section 6. Trademarks. is deleted and replaced with:
  417. //
  418. // 6. Trademarks. This License does not grant permission to use the trade
  419. // names, trademarks, service marks, or product names of the Licensor
  420. // and its affiliates, except as required to comply with Section 4(c) of
  421. // the License and to reproduce the content of the NOTICE file.
  422. //
  423. // You may obtain a copy of the Apache License at
  424. //
  425. // http://www.apache.org/licenses/LICENSE-2.0
  426. //
  427. // Unless required by applicable law or agreed to in writing, software
  428. // distributed under the Apache License with the above modification is
  429. // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  430. // KIND, either express or implied. See the Apache License for the specific
  431. // language governing permissions and limitations under the Apache License.
  432. // Index base class. Used to index various tables. Deriving adds some
  433. // type-safety so we don't accidentally use one kind of index with the wrong
  434. // kind of table.
  435. struct Index {
  436. Index() : value(~0u) {}
  437. explicit Index(uint32_t v) : value(v) {}
  438. bool operator==(const Index &other) const { return value == other.value; }
  439. bool operator!=(const Index &other) const { return !(*this == other); }
  440. bool operator<(const Index &other) const { return value < other.value; }
  441. uint32_t value;
  442. };
  443. // Value in file representation. Consists of a 2 bytes of type information
  444. // (type enum value, array bit, and inlined-value bit) and 6 bytes of data.
  445. // If possible, we attempt to store certain values directly in the local
  446. // data, such as ints, floats, enums, and special-case values of other types
  447. // (zero vectors, identity matrices, etc). For values that aren't stored
  448. // inline, the 6 data bytes are the offset from the start of the file to the
  449. // value's location.
  450. struct ValueRep {
  451. friend class CrateFile;
  452. ValueRep() = default;
  453. explicit constexpr ValueRep(uint64_t d) : data(d) {}
  454. constexpr ValueRep(int32_t t, bool isInlined, bool isArray, uint64_t payload)
  455. : data(_Combine(t, isInlined, isArray, payload)) {}
  456. static const uint64_t _IsArrayBit = 1ull << 63;
  457. static const uint64_t _IsInlinedBit = 1ull << 62;
  458. static const uint64_t _IsCompressedBit = 1ull << 61;
  459. static const uint64_t _PayloadMask = ((1ull << 48) - 1);
  460. inline bool IsArray() const { return data & _IsArrayBit; }
  461. inline void SetIsArray() { data |= _IsArrayBit; }
  462. inline bool IsInlined() const { return data & _IsInlinedBit; }
  463. inline void SetIsInlined() { data |= _IsInlinedBit; }
  464. inline bool IsCompressed() const { return data & _IsCompressedBit; }
  465. inline void SetIsCompressed() { data |= _IsCompressedBit; }
  466. inline int32_t GetType() const {
  467. return static_cast<int32_t>((data >> 48) & 0xFF);
  468. }
  469. inline void SetType(int32_t t) {
  470. data &= ~(0xFFull << 48); // clear type byte in data.
  471. data |= (static_cast<uint64_t>(t) << 48); // set it.
  472. }
  473. inline uint64_t GetPayload() const { return data & _PayloadMask; }
  474. inline void SetPayload(uint64_t payload) {
  475. data &= ~_PayloadMask; // clear existing payload.
  476. data |= payload & _PayloadMask;
  477. }
  478. inline uint64_t GetData() const { return data; }
  479. bool operator==(ValueRep other) const { return data == other.data; }
  480. bool operator!=(ValueRep other) const { return !(*this == other); }
  481. // friend inline size_t hash_value(ValueRep v) {
  482. // return static_cast<size_t>(v.data);
  483. //}
  484. std::string GetStringRepr() const {
  485. std::stringstream ss;
  486. ss << "ty: " << static_cast<int>(GetType()) << ", isArray: " << IsArray()
  487. << ", isInlined: " << IsInlined() << ", isCompressed: " << IsCompressed()
  488. << ", payload: " << GetPayload();
  489. return ss.str();
  490. }
  491. private:
  492. static constexpr uint64_t _Combine(int32_t t, bool isInlined, bool isArray,
  493. uint64_t payload) {
  494. return (isArray ? _IsArrayBit : 0) | (isInlined ? _IsInlinedBit : 0) |
  495. (static_cast<uint64_t>(t) << 48) | (payload & _PayloadMask);
  496. }
  497. uint64_t data;
  498. };
  499. // ----------------------------------------------------------------------------
  500. struct Field {
  501. Index token_index;
  502. ValueRep value_rep;
  503. };
  504. //
  505. // Spec describes the relation of a path(i.e. node) and field(e.g. vertex data)
  506. //
  507. struct Spec {
  508. Index path_index;
  509. Index fieldset_index;
  510. SpecType spec_type;
  511. };
  512. struct Section {
  513. Section() { memset(this, 0, sizeof(*this)); }
  514. Section(char const *name, int64_t start, int64_t size);
  515. char name[kSectionNameMaxLength + 1];
  516. int64_t start, size; // byte offset to section info and its data size
  517. };
  518. //
  519. // TOC = list of sections.
  520. //
  521. struct TableOfContents {
  522. // Section const *GetSection(SectionName) const;
  523. // int64_t GetMinimumSectionStart() const;
  524. std::vector<Section> sections;
  525. };
  526. template <class Int>
  527. static inline bool _ReadCompressedInts(const StreamReader *sr, Int *out,
  528. size_t size) {
  529. // TODO(syoyo): Error check
  530. using Compressor =
  531. typename std::conditional<sizeof(Int) == 4, Usd_IntegerCompression,
  532. Usd_IntegerCompression64>::type;
  533. std::vector<char> compBuffer(Compressor::GetCompressedBufferSize(size));
  534. uint64_t compSize;
  535. if (!sr->read8(&compSize)) {
  536. return false;
  537. }
  538. if (!sr->read(size_t(compSize), size_t(compSize),
  539. reinterpret_cast<uint8_t *>(compBuffer.data()))) {
  540. return false;
  541. }
  542. std::string err;
  543. bool ret = Compressor::DecompressFromBuffer(
  544. compBuffer.data(), size_t(compSize), out, size, &err);
  545. (void)err;
  546. return ret;
  547. }
  548. static inline bool ReadIndices(const StreamReader *sr,
  549. std::vector<Index> *indices) {
  550. // TODO(syoyo): Error check
  551. uint64_t n;
  552. if (!sr->read8(&n)) {
  553. return false;
  554. }
  555. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  556. std::cout << "ReadIndices: n = " << n << "\n";
  557. #endif
  558. indices->resize(size_t(n));
  559. size_t datalen = size_t(n) * sizeof(Index);
  560. if (datalen != sr->read(datalen, datalen,
  561. reinterpret_cast<uint8_t *>(indices->data()))) {
  562. return false;
  563. }
  564. return true;
  565. }
  566. class Parser {
  567. public:
  568. Parser(StreamReader *sr, int num_threads) : _sr(sr) {
  569. if (num_threads == -1) {
  570. num_threads = std::max(1, int(std::thread::hardware_concurrency()));
  571. }
  572. // Limit to 1024 threads.
  573. _num_threads = std::min(1024, num_threads);
  574. }
  575. bool ReadBootStrap();
  576. bool ReadTOC();
  577. // Read known sections
  578. bool ReadPaths();
  579. bool ReadTokens();
  580. bool ReadStrings();
  581. bool ReadFields();
  582. bool ReadFieldSets();
  583. bool ReadSpecs();
  584. ///
  585. /// Read TOC section
  586. ///
  587. bool ReadSection(Section *s);
  588. const std::string GetToken(Index token_index) {
  589. if (token_index.value <= _tokens.size()) {
  590. return _tokens[token_index.value];
  591. } else {
  592. _err += "Token index out of range: " + std::to_string(token_index.value) +
  593. "\n";
  594. return std::string();
  595. }
  596. }
  597. const std::string GetToken(Index token_index) const {
  598. if (token_index.value <= _tokens.size()) {
  599. return _tokens[token_index.value];
  600. } else {
  601. return std::string();
  602. }
  603. }
  604. // Get string from string index.
  605. std::string GetString(Index string_index) {
  606. if (string_index.value <= _string_indices.size()) {
  607. Index s_idx = _string_indices[string_index.value];
  608. return GetToken(s_idx);
  609. } else {
  610. _err +=
  611. "String index out of range: " + std::to_string(string_index.value) +
  612. "\n";
  613. return std::string();
  614. }
  615. }
  616. bool HasField(const std::string &key) const {
  617. // Simple linear search
  618. for (const auto &field : _fields) {
  619. const std::string field_name = GetToken(field.token_index);
  620. if (field_name.compare(key) == 0) {
  621. return true;
  622. }
  623. }
  624. return false;
  625. }
  626. bool GetField(Index index, Field &&field) const {
  627. if (index.value <= _fields.size()) {
  628. field = _fields[index.value];
  629. return true;
  630. } else {
  631. return false;
  632. }
  633. }
  634. std::string GetFieldString(Index index) {
  635. if (index.value <= _fields.size()) {
  636. // ok
  637. } else {
  638. return "#INVALID field index#";
  639. }
  640. const Field &f = _fields[index.value];
  641. std::string s = GetToken(f.token_index) + ":" + f.value_rep.GetStringRepr();
  642. return s;
  643. }
  644. Path GetPath(Index index) {
  645. if (index.value <= _paths.size()) {
  646. // ok
  647. } else {
  648. // TODO(syoyo): Report error
  649. return Path();
  650. }
  651. const Path &p = _paths[index.value];
  652. return p;
  653. }
  654. std::string GetPathString(Index index) {
  655. if (index.value <= _paths.size()) {
  656. // ok
  657. } else {
  658. return "#INVALID path index#";
  659. }
  660. const Path &p = _paths[index.value];
  661. return p.full_path_name();
  662. }
  663. std::string GetSpecString(Index index) {
  664. if (index.value <= _specs.size()) {
  665. // ok
  666. } else {
  667. return "#INVALID spec index#";
  668. }
  669. const Spec &spec = _specs[index.value];
  670. std::string path_str = GetPathString(spec.path_index);
  671. std::string specty_str = GetSpecTypeString(spec.spec_type);
  672. return "[Spec] path: " + path_str +
  673. ", fieldset id: " + std::to_string(spec.fieldset_index.value) +
  674. ", spec_type: " + specty_str;
  675. }
  676. ///
  677. /// Methods for reconstructing `Scene` object
  678. ///
  679. // In-memory storage for a single "spec" -- prim, property, etc.
  680. typedef std::pair<std::string, Value> FieldValuePair;
  681. typedef std::vector<FieldValuePair> FieldValuePairVector;
  682. // `_live_fieldsets` contains unpacked value keyed by fieldset index.
  683. // Used for reconstructing Scene object
  684. // TODO(syoyo): Use unordered_map(need hash function)
  685. std::map<Index, FieldValuePairVector>
  686. _live_fieldsets; // <fieldset index, List of field with unpacked Values>
  687. bool _BuildLiveFieldSets();
  688. ///
  689. /// Parse node's attribute from FieldValuePairVector.
  690. ///
  691. bool _ParseAttribute(const FieldValuePairVector &fvs, PrimAttrib *attr,
  692. const std::string &prop_name);
  693. bool _ReconstructXform(const Node &node,
  694. const FieldValuePairVector &fields,
  695. const std::unordered_map<uint32_t, uint32_t>
  696. &path_index_to_spec_index_map,
  697. Xform *xform);
  698. bool _ReconstructGeomMesh(const Node &node,
  699. const FieldValuePairVector &fields,
  700. const std::unordered_map<uint32_t, uint32_t>
  701. &path_index_to_spec_index_map,
  702. GeomMesh *mesh);
  703. bool _ReconstructMaterial(const Node &node,
  704. const FieldValuePairVector &fields,
  705. const std::unordered_map<uint32_t, uint32_t>
  706. &path_index_to_spec_index_map,
  707. Material *material);
  708. ///
  709. /// NOTE: Currently we only support UsdPreviewSurface
  710. ///
  711. bool _ReconstructShader(const Node &node, const FieldValuePairVector &fields,
  712. const std::unordered_map<uint32_t, uint32_t>
  713. &path_index_to_spec_index_map,
  714. PreviewSurface *shader);
  715. bool _ReconstructSceneRecursively(int parent_id, int level,
  716. const std::unordered_map<uint32_t, uint32_t>
  717. &path_index_to_spec_index_map,
  718. Scene *scene);
  719. bool ReconstructScene(Scene *scene);
  720. ///
  721. /// --------------------------------------------------
  722. ///
  723. std::string GetError() { return _err; }
  724. std::string GetWarning() { return _warn; }
  725. // Approximated memory usage in [mb]
  726. size_t GetMemoryUsage() const { return memory_used / (1024 * 1024); }
  727. //
  728. // APIs valid after successfull Parse()
  729. //
  730. size_t NumPaths() const { return _paths.size(); }
  731. private:
  732. bool ReadCompressedPaths(const uint64_t ref_num_paths);
  733. const StreamReader *_sr = nullptr;
  734. std::string _err;
  735. std::string _warn;
  736. int _num_threads{1};
  737. // Tracks the memory used(In advisorily manner since counting memory usage is
  738. // done by manually, so not all memory consumption could be tracked)
  739. size_t memory_used{0}; // in bytes.
  740. // Header(bootstrap)
  741. uint8_t _version[3] = {0, 0, 0};
  742. TableOfContents _toc;
  743. int64_t _toc_offset{0};
  744. // index to _toc.sections
  745. int64_t _tokens_index{-1};
  746. int64_t _paths_index{-1};
  747. int64_t _strings_index{-1};
  748. int64_t _fields_index{-1};
  749. int64_t _fieldsets_index{-1};
  750. int64_t _specs_index{-1};
  751. std::vector<std::string> _tokens;
  752. std::vector<Index> _string_indices;
  753. std::vector<Field> _fields;
  754. std::vector<Index> _fieldset_indices;
  755. std::vector<Spec> _specs;
  756. std::vector<Path> _paths;
  757. std::vector<Node> _nodes; // [0] = root node
  758. bool _BuildDecompressedPathsImpl(
  759. std::vector<uint32_t> const &pathIndexes,
  760. std::vector<int32_t> const &elementTokenIndexes,
  761. std::vector<int32_t> const &jumps, size_t curIndex, Path parentPath);
  762. bool _UnpackValueRep(const ValueRep &rep, Value *value);
  763. //
  764. // Construct node hierarchy.
  765. //
  766. bool _BuildNodeHierarchy(std::vector<uint32_t> const &pathIndexes,
  767. std::vector<int32_t> const &elementTokenIndexes,
  768. std::vector<int32_t> const &jumps, size_t curIndex,
  769. int64_t parentNodeIndex);
  770. //
  771. // Reader util functions
  772. //
  773. bool _ReadIndex(Index *i);
  774. // bool _ReadToken(std::string *s);
  775. bool _ReadString(std::string *s);
  776. bool _ReadValueRep(ValueRep *rep);
  777. bool _ReadPathArray(std::vector<Path> *d);
  778. // Dictionary
  779. bool _ReadDictionary(Value::Dictionary *d);
  780. bool _ReadTimeSamples(TimeSamples *d);
  781. // integral array
  782. template <typename T>
  783. bool _ReadIntArray(bool is_compressed, std::vector<T> *d);
  784. bool _ReadHalfArray(bool is_compressed, std::vector<uint16_t> *d);
  785. bool _ReadFloatArray(bool is_compressed, std::vector<float> *d);
  786. bool _ReadDoubleArray(bool is_compressed, std::vector<double> *d);
  787. // PathListOp
  788. bool _ReadPathListOp(ListOp<Path> *d);
  789. };
  790. bool Parser::_ReadIndex(Index *i) {
  791. // string is serialized as StringIndex
  792. uint32_t value;
  793. if (!_sr->read4(&value)) {
  794. _err += "Failed to read Index\n";
  795. return false;
  796. }
  797. (*i) = Index(value);
  798. return true;
  799. }
  800. /* Currently unused
  801. bool Parser::_ReadToken(std::string *s) {
  802. Index token_index;
  803. if (!_ReadIndex(&token_index)) {
  804. _err += "Failed to read Index for token data.\n";
  805. return false;
  806. }
  807. (*s) = GetToken(token_index);
  808. return true;
  809. }
  810. */
  811. bool Parser::_ReadString(std::string *s) {
  812. // string is serialized as StringIndex
  813. Index string_index;
  814. if (!_ReadIndex(&string_index)) {
  815. _err += "Failed to read Index for string data.\n";
  816. return false;
  817. }
  818. (*s) = GetString(string_index);
  819. return true;
  820. }
  821. bool Parser::_ReadValueRep(ValueRep *rep) {
  822. if (!_sr->read8(reinterpret_cast<uint64_t *>(rep))) {
  823. _err += "Failed to read ValueRep.\n";
  824. return false;
  825. }
  826. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  827. std::cout << "value = " << rep->GetData() << "\n";
  828. #endif
  829. return true;
  830. }
  831. template <typename T>
  832. bool Parser::_ReadIntArray(bool is_compressed, std::vector<T> *d) {
  833. if (!is_compressed) {
  834. size_t length;
  835. // < ver 0.7.0 use 32bit
  836. if ((_version[0] == 0) && ((_version[1] < 7))) {
  837. uint32_t n;
  838. if (!_sr->read4(&n)) {
  839. _err += "Failed to read the number of array elements.\n";
  840. return false;
  841. }
  842. length = size_t(n);
  843. } else {
  844. uint64_t n;
  845. if (!_sr->read8(&n)) {
  846. _err += "Failed to read the number of array elements.\n";
  847. return false;
  848. }
  849. length = size_t(n);
  850. }
  851. d->resize(length);
  852. // TODO(syoyo): Zero-copy
  853. if (!_sr->read(sizeof(T) * length, sizeof(T) * length,
  854. reinterpret_cast<uint8_t *>(d->data()))) {
  855. _err += "Failed to read integer array data.\n";
  856. return false;
  857. }
  858. return true;
  859. } else {
  860. size_t length;
  861. // < ver 0.7.0 use 32bit
  862. if ((_version[0] == 0) && ((_version[1] < 7))) {
  863. uint32_t n;
  864. if (!_sr->read4(&n)) {
  865. _err += "Failed to read the number of array elements.\n";
  866. return false;
  867. }
  868. length = size_t(n);
  869. } else {
  870. uint64_t n;
  871. if (!_sr->read8(&n)) {
  872. _err += "Failed to read the number of array elements.\n";
  873. return false;
  874. }
  875. length = size_t(n);
  876. }
  877. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  878. std::cout << "array.len = " << length << "\n";
  879. #endif
  880. d->resize(length);
  881. if (length < kMinCompressedArraySize) {
  882. size_t sz = sizeof(T) * length;
  883. // Not stored in compressed.
  884. // reader.ReadContiguous(odata, osize);
  885. if (!_sr->read(sz, sz, reinterpret_cast<uint8_t *>(d->data()))) {
  886. _err += "Failed to read uncompressed array data.\n";
  887. return false;
  888. }
  889. return true;
  890. }
  891. return _ReadCompressedInts(_sr, d->data(), d->size());
  892. }
  893. }
  894. bool Parser::_ReadHalfArray(bool is_compressed, std::vector<uint16_t> *d) {
  895. if (!is_compressed) {
  896. size_t length;
  897. // < ver 0.7.0 use 32bit
  898. if ((_version[0] == 0) && ((_version[1] < 7))) {
  899. uint32_t n;
  900. if (!_sr->read4(&n)) {
  901. _err += "Failed to read the number of array elements.\n";
  902. return false;
  903. }
  904. length = size_t(n);
  905. } else {
  906. uint64_t n;
  907. if (!_sr->read8(&n)) {
  908. _err += "Failed to read the number of array elements.\n";
  909. return false;
  910. }
  911. length = size_t(n);
  912. }
  913. d->resize(length);
  914. // TODO(syoyo): Zero-copy
  915. if (!_sr->read(sizeof(uint16_t) * length, sizeof(uint16_t) * length,
  916. reinterpret_cast<uint8_t *>(d->data()))) {
  917. _err += "Failed to read half array data.\n";
  918. return false;
  919. }
  920. return true;
  921. }
  922. //
  923. // compressed data is represented by integers or look-up table.
  924. //
  925. size_t length;
  926. // < ver 0.7.0 use 32bit
  927. if ((_version[0] == 0) && ((_version[1] < 7))) {
  928. uint32_t n;
  929. if (!_sr->read4(&n)) {
  930. _err += "Failed to read the number of array elements.\n";
  931. return false;
  932. }
  933. length = size_t(n);
  934. } else {
  935. uint64_t n;
  936. if (!_sr->read8(&n)) {
  937. _err += "Failed to read the number of array elements.\n";
  938. return false;
  939. }
  940. length = size_t(n);
  941. }
  942. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  943. std::cout << "array.len = " << length << "\n";
  944. #endif
  945. d->resize(length);
  946. if (length < kMinCompressedArraySize) {
  947. size_t sz = sizeof(uint16_t) * length;
  948. // Not stored in compressed.
  949. // reader.ReadContiguous(odata, osize);
  950. if (!_sr->read(sz, sz, reinterpret_cast<uint8_t *>(d->data()))) {
  951. _err += "Failed to read uncompressed array data.\n";
  952. return false;
  953. }
  954. return true;
  955. }
  956. // Read the code
  957. char code;
  958. if (!_sr->read1(&code)) {
  959. _err += "Failed to read the code.\n";
  960. return false;
  961. }
  962. if (code == 'i') {
  963. // Compressed integers.
  964. std::vector<int32_t> ints(length);
  965. if (!_ReadCompressedInts(_sr, ints.data(), ints.size())) {
  966. _err += "Failed to read compressed ints in ReadHalfArray.\n";
  967. return false;
  968. }
  969. for (size_t i = 0; i < length; i++) {
  970. float f = float(ints[i]);
  971. float16 h = float_to_half_full(f);
  972. (*d)[i] = h.u;
  973. }
  974. } else if (code == 't') {
  975. // Lookup table & indexes.
  976. uint32_t lutSize;
  977. if (!_sr->read4(&lutSize)) {
  978. _err += "Failed to read lutSize in ReadHalfArray.\n";
  979. return false;
  980. }
  981. std::vector<uint16_t> lut(lutSize);
  982. if (!_sr->read(sizeof(uint16_t) * lutSize, sizeof(uint16_t) * lutSize,
  983. reinterpret_cast<uint8_t *>(lut.data()))) {
  984. _err += "Failed to read lut table in ReadHalfArray.\n";
  985. return false;
  986. }
  987. std::vector<uint32_t> indexes(length);
  988. if (!_ReadCompressedInts(_sr, indexes.data(), indexes.size())) {
  989. _err += "Failed to read lut indices in ReadHalfArray.\n";
  990. return false;
  991. }
  992. auto o = d->data();
  993. for (auto index : indexes) {
  994. *o++ = lut[index];
  995. }
  996. } else {
  997. _err += "Invalid code. Data is currupted\n";
  998. return false;
  999. }
  1000. return true;
  1001. }
  1002. bool Parser::_ReadFloatArray(bool is_compressed, std::vector<float> *d) {
  1003. if (!is_compressed) {
  1004. size_t length;
  1005. // < ver 0.7.0 use 32bit
  1006. if ((_version[0] == 0) && ((_version[1] < 7))) {
  1007. uint32_t n;
  1008. if (!_sr->read4(&n)) {
  1009. _err += "Failed to read the number of array elements.\n";
  1010. return false;
  1011. }
  1012. length = size_t(n);
  1013. } else {
  1014. uint64_t n;
  1015. if (!_sr->read8(&n)) {
  1016. _err += "Failed to read the number of array elements.\n";
  1017. return false;
  1018. }
  1019. length = size_t(n);
  1020. }
  1021. d->resize(length);
  1022. // TODO(syoyo): Zero-copy
  1023. if (!_sr->read(sizeof(float) * length, sizeof(float) * length,
  1024. reinterpret_cast<uint8_t *>(d->data()))) {
  1025. _err += "Failed to read float array data.\n";
  1026. return false;
  1027. }
  1028. return true;
  1029. }
  1030. //
  1031. // compressed data is represented by integers or look-up table.
  1032. //
  1033. size_t length;
  1034. // < ver 0.7.0 use 32bit
  1035. if ((_version[0] == 0) && ((_version[1] < 7))) {
  1036. uint32_t n;
  1037. if (!_sr->read4(&n)) {
  1038. _err += "Failed to read the number of array elements.\n";
  1039. return false;
  1040. }
  1041. length = size_t(n);
  1042. } else {
  1043. uint64_t n;
  1044. if (!_sr->read8(&n)) {
  1045. _err += "Failed to read the number of array elements.\n";
  1046. return false;
  1047. }
  1048. length = size_t(n);
  1049. }
  1050. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1051. std::cout << "array.len = " << length << "\n";
  1052. #endif
  1053. d->resize(length);
  1054. if (length < kMinCompressedArraySize) {
  1055. size_t sz = sizeof(float) * length;
  1056. // Not stored in compressed.
  1057. // reader.ReadContiguous(odata, osize);
  1058. if (!_sr->read(sz, sz, reinterpret_cast<uint8_t *>(d->data()))) {
  1059. _err += "Failed to read uncompressed array data.\n";
  1060. return false;
  1061. }
  1062. return true;
  1063. }
  1064. // Read the code
  1065. char code;
  1066. if (!_sr->read1(&code)) {
  1067. _err += "Failed to read the code.\n";
  1068. return false;
  1069. }
  1070. if (code == 'i') {
  1071. // Compressed integers.
  1072. std::vector<int32_t> ints(length);
  1073. if (!_ReadCompressedInts(_sr, ints.data(), ints.size())) {
  1074. _err += "Failed to read compressed ints in ReadFloatArray.\n";
  1075. return false;
  1076. }
  1077. std::copy(ints.begin(), ints.end(), d->data());
  1078. } else if (code == 't') {
  1079. // Lookup table & indexes.
  1080. uint32_t lutSize;
  1081. if (!_sr->read4(&lutSize)) {
  1082. _err += "Failed to read lutSize in ReadFloatArray.\n";
  1083. return false;
  1084. }
  1085. std::vector<float> lut(lutSize);
  1086. if (!_sr->read(sizeof(float) * lutSize, sizeof(float) * lutSize,
  1087. reinterpret_cast<uint8_t *>(lut.data()))) {
  1088. _err += "Failed to read lut table in ReadFloatArray.\n";
  1089. return false;
  1090. }
  1091. std::vector<uint32_t> indexes(length);
  1092. if (!_ReadCompressedInts(_sr, indexes.data(), indexes.size())) {
  1093. _err += "Failed to read lut indices in ReadFloatArray.\n";
  1094. return false;
  1095. }
  1096. auto o = d->data();
  1097. for (auto index : indexes) {
  1098. *o++ = lut[index];
  1099. }
  1100. } else {
  1101. _err += "Invalid code. Data is currupted\n";
  1102. return false;
  1103. }
  1104. return true;
  1105. }
  1106. bool Parser::_ReadDoubleArray(bool is_compressed, std::vector<double> *d) {
  1107. if (!is_compressed) {
  1108. size_t length;
  1109. // < ver 0.7.0 use 32bit
  1110. if ((_version[0] == 0) && ((_version[1] < 7))) {
  1111. uint32_t n;
  1112. if (!_sr->read4(&n)) {
  1113. _err += "Failed to read the number of array elements.\n";
  1114. return false;
  1115. }
  1116. length = size_t(n);
  1117. } else {
  1118. uint64_t n;
  1119. if (!_sr->read8(&n)) {
  1120. _err += "Failed to read the number of array elements.\n";
  1121. return false;
  1122. }
  1123. length = size_t(n);
  1124. }
  1125. d->resize(length);
  1126. // TODO(syoyo): Zero-copy
  1127. if (!_sr->read(sizeof(double) * length, sizeof(double) * length,
  1128. reinterpret_cast<uint8_t *>(d->data()))) {
  1129. _err += "Failed to read double array data.\n";
  1130. return false;
  1131. }
  1132. return true;
  1133. }
  1134. //
  1135. // compressed data is represented by integers or look-up table.
  1136. //
  1137. size_t length;
  1138. // < ver 0.7.0 use 32bit
  1139. if ((_version[0] == 0) && ((_version[1] < 7))) {
  1140. uint32_t n;
  1141. if (!_sr->read4(&n)) {
  1142. _err += "Failed to read the number of array elements.\n";
  1143. return false;
  1144. }
  1145. length = size_t(n);
  1146. } else {
  1147. uint64_t n;
  1148. if (!_sr->read8(&n)) {
  1149. _err += "Failed to read the number of array elements.\n";
  1150. return false;
  1151. }
  1152. length = size_t(n);
  1153. }
  1154. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1155. std::cout << "array.len = " << length << "\n";
  1156. #endif
  1157. d->resize(length);
  1158. if (length < kMinCompressedArraySize) {
  1159. size_t sz = sizeof(double) * length;
  1160. // Not stored in compressed.
  1161. // reader.ReadContiguous(odata, osize);
  1162. if (!_sr->read(sz, sz, reinterpret_cast<uint8_t *>(d->data()))) {
  1163. _err += "Failed to read uncompressed array data.\n";
  1164. return false;
  1165. }
  1166. return true;
  1167. }
  1168. // Read the code
  1169. char code;
  1170. if (!_sr->read1(&code)) {
  1171. _err += "Failed to read the code.\n";
  1172. return false;
  1173. }
  1174. if (code == 'i') {
  1175. // Compressed integers.
  1176. std::vector<int32_t> ints(length);
  1177. if (!_ReadCompressedInts(_sr, ints.data(), ints.size())) {
  1178. _err += "Failed to read compressed ints in ReadDoubleArray.\n";
  1179. return false;
  1180. }
  1181. std::copy(ints.begin(), ints.end(), d->data());
  1182. } else if (code == 't') {
  1183. // Lookup table & indexes.
  1184. uint32_t lutSize;
  1185. if (!_sr->read4(&lutSize)) {
  1186. _err += "Failed to read lutSize in ReadDoubleArray.\n";
  1187. return false;
  1188. }
  1189. std::vector<double> lut(lutSize);
  1190. if (!_sr->read(sizeof(double) * lutSize, sizeof(double) * lutSize,
  1191. reinterpret_cast<uint8_t *>(lut.data()))) {
  1192. _err += "Failed to read lut table in ReadDoubleArray.\n";
  1193. return false;
  1194. }
  1195. std::vector<uint32_t> indexes(length);
  1196. if (!_ReadCompressedInts(_sr, indexes.data(), indexes.size())) {
  1197. _err += "Failed to read lut indices in ReadDoubleArray.\n";
  1198. return false;
  1199. }
  1200. auto o = d->data();
  1201. for (auto index : indexes) {
  1202. *o++ = lut[index];
  1203. }
  1204. } else {
  1205. _err += "Invalid code. Data is currupted\n";
  1206. return false;
  1207. }
  1208. return true;
  1209. }
  1210. bool Parser::_ReadTimeSamples(TimeSamples *d) {
  1211. (void)d;
  1212. // TODO(syoyo): Deferred loading of TimeSamples?(See USD's implementation)
  1213. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1214. std::cout << "ReadTimeSamples: offt before tell = " << _sr->tell() << "\n";
  1215. #endif
  1216. // 8byte for the offset for recursive value. See _RecursiveRead() in
  1217. // crateFile.cpp for details.
  1218. int64_t offset{0};
  1219. if (!_sr->read8(&offset)) {
  1220. _err += "Failed to read the offset for value in Dictionary.\n";
  1221. return false;
  1222. }
  1223. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1224. std::cout << "TimeSample times value offset = " << offset << "\n";
  1225. std::cout << "TimeSample tell = " << _sr->tell() << "\n";
  1226. #endif
  1227. // -8 to compensate sizeof(offset)
  1228. if (!_sr->seek_from_currect(offset - 8)) {
  1229. _err += "Failed to seek to TimeSample times. Invalid offset value: " +
  1230. std::to_string(offset) + "\n";
  1231. return false;
  1232. }
  1233. // TODO(syoyo): Deduplicate times?
  1234. ValueRep rep{0};
  1235. if (!_ReadValueRep(&rep)) {
  1236. _err += "Failed to read ValueRep for TimeSample' times element.\n";
  1237. return false;
  1238. }
  1239. // Save offset
  1240. size_t values_offset = _sr->tell();
  1241. Value value;
  1242. if (!_UnpackValueRep(rep, &value)) {
  1243. _err += "Failed to unpack value of TimeSample's times element.\n";
  1244. return false;
  1245. }
  1246. // must be an array of double.
  1247. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1248. std::cout << "TimeSample times:" << value.GetTypeName() << "\n";
  1249. std::cout << "TODO: Parse TimeSample values\n";
  1250. #endif
  1251. //
  1252. // Parse values for TimeSamples.
  1253. // TODO(syoyo): Delayed loading of values.
  1254. //
  1255. // seek position will be changed in `_UnpackValueRep`, so revert it.
  1256. if (!_sr->seek_set(values_offset)) {
  1257. _err += "Failed to seek to TimeSamples values.\n";
  1258. return false;
  1259. }
  1260. // 8byte for the offset for recursive value. See _RecursiveRead() in
  1261. // crateFile.cpp for details.
  1262. if (!_sr->read8(&offset)) {
  1263. _err += "Failed to read the offset for value in TimeSamples.\n";
  1264. return false;
  1265. }
  1266. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1267. std::cout << "TimeSample value offset = " << offset << "\n";
  1268. std::cout << "TimeSample tell = " << _sr->tell() << "\n";
  1269. #endif
  1270. // -8 to compensate sizeof(offset)
  1271. if (!_sr->seek_from_currect(offset - 8)) {
  1272. _err += "Failed to seek to TimeSample values. Invalid offset value: " +
  1273. std::to_string(offset) + "\n";
  1274. return false;
  1275. }
  1276. uint64_t num_values{0};
  1277. if (!_sr->read8(&num_values)) {
  1278. _err += "Failed to read the number of values from TimeSamples.\n";
  1279. return false;
  1280. }
  1281. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1282. std::cout << "Number of values = " << num_values << "\n";
  1283. std::cout << "TODO: TimeSamples Implement\n";
  1284. #endif
  1285. _warn += "TODO: Decode TimeSample's values\n";
  1286. // Move to next location.
  1287. // sizeof(uint64) = sizeof(ValueRep)
  1288. if (!_sr->seek_from_currect(int64_t(sizeof(uint64_t) * num_values))) {
  1289. _err += "Failed to seek over TimeSamples's values.\n";
  1290. return false;
  1291. }
  1292. return true;
  1293. }
  1294. bool Parser::_ReadPathListOp(ListOp<Path> *d) {
  1295. // read ListOpHeader
  1296. ListOpHeader h;
  1297. if (!_sr->read1(&h.bits)) {
  1298. _err += "Failed to read ListOpHeader\n";
  1299. return false;
  1300. }
  1301. if (h.IsExplicit()) {
  1302. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1303. std::cout << "Explicit\n";
  1304. #endif
  1305. d->ClearAndMakeExplicit();
  1306. }
  1307. // array data is not compressed
  1308. auto ReadFn = [this](std::vector<Path> &result) -> bool {
  1309. uint64_t n;
  1310. if (!_sr->read8(&n)) {
  1311. _err += "Failed to read # of elements in ListOp.\n";
  1312. return false;
  1313. }
  1314. std::vector<Index> ivalue(static_cast<size_t>(n));
  1315. if (!_sr->read(size_t(n) * sizeof(Index), size_t(n) * sizeof(Index),
  1316. reinterpret_cast<uint8_t *>(ivalue.data()))) {
  1317. _err += "Failed to read ListOp data.\n";
  1318. return false;
  1319. }
  1320. // reconstruct
  1321. result.resize(static_cast<size_t>(n));
  1322. for (size_t i = 0; i < n; i++) {
  1323. result[i] = GetPath(ivalue[i]);
  1324. }
  1325. return true;
  1326. };
  1327. if (h.HasExplicitItems()) {
  1328. std::vector<Path> items;
  1329. if (!ReadFn(items)) {
  1330. _err += "Failed to read ListOp::ExplicitItems.\n";
  1331. return false;
  1332. }
  1333. d->SetExplicitItems(items);
  1334. }
  1335. if (h.HasAddedItems()) {
  1336. std::vector<Path> items;
  1337. if (!ReadFn(items)) {
  1338. _err += "Failed to read ListOp::AddedItems.\n";
  1339. return false;
  1340. }
  1341. d->SetAddedItems(items);
  1342. }
  1343. if (h.HasPrependedItems()) {
  1344. std::vector<Path> items;
  1345. if (!ReadFn(items)) {
  1346. _err += "Failed to read ListOp::PrependedItems.\n";
  1347. return false;
  1348. }
  1349. d->SetPrependedItems(items);
  1350. }
  1351. if (h.HasAppendedItems()) {
  1352. std::vector<Path> items;
  1353. if (!ReadFn(items)) {
  1354. _err += "Failed to read ListOp::AppendedItems.\n";
  1355. return false;
  1356. }
  1357. d->SetAppendedItems(items);
  1358. }
  1359. if (h.HasDeletedItems()) {
  1360. std::vector<Path> items;
  1361. if (!ReadFn(items)) {
  1362. _err += "Failed to read ListOp::DeletedItems.\n";
  1363. return false;
  1364. }
  1365. d->SetDeletedItems(items);
  1366. }
  1367. if (h.HasOrderedItems()) {
  1368. std::vector<Path> items;
  1369. if (!ReadFn(items)) {
  1370. _err += "Failed to read ListOp::OrderedItems.\n";
  1371. return false;
  1372. }
  1373. d->SetOrderedItems(items);
  1374. }
  1375. return true;
  1376. }
  1377. bool Parser::_ReadDictionary(Value::Dictionary *d) {
  1378. Value::Dictionary dict;
  1379. uint64_t sz;
  1380. if (!_sr->read8(&sz)) {
  1381. _err += "Failed to read the number of elements for Dictionary data.\n";
  1382. return false;
  1383. }
  1384. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1385. std::cout << "# of elements in dict " << sz << "\n";
  1386. #endif
  1387. while (sz--) {
  1388. // key(StringIndex)
  1389. std::string key;
  1390. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1391. std::cout << "key before tell = " << _sr->tell() << "\n";
  1392. #endif
  1393. if (!_ReadString(&key)) {
  1394. _err += "Failed to read key string for Dictionary element.\n";
  1395. return false;
  1396. }
  1397. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1398. std::cout << "offt before tell = " << _sr->tell() << "\n";
  1399. #endif
  1400. // 8byte for the offset for recursive value. See _RecursiveRead() in
  1401. // crateFile.cpp for details.
  1402. int64_t offset{0};
  1403. if (!_sr->read8(&offset)) {
  1404. _err += "Failed to read the offset for value in Dictionary.\n";
  1405. return false;
  1406. }
  1407. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1408. std::cout << "value offset = " << offset << "\n";
  1409. std::cout << "tell = " << _sr->tell() << "\n";
  1410. #endif
  1411. // -8 to compensate sizeof(offset)
  1412. if (!_sr->seek_from_currect(offset - 8)) {
  1413. _err +=
  1414. "Failed to seek. Invalid offset value: " + std::to_string(offset) +
  1415. "\n";
  1416. return false;
  1417. }
  1418. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1419. std::cout << "+offset tell = " << _sr->tell() << "\n";
  1420. std::cout << "key = " << key << "\n";
  1421. #endif
  1422. ValueRep rep{0};
  1423. if (!_ReadValueRep(&rep)) {
  1424. _err += "Failed to read value for Dictionary element.\n";
  1425. return false;
  1426. }
  1427. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1428. std::cout << "vrep.ty = " << rep.GetType() << "\n";
  1429. std::cout << "vrep = " << GetValueTypeRepr(rep.GetType()) << "\n";
  1430. #endif
  1431. size_t saved_position = _sr->tell();
  1432. Value value;
  1433. if (!_UnpackValueRep(rep, &value)) {
  1434. _err += "Failed to unpack value of Dictionary element.\n";
  1435. return false;
  1436. }
  1437. dict[key] = value;
  1438. if (!_sr->seek_set(saved_position)) {
  1439. _err +=
  1440. "Failed to set seek in ReadDict\n";
  1441. return false;
  1442. }
  1443. }
  1444. (*d) = dict;
  1445. return true;
  1446. }
  1447. bool Parser::_UnpackValueRep(const ValueRep &rep, Value *value) {
  1448. ValueType ty = GetValueType(rep.GetType());
  1449. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1450. std::cout << GetValueTypeRepr(rep.GetType()) << "\n";
  1451. #endif
  1452. if (rep.IsInlined()) {
  1453. uint32_t d = (rep.GetPayload() & ((1ull << (sizeof(uint32_t) * 8)) - 1));
  1454. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1455. std::cout << "d = " << d << "\n";
  1456. std::cout << "ty.id = " << ty.id << "\n";
  1457. #endif
  1458. if (ty.id == VALUE_TYPE_BOOL) {
  1459. assert((!rep.IsCompressed()) && (!rep.IsArray()));
  1460. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1461. std::cout << "Bool: " << d << "\n";
  1462. #endif
  1463. value->SetBool(d ? true : false);
  1464. return true;
  1465. } else if (ty.id == VALUE_TYPE_ASSET_PATH) {
  1466. // AssetPath = std::string(storage format is TokenIndex).
  1467. std::string str = GetToken(Index(d));
  1468. value->SetAssetPath(str);
  1469. return true;
  1470. } else if (ty.id == VALUE_TYPE_SPECIFIER) {
  1471. assert((!rep.IsCompressed()) && (!rep.IsArray()));
  1472. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1473. std::cout << "Specifier: "
  1474. << GetSpecifierString(static_cast<Specifier>(d)) << "\n";
  1475. #endif
  1476. if (d >= NumSpecifiers) {
  1477. _err += "Invalid value for Specifier\n";
  1478. return false;
  1479. }
  1480. value->SetSpecifier(d);
  1481. return true;
  1482. } else if (ty.id == VALUE_TYPE_PERMISSION) {
  1483. assert((!rep.IsCompressed()) && (!rep.IsArray()));
  1484. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1485. std::cout << "Permission: "
  1486. << GetPermissionString(static_cast<Permission>(d)) << "\n";
  1487. #endif
  1488. if (d >= NumPermissions) {
  1489. _err += "Invalid value for Permission\n";
  1490. return false;
  1491. }
  1492. value->SetPermission(d);
  1493. return true;
  1494. } else if (ty.id == VALUE_TYPE_VARIABILITY) {
  1495. assert((!rep.IsCompressed()) && (!rep.IsArray()));
  1496. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1497. std::cout << "Variability: "
  1498. << GetVariabilityString(static_cast<Variability>(d)) << "\n";
  1499. #endif
  1500. if (d >= NumVariabilities) {
  1501. _err += "Invalid value for Variability\n";
  1502. return false;
  1503. }
  1504. value->SetVariability(d);
  1505. return true;
  1506. } else if (ty.id == VALUE_TYPE_TOKEN) {
  1507. assert((!rep.IsCompressed()) && (!rep.IsArray()));
  1508. std::string str = GetToken(Index(d));
  1509. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1510. std::cout << "value.token = " << str << "\n";
  1511. #endif
  1512. value->SetToken(str);
  1513. return true;
  1514. } else if (ty.id == VALUE_TYPE_STRING) {
  1515. assert((!rep.IsCompressed()) && (!rep.IsArray()));
  1516. std::string str = GetString(Index(d));
  1517. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1518. std::cout << "value.string = " << str << "\n";
  1519. #endif
  1520. value->SetString(str);
  1521. return true;
  1522. } else if (ty.id == VALUE_TYPE_INT) {
  1523. assert((!rep.IsCompressed()) && (!rep.IsArray()));
  1524. int ival;
  1525. memcpy(&ival, &d, sizeof(int));
  1526. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1527. std::cout << "value.int = " << ival << "\n";
  1528. #endif
  1529. value->SetInt(ival);
  1530. return true;
  1531. } else if (ty.id == VALUE_TYPE_FLOAT) {
  1532. assert((!rep.IsCompressed()) && (!rep.IsArray()));
  1533. float f;
  1534. memcpy(&f, &d, sizeof(float));
  1535. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1536. std::cout << "value.float = " << f << "\n";
  1537. #endif
  1538. value->SetFloat(f);
  1539. return true;
  1540. } else if (ty.id == VALUE_TYPE_DOUBLE) {
  1541. assert((!rep.IsCompressed()) && (!rep.IsArray()));
  1542. // Value is saved as float
  1543. float f;
  1544. memcpy(&f, &d, sizeof(float));
  1545. double v = double(f);
  1546. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1547. std::cout << "value.double = " << v << "\n";
  1548. #endif
  1549. value->SetDouble(v);
  1550. return true;
  1551. } else if (ty.id == VALUE_TYPE_VEC3I) {
  1552. assert((!rep.IsCompressed()) && (!rep.IsArray()));
  1553. // Value is represented in int8
  1554. int8_t data[3];
  1555. memcpy(&data, &d, 3);
  1556. Vec3i v;
  1557. v[0] = static_cast<int32_t>(data[0]);
  1558. v[1] = static_cast<int32_t>(data[1]);
  1559. v[2] = static_cast<int32_t>(data[2]);
  1560. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1561. std::cout << "value.vec3i = " << v[0] << ", " << v[1] << ", " << v[2]
  1562. << "\n";
  1563. #endif
  1564. value->SetVec3i(v);
  1565. return true;
  1566. } else if (ty.id == VALUE_TYPE_VEC3F) {
  1567. assert((!rep.IsCompressed()) && (!rep.IsArray()));
  1568. // Value is represented in int8
  1569. int8_t data[3];
  1570. memcpy(&data, &d, 3);
  1571. Vec3f v;
  1572. v[0] = static_cast<float>(data[0]);
  1573. v[1] = static_cast<float>(data[1]);
  1574. v[2] = static_cast<float>(data[2]);
  1575. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1576. std::cout << "value.vec3f = " << v[0] << ", " << v[1] << ", " << v[2]
  1577. << "\n";
  1578. #endif
  1579. value->SetVec3f(v);
  1580. return true;
  1581. } else if (ty.id == VALUE_TYPE_VEC3D) {
  1582. assert((!rep.IsCompressed()) && (!rep.IsArray()));
  1583. // Value is represented in int8
  1584. int8_t data[3];
  1585. memcpy(&data, &d, 3);
  1586. Vec3d v;
  1587. v[0] = static_cast<double>(data[0]);
  1588. v[1] = static_cast<double>(data[1]);
  1589. v[2] = static_cast<double>(data[2]);
  1590. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1591. std::cout << "value.vec3d = " << v[0] << ", " << v[1] << ", " << v[2]
  1592. << "\n";
  1593. #endif
  1594. value->SetVec3d(v);
  1595. return true;
  1596. } else if (ty.id == VALUE_TYPE_MATRIX2D) {
  1597. assert((!rep.IsCompressed()) && (!rep.IsArray()));
  1598. // Matrix contains diagnonal components only, and values are represented
  1599. // in int8
  1600. int8_t data[2];
  1601. memcpy(&data, &d, 2);
  1602. Matrix2d v;
  1603. memset(v.m, 0, sizeof(Matrix2d));
  1604. v.m[0][0] = static_cast<double>(data[0]);
  1605. v.m[1][1] = static_cast<double>(data[1]);
  1606. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1607. std::cout << "value.matrix(diag) = " << v.m[0][0] << ", " << v.m[1][1]
  1608. << "\n";
  1609. #endif
  1610. value->SetMatrix2d(v);
  1611. return true;
  1612. } else if (ty.id == VALUE_TYPE_MATRIX3D) {
  1613. assert((!rep.IsCompressed()) && (!rep.IsArray()));
  1614. // Matrix contains diagnonal components only, and values are represented
  1615. // in int8
  1616. int8_t data[3];
  1617. memcpy(&data, &d, 3);
  1618. Matrix3d v;
  1619. memset(v.m, 0, sizeof(Matrix3d));
  1620. v.m[0][0] = static_cast<double>(data[0]);
  1621. v.m[1][1] = static_cast<double>(data[1]);
  1622. v.m[2][2] = static_cast<double>(data[2]);
  1623. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1624. std::cout << "value.matrix(diag) = " << v.m[0][0] << ", " << v.m[1][1]
  1625. << ", " << v.m[2][2] << "\n";
  1626. #endif
  1627. value->SetMatrix3d(v);
  1628. return true;
  1629. } else if (ty.id == VALUE_TYPE_MATRIX4D) {
  1630. assert((!rep.IsCompressed()) && (!rep.IsArray()));
  1631. // Matrix contains diagnonal components only, and values are represented
  1632. // in int8
  1633. int8_t data[4];
  1634. memcpy(&data, &d, 4);
  1635. Matrix4d v;
  1636. memset(v.m, 0, sizeof(Matrix4d));
  1637. v.m[0][0] = static_cast<double>(data[0]);
  1638. v.m[1][1] = static_cast<double>(data[1]);
  1639. v.m[2][2] = static_cast<double>(data[2]);
  1640. v.m[3][3] = static_cast<double>(data[3]);
  1641. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1642. std::cout << "value.matrix(diag) = " << v.m[0][0] << ", " << v.m[1][1]
  1643. << ", " << v.m[2][2] << ", " << v.m[3][3] << "\n";
  1644. #endif
  1645. value->SetMatrix4d(v);
  1646. return true;
  1647. } else {
  1648. // TODO(syoyo)
  1649. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1650. std::cerr << "TODO: Inlined Value: " << GetValueTypeRepr(rep.GetType())
  1651. << "\n";
  1652. #endif
  1653. return false;
  1654. }
  1655. // ====================================================
  1656. } else {
  1657. // payload is the offset to data.
  1658. uint64_t offset = rep.GetPayload();
  1659. if (!_sr->seek_set(offset)) {
  1660. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1661. std::cerr << "Invalid offset\n";
  1662. #endif
  1663. return false;
  1664. }
  1665. // printf("rep = 0x%016lx\n", rep.GetData());
  1666. if (ty.id == VALUE_TYPE_TOKEN) {
  1667. // Guess array of Token
  1668. assert(!rep.IsCompressed());
  1669. assert(rep.IsArray());
  1670. uint64_t n;
  1671. if (!_sr->read8(&n)) {
  1672. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1673. std::cerr << "Failed to read the number of array elements\n";
  1674. #endif
  1675. return false;
  1676. }
  1677. std::vector<Index> v(static_cast<size_t>(n));
  1678. if (!_sr->read(size_t(n) * sizeof(Index), size_t(n) * sizeof(Index),
  1679. reinterpret_cast<uint8_t *>(v.data()))) {
  1680. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1681. std::cerr << "Failed to read TokenIndex array\n";
  1682. #endif
  1683. return false;
  1684. }
  1685. std::vector<std::string> tokens(static_cast<size_t>(n));
  1686. for (size_t i = 0; i < n; i++) {
  1687. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1688. std::cout << "Token[" << i << "] = " << GetToken(v[i]) << " ("
  1689. << v[i].value << ")\n";
  1690. #endif
  1691. tokens[i] = GetToken(v[i]);
  1692. }
  1693. value->SetTokenArray(tokens);
  1694. return true;
  1695. } else if (ty.id == VALUE_TYPE_STRING) {
  1696. assert(!rep.IsCompressed());
  1697. assert(rep.IsArray());
  1698. uint64_t n;
  1699. if (!_sr->read8(&n)) {
  1700. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1701. std::cerr << "Failed to read the number of array elements\n";
  1702. #endif
  1703. return false;
  1704. }
  1705. std::vector<Index> v(static_cast<size_t>(n));
  1706. if (!_sr->read(size_t(n) * sizeof(Index), size_t(n) * sizeof(Index),
  1707. reinterpret_cast<uint8_t *>(v.data()))) {
  1708. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1709. std::cerr << "Failed to read TokenIndex array\n";
  1710. #endif
  1711. return false;
  1712. }
  1713. std::vector<std::string> stringArray(static_cast<size_t>(n));
  1714. for (size_t i = 0; i < n; i++) {
  1715. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1716. std::cout << "String[" << i << "] = " << GetString(v[i]) << " ("
  1717. << v[i].value << ")\n";
  1718. #endif
  1719. stringArray[i] = GetString(v[i]);
  1720. }
  1721. // In TinyUSDZ, token == string
  1722. value->SetTokenArray(stringArray);
  1723. return true;
  1724. } else if (ty.id == VALUE_TYPE_INT) {
  1725. assert(rep.IsArray());
  1726. std::vector<int32_t> v;
  1727. if (!_ReadIntArray(rep.IsCompressed(), &v)) {
  1728. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1729. std::cerr << "Failed to read Int array\n";
  1730. #endif
  1731. return false;
  1732. }
  1733. if (v.empty()) {
  1734. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1735. std::cerr << "Empty Int array\n";
  1736. #endif
  1737. return false;
  1738. }
  1739. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1740. for (size_t i = 0; i < v.size(); i++) {
  1741. std::cout << "Int[" << i << "] = " << v[i] << "\n";
  1742. }
  1743. #endif
  1744. if (rep.IsArray()) {
  1745. value->SetIntArray(v.data(), v.size());
  1746. } else {
  1747. value->SetInt(v[0]);
  1748. }
  1749. return true;
  1750. } else if (ty.id == VALUE_TYPE_VEC2F) {
  1751. assert(!rep.IsCompressed());
  1752. if (rep.IsArray()) {
  1753. uint64_t n;
  1754. if (!_sr->read8(&n)) {
  1755. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1756. std::cerr << "Failed to read the number of array elements\n";
  1757. #endif
  1758. return false;
  1759. }
  1760. std::vector<Vec2f> v(static_cast<size_t>(n));
  1761. if (!_sr->read(size_t(n) * sizeof(Vec2f), size_t(n) * sizeof(Vec2f),
  1762. reinterpret_cast<uint8_t *>(v.data()))) {
  1763. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1764. std::cerr << "Failed to read Vec2f array\n";
  1765. #endif
  1766. return false;
  1767. }
  1768. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1769. for (size_t i = 0; i < v.size(); i++) {
  1770. std::cout << "Vec2f[" << i << "] = " << v[i][0] << ", " << v[i][1]
  1771. << "\n";
  1772. }
  1773. #endif
  1774. value->SetVec2fArray(v.data(), v.size());
  1775. } else {
  1776. Vec2f v;
  1777. if (!_sr->read(sizeof(Vec2f), sizeof(Vec2f),
  1778. reinterpret_cast<uint8_t *>(&v))) {
  1779. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1780. std::cerr << "Failed to read Vec2f\n";
  1781. #endif
  1782. return false;
  1783. }
  1784. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1785. std::cout << "Vec2f = " << v[0] << ", " << v[1] << "\n";
  1786. #endif
  1787. value->SetVec2f(v);
  1788. }
  1789. return true;
  1790. } else if (ty.id == VALUE_TYPE_VEC3F) {
  1791. assert(!rep.IsCompressed());
  1792. if (rep.IsArray()) {
  1793. uint64_t n;
  1794. if (!_sr->read8(&n)) {
  1795. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1796. std::cerr << "Failed to read the number of array elements\n";
  1797. #endif
  1798. return false;
  1799. }
  1800. std::vector<Vec3f> v(static_cast<size_t>(n));
  1801. if (!_sr->read(size_t(n) * sizeof(Vec3f), size_t(n) * sizeof(Vec3f),
  1802. reinterpret_cast<uint8_t *>(v.data()))) {
  1803. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1804. std::cerr << "Failed to read Vec3f array\n";
  1805. #endif
  1806. return false;
  1807. }
  1808. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1809. for (size_t i = 0; i < v.size(); i++) {
  1810. std::cout << "Vec3f[" << i << "] = " << v[i][0] << ", " << v[i][1]
  1811. << ", " << v[i][2] << "\n";
  1812. }
  1813. #endif
  1814. value->SetVec3fArray(v.data(), v.size());
  1815. } else {
  1816. Vec3f v;
  1817. if (!_sr->read(sizeof(Vec3f), sizeof(Vec3f),
  1818. reinterpret_cast<uint8_t *>(&v))) {
  1819. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1820. std::cerr << "Failed to read Vec3f\n";
  1821. #endif
  1822. return false;
  1823. }
  1824. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1825. std::cout << "Vec3f = " << v[0] << ", " << v[1] << ", " << v[2] << "\n";
  1826. #endif
  1827. value->SetVec3f(v);
  1828. }
  1829. return true;
  1830. } else if (ty.id == VALUE_TYPE_VEC4F) {
  1831. assert(!rep.IsCompressed());
  1832. if (rep.IsArray()) {
  1833. uint64_t n;
  1834. if (!_sr->read8(&n)) {
  1835. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1836. std::cerr << "Failed to read the number of array elements\n";
  1837. #endif
  1838. return false;
  1839. }
  1840. std::vector<Vec4f> v(static_cast<size_t>(n));
  1841. if (!_sr->read(size_t(n) * sizeof(Vec4f), size_t(n) * sizeof(Vec4f),
  1842. reinterpret_cast<uint8_t *>(v.data()))) {
  1843. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1844. std::cerr << "Failed to read Vec4f array\n";
  1845. #endif
  1846. return false;
  1847. }
  1848. value->SetVec4fArray(v.data(), v.size());
  1849. } else {
  1850. Vec4f v;
  1851. if (!_sr->read(sizeof(Vec4f), sizeof(Vec4f),
  1852. reinterpret_cast<uint8_t *>(&v))) {
  1853. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1854. std::cerr << "Failed to read Vec4f\n";
  1855. #endif
  1856. return false;
  1857. }
  1858. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1859. std::cout << "Vec4f = " << v[0] << ", " << v[1] << ", " << v[2] << ", "
  1860. << v[3] << "\n";
  1861. #endif
  1862. value->SetVec4f(v);
  1863. }
  1864. return true;
  1865. } else if (ty.id == VALUE_TYPE_TOKEN_VECTOR) {
  1866. assert(!rep.IsCompressed());
  1867. // std::vector<Index>
  1868. uint64_t n;
  1869. if (!_sr->read8(&n)) {
  1870. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1871. std::cerr << "Failed to read TokenVector value\n";
  1872. #endif
  1873. return false;
  1874. }
  1875. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1876. std::cout << "n = " << n << "\n";
  1877. #endif
  1878. std::vector<Index> indices(static_cast<size_t>(n));
  1879. if (!_sr->read(static_cast<size_t>(n) * sizeof(Index),
  1880. static_cast<size_t>(n) * sizeof(Index),
  1881. reinterpret_cast<uint8_t *>(indices.data()))) {
  1882. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1883. std::cerr << "Failed to read TokenVector value\n";
  1884. #endif
  1885. return false;
  1886. }
  1887. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1888. for (size_t i = 0; i < indices.size(); i++) {
  1889. std::cout << "tokenIndex[" << i << "] = " << int(indices[i].value)
  1890. << "\n";
  1891. }
  1892. #endif
  1893. std::vector<std::string> tokens(indices.size());
  1894. for (size_t i = 0; i < indices.size(); i++) {
  1895. tokens[i] = GetToken(indices[i]);
  1896. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1897. std::cout << "tokenVector[" << i << "] = " << tokens[i] << ", ("
  1898. << int(indices[i].value) << ")\n";
  1899. #endif
  1900. }
  1901. value->SetTokenArray(tokens);
  1902. return true;
  1903. } else if (ty.id == VALUE_TYPE_HALF) {
  1904. if (rep.IsArray()) {
  1905. std::vector<uint16_t> v;
  1906. if (!_ReadHalfArray(rep.IsCompressed(), &v)) {
  1907. _err += "Failed to read half array value\n";
  1908. return false;
  1909. }
  1910. value->SetHalfArray(v.data(), v.size());
  1911. return true;
  1912. } else {
  1913. assert(!rep.IsCompressed());
  1914. // ???
  1915. _err += "Non-inlined, non-array Half value is not supported.\n";
  1916. return false;
  1917. }
  1918. } else if (ty.id == VALUE_TYPE_FLOAT) {
  1919. if (rep.IsArray()) {
  1920. std::vector<float> v;
  1921. if (!_ReadFloatArray(rep.IsCompressed(), &v)) {
  1922. _err += "Failed to read float array value\n";
  1923. return false;
  1924. }
  1925. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1926. for (size_t i = 0; i < v.size(); i++) {
  1927. std::cout << "Float[" << i << "] = " << v[i] << "\n";
  1928. }
  1929. #endif
  1930. value->SetFloatArray(v.data(), v.size());
  1931. return true;
  1932. } else {
  1933. assert(!rep.IsCompressed());
  1934. // ???
  1935. _err += "Non-inlined, non-array Float value is not supported.\n";
  1936. return false;
  1937. }
  1938. } else if (ty.id == VALUE_TYPE_DOUBLE) {
  1939. if (rep.IsArray()) {
  1940. std::vector<double> v;
  1941. if (!_ReadDoubleArray(rep.IsCompressed(), &v)) {
  1942. _err += "Failed to read Double value\n";
  1943. return false;
  1944. }
  1945. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1946. for (size_t i = 0; i < v.size(); i++) {
  1947. std::cout << "Double[" << i << "] = " << v[i] << "\n";
  1948. }
  1949. #endif
  1950. value->SetDoubleArray(v.data(), v.size());
  1951. return true;
  1952. } else {
  1953. assert(!rep.IsCompressed());
  1954. double v;
  1955. if (!_sr->read_double(&v)) {
  1956. _err += "Failed to read Double value\n";
  1957. return false;
  1958. }
  1959. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1960. std::cout << "Double " << v << "\n";
  1961. #endif
  1962. value->SetDouble(v);
  1963. return true;
  1964. }
  1965. } else if (ty.id == VALUE_TYPE_VEC3I) {
  1966. assert(!rep.IsCompressed());
  1967. assert(rep.IsArray());
  1968. Vec3i v;
  1969. if (!_sr->read(sizeof(Vec3i), sizeof(Vec3i),
  1970. reinterpret_cast<uint8_t *>(&v))) {
  1971. _err += "Failed to read Vec3i value\n";
  1972. return false;
  1973. }
  1974. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1975. std::cout << "value.vec3i = " << v[0] << ", " << v[1] << ", " << v[2]
  1976. << "\n";
  1977. #endif
  1978. value->SetVec3i(v);
  1979. return true;
  1980. } else if (ty.id == VALUE_TYPE_VEC3F) {
  1981. assert(!rep.IsCompressed());
  1982. assert(rep.IsArray());
  1983. Vec3f v;
  1984. if (!_sr->read(sizeof(Vec3f), sizeof(Vec3f),
  1985. reinterpret_cast<uint8_t *>(&v))) {
  1986. _err += "Failed to read Vec3f value\n";
  1987. return false;
  1988. }
  1989. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  1990. std::cout << "value.vec3f = " << v[0] << ", " << v[1] << ", " << v[2]
  1991. << "\n";
  1992. #endif
  1993. value->SetVec3f(v);
  1994. return true;
  1995. } else if (ty.id == VALUE_TYPE_VEC3D) {
  1996. assert(!rep.IsCompressed());
  1997. if (rep.IsArray()) {
  1998. uint64_t n;
  1999. if (!_sr->read8(&n)) {
  2000. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2001. std::cerr << "Failed to read the number of array elements\n";
  2002. #endif
  2003. return false;
  2004. }
  2005. std::vector<Vec3d> v(static_cast<size_t>(n));
  2006. if (!_sr->read(size_t(n) * sizeof(Vec3d), size_t(n) * sizeof(Vec3d),
  2007. reinterpret_cast<uint8_t *>(v.data()))) {
  2008. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2009. std::cerr << "Failed to read Vec3d array\n";
  2010. #endif
  2011. return false;
  2012. }
  2013. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2014. for (size_t i = 0; i < v.size(); i++) {
  2015. std::cout << "Vec3d[" << i << "] = " << v[i][0] << ", " << v[i][1]
  2016. << ", " << v[i][2] << "\n";
  2017. }
  2018. #endif
  2019. value->SetVec3dArray(v.data(), v.size());
  2020. } else {
  2021. Vec3d v;
  2022. if (!_sr->read(sizeof(Vec3d), sizeof(Vec3d),
  2023. reinterpret_cast<uint8_t *>(&v))) {
  2024. _err += "Failed to read Vec3d value\n";
  2025. return false;
  2026. }
  2027. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2028. std::cout << "value.vec3d = " << v[0] << ", " << v[1] << ", " << v[2]
  2029. << "\n";
  2030. #endif
  2031. value->SetVec3d(v);
  2032. }
  2033. return true;
  2034. } else if (ty.id == VALUE_TYPE_VEC3H) {
  2035. assert(!rep.IsCompressed());
  2036. assert(rep.IsArray());
  2037. Vec3h v;
  2038. if (!_sr->read(sizeof(Vec3h), sizeof(Vec3h),
  2039. reinterpret_cast<uint8_t *>(&v))) {
  2040. _err += "Failed to read Vec3h value\n";
  2041. return false;
  2042. }
  2043. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2044. std::cout << "value.vec3d = " << to_float(v[0]) << ", " << to_float(v[1])
  2045. << ", " << to_float(v[2]) << "\n";
  2046. #endif
  2047. value->SetVec3h(v);
  2048. return true;
  2049. } else if (ty.id == VALUE_TYPE_QUATF) {
  2050. assert(!rep.IsCompressed());
  2051. if (rep.IsArray()) {
  2052. uint64_t n;
  2053. if (!_sr->read8(&n)) {
  2054. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2055. std::cerr << "Failed to read the number of array elements\n";
  2056. #endif
  2057. return false;
  2058. }
  2059. std::vector<Quatf> v(static_cast<size_t>(n));
  2060. if (!_sr->read(size_t(n) * sizeof(Quatf), size_t(n) * sizeof(Quatf),
  2061. reinterpret_cast<uint8_t *>(v.data()))) {
  2062. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2063. std::cerr << "Failed to read Quatf array\n";
  2064. #endif
  2065. return false;
  2066. }
  2067. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2068. for (size_t i = 0; i < v.size(); i++) {
  2069. std::cout << "Quatf[" << i << "] = " << v[i][0] << ", " << v[i][1]
  2070. << ", " << v[i][2] << "\n";
  2071. }
  2072. #endif
  2073. value->SetQuatfArray(v.data(), v.size());
  2074. } else {
  2075. Quatf v;
  2076. if (!_sr->read(sizeof(Quatf), sizeof(Quatf),
  2077. reinterpret_cast<uint8_t *>(&v))) {
  2078. _err += "Failed to read Quatf value\n";
  2079. return false;
  2080. }
  2081. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2082. std::cout << "value.quatf = " << v[0] << ", " << v[1] << ", " << v[2]
  2083. << ", " << v[3] << "\n";
  2084. #endif
  2085. value->SetQuatf(v);
  2086. }
  2087. return true;
  2088. } else if (ty.id == VALUE_TYPE_MATRIX4D) {
  2089. assert((!rep.IsCompressed()) && (!rep.IsArray()));
  2090. static_assert(sizeof(Matrix4d) == (8 * 16), "");
  2091. Matrix4d v;
  2092. if (!_sr->read(sizeof(Matrix4d), sizeof(Matrix4d),
  2093. reinterpret_cast<uint8_t *>(v.m))) {
  2094. _err += "Failed to read Matrix4d value\n";
  2095. return false;
  2096. }
  2097. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2098. std::cout << "value.matrix4d = ";
  2099. for (size_t i = 0; i < 4; i++) {
  2100. for (size_t j = 0; j < 4; j++) {
  2101. std::cout << v.m[i][j];
  2102. if ((i == 3) && (j == 3)) {
  2103. } else {
  2104. std::cout << ", ";
  2105. }
  2106. }
  2107. }
  2108. std::cout << "\n";
  2109. #endif
  2110. value->SetMatrix4d(v);
  2111. return true;
  2112. } else if (ty.id == VALUE_TYPE_DICTIONARY) {
  2113. assert(!rep.IsCompressed());
  2114. assert(!rep.IsArray());
  2115. Value::Dictionary dict;
  2116. if (!_ReadDictionary(&dict)) {
  2117. _err += "Failed to read Dictionary value\n";
  2118. return false;
  2119. }
  2120. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2121. std::cout << "Dict. nelems = " << dict.size() << "\n";
  2122. #endif
  2123. value->SetDictionary(dict);
  2124. return true;
  2125. } else if (ty.id == VALUE_TYPE_PATH_LIST_OP) {
  2126. // SdfListOp<class SdfPath>
  2127. // => underliying storage is the array of ListOp[PathIndex]
  2128. ListOp<Path> lst;
  2129. if (!_ReadPathListOp(&lst)) {
  2130. _err += "Failed to read PathListOp data\n";
  2131. return false;
  2132. }
  2133. value->SetPathListOp(lst);
  2134. return true;
  2135. } else if (ty.id == VALUE_TYPE_TIME_SAMPLES) {
  2136. TimeSamples ts;
  2137. if (!_ReadTimeSamples(&ts)) {
  2138. _err += "Failed to read TimeSamples data\n";
  2139. return false;
  2140. }
  2141. value->SetTimeSamples(ts);
  2142. return true;
  2143. } else if (ty.id == VALUE_TYPE_DOUBLE_VECTOR) {
  2144. std::vector<double> v;
  2145. if (!_ReadDoubleArray(rep.IsCompressed(), &v)) {
  2146. _err += "Failed to read DoubleVector value\n";
  2147. return false;
  2148. }
  2149. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2150. for (size_t i = 0; i < v.size(); i++) {
  2151. std::cout << "Double[" << i << "] = " << v[i] << "\n";
  2152. }
  2153. #endif
  2154. value->SetDoubleArray(v.data(), v.size());
  2155. return true;
  2156. } else {
  2157. // TODO(syoyo)
  2158. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2159. std::cerr << "[" << __LINE__
  2160. << "] TODO: " << GetValueTypeRepr(rep.GetType()) << "\n";
  2161. #endif
  2162. return false;
  2163. }
  2164. }
  2165. }
  2166. bool Parser::_BuildDecompressedPathsImpl(
  2167. std::vector<uint32_t> const &pathIndexes,
  2168. std::vector<int32_t> const &elementTokenIndexes,
  2169. std::vector<int32_t> const &jumps, size_t curIndex, Path parentPath) {
  2170. bool hasChild = false, hasSibling = false;
  2171. do {
  2172. auto thisIndex = curIndex++;
  2173. if (parentPath.IsEmpty()) {
  2174. // root node.
  2175. // Assume single root node in the scene.
  2176. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2177. std::cout << "paths[" << pathIndexes[thisIndex]
  2178. << "] is parent. name = " << parentPath.full_path_name()
  2179. << "\n";
  2180. #endif
  2181. parentPath = Path::AbsoluteRootPath();
  2182. _paths[pathIndexes[thisIndex]] = parentPath;
  2183. } else {
  2184. int32_t tokenIndex = elementTokenIndexes[thisIndex];
  2185. bool isPrimPropertyPath = tokenIndex < 0;
  2186. tokenIndex = std::abs(tokenIndex);
  2187. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2188. std::cout << "tokenIndex = " << tokenIndex << "\n";
  2189. #endif
  2190. if (tokenIndex >= int32_t(_tokens.size())) {
  2191. _err += "Invalid tokenIndex in _BuildDecompressedPathsImpl.\n";
  2192. return false;
  2193. }
  2194. auto const &elemToken = _tokens[size_t(tokenIndex)];
  2195. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2196. std::cout << "elemToken = " << elemToken << "\n";
  2197. std::cout << "[" << pathIndexes[thisIndex] << "].append = " << elemToken
  2198. << "\n";
  2199. #endif
  2200. // full path
  2201. _paths[pathIndexes[thisIndex]] =
  2202. isPrimPropertyPath ? parentPath.AppendProperty(elemToken)
  2203. : parentPath.AppendElement(elemToken);
  2204. // also set local path for 'primChildren' check
  2205. _paths[pathIndexes[thisIndex]].SetLocalPath(elemToken);
  2206. }
  2207. // If we have either a child or a sibling but not both, then just
  2208. // continue to the neighbor. If we have both then spawn a task for the
  2209. // sibling and do the child ourself. We think that our path trees tend
  2210. // to be broader more often than deep.
  2211. hasChild = (jumps[thisIndex] > 0) || (jumps[thisIndex] == -1);
  2212. hasSibling = (jumps[thisIndex] >= 0);
  2213. if (hasChild) {
  2214. if (hasSibling) {
  2215. // NOTE(syoyo): This recursive call can be parallelized
  2216. auto siblingIndex = thisIndex + size_t(jumps[thisIndex]);
  2217. if (!_BuildDecompressedPathsImpl(pathIndexes, elementTokenIndexes,
  2218. jumps, siblingIndex, parentPath)) {
  2219. return false;
  2220. }
  2221. }
  2222. // Have a child (may have also had a sibling). Reset parent path.
  2223. parentPath = _paths[pathIndexes[thisIndex]];
  2224. }
  2225. // If we had only a sibling, we just continue since the parent path is
  2226. // unchanged and the next thing in the reader stream is the sibling's
  2227. // header.
  2228. } while (hasChild || hasSibling);
  2229. return true;
  2230. }
  2231. // TODO(syoyo): Refactor
  2232. bool Parser::_BuildNodeHierarchy(
  2233. std::vector<uint32_t> const &pathIndexes,
  2234. std::vector<int32_t> const &elementTokenIndexes,
  2235. std::vector<int32_t> const &jumps, size_t curIndex,
  2236. int64_t parentNodeIndex) {
  2237. bool hasChild = false, hasSibling = false;
  2238. // NOTE: Need to indirectly lookup index through pathIndexes[] when accessing
  2239. // `_nodes`
  2240. do {
  2241. auto thisIndex = curIndex++;
  2242. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2243. std::cout << "thisIndex = " << thisIndex << ", curIndex = " << curIndex
  2244. << "\n";
  2245. #endif
  2246. if (parentNodeIndex == -1) {
  2247. // root node.
  2248. // Assume single root node in the scene.
  2249. assert(thisIndex == 0);
  2250. Node root(parentNodeIndex, _paths[pathIndexes[thisIndex]]);
  2251. _nodes[pathIndexes[thisIndex]] = root;
  2252. parentNodeIndex = int64_t(thisIndex);
  2253. } else {
  2254. if (parentNodeIndex >= int64_t(_nodes.size())) {
  2255. return false;
  2256. }
  2257. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2258. std::cout << "Hierarhy. parent[" << pathIndexes[size_t(parentNodeIndex)]
  2259. << "].add_child = " << pathIndexes[thisIndex] << "\n";
  2260. #endif
  2261. Node node(parentNodeIndex, _paths[pathIndexes[thisIndex]]);
  2262. assert(_nodes[size_t(pathIndexes[thisIndex])].GetParent() == -2);
  2263. _nodes[size_t(pathIndexes[thisIndex])] = node;
  2264. std::string name = _paths[pathIndexes[thisIndex]].local_path_name();
  2265. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2266. std::cout << "childName = " << name << "\n";
  2267. #endif
  2268. _nodes[size_t(pathIndexes[size_t(parentNodeIndex)])].AddChildren(
  2269. name, pathIndexes[thisIndex]);
  2270. }
  2271. hasChild = (jumps[thisIndex] > 0) || (jumps[thisIndex] == -1);
  2272. hasSibling = (jumps[thisIndex] >= 0);
  2273. if (hasChild) {
  2274. if (hasSibling) {
  2275. auto siblingIndex = thisIndex + size_t(jumps[thisIndex]);
  2276. if (!_BuildNodeHierarchy(pathIndexes, elementTokenIndexes, jumps,
  2277. siblingIndex, parentNodeIndex)) {
  2278. return false;
  2279. }
  2280. }
  2281. // Have a child (may have also had a sibling). Reset parent node index
  2282. parentNodeIndex = int64_t(thisIndex);
  2283. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2284. std::cout << "parentNodeIndex = " << parentNodeIndex << "\n";
  2285. #endif
  2286. }
  2287. // If we had only a sibling, we just continue since the parent path is
  2288. // unchanged and the next thing in the reader stream is the sibling's
  2289. // header.
  2290. } while (hasChild || hasSibling);
  2291. return true;
  2292. }
  2293. bool Parser::ReadCompressedPaths(const uint64_t ref_num_paths) {
  2294. std::vector<uint32_t> pathIndexes;
  2295. std::vector<int32_t> elementTokenIndexes;
  2296. std::vector<int32_t> jumps;
  2297. // Read number of encoded paths.
  2298. uint64_t numPaths;
  2299. if (!_sr->read8(&numPaths)) {
  2300. _err += "Failed to read the number of paths.\n";
  2301. return false;
  2302. }
  2303. if (ref_num_paths != numPaths) {
  2304. _err += "Size mismatch of numPaths at `PATHS` section.\n";
  2305. return false;
  2306. }
  2307. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2308. std::cout << "numPaths : " << numPaths << "\n";
  2309. #endif
  2310. pathIndexes.resize(static_cast<size_t>(numPaths));
  2311. elementTokenIndexes.resize(static_cast<size_t>(numPaths));
  2312. jumps.resize(static_cast<size_t>(numPaths));
  2313. // Create temporary space for decompressing.
  2314. std::vector<char> compBuffer(Usd_IntegerCompression::GetCompressedBufferSize(
  2315. static_cast<size_t>(numPaths)));
  2316. std::vector<char> workingSpace(
  2317. Usd_IntegerCompression::GetDecompressionWorkingSpaceSize(
  2318. static_cast<size_t>(numPaths)));
  2319. // pathIndexes.
  2320. {
  2321. uint64_t pathIndexesSize;
  2322. if (!_sr->read8(&pathIndexesSize)) {
  2323. _err += "Failed to read pathIndexesSize.\n";
  2324. return false;
  2325. }
  2326. if (pathIndexesSize !=
  2327. _sr->read(size_t(pathIndexesSize), size_t(pathIndexesSize),
  2328. reinterpret_cast<uint8_t *>(compBuffer.data()))) {
  2329. _err += "Failed to read pathIndexes data.\n";
  2330. return false;
  2331. }
  2332. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2333. std::cout << "comBuffer.size = " << compBuffer.size() << "\n";
  2334. std::cout << "pathIndexesSize = " << pathIndexesSize << "\n";
  2335. #endif
  2336. std::string err;
  2337. Usd_IntegerCompression::DecompressFromBuffer(
  2338. compBuffer.data(), size_t(pathIndexesSize), pathIndexes.data(),
  2339. size_t(numPaths), &err, workingSpace.data());
  2340. if (!err.empty()) {
  2341. _err += "Failed to decode pathIndexes\n" + err;
  2342. return false;
  2343. }
  2344. }
  2345. // elementTokenIndexes.
  2346. {
  2347. uint64_t elementTokenIndexesSize;
  2348. if (!_sr->read8(&elementTokenIndexesSize)) {
  2349. _err += "Failed to read elementTokenIndexesSize.\n";
  2350. return false;
  2351. }
  2352. if (elementTokenIndexesSize !=
  2353. _sr->read(size_t(elementTokenIndexesSize),
  2354. size_t(elementTokenIndexesSize),
  2355. reinterpret_cast<uint8_t *>(compBuffer.data()))) {
  2356. _err += "Failed to read elementTokenIndexes data.\n";
  2357. return false;
  2358. }
  2359. std::string err;
  2360. Usd_IntegerCompression::DecompressFromBuffer(
  2361. compBuffer.data(), size_t(elementTokenIndexesSize),
  2362. elementTokenIndexes.data(), size_t(numPaths), &err,
  2363. workingSpace.data());
  2364. if (!err.empty()) {
  2365. _err += "Failed to decode elementTokenIndexes\n" + err;
  2366. return false;
  2367. }
  2368. }
  2369. // jumps.
  2370. {
  2371. uint64_t jumpsSize;
  2372. if (!_sr->read8(&jumpsSize)) {
  2373. _err += "Failed to read jumpsSize.\n";
  2374. return false;
  2375. }
  2376. if (jumpsSize !=
  2377. _sr->read(size_t(jumpsSize), size_t(jumpsSize),
  2378. reinterpret_cast<uint8_t *>(compBuffer.data()))) {
  2379. _err += "Failed to read jumps data.\n";
  2380. return false;
  2381. }
  2382. std::string err;
  2383. Usd_IntegerCompression::DecompressFromBuffer(
  2384. compBuffer.data(), size_t(jumpsSize), jumps.data(), size_t(numPaths),
  2385. &err, workingSpace.data());
  2386. if (!err.empty()) {
  2387. _err += "Failed to decode jumps\n" + err;
  2388. return false;
  2389. }
  2390. }
  2391. _paths.resize(static_cast<size_t>(numPaths));
  2392. _nodes.resize(static_cast<size_t>(numPaths));
  2393. // Now build the paths.
  2394. if (!_BuildDecompressedPathsImpl(pathIndexes, elementTokenIndexes, jumps,
  2395. /* curIndex */ 0, Path())) {
  2396. return false;
  2397. }
  2398. // Now build node hierarchy.
  2399. if (!_BuildNodeHierarchy(pathIndexes, elementTokenIndexes, jumps,
  2400. /* curIndex */ 0, /* parent node index */ -1)) {
  2401. return false;
  2402. }
  2403. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2404. for (size_t i = 0; i < pathIndexes.size(); i++) {
  2405. std::cout << "pathIndexes[" << i << "] = " << pathIndexes[i] << "\n";
  2406. }
  2407. for (auto item : elementTokenIndexes) {
  2408. std::cout << "elementTokenIndexes " << item << "\n";
  2409. }
  2410. for (auto item : jumps) {
  2411. std::cout << "jumps " << item << "\n";
  2412. }
  2413. #endif
  2414. return true;
  2415. }
  2416. bool Parser::ReadSection(Section *s) {
  2417. size_t name_len = kSectionNameMaxLength + 1;
  2418. if (name_len !=
  2419. _sr->read(name_len, name_len, reinterpret_cast<uint8_t *>(s->name))) {
  2420. _err += "Failed to read section.name.\n";
  2421. return false;
  2422. }
  2423. if (!_sr->read8(&s->start)) {
  2424. _err += "Failed to read section.start.\n";
  2425. return false;
  2426. }
  2427. if (!_sr->read8(&s->size)) {
  2428. _err += "Failed to read section.size.\n";
  2429. return false;
  2430. }
  2431. return true;
  2432. }
  2433. bool Parser::ReadTokens() {
  2434. if ((_tokens_index < 0) || (_tokens_index >= int64_t(_toc.sections.size()))) {
  2435. _err += "Invalid index for `TOKENS` section.\n";
  2436. return false;
  2437. }
  2438. if ((_version[0] == 0) && (_version[1] < 4)) {
  2439. _err += "Version must be 0.4.0 or later, but got " +
  2440. std::to_string(_version[0]) + "." + std::to_string(_version[1]) +
  2441. "." + std::to_string(_version[2]) + "\n";
  2442. return false;
  2443. }
  2444. const Section &sec = _toc.sections[size_t(_tokens_index)];
  2445. if (!_sr->seek_set(uint64_t(sec.start))) {
  2446. _err += "Failed to move to `TOKENS` section.\n";
  2447. return false;
  2448. }
  2449. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2450. std::cout << "sec.start = " << sec.start << "\n";
  2451. #endif
  2452. // # of tokens.
  2453. uint64_t n;
  2454. if (!_sr->read8(&n)) {
  2455. _err += "Failed to read # of tokens at `TOKENS` section.\n";
  2456. return false;
  2457. }
  2458. // Tokens are lz4 compressed starting from version 0.4.0
  2459. // Compressed token data.
  2460. uint64_t uncompressedSize;
  2461. if (!_sr->read8(&uncompressedSize)) {
  2462. _err += "Failed to read uncompressedSize at `TOKENS` section.\n";
  2463. return false;
  2464. }
  2465. uint64_t compressedSize;
  2466. if (!_sr->read8(&compressedSize)) {
  2467. _err += "Failed to read compressedSize at `TOKENS` section.\n";
  2468. return false;
  2469. }
  2470. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2471. std::cout << "# of tokens = " << n
  2472. << ", uncompressedSize = " << uncompressedSize
  2473. << ", compressedSize = " << compressedSize << "\n";
  2474. #endif
  2475. std::vector<char> chars(static_cast<size_t>(uncompressedSize));
  2476. std::vector<char> compressed(static_cast<size_t>(compressedSize));
  2477. if (compressedSize !=
  2478. _sr->read(size_t(compressedSize), size_t(compressedSize),
  2479. reinterpret_cast<uint8_t *>(compressed.data()))) {
  2480. _err += "Failed to read compressed data at `TOKENS` section.\n";
  2481. return false;
  2482. }
  2483. if (uncompressedSize !=
  2484. LZ4Compression::DecompressFromBuffer(compressed.data(), chars.data(),
  2485. size_t(compressedSize),
  2486. size_t(uncompressedSize), &_err)) {
  2487. _err += "Failed to decompress data of Tokens.\n";
  2488. return false;
  2489. }
  2490. // Split null terminated string into _tokens.
  2491. const char *ps = chars.data();
  2492. const char *pe = chars.data() + chars.size();
  2493. const char *p = ps;
  2494. size_t n_remain = size_t(n);
  2495. auto my_strnlen = [](const char *s, const size_t max_length) -> size_t {
  2496. if (!s) return 0;
  2497. size_t i = 0;
  2498. for (; i < max_length; i++) {
  2499. if (s[i] == '\0') {
  2500. return i;
  2501. }
  2502. }
  2503. // null character not found.
  2504. return i;
  2505. };
  2506. // TODO(syoyo): Check if input string has exactly `n` tokens(`n` null
  2507. // characters)
  2508. for (size_t i = 0; i < n; i++) {
  2509. size_t len = my_strnlen(p, n_remain);
  2510. if ((p + len) > pe) {
  2511. _err += "Invalid token string array.\n";
  2512. return false;
  2513. }
  2514. std::string token;
  2515. if (len > 0) {
  2516. token = std::string(p, len);
  2517. }
  2518. p += len + 1; // +1 = '\0'
  2519. n_remain = size_t(pe - p);
  2520. assert(p <= pe);
  2521. if (p > pe) {
  2522. _err += "Invalid token string array.\n";
  2523. return false;
  2524. }
  2525. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2526. std::cout << "token[" << i << "] = " << token << "\n";
  2527. #endif
  2528. _tokens.push_back(token);
  2529. }
  2530. return true;
  2531. }
  2532. bool Parser::ReadStrings() {
  2533. if ((_strings_index < 0) ||
  2534. (_strings_index >= int64_t(_toc.sections.size()))) {
  2535. _err += "Invalid index for `STRINGS` section.\n";
  2536. return false;
  2537. }
  2538. const Section &s = _toc.sections[size_t(_strings_index)];
  2539. if (!_sr->seek_set(uint64_t(s.start))) {
  2540. _err += "Failed to move to `STRINGS` section.\n";
  2541. return false;
  2542. }
  2543. if (!ReadIndices(_sr, &_string_indices)) {
  2544. _err += "Failed to read StringIndex array.\n";
  2545. return false;
  2546. }
  2547. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2548. for (size_t i = 0; i < _string_indices.size(); i++) {
  2549. std::cout << "StringIndex[" << i << "] = " << _string_indices[i].value
  2550. << "\n";
  2551. }
  2552. #endif
  2553. return true;
  2554. }
  2555. bool Parser::ReadFields() {
  2556. if ((_fields_index < 0) || (_fields_index >= int64_t(_toc.sections.size()))) {
  2557. _err += "Invalid index for `FIELDS` section.\n";
  2558. return false;
  2559. }
  2560. if ((_version[0] == 0) && (_version[1] < 4)) {
  2561. _err += "Version must be 0.4.0 or later, but got " +
  2562. std::to_string(_version[0]) + "." + std::to_string(_version[1]) +
  2563. "." + std::to_string(_version[2]) + "\n";
  2564. return false;
  2565. }
  2566. const Section &s = _toc.sections[size_t(_fields_index)];
  2567. if (!_sr->seek_set(uint64_t(s.start))) {
  2568. _err += "Failed to move to `FIELDS` section.\n";
  2569. return false;
  2570. }
  2571. uint64_t num_fields;
  2572. if (!_sr->read8(&num_fields)) {
  2573. _err += "Failed to read # of fields at `FIELDS` section.\n";
  2574. return false;
  2575. }
  2576. _fields.resize(static_cast<size_t>(num_fields));
  2577. // indices
  2578. {
  2579. std::vector<char> comp_buffer(
  2580. Usd_IntegerCompression::GetCompressedBufferSize(
  2581. static_cast<size_t>(num_fields)));
  2582. // temp buffer for decompress
  2583. std::vector<uint32_t> tmp;
  2584. tmp.resize(static_cast<size_t>(num_fields));
  2585. uint64_t fields_size;
  2586. if (!_sr->read8(&fields_size)) {
  2587. _err += "Failed to read field legnth at `FIELDS` section.\n";
  2588. return false;
  2589. }
  2590. if (fields_size !=
  2591. _sr->read(size_t(fields_size), size_t(fields_size),
  2592. reinterpret_cast<uint8_t *>(comp_buffer.data()))) {
  2593. _err += "Failed to read field data at `FIELDS` section.\n";
  2594. return false;
  2595. }
  2596. std::string err;
  2597. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2598. std::cout << "fields_size = " << fields_size
  2599. << ", tmp.size = " << tmp.size()
  2600. << ", num_fields = " << num_fields << "\n";
  2601. #endif
  2602. Usd_IntegerCompression::DecompressFromBuffer(
  2603. comp_buffer.data(), size_t(fields_size), tmp.data(), size_t(num_fields),
  2604. &err);
  2605. if (!err.empty()) {
  2606. _err += err;
  2607. return false;
  2608. }
  2609. for (size_t i = 0; i < num_fields; i++) {
  2610. _fields[i].token_index.value = tmp[i];
  2611. }
  2612. }
  2613. // Value reps
  2614. {
  2615. uint64_t reps_size;
  2616. if (!_sr->read8(&reps_size)) {
  2617. _err += "Failed to read reps legnth at `FIELDS` section.\n";
  2618. return false;
  2619. }
  2620. std::vector<char> comp_buffer(static_cast<size_t>(reps_size));
  2621. if (reps_size !=
  2622. _sr->read(size_t(reps_size), size_t(reps_size),
  2623. reinterpret_cast<uint8_t *>(comp_buffer.data()))) {
  2624. _err += "Failed to read reps data at `FIELDS` section.\n";
  2625. return false;
  2626. }
  2627. // reps datasize = LZ4 compressed. uncompressed size = num_fields * 8 bytes
  2628. std::vector<uint64_t> reps_data;
  2629. reps_data.resize(static_cast<size_t>(num_fields));
  2630. size_t uncompressed_size = size_t(num_fields) * sizeof(uint64_t);
  2631. if (uncompressed_size != LZ4Compression::DecompressFromBuffer(
  2632. comp_buffer.data(),
  2633. reinterpret_cast<char *>(reps_data.data()),
  2634. size_t(reps_size), uncompressed_size, &_err)) {
  2635. return false;
  2636. }
  2637. for (size_t i = 0; i < num_fields; i++) {
  2638. _fields[i].value_rep = ValueRep(reps_data[i]);
  2639. }
  2640. }
  2641. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2642. std::cout << "num_fields = " << num_fields << "\n";
  2643. for (size_t i = 0; i < num_fields; i++) {
  2644. std::cout << "field[" << i
  2645. << "] name = " << GetToken(_fields[i].token_index)
  2646. << ", value = " << _fields[i].value_rep.GetStringRepr() << "\n";
  2647. }
  2648. #endif
  2649. return true;
  2650. }
  2651. bool Parser::ReadFieldSets() {
  2652. if ((_fieldsets_index < 0) ||
  2653. (_fieldsets_index >= int64_t(_toc.sections.size()))) {
  2654. _err += "Invalid index for `FIELDSETS` section.\n";
  2655. return false;
  2656. }
  2657. if ((_version[0] == 0) && (_version[1] < 4)) {
  2658. _err += "Version must be 0.4.0 or later, but got " +
  2659. std::to_string(_version[0]) + "." + std::to_string(_version[1]) +
  2660. "." + std::to_string(_version[2]) + "\n";
  2661. return false;
  2662. }
  2663. const Section &s = _toc.sections[size_t(_fieldsets_index)];
  2664. if (!_sr->seek_set(uint64_t(s.start))) {
  2665. _err += "Failed to move to `FIELDSETS` section.\n";
  2666. return false;
  2667. }
  2668. uint64_t num_fieldsets;
  2669. if (!_sr->read8(&num_fieldsets)) {
  2670. _err += "Failed to read # of fieldsets at `FIELDSETS` section.\n";
  2671. return false;
  2672. }
  2673. _fieldset_indices.resize(static_cast<size_t>(num_fieldsets));
  2674. // Create temporary space for decompressing.
  2675. std::vector<char> comp_buffer(Usd_IntegerCompression::GetCompressedBufferSize(
  2676. static_cast<size_t>(num_fieldsets)));
  2677. std::vector<uint32_t> tmp(static_cast<size_t>(num_fieldsets));
  2678. std::vector<char> working_space(
  2679. Usd_IntegerCompression::GetDecompressionWorkingSpaceSize(
  2680. static_cast<size_t>(num_fieldsets)));
  2681. uint64_t fsets_size;
  2682. if (!_sr->read8(&fsets_size)) {
  2683. _err += "Failed to read fieldsets size at `FIELDSETS` section.\n";
  2684. return false;
  2685. }
  2686. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2687. std::cout << "num_fieldsets = " << num_fieldsets
  2688. << ", fsets_size = " << fsets_size
  2689. << ", comp_buffer.size = " << comp_buffer.size() << "\n";
  2690. #endif
  2691. assert(fsets_size < comp_buffer.size());
  2692. if (fsets_size !=
  2693. _sr->read(size_t(fsets_size), size_t(fsets_size),
  2694. reinterpret_cast<uint8_t *>(comp_buffer.data()))) {
  2695. _err += "Failed to read fieldsets data at `FIELDSETS` section.\n";
  2696. return false;
  2697. }
  2698. std::string err;
  2699. Usd_IntegerCompression::DecompressFromBuffer(
  2700. comp_buffer.data(), size_t(fsets_size), tmp.data(), size_t(num_fieldsets),
  2701. &err, working_space.data());
  2702. if (!err.empty()) {
  2703. _err += err;
  2704. return false;
  2705. }
  2706. for (size_t i = 0; i != num_fieldsets; ++i) {
  2707. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2708. std::cout << "fieldset_index[" << i << "] = " << tmp[i] << "\n";
  2709. #endif
  2710. _fieldset_indices[i].value = tmp[i];
  2711. }
  2712. return true;
  2713. }
  2714. bool Parser::_BuildLiveFieldSets() {
  2715. for (auto fsBegin = _fieldset_indices.begin(),
  2716. fsEnd = std::find(fsBegin, _fieldset_indices.end(), Index());
  2717. fsBegin != _fieldset_indices.end(); fsBegin = fsEnd + 1,
  2718. fsEnd = std::find(fsBegin, _fieldset_indices.end(), Index())) {
  2719. auto &pairs =
  2720. _live_fieldsets[Index(uint32_t(fsBegin - _fieldset_indices.begin()))];
  2721. pairs.resize(size_t(fsEnd - fsBegin));
  2722. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2723. std::cout << "range size = " << (fsEnd - fsBegin) << "\n";
  2724. #endif
  2725. // TODO(syoyo): Parallelize.
  2726. for (size_t i = 0; fsBegin != fsEnd; ++fsBegin, ++i) {
  2727. assert((fsBegin->value >= 0) && (fsBegin->value < _fields.size()));
  2728. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2729. std::cout << "fieldIndex = " << (fsBegin->value) << "\n";
  2730. #endif
  2731. auto const &field = _fields[fsBegin->value];
  2732. pairs[i].first = GetToken(field.token_index);
  2733. if (!_UnpackValueRep(field.value_rep, &pairs[i].second)) {
  2734. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2735. std::cerr << "_BuildLiveFieldSets: Failed to unpack ValueRep : "
  2736. << field.value_rep.GetStringRepr() << "\n";
  2737. #endif
  2738. return false;
  2739. }
  2740. }
  2741. }
  2742. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2743. std::cout << "# of live fieldsets = " << _live_fieldsets.size() << "\n";
  2744. #endif
  2745. size_t sum = 0;
  2746. for (const auto &item : _live_fieldsets) {
  2747. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2748. std::cout << "livefieldsets[" << item.first.value
  2749. << "].count = " << item.second.size() << "\n";
  2750. #endif
  2751. sum += item.second.size();
  2752. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2753. for (size_t i = 0; i < item.second.size(); i++) {
  2754. std::cout << " [" << i << "] name = " << item.second[i].first << "\n";
  2755. }
  2756. #endif
  2757. }
  2758. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2759. std::cout << "Total fields used = " << sum << "\n";
  2760. #endif
  2761. return true;
  2762. }
  2763. bool Parser::_ParseAttribute(const FieldValuePairVector &fvs, PrimAttrib *attr,
  2764. const std::string &prop_name) {
  2765. bool success = false;
  2766. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2767. std::cout << "fvs.size = " << fvs.size() << "\n";
  2768. #endif
  2769. bool has_connection{false};
  2770. Variability variability{VariabilityVarying};
  2771. bool facevarying{false};
  2772. //
  2773. // Parse properties
  2774. //
  2775. for (const auto &fv : fvs) {
  2776. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2777. std::cout << "=== fvs.first " << fv.first
  2778. << ", second: " << fv.second.GetTypeName() << "\n";
  2779. #endif
  2780. if ((fv.first == "typeName") && (fv.second.GetTypeName() == "Token")) {
  2781. attr->type_name = fv.second.GetToken();
  2782. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2783. std::cout << "aaa: typeName: " << attr->type_name << "\n";
  2784. #endif
  2785. } else if (fv.first == "connectionPaths") {
  2786. // e.g. connection to texture file.
  2787. const ListOp<Path> paths = fv.second.GetPathListOp();
  2788. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2789. paths.Print();
  2790. #endif
  2791. // Currently we only support single explicit path.
  2792. if ((paths.GetExplicitItems().size() == 1)) {
  2793. const Path &path = paths.GetExplicitItems()[0];
  2794. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2795. std::cout << "full path: " << path.full_path_name() << "\n";
  2796. std::cout << "local path: " << path.local_path_name() << "\n";
  2797. #endif
  2798. attr->path = path;
  2799. attr->basic_type = "path";
  2800. has_connection = true;
  2801. } else {
  2802. return false;
  2803. }
  2804. } else if ((fv.first == "variablity") &&
  2805. (fv.second.GetTypeName() == "Variability")) {
  2806. variability = fv.second.GetVariability();
  2807. } else if ((fv.first == "interpolation") &&
  2808. (fv.second.GetTypeName() == "Token")) {
  2809. if (fv.second.GetToken() == "faceVarying") {
  2810. facevarying = true;
  2811. }
  2812. }
  2813. }
  2814. attr->facevarying = facevarying;
  2815. attr->variability = variability;
  2816. //
  2817. // Decode value(stored in "default" field)
  2818. //
  2819. for (const auto &fv : fvs) {
  2820. if (fv.first == "default") {
  2821. attr->name = prop_name;
  2822. attr->basic_type = std::string();
  2823. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2824. std::cout << "fv.second.GetTypeName = " << fv.second.GetTypeName()
  2825. << "\n";
  2826. #endif
  2827. if (fv.second.GetTypeName() == "Float") {
  2828. attr->floatVal = fv.second.GetFloat();
  2829. attr->basic_type = "float";
  2830. success = true;
  2831. } else if (fv.second.GetTypeName() == "Bool") {
  2832. if (!fv.second.GetBool(&attr->boolVal)) {
  2833. _err += "Failed to decode Int data";
  2834. return false;
  2835. }
  2836. attr->basic_type = "bool";
  2837. success = true;
  2838. } else if (fv.second.GetTypeName() == "Int") {
  2839. if (!fv.second.GetInt(&attr->intVal)) {
  2840. _err += "Failed to decode Int data";
  2841. return false;
  2842. }
  2843. attr->basic_type = "int";
  2844. success = true;
  2845. } else if (fv.second.GetTypeName() == "Vec3f") {
  2846. attr->buffer.Set(BufferData::BUFFER_DATA_TYPE_FLOAT, 3,
  2847. /* stride */ sizeof(float), fv.second.GetData());
  2848. // attr->variability = variability;
  2849. // attr->facevarying = facevarying;
  2850. success = true;
  2851. } else if (fv.second.GetTypeName() == "FloatArray") {
  2852. attr->buffer.Set(BufferData::BUFFER_DATA_TYPE_FLOAT, 1,
  2853. /* stride */ sizeof(float), fv.second.GetData());
  2854. attr->variability = variability;
  2855. attr->facevarying = facevarying;
  2856. success = true;
  2857. } else if (fv.second.GetTypeName() == "Vec2fArray") {
  2858. attr->buffer.Set(BufferData::BUFFER_DATA_TYPE_FLOAT, 2,
  2859. /* stride */ sizeof(float) * 2, fv.second.GetData());
  2860. attr->variability = variability;
  2861. attr->facevarying = facevarying;
  2862. success = true;
  2863. } else if (fv.second.GetTypeName() == "Vec3fArray") {
  2864. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2865. std::cout << "fv.second.data.size = " << fv.second.GetData().size()
  2866. << "\n";
  2867. #endif
  2868. attr->buffer.Set(BufferData::BUFFER_DATA_TYPE_FLOAT, 3,
  2869. /* stride */ sizeof(float) * 3, fv.second.GetData());
  2870. attr->variability = variability;
  2871. attr->facevarying = facevarying;
  2872. success = true;
  2873. } else if (fv.second.GetTypeName() == "Vec4fArray") {
  2874. attr->buffer.Set(BufferData::BUFFER_DATA_TYPE_FLOAT, 4,
  2875. /* stride */ sizeof(float) * 4, fv.second.GetData());
  2876. attr->variability = variability;
  2877. attr->facevarying = facevarying;
  2878. success = true;
  2879. } else if (fv.second.GetTypeName() == "IntArray") {
  2880. attr->buffer.Set(BufferData::BUFFER_DATA_TYPE_INT, 1,
  2881. /* stride */ sizeof(int32_t), fv.second.GetData());
  2882. attr->variability = variability;
  2883. attr->facevarying = facevarying;
  2884. success = true;
  2885. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2886. std::cout << "IntArray"
  2887. << "\n";
  2888. const int32_t *ptr =
  2889. reinterpret_cast<const int32_t *>(attr->buffer.data.data());
  2890. for (size_t i = 0; i < attr->buffer.GetNumElements(); i++) {
  2891. std::cout << "[" << i << "] = " << ptr[i] << "\n";
  2892. }
  2893. #endif
  2894. } else if (fv.second.GetTypeName() == "Token") {
  2895. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2896. std::cout << "bbb: token: " << fv.second.GetToken() << "\n";
  2897. #endif
  2898. attr->stringVal = fv.second.GetToken();
  2899. attr->basic_type = "string";
  2900. // attr->variability = variability;
  2901. // attr->facevarying = facevarying;
  2902. success = true;
  2903. }
  2904. }
  2905. }
  2906. if (!success && has_connection) {
  2907. // Attribute has a connection(has a path and no `default` field)
  2908. success = true;
  2909. }
  2910. return success;
  2911. }
  2912. bool Parser::_ReconstructXform(
  2913. const Node &node, const FieldValuePairVector &fields,
  2914. const std::unordered_map<uint32_t, uint32_t> &path_index_to_spec_index_map,
  2915. Xform *xform) {
  2916. for (const auto &fv : fields) {
  2917. if (fv.first == "properties") {
  2918. if (fv.second.GetTypeName() != "TokenArray") {
  2919. _err += "`properties` attribute must be TokenArray type\n";
  2920. return false;
  2921. }
  2922. }
  2923. }
  2924. //
  2925. // NOTE: Currently we assume one deeper node has Xform's attribute
  2926. //
  2927. for (size_t i = 0; i < node.GetChildren().size(); i++) {
  2928. int child_index = int(node.GetChildren()[i]);
  2929. if ((child_index < 0) || (child_index >= int(_nodes.size()))) {
  2930. _err += "Invalid child node id: " + std::to_string(child_index) +
  2931. ". Must be in range [0, " + std::to_string(_nodes.size()) + ")\n";
  2932. return false;
  2933. }
  2934. if (!path_index_to_spec_index_map.count(uint32_t(child_index))) {
  2935. // No specifier assigned to this child node.
  2936. // Should we report an error?
  2937. continue;
  2938. }
  2939. uint32_t spec_index =
  2940. path_index_to_spec_index_map.at(uint32_t(child_index));
  2941. if (spec_index >= _specs.size()) {
  2942. _err += "Invalid specifier id: " + std::to_string(spec_index) +
  2943. ". Must be in range [0, " + std::to_string(_specs.size()) + ")\n";
  2944. return false;
  2945. }
  2946. const Spec &spec = _specs[spec_index];
  2947. Path path = GetPath(spec.path_index);
  2948. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2949. std::cout << "Path prim part: " << path.GetPrimPart()
  2950. << ", prop part: " << path.GetPropPart()
  2951. << ", spec_index = " << spec_index << "\n";
  2952. #endif
  2953. if (!_live_fieldsets.count(spec.fieldset_index)) {
  2954. _err += "FieldSet id: " + std::to_string(spec.fieldset_index.value) +
  2955. " must exist in live fieldsets.\n";
  2956. return false;
  2957. }
  2958. const FieldValuePairVector &child_fields =
  2959. _live_fieldsets.at(spec.fieldset_index);
  2960. {
  2961. std::string prop_name = path.GetPropPart();
  2962. PrimAttrib attr;
  2963. bool ret = _ParseAttribute(child_fields, &attr, prop_name);
  2964. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  2965. std::cout << "Xform: prop: " << prop_name << ", ret = " << ret << "\n";
  2966. #endif
  2967. if (ret) {
  2968. // TODO(syoyo): Implement
  2969. }
  2970. }
  2971. }
  2972. return true;
  2973. }
  2974. bool Parser::_ReconstructGeomMesh(
  2975. const Node &node, const FieldValuePairVector &fields,
  2976. const std::unordered_map<uint32_t, uint32_t> &path_index_to_spec_index_map,
  2977. GeomMesh *mesh) {
  2978. bool has_position{false};
  2979. for (const auto &fv : fields) {
  2980. if (fv.first == "properties") {
  2981. if (fv.second.GetTypeName() != "TokenArray") {
  2982. _err += "`properties` attribute must be TokenArray type\n";
  2983. return false;
  2984. }
  2985. assert(fv.second.IsArray());
  2986. for (size_t i = 0; i < fv.second.GetStringArray().size(); i++) {
  2987. if (fv.second.GetStringArray()[i] == "points") {
  2988. has_position = true;
  2989. }
  2990. }
  2991. }
  2992. }
  2993. // Disable has_position check for a while, since Mesh may not have "points",
  2994. // but "position"
  2995. // if (!has_position) {
  2996. // _err += "No `position` field exist for Mesh node: " + node.GetLocalPath()
  2997. // +
  2998. // ".\n";
  2999. // return false;
  3000. //}
  3001. //
  3002. // NOTE: Currently we assume one deeper node has GeomMesh's attribute
  3003. //
  3004. for (size_t i = 0; i < node.GetChildren().size(); i++) {
  3005. int child_index = int(node.GetChildren()[i]);
  3006. if ((child_index < 0) || (child_index >= int(_nodes.size()))) {
  3007. _err += "Invalid child node id: " + std::to_string(child_index) +
  3008. ". Must be in range [0, " + std::to_string(_nodes.size()) + ")\n";
  3009. return false;
  3010. }
  3011. // const Node &child_node = _nodes[size_t(child_index)];
  3012. if (!path_index_to_spec_index_map.count(uint32_t(child_index))) {
  3013. // No specifier assigned to this child node.
  3014. // Should we report an error?
  3015. #if 0
  3016. _err += "GeomMesh: No specifier found for node id: " + std::to_string(child_index) +
  3017. "\n";
  3018. return false;
  3019. #else
  3020. continue;
  3021. #endif
  3022. }
  3023. uint32_t spec_index =
  3024. path_index_to_spec_index_map.at(uint32_t(child_index));
  3025. if (spec_index >= _specs.size()) {
  3026. _err += "Invalid specifier id: " + std::to_string(spec_index) +
  3027. ". Must be in range [0, " + std::to_string(_specs.size()) + ")\n";
  3028. return false;
  3029. }
  3030. const Spec &spec = _specs[spec_index];
  3031. Path path = GetPath(spec.path_index);
  3032. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3033. std::cout << "Path prim part: " << path.GetPrimPart()
  3034. << ", prop part: " << path.GetPropPart()
  3035. << ", spec_index = " << spec_index << "\n";
  3036. #endif
  3037. if (!_live_fieldsets.count(spec.fieldset_index)) {
  3038. _err += "FieldSet id: " + std::to_string(spec.fieldset_index.value) +
  3039. " must exist in live fieldsets.\n";
  3040. return false;
  3041. }
  3042. const FieldValuePairVector &child_fields =
  3043. _live_fieldsets.at(spec.fieldset_index);
  3044. {
  3045. std::string prop_name = path.GetPropPart();
  3046. PrimAttrib attr;
  3047. bool ret = _ParseAttribute(child_fields, &attr, prop_name);
  3048. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3049. std::cout << "prop: " << prop_name << ", ret = " << ret << "\n";
  3050. #endif
  3051. if (ret) {
  3052. // TODO(syoyo): Support more prop names
  3053. if (prop_name == "points") {
  3054. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3055. std::cout << "got point\n";
  3056. #endif
  3057. if ((attr.buffer.GetDataType() ==
  3058. BufferData::BUFFER_DATA_TYPE_FLOAT) &&
  3059. (attr.buffer.GetNumCoords() == 3)) {
  3060. mesh->points = std::move(attr);
  3061. }
  3062. } else if (prop_name == "doubleSided") {
  3063. if (attr.basic_type == "bool") {
  3064. mesh->doubleSided = attr.boolVal;
  3065. }
  3066. } else if (prop_name == "extent") {
  3067. // vec3f[2]
  3068. if ((attr.buffer.GetDataType() ==
  3069. BufferData::BUFFER_DATA_TYPE_FLOAT) &&
  3070. (attr.buffer.GetNumElements() == 2) &&
  3071. (attr.buffer.GetNumCoords() == 3)) {
  3072. std::vector<float> buf = attr.buffer.GetAsVec3fArray();
  3073. mesh->extent.lower[0] = buf[0];
  3074. mesh->extent.lower[1] = buf[1];
  3075. mesh->extent.lower[2] = buf[2];
  3076. mesh->extent.upper[0] = buf[3];
  3077. mesh->extent.upper[1] = buf[4];
  3078. mesh->extent.upper[2] = buf[5];
  3079. }
  3080. } else if (prop_name == "normals") {
  3081. if ((attr.buffer.GetDataType() ==
  3082. BufferData::BUFFER_DATA_TYPE_FLOAT) &&
  3083. (attr.buffer.GetNumCoords() == 3)) {
  3084. mesh->normals = std::move(attr);
  3085. }
  3086. } else if ((prop_name == "primvars:UVMap") &&
  3087. (attr.type_name == "texCoord2f[]")) {
  3088. // Explicit UV coord attribute.
  3089. // TODO(syoyo): Write PrimVar parser
  3090. // Currently we only support vec2f for uv coords.
  3091. if ((attr.buffer.GetDataType() ==
  3092. BufferData::BUFFER_DATA_TYPE_FLOAT) &&
  3093. (attr.buffer.GetNumCoords() == 2)) {
  3094. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3095. std::cout << "got explicit UVCoords!\n";
  3096. #endif
  3097. mesh->st.buffer = attr.buffer;
  3098. mesh->st.variability = attr.variability;
  3099. }
  3100. } else if (prop_name == "faceVertexCounts") {
  3101. // Path prim part: /Suzanne/Suzanne, prop part: faceVertexCounts
  3102. if ((attr.buffer.GetDataType() == BufferData::BUFFER_DATA_TYPE_INT) &&
  3103. (attr.buffer.GetNumCoords() == 1)) {
  3104. mesh->faceVertexCounts = attr.buffer.GetAsInt32Array();
  3105. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3106. // aaa: typeName: int[]
  3107. std::cout << "got faceVertexCounts. num = "
  3108. << attr.buffer.GetNumElements() << "\n";
  3109. std::cout << " num = " << mesh->faceVertexCounts.size() << "\n";
  3110. #endif
  3111. }
  3112. } else if (prop_name == "faceVertexIndices") {
  3113. if ((attr.buffer.GetDataType() == BufferData::BUFFER_DATA_TYPE_INT) &&
  3114. (attr.buffer.GetNumCoords() == 1)) {
  3115. mesh->faceVertexIndices = attr.buffer.GetAsInt32Array();
  3116. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3117. // aaa: typeName: int[]
  3118. std::cout << "got faceVertexIndices\n";
  3119. std::cout << " num = " << mesh->faceVertexIndices.size() << "\n";
  3120. #endif
  3121. }
  3122. } else if (prop_name == "holeIndices") {
  3123. if ((attr.buffer.GetDataType() == BufferData::BUFFER_DATA_TYPE_INT) &&
  3124. (attr.buffer.GetNumCoords() == 1)) {
  3125. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3126. // aaa: typeName: int[]
  3127. std::cout << "got holeIdicies\n";
  3128. #endif
  3129. mesh->holeIndices = attr.buffer.GetAsInt32Array();
  3130. }
  3131. } else if (prop_name == "cornerIndices") {
  3132. if ((attr.buffer.GetDataType() == BufferData::BUFFER_DATA_TYPE_INT) &&
  3133. (attr.buffer.GetNumCoords() == 1)) {
  3134. mesh->cornerIndices = attr.buffer.GetAsInt32Array();
  3135. }
  3136. } else if (prop_name == "cornerSharpnesses") {
  3137. if ((attr.buffer.GetDataType() ==
  3138. BufferData::BUFFER_DATA_TYPE_FLOAT) &&
  3139. (attr.buffer.GetNumCoords() == 1)) {
  3140. mesh->cornerSharpnesses = attr.buffer.GetAsFloatArray();
  3141. }
  3142. } else if (prop_name == "creaseIndices") {
  3143. if ((attr.buffer.GetDataType() == BufferData::BUFFER_DATA_TYPE_INT) &&
  3144. (attr.buffer.GetNumCoords() == 1)) {
  3145. mesh->creaseIndices = attr.buffer.GetAsInt32Array();
  3146. }
  3147. } else if (prop_name == "creaseLengths") {
  3148. if ((attr.buffer.GetDataType() == BufferData::BUFFER_DATA_TYPE_INT) &&
  3149. (attr.buffer.GetNumCoords() == 1)) {
  3150. mesh->creaseLengths = attr.buffer.GetAsInt32Array();
  3151. }
  3152. } else if (prop_name == "creaseSharpnesses") {
  3153. if ((attr.buffer.GetDataType() ==
  3154. BufferData::BUFFER_DATA_TYPE_FLOAT) &&
  3155. (attr.buffer.GetNumCoords() == 1)) {
  3156. mesh->creaseSharpnesses = attr.buffer.GetAsFloatArray();
  3157. }
  3158. } else if (prop_name == "subdivisionScheme") {
  3159. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3160. std::cout << "subdivisionScheme:" << attr.stringVal << "\n";
  3161. #endif
  3162. if (attr.stringVal.size()) {
  3163. if ((attr.stringVal.compare("none") == 0)) {
  3164. mesh->subdivisionScheme = SubdivisionSchemeNone;
  3165. } else if (attr.stringVal.compare("catmullClark") == 0) {
  3166. mesh->subdivisionScheme = SubdivisionSchemeCatmullClark;
  3167. } else if (attr.stringVal.compare("bilinear") == 0) {
  3168. mesh->subdivisionScheme = SubdivisionSchemeBilinear;
  3169. } else if (attr.stringVal.compare("loop") == 0) {
  3170. mesh->subdivisionScheme = SubdivisionSchemeLoop;
  3171. } else {
  3172. _err += "Unknown subdivision scheme: " + attr.stringVal + "\n";
  3173. return false;
  3174. }
  3175. }
  3176. } else {
  3177. // Assume Primvar.
  3178. if (mesh->attribs.count(prop_name)) {
  3179. _err += "Duplicated property name found: " + prop_name + "\n";
  3180. return false;
  3181. }
  3182. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3183. std::cout << "add [" << prop_name << "] to generic attrs\n";
  3184. #endif
  3185. mesh->attribs[prop_name] = std::move(attr);
  3186. }
  3187. }
  3188. }
  3189. }
  3190. return true;
  3191. }
  3192. bool Parser::_ReconstructMaterial(
  3193. const Node &node, const FieldValuePairVector &fields,
  3194. const std::unordered_map<uint32_t, uint32_t> &path_index_to_spec_index_map,
  3195. Material *material) {
  3196. (void)material;
  3197. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3198. std::cout << "Parse mateiral\n";
  3199. #endif
  3200. for (const auto &fv : fields) {
  3201. if (fv.first == "properties") {
  3202. if (fv.second.GetTypeName() != "TokenArray") {
  3203. _err += "`properties` attribute must be TokenArray type\n";
  3204. return false;
  3205. }
  3206. assert(fv.second.IsArray());
  3207. for (size_t i = 0; i < fv.second.GetStringArray().size(); i++) {
  3208. }
  3209. }
  3210. }
  3211. //
  3212. // NOTE: Currently we assume one deeper node has Material's attribute
  3213. //
  3214. for (size_t i = 0; i < node.GetChildren().size(); i++) {
  3215. int child_index = int(node.GetChildren()[i]);
  3216. if ((child_index < 0) || (child_index >= int(_nodes.size()))) {
  3217. _err += "Invalid child node id: " + std::to_string(child_index) +
  3218. ". Must be in range [0, " + std::to_string(_nodes.size()) + ")\n";
  3219. return false;
  3220. }
  3221. // const Node &child_node = _nodes[size_t(child_index)];
  3222. if (!path_index_to_spec_index_map.count(uint32_t(child_index))) {
  3223. // No specifier assigned to this child node.
  3224. #if 0
  3225. _err += "Material: No specifier found for node id: " + std::to_string(child_index) +
  3226. "\n";
  3227. return false;
  3228. #else
  3229. continue;
  3230. #endif
  3231. }
  3232. uint32_t spec_index =
  3233. path_index_to_spec_index_map.at(uint32_t(child_index));
  3234. if (spec_index >= _specs.size()) {
  3235. _err += "Invalid specifier id: " + std::to_string(spec_index) +
  3236. ". Must be in range [0, " + std::to_string(_specs.size()) + ")\n";
  3237. return false;
  3238. }
  3239. const Spec &spec = _specs[spec_index];
  3240. Path path = GetPath(spec.path_index);
  3241. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3242. std::cout << "Path prim part: " << path.GetPrimPart()
  3243. << ", prop part: " << path.GetPropPart()
  3244. << ", spec_index = " << spec_index << "\n";
  3245. #endif
  3246. if (!_live_fieldsets.count(spec.fieldset_index)) {
  3247. _err += "FieldSet id: " + std::to_string(spec.fieldset_index.value) +
  3248. " must exist in live fieldsets.\n";
  3249. return false;
  3250. }
  3251. const FieldValuePairVector &child_fields =
  3252. _live_fieldsets.at(spec.fieldset_index);
  3253. (void)child_fields;
  3254. {
  3255. std::string prop_name = path.GetPropPart();
  3256. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3257. std::cout << "prop: " << prop_name << "\n";
  3258. #endif
  3259. }
  3260. }
  3261. return true;
  3262. }
  3263. bool Parser::_ReconstructShader(
  3264. const Node &node, const FieldValuePairVector &fields,
  3265. const std::unordered_map<uint32_t, uint32_t> &path_index_to_spec_index_map,
  3266. PreviewSurface *shader) {
  3267. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3268. std::cout << "Parse shader\n";
  3269. #endif
  3270. for (const auto &fv : fields) {
  3271. if (fv.first == "properties") {
  3272. if (fv.second.GetTypeName() != "TokenArray") {
  3273. _err += "`properties` attribute must be TokenArray type\n";
  3274. return false;
  3275. }
  3276. assert(fv.second.IsArray());
  3277. for (size_t i = 0; i < fv.second.GetStringArray().size(); i++) {
  3278. }
  3279. }
  3280. }
  3281. #if 0
  3282. auto ParseAttribute = [](const FieldValuePairVector &fvs, PrimAttrib *attr,
  3283. const std::string &prop_name) -> bool {
  3284. bool success = false;
  3285. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3286. std::cout << "fvs.size = " << fvs.size() << "\n";
  3287. #endif
  3288. std::string type_name;
  3289. Variability variability{VariabilityVarying};
  3290. bool facevarying{false};
  3291. for (const auto &fv : fvs) {
  3292. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3293. std::cout << " fvs.first " << fv.first
  3294. << ", second: " << fv.second.GetTypeName() << "\n";
  3295. #endif
  3296. if ((fv.first == "typeName") && (fv.second.GetTypeName() == "Token")) {
  3297. type_name = fv.second.GetToken();
  3298. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3299. std::cout << "aaa: typeName: " << type_name << "\n";
  3300. #endif
  3301. (void)attr;
  3302. } else if (fv.first == "connectionPaths") {
  3303. // e.g. connection to texture file.
  3304. const ListOp<Path> paths = fv.second.GetPathListOp();
  3305. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3306. paths.Print();
  3307. #endif
  3308. // Currently we only support single explicit path.
  3309. if ((paths.GetExplicitItems().size() == 1)) {
  3310. const Path &path = paths.GetExplicitItems()[0];
  3311. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3312. std::cout << "full path: " << path.full_path_name() << "\n";
  3313. std::cout << "local path: " << path.local_path_name() << "\n";
  3314. #endif
  3315. } else {
  3316. return false;
  3317. }
  3318. } else if ((fv.first == "variablity") &&
  3319. (fv.second.GetTypeName() == "Variability")) {
  3320. variability = fv.second.GetVariability();
  3321. } else if ((fv.first == "interpolation") &&
  3322. (fv.second.GetTypeName() == "Token")) {
  3323. if (fv.second.GetToken() == "faceVarying") {
  3324. facevarying = true;
  3325. }
  3326. }
  3327. }
  3328. // Decode value(stored in "default" field)
  3329. for (const auto &fv : fvs) {
  3330. if (fv.first == "default") {
  3331. attr->name = prop_name;
  3332. attr->basic_type = std::string();
  3333. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3334. std::cout << "fv.second.GetTypeName = " << fv.second.GetTypeName()
  3335. << "\n";
  3336. #endif
  3337. if (fv.second.GetTypeName() == "Float") {
  3338. attr->floatVal = fv.second.GetFloat();
  3339. attr->basic_type = "float";
  3340. success = true;
  3341. } else if (fv.second.GetTypeName() == "Int") {
  3342. if (!fv.second.GetInt(&attr->intVal)) {
  3343. success = false;
  3344. break;
  3345. }
  3346. attr->basic_type = "int";
  3347. success = true;
  3348. } else if (fv.second.GetTypeName() == "Vec3f") {
  3349. attr->buffer.Set(BufferData::BUFFER_DATA_TYPE_FLOAT, 3,
  3350. /* stride */ sizeof(float), fv.second.GetData());
  3351. // attr->variability = variability;
  3352. // attr->facevarying = facevarying;
  3353. success = true;
  3354. } else if (fv.second.GetTypeName() == "FloatArray") {
  3355. attr->buffer.Set(BufferData::BUFFER_DATA_TYPE_FLOAT, 1,
  3356. /* stride */ sizeof(float), fv.second.GetData());
  3357. attr->variability = variability;
  3358. attr->facevarying = facevarying;
  3359. success = true;
  3360. } else if (fv.second.GetTypeName() == "Vec2fArray") {
  3361. attr->buffer.Set(BufferData::BUFFER_DATA_TYPE_FLOAT, 2,
  3362. /* stride */ sizeof(float) * 2, fv.second.GetData());
  3363. attr->variability = variability;
  3364. attr->facevarying = facevarying;
  3365. success = true;
  3366. } else if (fv.second.GetTypeName() == "Vec3fArray") {
  3367. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3368. std::cout << "fv.second.data.size = " << fv.second.GetData().size()
  3369. << "\n";
  3370. #endif
  3371. attr->buffer.Set(BufferData::BUFFER_DATA_TYPE_FLOAT, 3,
  3372. /* stride */ sizeof(float) * 3, fv.second.GetData());
  3373. attr->variability = variability;
  3374. attr->facevarying = facevarying;
  3375. success = true;
  3376. } else if (fv.second.GetTypeName() == "Vec4fArray") {
  3377. attr->buffer.Set(BufferData::BUFFER_DATA_TYPE_FLOAT, 4,
  3378. /* stride */ sizeof(float) * 4, fv.second.GetData());
  3379. attr->variability = variability;
  3380. attr->facevarying = facevarying;
  3381. success = true;
  3382. } else if (fv.second.GetTypeName() == "IntArray") {
  3383. attr->buffer.Set(BufferData::BUFFER_DATA_TYPE_INT, 1,
  3384. /* stride */ sizeof(int32_t), fv.second.GetData());
  3385. attr->variability = variability;
  3386. attr->facevarying = facevarying;
  3387. success = true;
  3388. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3389. std::cout << "IntArray"
  3390. << "\n";
  3391. const int32_t *ptr =
  3392. reinterpret_cast<const int32_t *>(attr->buffer.data.data());
  3393. for (size_t i = 0; i < attr->buffer.GetNumElements(); i++) {
  3394. std::cout << "[" << i << "] = " << ptr[i] << "\n";
  3395. }
  3396. #endif
  3397. } else if (fv.second.GetTypeName() == "Token") {
  3398. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3399. std::cout << "bbb: token: " << fv.second.GetToken() << "\n";
  3400. #endif
  3401. attr->stringVal = fv.second.GetToken();
  3402. attr->basic_type = "string";
  3403. // attr->variability = variability;
  3404. // attr->facevarying = facevarying;
  3405. success = true;
  3406. }
  3407. }
  3408. }
  3409. return success;
  3410. };
  3411. #endif
  3412. //
  3413. // NOTE: Currently we assume one deeper node has Material's attribute
  3414. //
  3415. for (size_t i = 0; i < node.GetChildren().size(); i++) {
  3416. int child_index = int(node.GetChildren()[i]);
  3417. if ((child_index < 0) || (child_index >= int(_nodes.size()))) {
  3418. _err += "Invalid child node id: " + std::to_string(child_index) +
  3419. ". Must be in range [0, " + std::to_string(_nodes.size()) + ")\n";
  3420. return false;
  3421. }
  3422. // const Node &child_node = _nodes[size_t(child_index)];
  3423. if (!path_index_to_spec_index_map.count(uint32_t(child_index))) {
  3424. // No specifier assigned to this child node.
  3425. _err += "No specifier found for node id: " + std::to_string(child_index) +
  3426. "\n";
  3427. return false;
  3428. }
  3429. uint32_t spec_index =
  3430. path_index_to_spec_index_map.at(uint32_t(child_index));
  3431. if (spec_index >= _specs.size()) {
  3432. _err += "Invalid specifier id: " + std::to_string(spec_index) +
  3433. ". Must be in range [0, " + std::to_string(_specs.size()) + ")\n";
  3434. return false;
  3435. }
  3436. const Spec &spec = _specs[spec_index];
  3437. Path path = GetPath(spec.path_index);
  3438. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3439. std::cout << "Path prim part: " << path.GetPrimPart()
  3440. << ", prop part: " << path.GetPropPart()
  3441. << ", spec_index = " << spec_index << "\n";
  3442. #endif
  3443. if (!_live_fieldsets.count(spec.fieldset_index)) {
  3444. _err += "FieldSet id: " + std::to_string(spec.fieldset_index.value) +
  3445. " must exist in live fieldsets.\n";
  3446. return false;
  3447. }
  3448. const FieldValuePairVector &child_fields =
  3449. _live_fieldsets.at(spec.fieldset_index);
  3450. {
  3451. std::string prop_name = path.GetPropPart();
  3452. PrimAttrib attr;
  3453. bool ret = _ParseAttribute(child_fields, &attr, prop_name);
  3454. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3455. std::cout << "prop: " << prop_name << ", ret = " << ret << "\n";
  3456. #endif
  3457. if (ret) {
  3458. // Currently we only support predefined PBR attributes.
  3459. if (prop_name.compare("outputs:surface") == 0) {
  3460. // Surface shader output available
  3461. } else if (prop_name.compare("outputs:displacement") == 0) {
  3462. // Displacement shader output available
  3463. } else if (prop_name.compare("inputs:metallic") == 0) {
  3464. // type: float
  3465. if ((attr.buffer.GetDataType() ==
  3466. BufferData::BUFFER_DATA_TYPE_FLOAT) &&
  3467. (attr.buffer.GetNumElements() == 1) &&
  3468. (attr.buffer.GetNumCoords() == 1)) {
  3469. shader->metallic.value = attr.buffer.GetAsFloat();
  3470. }
  3471. } else if (prop_name.compare("inputs:metallic.connect") == 0) {
  3472. // Currently we assume texture is assigned to this attribute.
  3473. shader->metallic.path = attr.stringVal;
  3474. } else if (prop_name.compare("inputs:diffuseColor") == 0) {
  3475. if ((attr.buffer.GetDataType() ==
  3476. BufferData::BUFFER_DATA_TYPE_FLOAT) &&
  3477. (attr.buffer.GetNumElements() == 1) &&
  3478. (attr.buffer.GetNumCoords() == 3)) {
  3479. shader->diffuseColor.color = attr.buffer.GetAsColor3f();
  3480. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3481. std::cout << "diffuseColor: " << shader->diffuseColor.color[0]
  3482. << ", " << shader->diffuseColor.color[1] << ", "
  3483. << shader->diffuseColor.color[2] << "\n";
  3484. #endif
  3485. }
  3486. } else if (prop_name.compare("inputs:diffuseColor.connect") == 0) {
  3487. // Currently we assume texture is assigned to this attribute.
  3488. shader->diffuseColor.path = attr.stringVal;
  3489. } else if (prop_name.compare("inputs:emissiveColor") == 0) {
  3490. if ((attr.buffer.GetDataType() ==
  3491. BufferData::BUFFER_DATA_TYPE_FLOAT) &&
  3492. (attr.buffer.GetNumElements() == 1) &&
  3493. (attr.buffer.GetNumCoords() == 3)) {
  3494. shader->emissiveColor.color = attr.buffer.GetAsColor3f();
  3495. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3496. std::cout << "emissiveColor: " << shader->emissiveColor.color[0]
  3497. << ", " << shader->emissiveColor.color[1] << ", "
  3498. << shader->emissiveColor.color[2] << "\n";
  3499. #endif
  3500. }
  3501. } else if (prop_name.compare("inputs:emissiveColor.connect") == 0) {
  3502. // Currently we assume texture is assigned to this attribute.
  3503. shader->emissiveColor.path = attr.stringVal;
  3504. }
  3505. }
  3506. }
  3507. }
  3508. return true;
  3509. }
  3510. bool Parser::_ReconstructSceneRecursively(
  3511. int parent, int level,
  3512. const std::unordered_map<uint32_t, uint32_t> &path_index_to_spec_index_map,
  3513. Scene *scene) {
  3514. if ((parent < 0) || (parent >= int(_nodes.size()))) {
  3515. _err += "Invalid parent node id: " + std::to_string(parent) +
  3516. ". Must be in range [0, " + std::to_string(_nodes.size()) + ")\n";
  3517. return false;
  3518. }
  3519. const Node &node = _nodes[size_t(parent)];
  3520. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3521. auto IndentStr = [](int l) -> std::string {
  3522. std::string indent;
  3523. for (size_t i = 0; i < size_t(l); i++) {
  3524. indent += " ";
  3525. }
  3526. return indent;
  3527. };
  3528. std::cout << IndentStr(level) << "lv[" << level << "] node_index[" << parent
  3529. << "] " << node.GetLocalPath() << " ==\n";
  3530. std::cout << IndentStr(level) << " childs = [";
  3531. for (size_t i = 0; i < node.GetChildren().size(); i++) {
  3532. std::cout << node.GetChildren()[i];
  3533. if (i != (node.GetChildren().size() - 1)) {
  3534. std::cout << ", ";
  3535. }
  3536. }
  3537. std::cout << "]\n";
  3538. #endif
  3539. if (!path_index_to_spec_index_map.count(uint32_t(parent))) {
  3540. // No specifier assigned to this node.
  3541. #if 0
  3542. _err += "Scene: No specifier found for node id: " + std::to_string(parent) + "\n";
  3543. return false;
  3544. #else
  3545. return true; // would be OK.
  3546. #endif
  3547. }
  3548. uint32_t spec_index = path_index_to_spec_index_map.at(uint32_t(parent));
  3549. if (spec_index >= _specs.size()) {
  3550. _err += "Invalid specifier id: " + std::to_string(spec_index) +
  3551. ". Must be in range [0, " + std::to_string(_specs.size()) + ")\n";
  3552. return false;
  3553. }
  3554. const Spec &spec = _specs[spec_index];
  3555. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3556. std::cout << IndentStr(level)
  3557. << " specTy = " << GetSpecTypeString(spec.spec_type) << "\n";
  3558. std::cout << IndentStr(level)
  3559. << " fieldSetIndex = " << spec.fieldset_index.value << "\n";
  3560. #endif
  3561. if (!_live_fieldsets.count(spec.fieldset_index)) {
  3562. _err += "FieldSet id: " + std::to_string(spec.fieldset_index.value) +
  3563. " must exist in live fieldsets.\n";
  3564. return false;
  3565. }
  3566. const FieldValuePairVector &fields = _live_fieldsets.at(spec.fieldset_index);
  3567. // root only attributes.
  3568. if (parent == 0) {
  3569. for (const auto &fv : fields) {
  3570. if ((fv.first == "upAxis") &&
  3571. (fv.second.GetTypeId() == VALUE_TYPE_TOKEN)) {
  3572. std::string v = fv.second.GetToken();
  3573. if ((v != "Y") && (v != "Z") && (v != "X")) {
  3574. _err += "Currently `upAxis` must be 'X', 'Y' or 'Z' but got '" + v +
  3575. "'\n";
  3576. return false;
  3577. }
  3578. scene->upAxis = v;
  3579. } else if (fv.first == "metersPerUnit") {
  3580. if ((fv.second.GetTypeId() == VALUE_TYPE_DOUBLE) ||
  3581. (fv.second.GetTypeId() == VALUE_TYPE_FLOAT)) {
  3582. scene->metersPerUnit = fv.second.GetDouble();
  3583. } else {
  3584. _err +=
  3585. "Currently `metersPerUnit` value must be double or float type, "
  3586. "but got '" +
  3587. fv.second.GetTypeName() + "'\n";
  3588. return false;
  3589. }
  3590. } else if (fv.first == "timeCodesPerSecond") {
  3591. if ((fv.second.GetTypeId() == VALUE_TYPE_DOUBLE) ||
  3592. (fv.second.GetTypeId() == VALUE_TYPE_FLOAT)) {
  3593. scene->timeCodesPerSecond = fv.second.GetDouble();
  3594. } else {
  3595. _err +=
  3596. "Currently `timeCodesPerSecond` value must be double or float "
  3597. "type, but got '" +
  3598. fv.second.GetTypeName() + "'\n";
  3599. return false;
  3600. }
  3601. } else if ((fv.first == "defaultPrim") &&
  3602. (fv.second.GetTypeId() == VALUE_TYPE_TOKEN)) {
  3603. scene->defaultPrim = fv.second.GetToken();
  3604. } else {
  3605. // TODO(syoyo): `customLayerData`
  3606. }
  3607. }
  3608. }
  3609. std::string node_type;
  3610. for (const auto &fv : fields) {
  3611. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3612. std::cout << IndentStr(level) << " \"" << fv.first
  3613. << "\" : ty = " << fv.second.GetTypeName() << "\n";
  3614. #endif
  3615. if (fv.second.GetTypeId() == VALUE_TYPE_SPECIFIER) {
  3616. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3617. std::cout << IndentStr(level) << " specifier = "
  3618. << GetSpecifierString(fv.second.GetSpecifier()) << "\n";
  3619. #endif
  3620. } else if (fv.second.GetTypeId() == VALUE_TYPE_TOKEN) {
  3621. if (fv.first == "typeName") {
  3622. node_type = fv.second.GetToken();
  3623. }
  3624. // std::cout << IndentStr(level) << " token = " << fv.second.GetToken()
  3625. // << "\n";
  3626. } else if (fv.second.GetTypeId() == VALUE_TYPE_STRING) {
  3627. // std::cout << IndentStr(level) << " string = " <<
  3628. // fv.second.GetString() << "\n";
  3629. } else if (fv.second.GetTypeId() == VALUE_TYPE_DOUBLE) {
  3630. // std::cout << IndentStr(level) << " double = " <<
  3631. // fv.second.GetDouble() << "\n";
  3632. } else if (fv.second.GetTypeId() == VALUE_TYPE_FLOAT) {
  3633. // std::cout << IndentStr(level) << " float = " <<
  3634. // fv.second.GetDouble() << "\n";
  3635. } else if (fv.second.GetTypeId() == VALUE_TYPE_VARIABILITY) {
  3636. // std::cout << IndentStr(level) << " variability = " <<
  3637. // GetVariabilityString(fv.second.GetVariability()) << "\n";
  3638. } else if ((fv.first == "primChildren") &&
  3639. (fv.second.GetTypeName() == "TokenArray")) {
  3640. // Check if TokenArray contains known child nodes
  3641. const auto &tokens = fv.second.GetStringArray();
  3642. bool valid = true;
  3643. for (const auto &token : tokens) {
  3644. if (!node.GetPrimChildren().count(token)) {
  3645. _err += "primChild '" + token + "' not found in node '" +
  3646. node.GetPath().full_path_name() + "'\n";
  3647. valid = false;
  3648. break;
  3649. }
  3650. }
  3651. } else if (fv.second.GetTypeName() == "TokenArray") {
  3652. assert(fv.second.IsArray());
  3653. #if 0
  3654. const auto &strs = fv.second.GetStringArray();
  3655. for (const auto &str : strs) {
  3656. std::cout << IndentStr(level + 2) << str << "\n";
  3657. }
  3658. #endif
  3659. }
  3660. }
  3661. if (node_type == "Xform") {
  3662. Xform xform;
  3663. if (!_ReconstructXform(node, fields, path_index_to_spec_index_map,
  3664. &xform)) {
  3665. _err += "Failed to reconstruct Xform.\n";
  3666. return false;
  3667. }
  3668. scene->xforms.push_back(xform);
  3669. } else if (node_type == "Mesh") {
  3670. GeomMesh mesh;
  3671. if (!_ReconstructGeomMesh(node, fields, path_index_to_spec_index_map,
  3672. &mesh)) {
  3673. _err += "Failed to reconstruct GeomMesh.\n";
  3674. return false;
  3675. }
  3676. mesh.name = node.GetLocalPath(); // FIXME
  3677. scene->geom_meshes.push_back(mesh);
  3678. } else if (node_type == "Material") {
  3679. Material material;
  3680. if (!_ReconstructMaterial(node, fields, path_index_to_spec_index_map,
  3681. &material)) {
  3682. _err += "Failed to reconstruct Material.\n";
  3683. return false;
  3684. }
  3685. scene->materials.push_back(material);
  3686. } else if (node_type == "Shader") {
  3687. PreviewSurface shader;
  3688. if (!_ReconstructShader(node, fields, path_index_to_spec_index_map,
  3689. &shader)) {
  3690. _err += "Failed to reconstruct PreviewSurface(Shader).\n";
  3691. return false;
  3692. }
  3693. scene->shaders.push_back(shader);
  3694. } else {
  3695. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3696. std::cout << "TODO or we can ignore this node: node_type: " << node_type
  3697. << "\n";
  3698. #endif
  3699. }
  3700. for (size_t i = 0; i < node.GetChildren().size(); i++) {
  3701. if (!_ReconstructSceneRecursively(int(node.GetChildren()[i]), level + 1,
  3702. path_index_to_spec_index_map, scene)) {
  3703. return false;
  3704. }
  3705. }
  3706. return true;
  3707. }
  3708. bool Parser::ReconstructScene(Scene *scene) {
  3709. if (_nodes.empty()) {
  3710. _warn += "Empty scene.\n";
  3711. return true;
  3712. }
  3713. std::unordered_map<uint32_t, uint32_t>
  3714. path_index_to_spec_index_map; // path_index -> spec_index
  3715. {
  3716. for (size_t i = 0; i < _specs.size(); i++) {
  3717. if (_specs[i].path_index.value == ~0u) {
  3718. continue;
  3719. }
  3720. // path_index should be unique.
  3721. assert(path_index_to_spec_index_map.count(_specs[i].path_index.value) ==
  3722. 0);
  3723. path_index_to_spec_index_map[_specs[i].path_index.value] = uint32_t(i);
  3724. }
  3725. }
  3726. int root_node_id = 0;
  3727. return _ReconstructSceneRecursively(root_node_id, /* level */ 0,
  3728. path_index_to_spec_index_map, scene);
  3729. }
  3730. bool Parser::ReadSpecs() {
  3731. if ((_specs_index < 0) || (_specs_index >= int64_t(_toc.sections.size()))) {
  3732. _err += "Invalid index for `SPECS` section.\n";
  3733. return false;
  3734. }
  3735. if ((_version[0] == 0) && (_version[1] < 4)) {
  3736. _err += "Version must be 0.4.0 or later, but got " +
  3737. std::to_string(_version[0]) + "." + std::to_string(_version[1]) +
  3738. "." + std::to_string(_version[2]) + "\n";
  3739. return false;
  3740. }
  3741. const Section &s = _toc.sections[size_t(_specs_index)];
  3742. if (!_sr->seek_set(uint64_t(s.start))) {
  3743. _err += "Failed to move to `SPECS` section.\n";
  3744. return false;
  3745. }
  3746. uint64_t num_specs;
  3747. if (!_sr->read8(&num_specs)) {
  3748. _err += "Failed to read # of specs size at `SPECS` section.\n";
  3749. return false;
  3750. }
  3751. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3752. std::cout << "num_specs " << num_specs << "\n";
  3753. #endif
  3754. _specs.resize(static_cast<size_t>(num_specs));
  3755. // Create temporary space for decompressing.
  3756. std::vector<char> comp_buffer(Usd_IntegerCompression::GetCompressedBufferSize(
  3757. static_cast<size_t>(num_specs)));
  3758. std::vector<uint32_t> tmp(static_cast<size_t>(num_specs));
  3759. std::vector<char> working_space(
  3760. Usd_IntegerCompression::GetDecompressionWorkingSpaceSize(
  3761. static_cast<size_t>(num_specs)));
  3762. // path indices
  3763. {
  3764. uint64_t path_indexes_size;
  3765. if (!_sr->read8(&path_indexes_size)) {
  3766. _err += "Failed to read path indexes size at `SPECS` section.\n";
  3767. return false;
  3768. }
  3769. assert(path_indexes_size < comp_buffer.size());
  3770. if (path_indexes_size !=
  3771. _sr->read(size_t(path_indexes_size), size_t(path_indexes_size),
  3772. reinterpret_cast<uint8_t *>(comp_buffer.data()))) {
  3773. _err += "Failed to read path indexes data at `SPECS` section.\n";
  3774. return false;
  3775. }
  3776. std::string err;
  3777. if (!Usd_IntegerCompression::DecompressFromBuffer(
  3778. comp_buffer.data(), size_t(path_indexes_size), tmp.data(),
  3779. size_t(num_specs), &err, working_space.data())) {
  3780. _err += "Failed to decode pathIndexes at `SPECS` section.\n";
  3781. _err += err;
  3782. return false;
  3783. }
  3784. for (size_t i = 0; i < num_specs; ++i) {
  3785. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3786. std::cout << "spec[" << i << "].path_index = " << tmp[i] << "\n";
  3787. #endif
  3788. _specs[i].path_index.value = tmp[i];
  3789. }
  3790. }
  3791. // fieldset indices
  3792. {
  3793. uint64_t fset_indexes_size;
  3794. if (!_sr->read8(&fset_indexes_size)) {
  3795. _err += "Failed to read fieldset indexes size at `SPECS` section.\n";
  3796. return false;
  3797. }
  3798. assert(fset_indexes_size < comp_buffer.size());
  3799. if (fset_indexes_size !=
  3800. _sr->read(size_t(fset_indexes_size), size_t(fset_indexes_size),
  3801. reinterpret_cast<uint8_t *>(comp_buffer.data()))) {
  3802. _err += "Failed to read fieldset indexes data at `SPECS` section.\n";
  3803. return false;
  3804. }
  3805. std::string err;
  3806. if (!Usd_IntegerCompression::DecompressFromBuffer(
  3807. comp_buffer.data(), size_t(fset_indexes_size), tmp.data(),
  3808. size_t(num_specs), &err, working_space.data())) {
  3809. _err += "Failed to decode fieldset indices at `SPECS` section.\n";
  3810. _err += err;
  3811. return false;
  3812. }
  3813. for (size_t i = 0; i != num_specs; ++i) {
  3814. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3815. std::cout << "specs[" << i << "].fieldset_index = " << tmp[i] << "\n";
  3816. #endif
  3817. _specs[i].fieldset_index.value = tmp[i];
  3818. }
  3819. }
  3820. // spec types
  3821. {
  3822. uint64_t spectype_size;
  3823. if (!_sr->read8(&spectype_size)) {
  3824. _err += "Failed to read spectype size at `SPECS` section.\n";
  3825. return false;
  3826. }
  3827. assert(spectype_size < comp_buffer.size());
  3828. if (spectype_size !=
  3829. _sr->read(size_t(spectype_size), size_t(spectype_size),
  3830. reinterpret_cast<uint8_t *>(comp_buffer.data()))) {
  3831. _err += "Failed to read spectype data at `SPECS` section.\n";
  3832. return false;
  3833. }
  3834. std::string err;
  3835. if (!Usd_IntegerCompression::DecompressFromBuffer(
  3836. comp_buffer.data(), size_t(spectype_size), tmp.data(),
  3837. size_t(num_specs), &err, working_space.data())) {
  3838. _err += "Failed to decode fieldset indices at `SPECS` section.\n";
  3839. _err += err;
  3840. return false;
  3841. }
  3842. for (size_t i = 0; i != num_specs; ++i) {
  3843. // std::cout << "spectype = " << tmp[i] << "\n";
  3844. _specs[i].spec_type = static_cast<SpecType>(tmp[i]);
  3845. }
  3846. }
  3847. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3848. for (size_t i = 0; i != num_specs; ++i) {
  3849. std::cout << "spec[" << i << "].pathIndex = " << _specs[i].path_index.value
  3850. << ", fieldset_index = " << _specs[i].fieldset_index.value
  3851. << ", spec_type = " << _specs[i].spec_type << "\n";
  3852. std::cout << "spec[" << i
  3853. << "] string_repr = " << GetSpecString(Index(uint32_t(i)))
  3854. << "\n";
  3855. }
  3856. #endif
  3857. return true;
  3858. }
  3859. bool Parser::ReadPaths() {
  3860. if ((_paths_index < 0) || (_paths_index >= int64_t(_toc.sections.size()))) {
  3861. _err += "Invalid index for `PATHS` section.\n";
  3862. return false;
  3863. }
  3864. if ((_version[0] == 0) && (_version[1] < 4)) {
  3865. _err += "Version must be 0.4.0 or later, but got " +
  3866. std::to_string(_version[0]) + "." + std::to_string(_version[1]) +
  3867. "." + std::to_string(_version[2]) + "\n";
  3868. return false;
  3869. }
  3870. const Section &s = _toc.sections[size_t(_paths_index)];
  3871. if (!_sr->seek_set(uint64_t(s.start))) {
  3872. _err += "Failed to move to `PATHS` section.\n";
  3873. return false;
  3874. }
  3875. uint64_t num_paths;
  3876. if (!_sr->read8(&num_paths)) {
  3877. _err += "Failed to read # of paths at `PATHS` section.\n";
  3878. return false;
  3879. }
  3880. if (!ReadCompressedPaths(num_paths)) {
  3881. _err += "Failed to read compressed paths.\n";
  3882. return false;
  3883. }
  3884. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3885. std::cout << "# of paths " << _paths.size() << "\n";
  3886. for (size_t i = 0; i < _paths.size(); i++) {
  3887. std::cout << "path[" << i << "] = " << _paths[i].full_path_name() << "\n";
  3888. }
  3889. #endif
  3890. return true;
  3891. }
  3892. bool Parser::ReadBootStrap() {
  3893. // parse header.
  3894. uint8_t magic[8];
  3895. if (8 != _sr->read(/* req */ 8, /* dst len */ 8, magic)) {
  3896. _err += "Failed to read magic number.\n";
  3897. return false;
  3898. }
  3899. // std::cout << int(magic[0]) << "\n";
  3900. // std::cout << int(magic[1]) << "\n";
  3901. // std::cout << int(magic[2]) << "\n";
  3902. // std::cout << int(magic[3]) << "\n";
  3903. // std::cout << int(magic[4]) << "\n";
  3904. // std::cout << int(magic[5]) << "\n";
  3905. // std::cout << int(magic[6]) << "\n";
  3906. // std::cout << int(magic[7]) << "\n";
  3907. if (memcmp(magic, "PXR-USDC", 8)) {
  3908. _err += "Invalid magic number. Expected 'PXR-USDC' but got '" +
  3909. std::string(magic, magic + 8) + "'\n";
  3910. return false;
  3911. }
  3912. // parse version(first 3 bytes from 8 bytes)
  3913. uint8_t version[8];
  3914. if (8 != _sr->read(8, 8, version)) {
  3915. _err += "Failed to read magic number.\n";
  3916. return false;
  3917. }
  3918. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3919. std::cout << "version = " << int(version[0]) << "." << int(version[1]) << "."
  3920. << int(version[2]) << "\n";
  3921. #endif
  3922. _version[0] = version[0];
  3923. _version[1] = version[1];
  3924. _version[2] = version[2];
  3925. // We only support version 0.4.0 or later.
  3926. if ((version[0] == 0) && (version[1] < 4)) {
  3927. _err += "Version must be 0.4.0 or later, but got " +
  3928. std::to_string(version[0]) + "." + std::to_string(version[1]) +
  3929. "." + std::to_string(version[2]) + "\n";
  3930. return false;
  3931. }
  3932. _toc_offset = 0;
  3933. if (!_sr->read8(&_toc_offset)) {
  3934. _err += "Failed to read TOC offset.\n";
  3935. return false;
  3936. }
  3937. if ((_toc_offset <= 88) || (_toc_offset >= int64_t(_sr->size()))) {
  3938. _err += "Invalid TOC offset value: " + std::to_string(_toc_offset) +
  3939. ", filesize = " + std::to_string(_sr->size()) + ".\n";
  3940. return false;
  3941. }
  3942. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3943. std::cout << "toc offset = " << _toc_offset << "\n";
  3944. #endif
  3945. return true;
  3946. }
  3947. bool Parser::ReadTOC() {
  3948. if ((_toc_offset <= 88) || (_toc_offset >= int64_t(_sr->size()))) {
  3949. _err += "Invalid toc offset\n";
  3950. return false;
  3951. }
  3952. if (!_sr->seek_set(uint64_t(_toc_offset))) {
  3953. _err += "Failed to move to TOC offset\n";
  3954. return false;
  3955. }
  3956. // read # of sections.
  3957. uint64_t num_sections{0};
  3958. if (!_sr->read8(&num_sections)) {
  3959. _err += "Failed to read TOC(# of sections)\n";
  3960. return false;
  3961. }
  3962. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3963. std::cout << "toc sections = " << num_sections << "\n";
  3964. #endif
  3965. _toc.sections.resize(static_cast<size_t>(num_sections));
  3966. for (size_t i = 0; i < num_sections; i++) {
  3967. if (!ReadSection(&_toc.sections[i])) {
  3968. _err += "Failed to read TOC section at " + std::to_string(i) + "\n";
  3969. return false;
  3970. }
  3971. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  3972. std::cout << "section[" << i << "] name = " << _toc.sections[i].name
  3973. << ", start = " << _toc.sections[i].start
  3974. << ", size = " << _toc.sections[i].size << "\n";
  3975. #endif
  3976. // find index
  3977. if (0 == strncmp(_toc.sections[i].name, "TOKENS", kSectionNameMaxLength)) {
  3978. _tokens_index = int64_t(i);
  3979. } else if (0 == strncmp(_toc.sections[i].name, "STRINGS",
  3980. kSectionNameMaxLength)) {
  3981. _strings_index = int64_t(i);
  3982. } else if (0 == strncmp(_toc.sections[i].name, "FIELDS",
  3983. kSectionNameMaxLength)) {
  3984. _fields_index = int64_t(i);
  3985. } else if (0 == strncmp(_toc.sections[i].name, "FIELDSETS",
  3986. kSectionNameMaxLength)) {
  3987. _fieldsets_index = int64_t(i);
  3988. } else if (0 ==
  3989. strncmp(_toc.sections[i].name, "SPECS", kSectionNameMaxLength)) {
  3990. _specs_index = int64_t(i);
  3991. } else if (0 ==
  3992. strncmp(_toc.sections[i].name, "PATHS", kSectionNameMaxLength)) {
  3993. _paths_index = int64_t(i);
  3994. }
  3995. }
  3996. return true;
  3997. }
  3998. } // namespace
  3999. bool LoadUSDCFromMemory(const uint8_t *addr, const size_t length, Scene *scene,
  4000. std::string *warn, std::string *err,
  4001. const USDLoadOptions &options) {
  4002. if (scene == nullptr) {
  4003. if (err) {
  4004. (*err) = "null pointer for `scene` argument.\n";
  4005. }
  4006. return false;
  4007. }
  4008. bool swap_endian = false; // @FIXME
  4009. if (length > size_t(1024 * 1024 * options.max_memory_limit_in_mb)) {
  4010. if (err) {
  4011. (*err) += "USDZ data is too large(size = " + std::to_string(length) +
  4012. ", which exceeds memory limit " +
  4013. std::to_string(options.max_memory_limit_in_mb) + " [mb]).\n";
  4014. }
  4015. return false;
  4016. }
  4017. StreamReader sr(addr, length, swap_endian);
  4018. Parser parser(&sr, options.num_threads);
  4019. if (!parser.ReadBootStrap()) {
  4020. if (warn) {
  4021. (*warn) = parser.GetWarning();
  4022. }
  4023. if (err) {
  4024. (*err) = parser.GetError();
  4025. }
  4026. return false;
  4027. }
  4028. if (!parser.ReadTOC()) {
  4029. if (warn) {
  4030. (*warn) = parser.GetWarning();
  4031. }
  4032. if (err) {
  4033. (*err) = parser.GetError();
  4034. }
  4035. return false;
  4036. }
  4037. // Read known sections
  4038. if (!parser.ReadTokens()) {
  4039. if (warn) {
  4040. (*warn) = parser.GetWarning();
  4041. }
  4042. if (err) {
  4043. (*err) = parser.GetError();
  4044. }
  4045. return false;
  4046. }
  4047. if (!parser.ReadStrings()) {
  4048. if (warn) {
  4049. (*warn) = parser.GetWarning();
  4050. }
  4051. if (err) {
  4052. (*err) = parser.GetError();
  4053. }
  4054. return false;
  4055. }
  4056. if (!parser.ReadFields()) {
  4057. if (warn) {
  4058. (*warn) = parser.GetWarning();
  4059. }
  4060. if (err) {
  4061. (*err) = parser.GetError();
  4062. }
  4063. return false;
  4064. }
  4065. if (!parser.ReadFieldSets()) {
  4066. if (warn) {
  4067. (*warn) = parser.GetWarning();
  4068. }
  4069. if (err) {
  4070. (*err) = parser.GetError();
  4071. }
  4072. return false;
  4073. }
  4074. if (!parser.ReadPaths()) {
  4075. if (warn) {
  4076. (*warn) = parser.GetWarning();
  4077. }
  4078. if (err) {
  4079. (*err) = parser.GetError();
  4080. }
  4081. return false;
  4082. }
  4083. if (!parser.ReadSpecs()) {
  4084. if (warn) {
  4085. (*warn) = parser.GetWarning();
  4086. }
  4087. if (err) {
  4088. (*err) = parser.GetError();
  4089. }
  4090. return false;
  4091. }
  4092. // TODO(syoyo): Read unknown sections
  4093. ///
  4094. /// Reconstruct C++ representation of USD scene graph.
  4095. ///
  4096. if (!parser._BuildLiveFieldSets()) {
  4097. if (warn) {
  4098. (*warn) = parser.GetWarning();
  4099. }
  4100. if (err) {
  4101. (*err) = parser.GetError();
  4102. }
  4103. }
  4104. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  4105. std::cout << "num_paths: " << parser.NumPaths() << "\n";
  4106. #endif
  4107. for (size_t i = 0; i < parser.NumPaths(); i++) {
  4108. Path path = parser.GetPath(Index(uint32_t(i)));
  4109. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  4110. std::cout << "path[" << i << "].name = " << path.full_path_name() << "\n";
  4111. #endif
  4112. }
  4113. // Create `Scene` object
  4114. // std::cout << "reconstruct scene:\n";
  4115. {
  4116. if (!parser.ReconstructScene(scene)) {
  4117. if (warn) {
  4118. (*warn) = parser.GetWarning();
  4119. }
  4120. if (err) {
  4121. (*err) = parser.GetError();
  4122. }
  4123. return false;
  4124. }
  4125. }
  4126. if (warn) {
  4127. (*warn) = parser.GetWarning();
  4128. }
  4129. return true;
  4130. }
  4131. bool LoadUSDCFromFile(const std::string &filename, Scene *scene,
  4132. std::string *warn, std::string *err,
  4133. const USDLoadOptions &options) {
  4134. std::vector<uint8_t> data;
  4135. {
  4136. std::ifstream ifs(filename.c_str(), std::ifstream::binary);
  4137. if (!ifs) {
  4138. if (err) {
  4139. (*err) = "File not found or cannot open file : " + filename;
  4140. }
  4141. return false;
  4142. }
  4143. // TODO(syoyo): Use mmap
  4144. ifs.seekg(0, ifs.end);
  4145. size_t sz = static_cast<size_t>(ifs.tellg());
  4146. if (int64_t(sz) < 0) {
  4147. // Looks reading directory, not a file.
  4148. if (err) {
  4149. (*err) += "Looks like filename is a directory : \"" + filename + "\"\n";
  4150. }
  4151. return false;
  4152. }
  4153. if (sz < (11 * 8)) {
  4154. // ???
  4155. if (err) {
  4156. (*err) +=
  4157. "File size too short. Looks like this file is not a USDC : \"" +
  4158. filename + "\"\n";
  4159. }
  4160. return false;
  4161. }
  4162. if (sz > size_t(1024 * 1024 * options.max_memory_limit_in_mb)) {
  4163. if (err) {
  4164. (*err) += "USDZ file is too large(size = " + std::to_string(sz) +
  4165. ", which exceeds memory limit " +
  4166. std::to_string(options.max_memory_limit_in_mb) + " [mb]).\n";
  4167. }
  4168. return false;
  4169. }
  4170. data.resize(sz);
  4171. ifs.seekg(0, ifs.beg);
  4172. ifs.read(reinterpret_cast<char *>(&data.at(0)),
  4173. static_cast<std::streamsize>(sz));
  4174. }
  4175. return LoadUSDCFromMemory(data.data(), data.size(), scene, warn, err,
  4176. options);
  4177. }
  4178. namespace {
  4179. static std::string GetFileExtension(const std::string &filename) {
  4180. if (filename.find_last_of(".") != std::string::npos)
  4181. return filename.substr(filename.find_last_of(".") + 1);
  4182. return "";
  4183. }
  4184. static std::string str_tolower(std::string s) {
  4185. std::transform(s.begin(), s.end(), s.begin(),
  4186. // static_cast<int(*)(int)>(std::tolower) // wrong
  4187. // [](int c){ return std::tolower(c); } // wrong
  4188. // [](char c){ return std::tolower(c); } // wrong
  4189. [](unsigned char c) { return std::tolower(c); } // correct
  4190. );
  4191. return s;
  4192. }
  4193. } // namespace
  4194. bool LoadUSDZFromFile(const std::string &filename, Scene *scene,
  4195. std::string *warn, std::string *err,
  4196. const USDLoadOptions &options) {
  4197. // <filename, byte_begin, byte_end>
  4198. std::vector<std::tuple<std::string, size_t, size_t>> assets;
  4199. std::vector<uint8_t> data;
  4200. {
  4201. std::ifstream ifs(filename.c_str(), std::ifstream::binary);
  4202. if (!ifs) {
  4203. if (err) {
  4204. (*err) = "File not found or cannot open file : " + filename;
  4205. }
  4206. return false;
  4207. }
  4208. // TODO(syoyo): Use mmap
  4209. ifs.seekg(0, ifs.end);
  4210. size_t sz = static_cast<size_t>(ifs.tellg());
  4211. if (int64_t(sz) < 0) {
  4212. // Looks reading directory, not a file.
  4213. if (err) {
  4214. (*err) += "Looks like filename is a directory : \"" + filename + "\"\n";
  4215. }
  4216. return false;
  4217. }
  4218. if (sz < (11 * 8) + 30) { // 88 for USDC header, 30 for ZIP header
  4219. // ???
  4220. if (err) {
  4221. (*err) +=
  4222. "File size too short. Looks like this file is not a USDZ : \"" +
  4223. filename + "\"\n";
  4224. }
  4225. return false;
  4226. }
  4227. data.resize(sz);
  4228. ifs.seekg(0, ifs.beg);
  4229. ifs.read(reinterpret_cast<char *>(&data.at(0)),
  4230. static_cast<std::streamsize>(sz));
  4231. }
  4232. size_t offset = 0;
  4233. while ((offset + 30) < data.size()) {
  4234. //
  4235. // PK zip format:
  4236. // https://users.cs.jmu.edu/buchhofp/forensics/formats/pkzip.html
  4237. //
  4238. std::vector<char> local_header(30);
  4239. memcpy(local_header.data(), data.data() + offset, 30);
  4240. // if we've reached the global header, stop reading
  4241. if (local_header[2] != 0x03 || local_header[3] != 0x04) break;
  4242. offset += 30;
  4243. // read in the variable name
  4244. uint16_t name_len;
  4245. memcpy(&name_len, &local_header[26], sizeof(uint16_t));
  4246. if ((offset + name_len) > data.size()) {
  4247. if (err) {
  4248. (*err) += "Invalid ZIP data\n";
  4249. }
  4250. return false;
  4251. }
  4252. std::string varname(name_len, ' ');
  4253. memcpy(&varname[0], data.data() + offset, name_len);
  4254. offset += name_len;
  4255. // std::cout << "varname = " << varname << "\n";
  4256. // read in the extra field
  4257. uint16_t extra_field_len;
  4258. memcpy(&extra_field_len, &local_header[28], sizeof(uint16_t));
  4259. if (extra_field_len > 0) {
  4260. if (offset + extra_field_len > data.size()) {
  4261. if (err) {
  4262. (*err) += "Invalid extra field length in ZIP data\n";
  4263. }
  4264. return false;
  4265. }
  4266. }
  4267. offset += extra_field_len;
  4268. // In usdz, data must be aligned at 64bytes boundary.
  4269. if ((offset % 64) != 0) {
  4270. if (err) {
  4271. (*err) += "Data offset must be mulitple of 64bytes for USDZ, but got " +
  4272. std::to_string(offset) + ".\n";
  4273. }
  4274. return false;
  4275. }
  4276. uint16_t compr_method = *reinterpret_cast<uint16_t *>(&local_header[0] + 8);
  4277. // uint32_t compr_bytes = *reinterpret_cast<uint32_t*>(&local_header[0]+18);
  4278. uint32_t uncompr_bytes =
  4279. *reinterpret_cast<uint32_t *>(&local_header[0] + 22);
  4280. // USDZ only supports uncompressed ZIP
  4281. if (compr_method != 0) {
  4282. if (err) {
  4283. (*err) += "Compressed ZIP is not supported for USDZ\n";
  4284. }
  4285. return false;
  4286. }
  4287. // std::cout << "offset = " << offset << "\n";
  4288. // [offset, uncompr_bytes]
  4289. assets.push_back(std::make_tuple(varname, offset, offset + uncompr_bytes));
  4290. offset += uncompr_bytes;
  4291. }
  4292. #if TINYUSDZ_LOCAL_DEBUG_PRINT
  4293. for (size_t i = 0; i < assets.size(); i++) {
  4294. std::cout << "[" << i << "] " << std::get<0>(assets[i]) << " : byte range ("
  4295. << std::get<1>(assets[i]) << ", " << std::get<2>(assets[i])
  4296. << ")\n";
  4297. }
  4298. #endif
  4299. int32_t usdc_index = -1;
  4300. {
  4301. bool warned = false; // to report single warning message.
  4302. for (size_t i = 0; i < assets.size(); i++) {
  4303. std::string ext = str_tolower(GetFileExtension(std::get<0>(assets[i])));
  4304. if (ext.compare("usdc") == 0) {
  4305. if ((usdc_index > -1) && (!warned)) {
  4306. if (warn) {
  4307. (*warn) +=
  4308. "Multiple USDC files were found in USDZ. Use the first found "
  4309. "one: " +
  4310. std::get<0>(assets[size_t(usdc_index)]) + "]\n";
  4311. }
  4312. warned = true;
  4313. }
  4314. if (usdc_index == -1) {
  4315. usdc_index = int32_t(i);
  4316. }
  4317. }
  4318. }
  4319. }
  4320. if (usdc_index == -1) {
  4321. if (err) {
  4322. (*err) += "USDC file not found in USDZ\n";
  4323. }
  4324. return false;
  4325. }
  4326. {
  4327. const size_t start_addr = std::get<1>(assets[size_t(usdc_index)]);
  4328. const size_t end_addr = std::get<2>(assets[size_t(usdc_index)]);
  4329. const size_t usdc_size = end_addr - start_addr;
  4330. const uint8_t *usdc_addr = &data[start_addr];
  4331. bool ret =
  4332. LoadUSDCFromMemory(usdc_addr, usdc_size, scene, warn, err, options);
  4333. if (!ret) {
  4334. if (err) {
  4335. (*err) += "Failed to load USDC.\n";
  4336. }
  4337. return false;
  4338. }
  4339. }
  4340. // Decode images
  4341. for (size_t i = 0; i < assets.size(); i++) {
  4342. const std::string &uri = std::get<0>(assets[i]);
  4343. const std::string ext = GetFileExtension(uri);
  4344. if ((ext.compare("png") == 0) || (ext.compare("jpg") == 0) ||
  4345. (ext.compare("jpeg") == 0)) {
  4346. const size_t start_addr = std::get<1>(assets[i]);
  4347. const size_t end_addr = std::get<2>(assets[i]);
  4348. const size_t usdc_size = end_addr - start_addr;
  4349. const uint8_t *usdc_addr = &data[start_addr];
  4350. Image image;
  4351. std::string _warn, _err;
  4352. bool ret = DecodeImage(usdc_addr, usdc_size, uri, &image, &_warn, &_err);
  4353. if (!_warn.empty()) {
  4354. if (warn) {
  4355. (*warn) += _warn;
  4356. }
  4357. }
  4358. if (!_err.empty()) {
  4359. if (err) {
  4360. (*err) += _err;
  4361. }
  4362. }
  4363. if (!ret) {
  4364. }
  4365. }
  4366. }
  4367. return true;
  4368. }
  4369. size_t GeomMesh::GetNumPoints() const {
  4370. size_t n = points.buffer.GetNumElements();
  4371. return n;
  4372. }
  4373. bool GeomMesh::GetPoints(std::vector<float> *v) const {
  4374. // Currently we only support float3[]
  4375. if (points.buffer.GetDataType() != BufferData::BUFFER_DATA_TYPE_FLOAT) {
  4376. return false;
  4377. }
  4378. if ((points.buffer.GetNumCoords() < 0) ||
  4379. (points.buffer.GetNumCoords() != 3)) {
  4380. return false;
  4381. }
  4382. if ((points.buffer.GetStride() != (3 * sizeof(float)))) {
  4383. return false;
  4384. }
  4385. size_t c = size_t(points.buffer.GetNumCoords());
  4386. size_t n = points.buffer.GetNumElements();
  4387. v->resize(n * c);
  4388. memcpy(v->data(), points.buffer.data.data(), n * c * sizeof(float));
  4389. return true;
  4390. }
  4391. bool GeomMesh::GetFacevaryingNormals(std::vector<float> *v) const {
  4392. if (normals.variability != VariabilityVarying) {
  4393. return false;
  4394. }
  4395. // Currently we only support float3[]
  4396. if (normals.buffer.GetDataType() != BufferData::BUFFER_DATA_TYPE_FLOAT) {
  4397. return false;
  4398. }
  4399. if ((normals.buffer.GetNumCoords() < 0) ||
  4400. (normals.buffer.GetNumCoords() != 3)) {
  4401. return false;
  4402. }
  4403. if ((normals.buffer.GetStride() != (3 * sizeof(float)))) {
  4404. return false;
  4405. }
  4406. size_t n = normals.buffer.GetNumElements();
  4407. size_t c = size_t(normals.buffer.GetNumCoords());
  4408. v->resize(n * c);
  4409. #ifdef TINYUSDZ_LOCAL_DEBUG_PRINT
  4410. std::cout << "fvnormal numelements = " << n << ", numcoords = " << c << "\n";
  4411. #endif
  4412. memcpy(v->data(), normals.buffer.data.data(), n * c * sizeof(float));
  4413. return true;
  4414. }
  4415. bool GeomMesh::GetFacevaryingTexcoords(std::vector<float> *v) const {
  4416. if (st.variability != VariabilityVarying) {
  4417. return false;
  4418. }
  4419. // Currently we only support float3[]
  4420. if (st.buffer.GetDataType() != BufferData::BUFFER_DATA_TYPE_FLOAT) {
  4421. return false;
  4422. }
  4423. if ((st.buffer.GetNumCoords() < 0) || (st.buffer.GetNumCoords() != 2)) {
  4424. return false;
  4425. }
  4426. if ((st.buffer.GetStride() != (2 * sizeof(float)))) {
  4427. return false;
  4428. }
  4429. size_t n = st.buffer.GetNumElements();
  4430. size_t c = size_t(st.buffer.GetNumCoords());
  4431. v->resize(n * c);
  4432. #ifdef TINYUSDZ_LOCAL_DEBUG_PRINT
  4433. std::cout << "fvtexcoords numelements = " << n << ", numcoords = " << c
  4434. << "\n";
  4435. #endif
  4436. memcpy(v->data(), st.buffer.data.data(), n * c * sizeof(float));
  4437. return true;
  4438. }
  4439. static_assert(sizeof(Field) == 16, "");
  4440. static_assert(sizeof(Spec) == 12, "");
  4441. static_assert(sizeof(Index) == 4, "");
  4442. static_assert(sizeof(Vec4h) == 8, "");
  4443. static_assert(sizeof(Vec4f) == 16, "");
  4444. static_assert(sizeof(Vec4d) == 32, "");
  4445. static_assert(sizeof(Matrix4d) == (8 * 16), "");
  4446. } // namespace tinyusdz