Port colored OBJ import pipeline from BambuStudio

This commit is contained in:
SoftFever
2026-08-23 22:11:49 +08:00
parent 94a1cd6c93
commit b1e3cdc666
9 changed files with 893 additions and 297 deletions
+105 -7
View File
@@ -262,12 +262,9 @@ static bool obj_parseline(const char *line, ObjData &data)
}
face_index_count++;
}
if (face_index_count == 3) {//tri
data.usemtls.back().face_end++;
} else if (face_index_count == 4) {//quad
data.usemtls.back().face_end++;
data.usemtls.back().face_end++;
}
if (face_index_count >= 3) {
data.usemtls.back().face_end += face_index_count - 2;
}
}
vertex.coordIdx = -1;
vertex.normalIdx = -1;
@@ -374,6 +371,107 @@ static bool obj_parseline(const char *line, ObjData &data)
return true;
}
static std::string cur_mtl_name = "";
static bool mtl_is_space(char c)
{
return c == ' ' || c == '\t' || c == '\r';
}
static const char* mtl_skip_ws(const char *line)
{
while (mtl_is_space(*line))
++line;
return line;
}
static const char* mtl_skip_token(const char *line)
{
while (*line != 0 && !mtl_is_space(*line))
++line;
return line;
}
static bool mtl_token_equals(const char *begin, const char *end, const char *token)
{
const size_t len = static_cast<size_t>(end - begin);
return strlen(token) == len && strncmp(begin, token, len) == 0;
}
static std::string mtl_trim_value(const char *line)
{
const char *begin = mtl_skip_ws(line);
const char *end = begin + strlen(begin);
while (end > begin && mtl_is_space(*(end - 1)))
--end;
return std::string(begin, end);
}
static bool mtl_skip_numeric_token(const char *&line)
{
const char *begin = mtl_skip_ws(line);
if (*begin == 0)
return false;
char *endptr = 0;
strtod(begin, &endptr);
if (endptr == begin || (!mtl_is_space(*endptr) && *endptr != 0))
return false;
line = mtl_skip_ws(endptr);
return true;
}
static bool mtl_skip_required_tokens(const char *&line, int count)
{
for (int i = 0; i < count; ++i) {
line = mtl_skip_ws(line);
if (*line == 0)
return false;
line = mtl_skip_token(line);
}
line = mtl_skip_ws(line);
return true;
}
static std::string mtl_parse_texture_name(const char *line)
{
const char *original = mtl_skip_ws(line);
const char *current = original;
while (*current == '-') {
const char *option_begin = current;
const char *option_end = mtl_skip_token(current);
current = option_end;
if (mtl_token_equals(option_begin, option_end, "-o") ||
mtl_token_equals(option_begin, option_end, "-s") ||
mtl_token_equals(option_begin, option_end, "-t")) {
int skipped = 0;
while (skipped < 3 && mtl_skip_numeric_token(current))
++skipped;
if (skipped == 0)
return mtl_trim_value(original);
continue;
}
int option_args = -1;
if (mtl_token_equals(option_begin, option_end, "-mm"))
option_args = 2;
else if (mtl_token_equals(option_begin, option_end, "-bm") ||
mtl_token_equals(option_begin, option_end, "-boost") ||
mtl_token_equals(option_begin, option_end, "-texres") ||
mtl_token_equals(option_begin, option_end, "-clamp") ||
mtl_token_equals(option_begin, option_end, "-blendu") ||
mtl_token_equals(option_begin, option_end, "-blendv") ||
mtl_token_equals(option_begin, option_end, "-cc") ||
mtl_token_equals(option_begin, option_end, "-imfchan") ||
mtl_token_equals(option_begin, option_end, "-type"))
option_args = 1;
if (option_args < 0 || !mtl_skip_required_tokens(current, option_args))
return mtl_trim_value(original);
}
return mtl_trim_value(current);
}
static bool mtl_parseline(const char *line, MtlData &data)
{
if (*line == 0) return true;
@@ -401,7 +499,7 @@ static bool mtl_parseline(const char *line, MtlData &data)
if (*(line++) != 'a' || *(line++) != 'p' || *(line++) != '_' || *(line++) != 'K' || *(line++) != 'd') return false;
EATWS();
if (data.new_mtl_unmap.find(cur_mtl_name) != data.new_mtl_unmap.end()) {
data.new_mtl_unmap[cur_mtl_name]->map_Kd = line;
data.new_mtl_unmap[cur_mtl_name]->map_Kd = mtl_parse_texture_name(line);
}
break;
}