30 Vector<std::unique_ptr<Geometry>> &r_all_geometries)
32 auto new_geometry = [&]() {
33 r_all_geometries.append(std::make_unique<Geometry>());
34 Geometry *
g = r_all_geometries.last().get();
35 g->geom_type_ = new_type;
36 g->geometry_name_ = name.
is_empty() ?
"New object" : name;
44 return new_geometry();
60 return new_geometry();
63 return new_geometry();
70 r_global_vertices.
vertices.append(vert);
77 if (srgb.x >= 0 && srgb.y >= 0 && srgb.z >= 0) {
84 if (blocks.is_empty() || (blocks.last().start_vertex_index + blocks.last().colors.size() !=
85 r_global_vertices.
vertices.size() - 1)) {
90 blocks.last().colors.append(linear);
101 const int mrgb_length = 8;
102 while (p + mrgb_length <= end) {
104 std::from_chars_result res = std::from_chars(p, p + mrgb_length, value, 16);
105 if (res.ec == std::errc::invalid_argument || res.ec == std::errc::result_out_of_range) {
108 unsigned char srgb[4];
109 srgb[0] = (value >> 16) & 0xFF;
110 srgb[1] = (value >> 8) & 0xFF;
111 srgb[2] = value & 0xFF;
119 if (blocks.is_empty() || (blocks.last().start_vertex_index + blocks.last().colors.size() !=
120 r_global_vertices.
vertices.size())) {
123 blocks.append(block);
125 blocks.last().colors.append({linear[0], linear[1], linear[2]});
128 blocks.last().start_vertex_index--;
159 int edge_v1, edge_v2;
163 edge_v1 += edge_v1 < 0 ? r_global_vertices.
vertices.size() : -1;
164 edge_v2 += edge_v2 < 0 ? r_global_vertices.
vertices.size() : -1;
175 const int material_index,
176 const int group_index,
177 const bool shaded_smooth)
182 if (group_index >= 0) {
190 bool face_valid =
true;
192 while (p < end && face_valid) {
194 bool got_uv =
false, got_normal =
false;
198 if (p < end && *p ==
'/') {
201 if (p < end && *p !=
'/') {
206 if (p < end && *p ==
'/') {
216 "Invalid vertex index %i (valid range [0, %zu)), ignoring face\n",
218 (
size_t)global_vertices.
vertices.size());
228 "Invalid UV index %i (valid range [0, %zu)), ignoring face\n",
238 corner.vertex_normal_index +=
corner.vertex_normal_index < 0 ?
241 if (
corner.vertex_normal_index < 0 ||
244 "Invalid normal index %i (valid range [0, %zu)), ignoring face\n",
245 corner.vertex_normal_index,
272 Vector<std::unique_ptr<Geometry>> &r_all_geometries)
275 if (!
StringRef(p, end).startswith(
"bspline")) {
276 std::cerr <<
"Curve type not supported: '" << std::string(p, end) <<
"'" << std::endl;
305 index += index < 0 ? global_vertices.
vertices.size() : -1;
314 std::cerr <<
"Invalid OBJ curve parm line" << std::endl;
318 std::cerr <<
"OBJ curve surfaces are not supported: '" << *p <<
"'" << std::endl;
326 if (val != FLT_MAX) {
330 std::cerr <<
"OBJ curve parm line has invalid number" << std::endl;
338 if (rest_line.
find(
"off") != string::npos || rest_line.
find(
"null") != string::npos ||
339 rest_line.
find(
"default") != string::npos) {
344 r_group_name = rest_line;
353 r_state_shaded_smooth =
false;
359 r_state_shaded_smooth =
smooth != 0;
363 : import_params_(import_params), read_buffer_size_(read_buffer_size)
367 fprintf(stderr,
"Cannot read from OBJ file:'%s'.\n", import_params_.
filepath);
382 const size_t keyword_len = keyword.
size();
383 if (end - p < keyword_len + 1) {
386 if (memcmp(p, keyword.
data(), keyword_len) != 0) {
391 if (p[keyword_len] >
' ') {
394 p += keyword_len + 1;
401 const Vector<std::unique_ptr<Geometry>> &all_geometries,
406 all_geometries.begin(), all_geometries.end(), [](
const std::unique_ptr<Geometry> &
g) {
407 return g->get_vertex_count() == 0;
430 bool state_shaded_smooth =
false;
431 string state_group_name;
432 int state_group_index = -1;
433 string state_material_name;
434 int state_material_index = -1;
440 size_t buffer_offset = 0;
441 size_t line_number = 0;
444 size_t bytes_read = fread(
buffer.data() + buffer_offset, 1, read_buffer_size_, obj_file_);
445 if (bytes_read == 0 && buffer_offset == 0) {
452 buffer.data() + buffer_offset + bytes_read);
455 if (bytes_read < read_buffer_size_) {
456 if (bytes_read == 0 ||
buffer[buffer_offset + bytes_read - 1] !=
'\n') {
457 buffer[buffer_offset + bytes_read] =
'\n';
462 size_t buffer_end = buffer_offset + bytes_read;
463 if (buffer_end == 0) {
468 size_t last_nl = buffer_end;
469 while (last_nl > 0) {
471 if (
buffer[last_nl] ==
'\n') {
475 if (
buffer[last_nl] !=
'\n') {
478 "OBJ file contains a line #%zu that is too long (max. length %zu)\n",
488 while (!buffer_str.is_empty()) {
490 const char *p = line.
begin(), *end = line.
end();
512 if (state_material_index == -1 && !state_material_name.empty() &&
516 state_material_index = 0;
523 state_material_index,
525 state_shaded_smooth);
533 state_shaded_smooth =
false;
534 state_group_name =
"";
538 state_material_index = -1;
547 if (new_index == state_group_index) {
561 if (new_mat_index == state_material_index) {
572 else if (*p ==
'#') {
588 else if (
StringRef(p, end).startswith(
"end")) {
592 std::cout <<
"OBJ element not recognized: '" << std::string(p, end) <<
"'" << std::endl;
598 size_t left_size = buffer_end - last_nl;
599 memmove(
buffer.data(),
buffer.data() + last_nl, left_size);
600 buffer_offset = left_size;
604 add_default_mtl_library();
675 std::cerr <<
"OBJ import: only sphere MTL projection type is supported: '" << line <<
"'"
685 for (
int i = 0; i < opt.second; ++i) {
699 const char *mtl_dir_path)
705 if (!is_map && !is_refl && !is_bump) {
711 std::cerr <<
"OBJ import: MTL texture map type not supported: '" << line <<
"'" << std::endl;
727 return mtl_libraries_;
730 void OBJParser::add_mtl_library(
StringRef path)
737 if (!mtl_libraries_.
contains(path)) {
738 mtl_libraries_.
append(path);
742 void OBJParser::add_default_mtl_library()
755 add_mtl_library(mtl_file_base);
772 fprintf(stderr,
"OBJ import: cannot read from MTL file: '%s'\n", mtl_file_path_);
779 while (!buffer_str.is_empty()) {
781 const char *p = line.
begin(), *end = line.
end();
789 if (r_materials.contains(mat_name)) {
794 r_materials.lookup_or_add(
string(mat_name), std::make_unique<MTLMaterial>()).get();
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
FILE * BLI_fopen(const char *filepath, const char *mode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void * BLI_file_read_text_as_mem(const char *filepath, size_t pad_bytes, size_t *r_size)
MINLINE void srgb_to_linearrgb_v3_v3(float linear[3], const float srgb[3])
MINLINE void srgb_to_linearrgb_uchar4(float linear[4], const unsigned char srgb[4])
MINLINE float normalize_v3(float r[3])
void BLI_split_dir_part(const char *string, char *dir, size_t dirlen)
const char * BLI_path_basename(const char *path) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT
bool BLI_path_extension_replace(char *path, size_t maxlen, const char *ext) ATTR_NONNULL()
size_t BLI_path_join(char *__restrict dst, size_t dst_len, const char *path_first,...) ATTR_NONNULL(1
void BLI_split_file_part(const char *string, char *file, size_t filelen)
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
void add_new(const Key &key, const Value &value)
Value & lookup_or_add(const Key &key, const Value &value)
constexpr int64_t find(char c, int64_t pos=0) const
constexpr const char * begin() const
constexpr const char * end() const
constexpr bool is_empty() const
constexpr bool startswith(StringRef prefix) const
constexpr bool endswith(StringRef suffix) const
constexpr int64_t size() const
constexpr StringRef trim() const
constexpr const char * data() const
constexpr StringRef drop_prefix(int64_t n) const
constexpr StringRef drop_suffix(int64_t n) const
bool contains(const T &value) const
void append(const T &value)
void parse_and_store(Map< std::string, std::unique_ptr< MTLMaterial >> &r_materials)
MTLParser(StringRefNull mtl_library_, StringRefNull obj_filepath)
Span< std::string > mtl_libraries() const
void parse(Vector< std::unique_ptr< Geometry >> &r_all_geometries, GlobalVertices &r_global_vertices)
OBJParser(const OBJImportParams &import_params, size_t read_buffer_size)
IconTextureDrawCall normal
ccl_global float * buffer
void(* MEM_freeN)(void *vmemh)
static char * trim(char *str)
static void geom_add_curve_vertex_indices(Geometry *geom, const char *p, const char *end, const GlobalVertices &global_vertices)
static void geom_add_vertex(const char *p, const char *end, GlobalVertices &r_global_vertices)
static void geom_add_mrgb_colors(const char *p, const char *end, GlobalVertices &r_global_vertices)
static void parse_texture_map(const char *p, const char *end, MTLMaterial *material, const char *mtl_dir_path)
const char * parse_floats(const char *p, const char *end, float fallback, float *dst, int count, bool require_trailing_space)
void fixup_line_continuations(char *p, char *end)
static void geom_add_edge(Geometry *geom, const char *p, const char *end, GlobalVertices &r_global_vertices)
static void geom_add_uv_vertex(const char *p, const char *end, GlobalVertices &r_global_vertices)
static bool parse_texture_option(const char *&p, const char *end, MTLMaterial *material, tex_map_XX &tex_map)
const char * drop_non_whitespace(const char *p, const char *end)
static void use_all_vertices_if_no_faces(Geometry *geom, const Vector< std::unique_ptr< Geometry >> &all_geometries, const GlobalVertices &global_vertices)
static bool parse_keyword(const char *&p, const char *end, StringRef keyword)
static Geometry * geom_set_curve_type(Geometry *geom, const char *p, const char *end, const StringRef group_name, Vector< std::unique_ptr< Geometry >> &r_all_geometries)
const char * parse_int(const char *p, const char *end, int fallback, int &dst, bool skip_space)
const char * drop_whitespace(const char *p, const char *end)
static void geom_add_vertex_normal(const char *p, const char *end, GlobalVertices &r_global_vertices)
static void geom_add_curve_parameters(Geometry *geom, const char *p, const char *end)
static eMTLSyntaxElement mtl_line_start_to_enum(const char *&p, const char *end)
static void geom_set_curve_degree(Geometry *geom, const char *p, const char *end)
StringRef read_next_line(StringRef &buffer)
static void geom_update_smooth_group(const char *p, const char *end, bool &r_state_shaded_smooth)
static Geometry * create_geometry(Geometry *const prev_geometry, const eGeometryType new_type, StringRef name, Vector< std::unique_ptr< Geometry >> &r_all_geometries)
static void geom_update_group(const StringRef rest_line, std::string &r_group_name)
static const std::pair< StringRef, int > unsupported_texture_options[]
const char * parse_float(const char *p, const char *end, float fallback, float &dst, bool skip_space, bool require_trailing_space)
static void geom_add_polygon(Geometry *geom, const char *p, const char *end, const GlobalVertices &global_vertices, const int material_index, const int group_index, const bool shaded_smooth)
static const pxr::TfToken g("g", pxr::TfToken::Immortal)
smooth(Type::FLOAT, "mask_weight")
Vector< PolyElem > face_elements_
void track_all_vertices(int count)
Vector< std::string > material_order_
Map< std::string, int > group_indices_
NurbsElement nurbs_element_
Vector< std::string > group_order_
Map< std::string, int > material_indices_
void track_vertex_index(int index)
std::string geometry_name_
Vector< PolyCorner > face_corners_
Vector< float3 > vertex_normals
Vector< float3 > vertices
Vector< float2 > uv_vertices
Vector< VertexColorsBlock > vertex_colors
Vector< int > curv_indices