C++ 中的 OBJ 文件有 ubuntu 个问题
OBJ file in C++ with ubuntu problems
我在读取 OBJ 文件时遇到问题...
问题 1 是向量被声明为浮点数(并且已被声明为双精度数),但在终端中打印出来的都是整数。
终端输出为:
1-1-1
1-11
-1-11
-1-1-1
应该是什么时候:
1.000000 -1.000000 -1.000000
1.000000 -1.000000 1.000000
-1.000000 -1.000000 1.000000
-1.000000 -1.000000 -1.000000
问题2是我一直无法正确读取文件中的人脸。输出为:
1
5
1
2
应该是:
1 2 3 4
5 8 7 6
1 5 6 2
2 6 7 3
我正在尝试让结果正确打印出来,因为接下来我将使用动态内存分配将这些结果放入节点中,因为它们的大小各不相同。
这是代码:
/* This function opens the OBJ file */
void openFile(string nf){
std::ifstream file;
file.open (nf, std::ifstream::out);
string line;
string o_name;
string faces;
char o;
char v;
char f;
int i = 0;
float x;
float y;
float z;
if(file.is_open()){
std::cout<< "file is open!\n";
//include actions for OBJ file...Just read. You work from memory
while(std::getline(file, line))
{
if(line.empty()) //line is empty, then file is empty!
std::cout << "file is empty! \n";
/* finds the shape name*/
if (line[i] == 'o')
{
std::istringstream iss (line);
iss >> o >> o_name;
std::cout << o_name << endl;
line.clear();
//createNodeO(string o_name);
}
/* finds the vertices*/
if (line[i] == 'v')
{
std::istringstream iss (line);
iss >> v >> x >> y >> z;
std::cout << x << y << z << endl;
line.clear();
//createNodeO(float x, float y, float z);
}
/* finds the faces*/
if (line[i] == 'f')
{
std::istringstream iss (line);
iss >> f >> faces;
std::cout << faces << endl;
//createNodeO(string faces);
}
}
}
else{
std::cout<< "could not open the file!\n";
}
file.close();
std::cout<< "file is closed!\n";
}
根据 g++ 编译器,当涉及到面部部分时,我很疯狂。请帮忙!
这有点像我会做的。如果您喜欢,也可以对每种类型使用 operator>>
。
与您的示例的不同之处:
我忽略了除顶点和面之外的所有内容,并假设顶点中没有 w,文件中也没有 vt、vn、vp 等。可能还有您可能 运行 加入的名称、组、材料等。如果您发现自己陷入困境或者编写解析器的愿望减弱,您可以查看一个库来完成它。 http://www.assimp.org/ is a good one, and there's a good viewer here http://www.open3mod.com/ 如果您正在解析的内容看起来不太正确,这绝对可以提供帮助。
您的代码正在标记化并直接写入您的目标变量,我选择先标记化,然后在对该行进行一些基本验证后将标记转换为正确的类型。要么工作。我通常会像您那样做,也许使用 operator>>
或辅助函数。
我用这里的一些文件进行了测试:https://people.sc.fsu.edu/~jburkardt/data/obj/obj.html
希望这对您有所帮助。
#include <fstream>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
struct vertex
{
double x, y, z;
};
struct face
{
std::vector<int> v;
};
struct object
{
std::vector<vertex> verts;
std::vector<face> faces;
};
std::ostream& operator<<(std::ostream& out, const vertex& v)
{
out << "v "
<< std::fixed << std::setprecision(6) << v.x << " "
<< std::fixed << std::setprecision(6) << v.y << " "
<< std::fixed << std::setprecision(6) << v.z;
return out;
}
std::ostream& operator<<(std::ostream& out, const face& f)
{
out << "f";
for (size_t i = 0; i < f.v.size(); ++i)
{
out << " " << f.v[i];
}
return out;
}
std::ostream& operator<<(std::ostream& out, const object& o)
{
for (size_t i = 0; i < o.verts.size(); ++i)
{
out << o.verts[i] << "\n";
}
for (size_t i = 0; i < o.faces.size(); ++i)
{
out << o.faces[i] << "\n";
}
return out;
}
std::vector<std::string> split(const std::string& s)
{
std::vector<std::string> ret;
std::string token;
std::stringstream ss(s);
while (ss >> token)
{
ret.push_back(token);
}
return ret;
}
int main(int argc, char **argv)
{
if (argc != 2)
{
std::cerr << "Usage: " << argv[0] << " <obj filename>\n";
return -1;
}
std::fstream in(argv[1]);
if (!in)
{
std::cerr << "File: " << argv[1] << " could not be opened\n";
return -1;
}
object o;
std::string line;
int lineNumber = 0;
while (std::getline(in, line))
{
++lineNumber;
if (line.empty() || line[0] == '#')
{
continue;
}
std::vector<std::string> tokens = split(line);
if (line[0] == 'v')
{
if (tokens.size() < 4)
{
std::cerr << "Invalid vert: '" << line << "' on line: " << lineNumber << "\n";
continue;
}
vertex v;
v.x = std::stod(tokens[1]);
v.y = std::stod(tokens[2]);
v.z = std::stod(tokens[3]);
o.verts.push_back(v);
}
else if (line[0] == 'f')
{
if (tokens.size() < 4)
{
std::cerr << "Invalid face: '" << line << "' on line: " << lineNumber << "\n";
continue;
}
face f;
for (size_t i = 1; i < tokens.size(); ++i)
{
f.v.push_back(std::stoi(tokens[i]));
}
o.faces.push_back(f);
}
}
std::cout << o;
return 0;
}
我在读取 OBJ 文件时遇到问题... 问题 1 是向量被声明为浮点数(并且已被声明为双精度数),但在终端中打印出来的都是整数。 终端输出为:
1-1-1
1-11
-1-11
-1-1-1
应该是什么时候:
1.000000 -1.000000 -1.000000
1.000000 -1.000000 1.000000
-1.000000 -1.000000 1.000000
-1.000000 -1.000000 -1.000000
问题2是我一直无法正确读取文件中的人脸。输出为:
1
5
1
2
应该是:
1 2 3 4
5 8 7 6
1 5 6 2
2 6 7 3
我正在尝试让结果正确打印出来,因为接下来我将使用动态内存分配将这些结果放入节点中,因为它们的大小各不相同。 这是代码:
/* This function opens the OBJ file */
void openFile(string nf){
std::ifstream file;
file.open (nf, std::ifstream::out);
string line;
string o_name;
string faces;
char o;
char v;
char f;
int i = 0;
float x;
float y;
float z;
if(file.is_open()){
std::cout<< "file is open!\n";
//include actions for OBJ file...Just read. You work from memory
while(std::getline(file, line))
{
if(line.empty()) //line is empty, then file is empty!
std::cout << "file is empty! \n";
/* finds the shape name*/
if (line[i] == 'o')
{
std::istringstream iss (line);
iss >> o >> o_name;
std::cout << o_name << endl;
line.clear();
//createNodeO(string o_name);
}
/* finds the vertices*/
if (line[i] == 'v')
{
std::istringstream iss (line);
iss >> v >> x >> y >> z;
std::cout << x << y << z << endl;
line.clear();
//createNodeO(float x, float y, float z);
}
/* finds the faces*/
if (line[i] == 'f')
{
std::istringstream iss (line);
iss >> f >> faces;
std::cout << faces << endl;
//createNodeO(string faces);
}
}
}
else{
std::cout<< "could not open the file!\n";
}
file.close();
std::cout<< "file is closed!\n";
}
根据 g++ 编译器,当涉及到面部部分时,我很疯狂。请帮忙!
这有点像我会做的。如果您喜欢,也可以对每种类型使用 operator>>
。
与您的示例的不同之处:
我忽略了除顶点和面之外的所有内容,并假设顶点中没有 w,文件中也没有 vt、vn、vp 等。可能还有您可能 运行 加入的名称、组、材料等。如果您发现自己陷入困境或者编写解析器的愿望减弱,您可以查看一个库来完成它。 http://www.assimp.org/ is a good one, and there's a good viewer here http://www.open3mod.com/ 如果您正在解析的内容看起来不太正确,这绝对可以提供帮助。
您的代码正在标记化并直接写入您的目标变量,我选择先标记化,然后在对该行进行一些基本验证后将标记转换为正确的类型。要么工作。我通常会像您那样做,也许使用 operator>>
或辅助函数。
我用这里的一些文件进行了测试:https://people.sc.fsu.edu/~jburkardt/data/obj/obj.html
希望这对您有所帮助。
#include <fstream>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
struct vertex
{
double x, y, z;
};
struct face
{
std::vector<int> v;
};
struct object
{
std::vector<vertex> verts;
std::vector<face> faces;
};
std::ostream& operator<<(std::ostream& out, const vertex& v)
{
out << "v "
<< std::fixed << std::setprecision(6) << v.x << " "
<< std::fixed << std::setprecision(6) << v.y << " "
<< std::fixed << std::setprecision(6) << v.z;
return out;
}
std::ostream& operator<<(std::ostream& out, const face& f)
{
out << "f";
for (size_t i = 0; i < f.v.size(); ++i)
{
out << " " << f.v[i];
}
return out;
}
std::ostream& operator<<(std::ostream& out, const object& o)
{
for (size_t i = 0; i < o.verts.size(); ++i)
{
out << o.verts[i] << "\n";
}
for (size_t i = 0; i < o.faces.size(); ++i)
{
out << o.faces[i] << "\n";
}
return out;
}
std::vector<std::string> split(const std::string& s)
{
std::vector<std::string> ret;
std::string token;
std::stringstream ss(s);
while (ss >> token)
{
ret.push_back(token);
}
return ret;
}
int main(int argc, char **argv)
{
if (argc != 2)
{
std::cerr << "Usage: " << argv[0] << " <obj filename>\n";
return -1;
}
std::fstream in(argv[1]);
if (!in)
{
std::cerr << "File: " << argv[1] << " could not be opened\n";
return -1;
}
object o;
std::string line;
int lineNumber = 0;
while (std::getline(in, line))
{
++lineNumber;
if (line.empty() || line[0] == '#')
{
continue;
}
std::vector<std::string> tokens = split(line);
if (line[0] == 'v')
{
if (tokens.size() < 4)
{
std::cerr << "Invalid vert: '" << line << "' on line: " << lineNumber << "\n";
continue;
}
vertex v;
v.x = std::stod(tokens[1]);
v.y = std::stod(tokens[2]);
v.z = std::stod(tokens[3]);
o.verts.push_back(v);
}
else if (line[0] == 'f')
{
if (tokens.size() < 4)
{
std::cerr << "Invalid face: '" << line << "' on line: " << lineNumber << "\n";
continue;
}
face f;
for (size_t i = 1; i < tokens.size(); ++i)
{
f.v.push_back(std::stoi(tokens[i]));
}
o.faces.push_back(f);
}
}
std::cout << o;
return 0;
}