diff --git a/.gitignore b/.gitignore index bd99fc5..799efd5 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,5 @@ -outputs/ \ No newline at end of file +outputs/ + +data/objaverse/ + +scripts/__pycache__/ \ No newline at end of file diff --git a/README.md b/README.md index 5b1bb59..6f17fa6 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,10 @@ For the best quality of texture synthesis, there are some necessary pre-processi We provide `scripts/normalize_mesh.py` and `scripts/rotate_mesh.py` to make the mesh preprocessing easy for you. +If you already have a normalized mesh but haven't parameterized it yet, please use `scripts/parameterize_mesh.py` to generate the UV map. + +> NOTE: we expect the mesh to be triangulated. + A mesh ready for next steps should look like this:

@@ -112,6 +116,16 @@ python scripts/generate_texture.py \ If you want some high-res textures, you can set `--device` to `a6000` for 3k resolution. To play around other parameters, please check `scripts/generate_texture.py`, or simply run `python scripts/generate_texture.py -h`. +## Benchmark on Objaverse subset + +To generate textures for the Objaverse objects we used in the paper, please run the following script to download and pre-process those meshes: + +```shell +python scripts/download_objaverse_subset.py +``` + +All pre-processed meshes will be downloaded to `data/objaverse/`. + ## Citation If you found our work helpful, please kindly cite this papers: diff --git a/data/objaverse_subset.txt b/data/objaverse_subset.txt new file mode 100644 index 0000000..21aeb53 --- /dev/null +++ b/data/objaverse_subset.txt @@ -0,0 +1,410 @@ +Bible_3e5393bd35e34531a576e22d45611060 +Bible_ee7660359dda4c90990cb7440211b873 +Bible_f5bf29193be44caaad2df1db3db44871 +CD_player_00a66884dacb498b85701acd1cc77c5e +CD_player_dbf0dbcf4229429088b0a984e8f05666 +Lego_8b1319902fef43dc904a257a377d9676 +Tabasco_sauce_0880be4c17d34b95af74efde0dea22c3 +Tabasco_sauce_d78ccbe406f744b881aa2c339fbd27ef +aerosol_can_10ac5e64861a4cb4868a244d08496b97 +aerosol_can_211e925eaa5c49a2b9216d785413cc2a +aerosol_can_4c8af55af44c4e888fa9e3ca037f65e3 +airplane_3ca2f507a0a749799e16a4eee12e456c +alarm_clock_8464d97835954b7f9d4c35257f8f7bd4 +ambulance_ae7f73580602427b8352cedf8aaec0fa +ambulance_fe533dcb116d4d35bf55fcf5c0bfb008 +apple_25baea74f1914aafb9ddef58d0106969 +apple_b496adbf9b924ff99939ad38330eb3cf +apple_e3173857f9384aa4928daeabff75da44 +apricot_01994d08f4834acd9734f1a4281570d8 +armchair_0e06763d63f44733b99c06ae18dcb13d +armchair_6e35f6fdf1264db4880049b802f18ea2 +armchair_d8072e417dbd476cadb270e39ad3d7c8 +army_tank_fe9bb26f88ce4efd9b0855ea383f3e78 +baby_buggy_a9e7ff47a1c442c9bd97b8fe8bfc8e12 +backpack_9fa2da2c42234b58896e8d23393cac24 +bagel_c2f9b76e6b184138a23dfda89829fa8b +ball_80f10af6cb604d7cbbd141050d093b2b +banana_1787fb8e12f14318899702ae6c502de5 +banana_5d99827c456940bf9055dfe2dbc561e8 +banana_ada7c35a1a5742f1b4c528eb3daee35b +banjo_21d81a73dcdc48a3a4de947e3e4cde2d +banjo_8c375ece6c444908bf8bfe784c332d30 +barrel_341eecd25e7f4914a6d321e71e5629af +barrel_b53fb9b3547148d7afe84a073ccd99db +barrel_eb700168ef994b96bc7865febae8c2ab +baseball_0d784e804a764432a7111671257ffdf7 +baseball_bat_49b1172903c6436f9025bb288d9db518 +baseball_bat_97f741e3820a44a694fe27775dd1a7f5 +baseball_bat_d0bc56c99ce3427db7e925d5b0964256 +baseball_glove_52b2faaf84ff4300b64195757976509a +basket_2a43e6e50fdf4d8aac6bccd9e4ba629d +basket_7f39b77440c4416cab9dbba79f3262a2 +basketball_5fe39851c88f4db5b343fd38ce8ef4ce +basketball_a8fcf2220c264a30aef6bd8fd51898d4 +bathtub_cf373495a56049f6be1692ca6463aa2a +beanbag_0b420d09aa224062ad6c8031c382661e +beanbag_a77f888bac654f8191442e74f0db4e7a +bed_b547d81073b64d3e97200fd3ae9a74af +bed_dc3024aa5e234f4299641f072558b9a8 +bed_ef4fef24c990461986a96f5462c5248d +bedpan_0e5451ae286d40088fcaefa2b6fb5e97 +bench_9ef388cd9cb947f48957a497e8b8184a +bicycle_d518e2ce054541e6b329dc2343307462 +binoculars_885f1fe05f924bd995a89cfc3b6fe8a9 +binoculars_8a3f1ff2c1c14f74915222454eba92b9 +binoculars_b77fcf18510f410c915456193111a8db +birdhouse_8c19d6525acf441b9cf3c1fd91598ff6 +birdhouse_f1852103f68944b680ade1592ea50c1c +birthday_cake_39e6c82654e843dd819a3408374da0a8 +birthday_cake_b095a072c707490ba8ff798e7177748c +blimp_7b142df10734454da1fc8c98a2ccae89 +blimp_c7b8207727da4a2f9f22059a02f21725 +boat_72fed167ee4a4ff09193cf59f30e5033 +bookcase_51d928b33e5549898cc86cbdaf966d83 +bookcase_a4112060b9aa43a8af876f922f962cce +bottle_4f458eea419347639f3e210201cd3a5f +bottle_97802a0adf12404b8370a3b75c5b9237 +bowl_f1eccbd01c884fe28ec65ce699cf7b81 +bread_ba2dccb476b64730a0bf997855245d22 +bread_daf4801f72ae4f9eba9c338afbbb2926 +briefcase_4f4f28032a6e48eba05e51e7ea298334 +briefcase_cb5c52c48f6c4540b2eaae6852267cc5 +broccoli_a5971983ab3e4fa6b395e310490ccb9f +broom_7d8682b03038465c96b3479a0368ec9a +broom_addb9901772f488eac5476b1feb60914 +bucket_1702f71e798b4cc794ec12f8219405b9 +bucket_68d83e2d634940f594df30998aba652c +bucket_998d8d17a4334167a4907f780491dff0 +bulldog_206d1a40d4654d1e940c9ec05b2cc14f +bulldozer_23e952d905ca4bc788517afd9086edd7 +burrito_985466172dd34d4ca3a9b555a09ef1e2 +burrito_9999197bbac04e3796ce1f4f04470490 +cabinet_1bf163160fa34a2bac8c9c6218675478 +cabinet_b1a6eed00f1246d9b8f8f08003c59362 +cabinet_b7e25d2b684747c08e90b8cf446bdb43 +calculator_b4bb8bd7791648fdb36c458fd9a877bf +camera_4b3a4cffbbe4499b9e69eaf3157abf06 +can_32c47e171fc54617aef4c5696f27a7a5 +can_b521c9a1162d45d2b4f138206e114fd2 +candle_222643de666b4dad9924bcf03fc7260a +candle_7816316002f1426c94d4c9b4c59e5696 +candle_e327859b5b66470b9607f57af931646d +canoe_45bd80f76b294b4985b76f055b7f8d72 +canoe_9922d5678af84adeb1c9b479856446ca +cappuccino_04f2c34a3df94e58be97c2830e7e462a +cappuccino_0592fecb8a124d598befd935159bd561 +carrot_53c1ac4a7089403a850519eba65de629 +chair_304253851afd493d958fc8e256c189df +chair_99fc178ecc0943ae81454a3735e2eb5f +chair_c5d80712ee2c4741a5f059530e523a7c +chaise_longue_f25cb76a65ea4d88a92dc4d994cf4094 +chaise_longue_f53f358e46ae4768a97a3ee772dcc314 +chalice_3bc4be75e7634ce0bc8e07b50e2bc369 +chalice_e1a72a2329e942f584e379c24db4fe6a +chalice_f2933520da4a415bac61ed677275d2f9 +chocolate_bar_6e9c67e3adc345a4b12d0e4f825851a2 +cigarette_e3a5fd374386419680a26a3acaa18728 +clipboard_1b418690fedc45739274d05e81b88ffd +clipboard_c8a67ebe663544dd9dca484c16f7f21f +clipboard_f0452a4970e04fc6960bb00bf02d5890 +clock_3031fd7b1adc408ba27ab3515a5c34d8 +clock_87f51c328f854b4582eb55f54b644bd2 +clock_c03d8b43ea2a455eb9f101eef1f0d95f +clutch_bag_5c5a6601578346aa8ce974453909f175 +clutch_bag_c1969377971847a5aa98aab13613d424 +clutch_bag_e0bfc49fde124fb89cd5cacb0be1a1d6 +coconut_49a8eaee73a943e08fb77049f8b0d16d +coffee_maker_383923d4412f4b66937d9c1779a9a0a2 +coffee_maker_6784e4f16a7248518cd5ef1118a2198a +coffee_maker_9a87c4971eed4fd5aa6e1e3441cd1e70 +coffee_table_02302fca239e4d7a9d26ce5cc46225e5 +coffee_table_8d8bd092c4294c55ac726666306365d3 +coffee_table_d53bd92890934d249d4ea2e099ae0461 +coffeepot_7076495f9b5946c596dbd3475972a1db +coffeepot_bb1023a8c09141d29996924e425fe6c5 +comic_book_728d17781c464189953e2d9482373b36 +compass_3ff33f5baae24b9eab100442fce797e7 +compass_5c47b26f85eb4659af66c10c568c1df3 +computer_keyboard_99de8bd7fb8d40c39989ddac0f98214a +computer_keyboard_a884bf6ce8b74648b6813564a443824a +computer_keyboard_b50191176b6a4509aabca39d93bf7c18 +cowboy_hat_2d400d61c1d14401865e8b74a0b72016 +cowboy_hat_4d0db60c85104d8880fab712f158b0b4 +cowboy_hat_e8d5a5d300024a7fa981cd294e97ce60 +crate_2f11377a2e6049049473f854007882d5 +crate_44734b4051d84aa0aeae7c6dad4d8c3f +crate_fb9c3b70ceed474bb0e40717a6ad8ec8 +crown_bdeedbaad80e41f19d6a50b17cbe7051 +crown_bee9ec58623442249c2f531e7f313177 +crucifix_178f5f9db1644cbd86a770291b625a81 +cucumber_9231e77e152d4e54b1673eae6686ba0d +cup_0c770364d18042148f398a0dcc722d9e +cup_7867aa1e7d7041a3af665f329829a0c1 +cup_848e8db6ec734f06ac3920b58905b176 +cupcake_a11f63180d6f460b928ecfe85506d7b9 +cushion_32684986ac4548978035735edbf63709 +cushion_3c4ba0da6dc0439a9161e2def1635d21 +cushion_eef01b5f8ab14e3d8304bf6b437f2760 +dagger_0eb900e627dd4ddc905477d37b6df0c0 +dagger_3b1d248e9ae443ec9a5d154abe7e238d +dagger_d0742ee791ad438f89ec1eec06c1f212 +deck_chair_44f7c6fffc0c4061905e4cab73953a56 +deck_chair_f0162201004b4aea8e29b754459d9f75 +deer_01f33919650c421e91666908db8c421e +desk_1837f10d9b064fd88a607a3d391a17af +desk_9824a5e58892410c956cfaf9f2b07c29 +dog_85229c525ded401ca3a1456e1f238758 +doll_a62703a137174702ae9de50d5d33524d +dolphin_08a93ccc711c44d89eac6a845c927b4b +dolphin_9c2c626c8dbb414eb632cc7923a69474 +dolphin_c9ec32a675ec44c7a5540eb3abfceddc +doughnut_1e8d2897bdbc4f8fb2b8ed9ab9fac453 +doughnut_3d16c309fcbb4ec488faecb209e4ce2e +doughnut_e5db252dcdc74bdf81cc4d7be5c03160 +duffel_bag_fad3c3c733f04bf599233bae74921ca6 +dumbbell_33d7aecfa8504b52b4740e684eb0eaca +dumbbell_9a511d27d3e146189cf85535d010c145 +dumbbell_d01dad33772a42bfb6400291cefcc535 +dumpster_7cce16ad3deb472086c9997e01884115 +dumpster_bed7cc2208ae481f800a1d8516839be5 +dumpster_f80a2a0af6924562be10be7354b7a72f +elephant_6eb0b6ef28e94f5bad9e4ac795c1d85d +fan_87b4aecaf25a424a81f76d7c5da5b701 +faucet_13c190d8bd9340759c7c4480feb84c25 +faucet_37c810a063e84b93aa4405de11cd2866 +faucet_6023c6badaa646fb936218f77eb4de11 +file_cabinet_f323dd4bb9f640a4859bd8dd31ec233c +file_cabinet_f5a20366fbfc4ee686025a5dd374d323 +fire_extinguisher_3bb4f120d0df42fcba3dc4f550aaa9e5 +fire_extinguisher_a390303a1e8e49afa629aa047d6493b1 +fire_extinguisher_ac2076c22a474f5c9b533727966d88e2 +first-aid_kit_38e725fbd2a24183a8f4563b68865e5f +fish_81d01e6ce8f745778e2629bca80724af +flashlight_147f57282f7046b09bc540bab1370db0 +flashlight_576daeaa281840cfb3ece4850cc42469 +forklift_99325395edd44438b36ad04cb308a3a0 +frog_0e6df765d30943bd877970b3da1aa90d +frying_pan_09c0e8587a1148548a85014c34ee76c7 +frying_pan_127e434667c54313b9a9300404f7f8bd +frying_pan_a3a5af14a6ef47fea2e513140503df1a +gargoyle_cb31805592fc4a4a99d9a294cbe50694 +globe_f5beb76618cb40c9adcc4b3a40c615a3 +glove_b0c4b928c9ec4c3b997c35d9f7dd31a2 +goldfish_08cc55fc36994e04ad24bf36b9aef6e5 +goose_3784966feebe435b9a1bcd99d17800d9 +guitar_4142c4c8d5b8439eb40f68680f265df9 +guitar_4281970c9fe94a778df26fa6f0c58a96 +guitar_a1ad2734fdf14d0b90e90aea8a6c1dad +gun_b45efecfd928440b9e7283789e5a9c3d +hair_dryer_3ed91f860fc6461cbe95361f3b80e1c9 +hair_dryer_8ac03ddde0e349b18766e4dad7edab26 +hairbrush_8a5b6393546844d4913f0888042b90db +hamburger_488802f3c3ad405f8a180bc2f67f04ce +hamburger_e9cda9a048e64f9886a7d71d90f466b6 +hammer_1b32c678cb9e4d14805e48e77891c459 +hammer_5bdc836016a3444ea140b34d47fee024 +hammer_79f66456163749c0a8ed733698ca5a16 +hardback_book_0fa0174b26d34275bf09436927d42623 +hardback_book_b52fdceb5c4d4b94a78306ff13ab9872 +helicopter_209c56eb6c36418abafafca259a8b818 +helmet_1d489db9cdc24161a7537926a20bb17b +helmet_4016930e82234387b4a1fcd3c5bb0c12 +helmet_7b45769ec16e4575b3fdf3f324f1c471 +highchair_925ccdc0b8d94d1f8250ac6faa9a1bae +hippopotamus_aae1df2e73e141c081c92f64595a7d25 +hockey_stick_3f6b365520474d6c8353b40afece41dd +hourglass_baafc6537f2c4b6696ff0829cc32f772 +hourglass_bcd15948e8124461bb811e95bf848552 +hummingbird_b1c02672937d4f2ba7124639c0781039 +iPod_6839a82c7c644fe5a99fce0bf11be727 +iPod_95c2cdb3812149c88daf1dc8431d1e05 +iPod_f24b0ed98e8e46f3a8441ebcb6f055f6 +jar_3de9bc73be624f47876d1a34b98813ab +jar_72d084f7de4c4e599940410963702493 +jeep_33177fb8529643b5a263653e4f706e4d +jeep_5cd3ea8eb94c4f5597cc086b2df40e58 +jet_plane_804d6814818247978f28d12efcc38cce +jet_plane_ca46149feec7481289f4a3829c8a536d +keg_0a3da81bfa904cafa446ab97e7a62cad +keg_c8208a0a46304cf8a3b78c21dcf2dba7 +keg_d0fc5ee914c64e12a730f751df2a0f34 +kettle_057932f264fe4f84b070fc3d9104fde8 +kettle_0c55bd8e29384070a72c33ef744d11be +kettle_4b277d86dbde4b538abd74266d0acb73 +key_7dd0e287b9634b9ab07ef7028e9e5e5d +key_a03f60e8464e494a89a8565d31d57471 +key_d63a3622b7d24be785aee44635750fed +knife_064fa20765464def90551197e32da7bb +knife_6c13b2e374784df680276735ad6f1aa5 +knife_ec9c547a71a5441d8a066abed15ab62a +ladybug_1fc1cabfad294fcd91689426f8b44554 +ladybug_c40bca9926264486be17efa258625b77 +lantern_583a67982908427298dd3e9204bdb4f2 +laptop_computer_9e37ff6c22094e91a81e9e3be1e32b80 +laptop_computer_a5483e74a73143cdb3a453ebd167ce06 +lemon_2a9e10ffd5b0405eaabfe496d61de0bd +lightbulb_fc7dcd48bbce43c2b0b458a7beaec12d +lizard_ab30351d594f40fa92ec4e98fec412e5 +machine_gun_a0c58606b1fd434a8db6983cf30c5375 +machine_gun_ee1c36acc61749f787be7e4a694e3b1f +martini_ca451fe549c148bebe3666ea79f7249c +matchbox_d6594cf163044fce92e4e8f539257391 +microscope_4530d07e89fd46fcab248e855cf5dc0f +microscope_d40fdecddc254175996276153ea5ed7d +microwave_oven_34a92d45ac344761a55b9fc69e0af333 +microwave_oven_59b932c6bf7842d59830e1b45bc9c261 +milk_4b64a7bbfc974893bd3a9c77cd3c9d2b +milk_4f8003c35c13451eaf176ba3e44de20b +milk_can_d7fc643e570545fb835e55d810cf597d +milk_can_ee5edb945f33416a9e63f3b4aa665d56 +milk_e0b6c3a33221476cbb321468586677f9 +minivan_6f2f754c78794734b794237913ba97cc +minivan_98d85b403ba0426f84636b575319e4f7 +money_49f31b8a421c4da1b9043fc53c9a5eb0 +motorcycle_4caff3c560474f8988a37d7ceed5236d +muffin_511aa069fb8f4e759de014e569b22a05 +muffin_95c65289eab9470c9b74df95e5dc4b86 +mug_922cd7d18c6748d49fe651ded8a04cf4 +mushroom_0bbf336a2cb2467bb34608e6b38ef3ff +mushroom_357416df2f5740a183e26c8b4c74a55c +onion_b110a32f87714dbabc431410e47b9cab +ottoman_8d23019e11a64894a8cdbb30e36bf1d6 +ottoman_a2f2aef33fb942cc9d72d13df8a8b09f +ottoman_b3485341f15240279c180685f0e2cb86 +pancake_d96d5cd080e148898199ca775519b593 +pelican_ce594691279644ccb366dce0658ce756 +pen_44b6c784e189434596f126df05b7dfe2 +pen_9e0dba29de734ac4b20060ec873dc36c +pencil_768e1a7e70ca4badb5cec0705c5a1b7c +pencil_8b0f41f8b2dc475ca0083f381abc54bd +pencil_box_160d40d975f94edfa5eb6e6f6a4201ee +pencil_box_86ccd4717a3e423a98aebcca7fac3b7a +pencil_fcab4a86262340a4ab7a3d9ea0585f85 +piano_1880032c6a634cf18b6e58e0972d4e90 +pickup_truck_40c94d8b31f94df3bd80348cac8624f1 +pickup_truck_df3578dca7f844ab8b7205a1fbea5ed5 +pie_57396e794e2947c5b29c36c7d4764dc3 +pigeon_901d1a2e9e26465db2432939b35bc384 +piggy_bank_ac418fa936fb448b8eac927ca99bbf30 +pillow_eab682dd4a834a2d8c318cbcfa65cb36 +pistol_dc0d58d286ad4efca1b1d68c278c518f +pliers_a3a6436253c244cca0c280b9b4026c4b +polar_bear_5c288986918b429fa5fd04edad5cf60e +police_cruiser_3fee3d9c85b8468bb18833bf9521a87b +police_cruiser_f1f9ffc006ce4b9c8661ef9a36951f83 +pot_6b77d17ccf304ebc9e576d1ab9c5f94b +pretzel_9ce8ab24383c4c93b4c1c7c3848abc52 +pudding_16c2f3b8706f4fd7b64139238f5ab1f8 +pudding_5af966079ae64db9b89dd826ab6b54aa +pumpkin_4e1a4eb6b9854983b66098d989dfc91a +pumpkin_94244ddae2a0411fad12da680912b238 +race_car_8dd45092d0d34a398d1c0d8b1591a0f2 +radish_673907bd73384332b426d2dd8cc5edec +rat_2b92a90c3fdd4460ab3ba2212868cc2f +rat_ba8557c211ef42cc81aeb1103110c422 +refrigerator_55325e3b09ac48b2ae3803bccf804741 +refrigerator_8e1fddb38fa8400c9fcc784abe29aaaa +remote_control_35ac912c7dc14175ab8be82a2c5fe551 +remote_control_424f51f77f7c4824a1453d1706f3f914 +remote_control_f1bbc61a42b94ee9a2976ca744f8962e +rifle_2148cca2447d455d90b2001df1614a7a +rifle_436c3cc7778d49ada714c4f4df894445 +rifle_6101793f444f40b0b2c238a7b2eb6e78 +rocking_chair_897ce33a65d04bb69eb3d87d0742464f +rocking_chair_aad16a6c11fd4321b515f3292f45844b +rocking_chair_db49335b96b94c4da10892f09ff6ee0c +saltshaker_5ba5959ecc044c5fa44dded4c75ea25a +saltshaker_c994f981028e4c4187d666e7c2620e4a +saucepan_057934f97c4042e09a9882543dd5341e +saucepan_e9bb779c489140518c4a9882636d1c8f +sausage_5bec36e4ffb1434e8136088a6314bb6c +sausage_602747b4fe4d435e8a37c7a2e3edce03 +school_bus_cd59a3e9fcea4e3cbb6918c1268a94e3 +screwdriver_0a154cfc51c4417485ddd19637982b33 +screwdriver_4cefe2f12a684cc4bf25c0e9f39b3d16 +screwdriver_82c3c56910be4bc9a1c973ea0c3b66a0 +sewing_machine_4f6c74f9f904439b8554078d1be14821 +shark_19c928e69d3748ea941e6c5537c7502b +shark_aeb86b5a9233452a841dcf1882f22547 +sheep_67abff7459f34afca11e3effab62c761 +shield_041ee3f9d8ce453dbdc1a696431041c6 +shield_6e6984811b3c4e9ea5fd16e1fa47517e +shield_f405dd5b3e304f66bb4502467ca7fec2 +shoe_b601649de568470db6e9d8d5c9c76b73 +shopping_bag_c7da540534134560af463fdd29ed209f +shovel_27e4c28f2ad94fc3bd5dac5a5165e4ab +shovel_3d90bd005c324876a49a19e694325173 +skateboard_59e9c369ae7148378c496aef09fa7cf1 +skateboard_c60420a840134dc9b4646f43911906d1 +snowman_37d1202f7f45483a88f5890c6daf8885 +snowman_a631ab27f32949e6a8f2ed94d040b9eb +soccer_ball_3ceae2eee6264843a77aaaf298134744 +soccer_ball_6ef2e4a19ece4c568698e298c925bd3c +sofa_a0d66f10a850469c9cb04c3cecc62a05 +sofa_bed_261076b1e9e94223bfb59a0d5577dd82 +sofa_ef3832963ab24d129ec88fd4cac4818f +sofa_f8def3c5f656454c935fe3d626ed9fab +space_shuttle_2a9c2b23a4124fc29f62bb1ae2e522f6 +space_shuttle_430a040458ad4db5b4fcde4c7db15e1a +space_shuttle_892969a88e71495d9e869f96c95f0abf +spider_6890f5b34af947f4b416a23cbd4e56c0 +stool_8ab0baf0f68f42788285e4f952c454ba +stool_b221ad482e084c449408c229cab380d6 +suitcase_d622ab7c84f341628b6dd516ce39ccad +suitcase_fb509f0edeae4f75ab4368a8133f4ccc +sunflower_3e38e8351c6e48e786cdd8bd181a09db +sunflower_589a1058cb424781b4970a469bf4f538 +sunhat_3598d9e686ad46dc838e1443b910d91e +sunhat_f7bbf5d03a604452916d5c0cc85c867c +sushi_5ee3c671e6014f04ba3971c243acdfb9 +sword_814a3d5f916e4439aa4bac2aa7b812ec +sword_ac1ceaf3568c4f7ca335851279f922fc +sword_ae3dcd8addb54abbb4c3b520571f1909 +syringe_324b3ed0026940808db353c8c6d7450e +syringe_7c0620856f0444cf8e9bbcd8670b6247 +table_4d7f3c58a09c4a899e68ad837edd2b6b +table_77ec465b45574d12bf527a26ece473e8 +table_lamp_2fd7954d31dc47d7a48f9e0cb8faeeba +table_lamp_346d74713027437992db6afabb768694 +teacup_49d0b382def54ff1b544cc6293ea1b22 +teacup_edbb7502a3f54d638f7b66aaf3716b80 +teakettle_73d7b6f9a0b7410b945205338b090566 +teakettle_d3307264b4b14e079ba5c861eeac839e +teapot_56dde1d5fdb44867b5a48e232cd95b2f +teddy_bear_f6a6667cd63240639a4ea9598ca4d8fc +telephone_b812224a5c354de5854c82547e1dc4ca +telephone_bc379c569b8e4c34a1f9e64e626fe66c +television_set_6099a956fb4c4a21b2957bc2e4874d55 +television_set_80a0f58dcb604405869637c8387f5d36 +toilet_1207c326615c43a78e9944c33ba401a5 +toilet_531e32a371004849bd72a507aaf81643 +toilet_60e93498c4ca47d48af8b7c60e0916c2 +toothbrush_2f4bd3002b2e456c99abee54b488967d +toothbrush_8be42d538a6543a0981e3e48b11410fe +trailer_truck_64d88784946d4172b9e8acd3b4154f8b +trailer_truck_8cd40f962f2c440c9caf1db1a505357f +trailer_truck_cbc508a5ad424d79b2f2c8a3de7e1cd3 +trash_can_269cc79ce7ca4dcf88030e7b7151dc36 +trash_can_e5e0f42aec4846a0bff905d0601fdd1e +tricycle_158d45e79a9b449fbff24ddb7b36446d +truck_4cb3b3029ed142cc9291e83e93a293a0 +truck_9e3400f575a541b88417e85f766fc773 +typewriter_0b6766c2df0e4901b8c387283d544027 +typewriter_22536ec10cc2462db661e5279d83ab7e +umbrella_54daa7a355d64f29a82695adc2ac1918 +urn_77db9590a6314582ac9504e785449785 +videotape_29642e0a9cad4275ac78c1d4f12660d6 +violin_52d850660e1d4358ad96b922ea75f62c +watch_a9ca3807f0f54df689bb6e77b732bc84 +watch_e3a78e329e7d4050a1c9d1c0bd19e47f +water_cooler_d345524901c7482393c2c93560f2ed90 +water_faucet_5b8d5bb5ecdd4d8a80f71eabd4d08249 +water_faucet_69de7b6bd3004eba8c6aa41d37858d86 +watermelon_83f6af2628494e0384a995fcc7815240 +watermelon_d9c7f3d06d2a4e4eae0fd0cfca9870aa +windmill_30deb775546f4059905c687933a32d1f +wrench_0ac105eb165c40aba9dab37c0615bb17 +wrench_412fdac55c8649a89992dd52ac4d9e19 +wrench_a0fe4b9d7d324267b975f30bbfa3a81e +zucchini_457cf1ce9c254830b59fc113371e5820 diff --git a/requirements.txt b/requirements.txt index c5e3852..a94121e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,4 +11,7 @@ gradio pytorch-lightning==1.9.1 omegaconf triton -accelerate \ No newline at end of file +accelerate +objaverse +mathutils +iopath==0.1.10 \ No newline at end of file diff --git a/scripts/blender_process_glb.py b/scripts/blender_process_glb.py new file mode 100644 index 0000000..3f314fe --- /dev/null +++ b/scripts/blender_process_glb.py @@ -0,0 +1,67 @@ +""" + Script of pre-processing GLB meshes via Blender + NOTE: Blender must be installed first! + + Utils: + ` + blender --background --factory-startup \ + --python scripts/blender_process_glb.py -- \ + \ + + ` + +""" + +import sys +import pathlib + +import numpy as np +from mathutils import Vector, Matrix + +try: + import bpy +except ImportError: + print("=> Please install Blender and add it to the PATH") + +def normalize(vector): + return vector / (np.linalg.norm(vector) + 1e-8) + + +def center_and_rescale(): + all_verts = [] + for object in bpy.context.scene.objects: + if object.name not in ["Camera", "Light"] and object.data is not None: + vertices = object.data.vertices + verts = [object.matrix_world @ vert.co for vert in vertices] + np_verts = np.array([vert.to_tuple() for vert in verts]) + all_verts.append(np_verts) + + all_verts = np.concatenate(all_verts, axis=0) + mean_position = (all_verts.max(axis=0) + all_verts.min(axis=0)) / 2 + bounds = all_verts.max(axis=0) - all_verts.min(axis=0) + scale_factor = 1 / bounds.max() + + for object in bpy.context.scene.objects: + if object.name not in ["Camera", "Light"] and object.data is not None: + for vert in object.data.vertices: + non_inverted_new_position = (object.matrix_world @ vert.co - Vector((mean_position[0], mean_position[1], mean_position[2]))) + non_inverted_new_position = Vector((scale_factor, scale_factor, scale_factor)) * non_inverted_new_position + new_position = object.matrix_world.inverted() @ non_inverted_new_position + vert.co = new_position + +bpy.data.objects['Cube'].select_set(True) +bpy.ops.object.delete() +bpy.data.objects['Light'].select_set(True) +bpy.ops.object.delete() + +sys.argv = sys.argv[sys.argv.index("--python") + 2:] +path_to_glb = pathlib.Path(sys.argv[1]) +obj_dir = pathlib.Path(sys.argv[2]) + +print("=> Loading and preprocessing objects") +bpy.ops.import_scene.gltf(filepath=str(path_to_glb)) +center_and_rescale() + +output_dir = obj_dir / path_to_glb.stem +output_dir.mkdir(exist_ok=True) +bpy.ops.export_scene.obj(filepath=str(output_dir / "mesh.obj")) diff --git a/scripts/download_objaverse_subset.py b/scripts/download_objaverse_subset.py new file mode 100644 index 0000000..d18b124 --- /dev/null +++ b/scripts/download_objaverse_subset.py @@ -0,0 +1,151 @@ +import os +import sys +import objaverse +import subprocess +import xatlas +import trimesh + +from PIL import Image +from pathlib import Path +from tqdm import tqdm + +# torch +import torch + +from torchvision import transforms + +# pytorch3d +from pytorch3d.io import ( + load_obj, + save_obj +) + +# customized +sys.path.append(".") +from scripts.parameterize_mesh import parameterize_mesh + +SUBSET = "./data/objaverse_subset.txt" +DATA_DIR = "./data/objaverse" + +# Setup +if torch.cuda.is_available(): + DEVICE = torch.device("cuda:0") + torch.cuda.set_device(DEVICE) +else: + DEVICE = torch.device("cpu") + +os.makedirs(DATA_DIR, exist_ok=True) + +def get_objaverse_subset(): + with open(SUBSET) as f: + ids = [l.rstrip().split("_")[-1] for l in f.readlines()] + + return ids + +def adjust_uv_map(faces, aux, device=DEVICE): + """ + adjust UV map to be compatiable with multiple textures. + UVs for different materials will be decomposed and placed horizontally + + +-----+-----+-----+-- + | 1 | 2 | 3 | + +-----+-----+-----+-- + + """ + + textures_ids = faces.textures_idx + materials_idx = faces.materials_idx + verts_uvs = aux.verts_uvs + + num_materials = torch.unique(materials_idx).shape[0] + + try: + new_verts_uvs = verts_uvs.clone() + + # HACK map verts_uvs to 0 and 1 + new_verts_uvs[new_verts_uvs != 1] %= 1 + + for material_id in range(num_materials): + # apply offsets to horizontal axis + faces_ids = textures_ids[materials_idx == material_id].unique() + new_verts_uvs[faces_ids, 0] += material_id + + new_verts_uvs[:, 0] /= num_materials + new_faces_uvs = faces.textures_idx + except AttributeError: + new_verts_uvs = torch.tensor([ + [0, 0], + [0, 1], + [1, 0] + ]).to(device) + + num_faces = faces.verts_idx.shape[0] + new_faces_uvs = torch.tensor([[0, 1, 2]]).to(device).long() + new_faces_uvs = new_faces_uvs.repeat(num_faces, 1) + + return new_verts_uvs, new_faces_uvs + +def load_and_adjust_mesh(mesh_path, device=DEVICE): + verts, faces, aux = load_obj(mesh_path, device=device) + + dummy_texture = Image.open("./samples/textures/white.png").convert("RGB").resize((512, 512)) + + # collapse textures of multiple materials to one texture map + new_verts_uvs, new_faces_uvs = adjust_uv_map(faces, aux) + + return verts, faces, new_verts_uvs, new_faces_uvs, dummy_texture + +def collapse_objects(input_path, output_path, device=DEVICE, inplace=False): + verts, faces, new_verts_uvs, new_faces_uvs, dummy_texture = load_and_adjust_mesh(input_path) + output_path = input_path if inplace else output_path + os.makedirs(output_path.parent, exist_ok=True) + + texture_map = transforms.ToTensor()(dummy_texture).to(device) + texture_map = texture_map.permute(1, 2, 0) + + save_obj( + str(output_path), + verts=verts, + faces=faces.verts_idx, + decimal_places=5, + verts_uvs=new_verts_uvs, + faces_uvs=new_faces_uvs, + texture_map=texture_map + ) + +def remove_tails(mtl_path): + with open(mtl_path) as f: + mtl_data = [l.rstrip() for l in f.readlines()] + + with open(mtl_path, "w") as f: + for l in mtl_data: + if "map_Bump" not in l and "map_Kd" not in l: + f.write(l+'\n') + +if __name__ == "__main__": + objaverse_subset = get_objaverse_subset() + + # cache objects to ~/.objaverse/ + objects = objaverse.load_objects(objaverse_subset) + + print("=> processing...") + for key, value in tqdm(objects.items()): + # convert glb to obj + cmd = [ + "blender", # NOTE please make sure you installed blender + "--background", "--factory-startup", "--python", "scripts/blender_process_glb.py", "--", + str(value), + DATA_DIR + ] + _ = subprocess.call(cmd, stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL) + + output_dir = Path(DATA_DIR) / str(Path(value).stem) + + obj_path = output_dir / "mesh.obj" + mtl_path = output_dir / "mesh.mtl" + + remove_tails(mtl_path) + collapse_objects(obj_path, obj_path, DEVICE, inplace=True) + parameterize_mesh(obj_path, obj_path) # xatlas produces great UVs + + print("=> done!") \ No newline at end of file diff --git a/scripts/parameterize_mesh.py b/scripts/parameterize_mesh.py new file mode 100644 index 0000000..093a675 --- /dev/null +++ b/scripts/parameterize_mesh.py @@ -0,0 +1,20 @@ +import xatlas +import trimesh +import argparse + +def parameterize_mesh(input_path, output_path): + # parameterize the mesh + mesh = trimesh.load_mesh(input_path, force='mesh') + vertices, faces = mesh.vertices, mesh.faces + + vmapping, indices, uvs = xatlas.parametrize(vertices, faces) + xatlas.export(str(output_path), vertices[vmapping], indices, uvs) + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("--input_path", type=str, required=True) + parser.add_argument("--output_path", type=str, required=True) + args = parser.parse_args() + + parameterize_mesh(args.input_path, args.output_path) + \ No newline at end of file