| 965 | } |
| 966 | |
| 967 | Expected<std::vector<MeshLoad::NamedMesh>> loadModelsFromObj( |
| 968 | const std::filesystem::path& dir, |
| 969 | bool mergeAllObjects, |
| 970 | const char* data, |
| 971 | const std::vector<size_t>& newlines, |
| 972 | const std::vector<ElementGroup<ObjElement>>& groups, |
| 973 | const MeshLoad::ObjLoadSettings& settings ) |
| 974 | { |
| 975 | MR_TIMER; |
| 976 | Vector<Vector3d,VertId> points; // flat list of all points in this object scope |
| 977 | std::vector<Color> colors; // flat list of all colors in this object scope |
| 978 | std::vector<UVCoord> uvCoords; // flat list of all uv coords in this object scope |
| 979 | |
| 980 | size_t numPoints = 0; |
| 981 | size_t numUVs = 0; |
| 982 | size_t numFaces = 0; |
| 983 | bool colorChecked = false; |
| 984 | bool hasColors = false; |
| 985 | |
| 986 | Expected<MtlLibrary> mtl = unexpected( "absent" ); // all materials |
| 987 | |
| 988 | std::string parseError; |
| 989 | |
| 990 | Timer timer( "prepare groups" ); // calculate sizes and read material |
| 991 | |
| 992 | auto sb = subprogress( settings.callback, 0.0f, 0.2f ); |
| 993 | int groupId = 0; |
| 994 | for ( const auto& g : groups ) |
| 995 | { |
| 996 | switch ( g.element ) |
| 997 | { |
| 998 | case ObjElement::Vertex: |
| 999 | numPoints += ( g.end - g.begin ); |
| 1000 | if ( !colorChecked ) |
| 1001 | { |
| 1002 | colorChecked = true; |
| 1003 | constexpr Vector3d cInvalidColor = { -1., -1., -1. }; |
| 1004 | Vector3d v; |
| 1005 | Vector3d c{ cInvalidColor }; |
| 1006 | std::string_view line( data + newlines[g.begin], newlines[g.begin + 1] - newlines[g.begin] ); |
| 1007 | auto res = parseObjCoordinate( line, v, &c ); |
| 1008 | if ( !res.has_value() ) |
| 1009 | return unexpected( res.error() ); |
| 1010 | hasColors = c != cInvalidColor; |
| 1011 | } |
| 1012 | break; |
| 1013 | case ObjElement::TextureVertex: |
| 1014 | numUVs += ( g.end - g.begin ); |
| 1015 | break; |
| 1016 | case ObjElement::Face: |
| 1017 | numFaces += ( g.end - g.begin ); |
| 1018 | break; |
| 1019 | case ObjElement::MaterialLibrary: |
| 1020 | { |
| 1021 | std::string_view line( data + newlines[g.begin], newlines[g.end] - newlines[g.begin] ); |
| 1022 | // TODO: support multiple files |
| 1023 | std::string filename( line.substr( strlen( "mtllib" ), std::string_view::npos ) ); |
| 1024 | boost::trim( filename ); |
no test coverage detected