| 565 | } |
| 566 | |
| 567 | Expected<MeshLoad::NamedMesh> loadSingleModelFromObj( |
| 568 | const std::filesystem::path& dir, |
| 569 | const Vector<Vector3d, VertId>& points, // all points from file |
| 570 | const std::vector<Color>& colors, // all colors from file |
| 571 | const std::vector<UVCoord>& uvCoords, // all uvs from file |
| 572 | ObjFaces& faces, // all faces from file, this object's vertex ids will be replaced with new unique values |
| 573 | const std::vector<MaterialScope>& materialScope, // all material scopes from file |
| 574 | size_t minFace, size_t maxFace, // this model faces span in `faces`, max face excluding |
| 575 | const MeshLoad::ObjLoadSettings& settings, |
| 576 | const MtlLibrary* mtl ) // optional materials, if nullptr `materialScope` will be ignored |
| 577 | { |
| 578 | MR_TIMER; |
| 579 | assert( faces.face2vert.size() == faces.face2texv.size() ); |
| 580 | |
| 581 | bool haveColors = false; |
| 582 | bool haveUVs = false; |
| 583 | int firstVert = -1; |
| 584 | if ( minFace < faces.size() ) // do not crash if minFace = 0 and faces are empty |
| 585 | { |
| 586 | haveUVs = faces.numTexVerts( minFace ) != 0; |
| 587 | firstVert = faces.getVert( minFace, 0 ); |
| 588 | } |
| 589 | if ( firstVert < 0 ) |
| 590 | firstVert = int( points.size() ) + firstVert; |
| 591 | else |
| 592 | --firstVert; |
| 593 | if ( firstVert < 0 || firstVert >= points.size() ) |
| 594 | return unexpected( "Out of bounds Vertex ID in OBJ-file" ); |
| 595 | haveColors = firstVert < colors.size(); |
| 596 | |
| 597 | Timer timer( "prepare VertexRepr" ); |
| 598 | |
| 599 | auto getVertexRepr = [&] ( size_t fId, int ind ) -> Expected<VertexRepr> |
| 600 | { |
| 601 | VertexRepr repr; |
| 602 | repr.vId = faces.getVert( fId, ind ); |
| 603 | if ( repr.vId < 0 ) |
| 604 | repr.vId = int( points.size() ) + repr.vId; |
| 605 | else |
| 606 | --repr.vId; |
| 607 | if ( repr.vId < 0 || repr.vId >= points.size() ) |
| 608 | return unexpected( std::string( "Out of bounds Vertex ID in OBJ-file" ) ); |
| 609 | |
| 610 | if ( faces.face2texv[fId] + ind < faces.face2texv[fId + 1] ) |
| 611 | { |
| 612 | repr.vtId = faces.getTexVert( fId, ind ); |
| 613 | if ( repr.vtId < 0 ) |
| 614 | repr.vtId = int( uvCoords.size() ) + repr.vtId; |
| 615 | else |
| 616 | --repr.vtId; |
| 617 | if ( repr.vtId < 0 || repr.vtId >= uvCoords.size() ) |
| 618 | return unexpected( std::string( "Out of bounds Texture Vertex ID in OBJ-file" ) ); |
| 619 | } |
| 620 | return repr; |
| 621 | }; |
| 622 | |
| 623 | std::string error; |
| 624 | tbb::task_group_context ctx; |
no test coverage detected