SkillAgentSearch skills...

Rapidobj

A fast, header-only, C++17 library for parsing Wavefront .obj files.

Install / Use

/learn @guybrush77/Rapidobj
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

rapidobjrapidobj

Standard License Platform Build Status

About

rapidobj is an easy-to-use and fast single-header C++17 library that loads and parses Wavefront .obj files.

The .obj file format was first used by Wavefront Technologies around 1990. However, this 3D geometry file format did not age well. An .obj file is a text file and, consequently, large models take a lot of of disk space and are slow to load and parse. Moreover, after loading and parsing, additional processing steps are required to transform the data into a format suitable for hardware (i.e. GPU) rendering. Nevertheless, .obj files are common enough that it's useful to have an efficient way to parse them.

Benchmarks

rapidobj's API was influenced by another single header C++ library, tinyobjloader. From users' point of view, the two libraries look fairly similar. That said, tinyobjloader has been around for some time; it is a mature and well tested library. So, why use rapidobj library? It is fast, and especially so when parsing large files. It was designed to take full advantage of modern computer hardware.

See Benchmarks page.

For an independent evaluation of this and other .obj parsers, check out Comparing .obj parse libraries.

Integration

Prerequisites

You will need a C++ compiler that fully supports C++17 standard. In practice, this means:

  • GCC 8 or higher
  • MSVC 19.14 or higher
  • Clang 7 or higher

If you intend to use CMake as your build system, you will need to install CMake version 3.20 or higher.

Manual Integration

The simplest way to integrate the library in your project is to copy the header file, rapidobj.hpp, to a location that is in your compiler's include path. To use the library from your application, include the header file:

#include "rapidobj.hpp"

To compile your project, make sure to use the C++17 switch (-std=c++17 for g++ and clang, /std:c++17 for MSVC).

There are some extra considerations when building a Linux project: you need to link your application against libpthread library. For example, assuming g++ compiler:

g++ -std=c++17 my_src.cpp -pthread -o my_app

:page_facing_up: If you are using gcc version 8, you also have to link against the stdc++fs library (std::filesystem used by rapidobj is not part of libstdc++ until gcc version 9).

CMake Integration

External

This section explains how to use rapidobj external to your project. If using the command line, perform cmake configuration and generation steps from inside the rapidobj folder:

cmake -B build .

The next step is to actually install the rapidobj package:

cd build
sudo make install

The install command will copy the files to well defined system directories. Note that this command will likely require administrative access.

The only remaining step is to find the rapidobj package from inside your own CMakeLists.txt file and link against it. For example:

add_executable(my_app my_src.cpp)

find_package(RapidObj REQUIRED)

target_link_libraries(my_app PRIVATE rapidobj::rapidobj)

rapidobj cmake script places the header file in a rapidobj subfolder of the include directory. Consequently, the include directive in your code should look like this:

#include "rapidobj/rapidobj.hpp"

What if you don't want to install rapidobj in a system directory? rapidobj allows you to specify custom install folders. CMake cache variable RAPIDOBJ_INCLUDE_DIR is used to set header file install location; RAPIDOBJ_CMAKE_DIR is used to set cmake files install location. For example, to install rapidobj in a folder local inside your home directory, the cmake configuration and generation steps are as follows:

cmake -B build -DRAPIDOBJ_INCLUDE_DIR=${HOME}/local/include -DRAPIDOBJ_CMAKE_DIR=${HOME}/local/cmake .

The install step is almost the same as before:

cd build
make install

The only difference is that administrative access (i.e. sudo) is no longer required since the destination is users' home folder, as opposed to system folders.

Because the files have been installed to a custom location that CMake does not know about, CMake cannot find the rapidobj package automatically. We can fix this by providing a hint about the cmake directory whereabouts:

add_executable(my_app my_src.cpp)

find_package(RapidObj REQUIRED HINTS $ENV{HOME}/local/cmake)

target_link_libraries(my_app PRIVATE rapidobj::rapidobj)

Once the package has been successfully installed, rapidobj directory can be deleted.

Embedded

Another way to use rapidobj is to embed it inside your project. In your project's root, create a folder named thirdparty and then copy rapidobj to this folder. Installation is not required; it is sufficient to add rapidobj's subfolder to your project:

add_executable(my_app my_src.cpp)

add_subdirectory(thirdparty/rapidobj)

target_link_libraries(my_app PRIVATE rapidobj::rapidobj)

If you do not wish to manually download and place rapidobj files, you can automate these steps by using CMake's FetchContent module:

add_executable(my_app my_src.cpp)

include(FetchContent)

FetchContent_Declare(rapidobj
    GIT_REPOSITORY  https://github.com/guybrush77/rapidobj.git
    GIT_TAG         origin/master)

FetchContent_MakeAvailable(rapidobj)

target_link_libraries(my_app PRIVATE rapidobj::rapidobj)

API

ParseFile

Loads a Wavefront .obj data from a file, parses it and returns a binary Result object.

Signature:

Result ParseFile(
    const std::filesystem::path& obj_filepath,
    const MaterialLibrary&       mtl_library = MaterialLibrary::Default());

Parameters:

  • obj_filepath - Path to .obj file to be parsed.
  • mtl_library - MaterialLibrary object specifies .mtl file search path(s) and loading policy.

Result:

  • Result - The .obj file data in a binary format.
<details> <summary><i>Show examples</i></summary>
rapidobj::Result result = rapidobj::ParseFile("/home/user/teapot/teapot.obj");
</details>

ParseStream

Loads a Wavefront .obj data from a standard library input stream, parses it and returns a binary Result object. Because input streams are sequential, this function is usually less performant than the similar ParseFile function.

Signature:

Result ParseStream(
    std::istream&          obj_stream,
    const MaterialLibrary& mtl_library = MaterialLibrary::Default());

Parameters:

  • obj_filepath - Input stream to parse.
  • mtl_library - MaterialLibrary object specifies .mtl file search path(s) and loading policy.

Result:

  • Result - The .obj file data in a binary format.
<details> <summary><i>Show examples</i></summary>
std::ifstream stream("/home/user/teapot/teapot.obj");
rapidobj::Result result = rapidobj::ParseStream(stream);
</details>

MaterialLibrary

An object of type MaterialLibrary is used as an argument for the Parse functions. It informs these functions how materials are to be handled.

Signature:

struct MaterialLibrary final {
    static MaterialLibrary Default();
    static MaterialLibrary Default(Load policy);
    static MaterialLibrary SearchPath(std::filesystem::path path, Load policy = Load::Mandatory);
    static MaterialLibrary SearchPaths(std::vector<std::filesystem::path> paths,
                                       Load policy = Load::Mandatory);
    static MaterialLibrary String(std::string_view text);
    static MaterialLibrary Ignore();
};

Default()

A convenience constructor.

For ParseFile, this constructor is identical to MaterialLibrary::SearchPath(".", Load::Mandatory).

For ParseStream, this constructor is identical to MaterialLibrary::Ignore(), except that Mesh::material_ids will be populated.

<details> <summary><i>Show examples</i></summary>
// Default search assumes .obj and .mtl file are in the same folder.
//  
// home
// └── user
//     └── teapot
//         ├── teapot.mtl
//         └── teapot.obj
Result result = ParseFile("/home/user/teapot/teapot.obj", MaterialLibrary::Default());
// MaterialLibrary::Default can be omitted since it is the default argument of ParseFile.
//
// home
// └── user
//     └── teapot
//         ├── teapot.mtl
//         └── teapot.obj
Result result = ParseFile("/home/user/teapot/teapot.obj");
// MaterialLibrary::Default can be omitted since it is 
View on GitHub
GitHub Stars212
CategoryDevelopment
Updated2d ago
Forks26

Languages

C++

Security Score

100/100

Audited on Mar 29, 2026

No findings