Merge pull request #178 from ZKing1000/master

Added support for line paths.
This commit is contained in:
Syoyo Fujita
2018-07-25 16:02:49 +09:00
committed by GitHub

View File

@@ -236,9 +236,14 @@ typedef struct {
std::vector<tag_t> tags; // SubD tag std::vector<tag_t> tags; // SubD tag
} mesh_t; } mesh_t;
typedef struct {
std::vector<int> indices; // pairs of indices for lines
} path_t;
typedef struct { typedef struct {
std::string name; std::string name;
mesh_t mesh; mesh_t mesh;
path_t path;
} shape_t; } shape_t;
// Vertex attributes // Vertex attributes
@@ -401,6 +406,11 @@ struct face_t {
face_t() : smoothing_group_id(0) {} face_t() : smoothing_group_id(0) {}
}; };
struct line_t {
int idx0;
int idx1;
};
struct tag_sizes { struct tag_sizes {
tag_sizes() : num_ints(0), num_reals(0), num_strings(0) {} tag_sizes() : num_ints(0), num_reals(0), num_strings(0) {}
int num_ints; int num_ints;
@@ -1015,16 +1025,22 @@ static int pnpoly(int nvert, T *vertx, T *verty, T testx,
} }
// TODO(syoyo): refactor function. // TODO(syoyo): refactor function.
static bool exportFaceGroupToShape(shape_t *shape, static bool exportGroupsToShape(shape_t *shape,
const std::vector<face_t> &faceGroup, const std::vector<face_t> &faceGroup,
std::vector<int> &lineGroup,
const std::vector<tag_t> &tags, const std::vector<tag_t> &tags,
const int material_id, const int material_id,
const std::string &name, bool triangulate, const std::string &name, bool triangulate,
const std::vector<real_t> &v) { const std::vector<real_t> &v) {
if (faceGroup.empty()) {
if (faceGroup.empty() && lineGroup.empty()) {
return false; return false;
} }
if (!faceGroup.empty()) {
// Flatten vertices and indices // Flatten vertices and indices
for (size_t i = 0; i < faceGroup.size(); i++) { for (size_t i = 0; i < faceGroup.size(); i++) {
const face_t &face = faceGroup[i]; const face_t &face = faceGroup[i];
@@ -1254,6 +1270,12 @@ static bool exportFaceGroupToShape(shape_t *shape,
shape->name = name; shape->name = name;
shape->mesh.tags = tags; shape->mesh.tags = tags;
}
if(!lineGroup.empty()){
shape->path.indices.swap(lineGroup);
}
return true; return true;
} }
@@ -1764,6 +1786,7 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
std::vector<real_t> vc; std::vector<real_t> vc;
std::vector<tag_t> tags; std::vector<tag_t> tags;
std::vector<face_t> faceGroup; std::vector<face_t> faceGroup;
std::vector<int> lineGroup;
std::string name; std::string name;
// material // material
@@ -1841,6 +1864,32 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
continue; continue;
} }
// line
if (token[0] == 'l' && IS_SPACE((token[1]))){
token += 2;
line_t line_cache;
bool end_line_bit = 0;
while(!IS_NEW_LINE(token[0])){
//get index from string
int idx;
fixIndex(parseInt(&token), 0, &idx);
// move to next space or end of string (\0 / \n)
token += strcspn(token, " \t\r")+1;
if(!end_line_bit){
line_cache.idx0 = idx;
} else {
line_cache.idx1 = idx;
lineGroup.push_back(line_cache.idx0);
lineGroup.push_back(line_cache.idx1);
line_cache = line_t();
}
end_line_bit = !end_line_bit;
}
continue;
}
// face // face
if (token[0] == 'f' && IS_SPACE((token[1]))) { if (token[0] == 'f' && IS_SPACE((token[1]))) {
token += 2; token += 2;
@@ -1890,8 +1939,8 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
if (newMaterialId != material) { if (newMaterialId != material) {
// Create per-face material. Thus we don't add `shape` to `shapes` at // Create per-face material. Thus we don't add `shape` to `shapes` at
// this time. // this time.
// just clear `faceGroup` after `exportFaceGroupToShape()` call. // just clear `faceGroup` after `exportGroupsToShape()` call.
exportFaceGroupToShape(&shape, faceGroup, tags, material, name, exportGroupsToShape(&shape, faceGroup, lineGroup, tags, material, name,
triangulate, v); triangulate, v);
faceGroup.clear(); faceGroup.clear();
material = newMaterialId; material = newMaterialId;
@@ -1946,7 +1995,7 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
// group name // group name
if (token[0] == 'g' && IS_SPACE((token[1]))) { if (token[0] == 'g' && IS_SPACE((token[1]))) {
// flush previous face group. // flush previous face group.
bool ret = exportFaceGroupToShape(&shape, faceGroup, tags, material, name, bool ret = exportGroupsToShape(&shape, faceGroup, lineGroup, tags, material, name,
triangulate, v); triangulate, v);
(void)ret; // return value not used. (void)ret; // return value not used.
@@ -1983,7 +2032,7 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
// object name // object name
if (token[0] == 'o' && IS_SPACE((token[1]))) { if (token[0] == 'o' && IS_SPACE((token[1]))) {
// flush previous face group. // flush previous face group.
bool ret = exportFaceGroupToShape(&shape, faceGroup, tags, material, name, bool ret = exportGroupsToShape(&shape, faceGroup, lineGroup, tags, material, name,
triangulate, v); triangulate, v);
if (ret) { if (ret) {
shapes->push_back(shape); shapes->push_back(shape);
@@ -2091,9 +2140,9 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
// Ignore unknown command. // Ignore unknown command.
} }
bool ret = exportFaceGroupToShape(&shape, faceGroup, tags, material, name, bool ret = exportGroupsToShape(&shape, faceGroup, lineGroup, tags, material, name,
triangulate, v); triangulate, v);
// exportFaceGroupToShape return false when `usemtl` is called in the last // exportGroupsToShape return false when `usemtl` is called in the last
// line. // line.
// we also add `shape` to `shapes` when `shape.mesh` has already some // we also add `shape` to `shapes` when `shape.mesh` has already some
// faces(indices) // faces(indices)