使用对象文件读取三角形数据网格

Reading Triangle Data Mesh With Object Files

本文关键字:数据 数据网 网格 三角形 读取 对象 文件      更新时间:2023-10-16

我需要在 c++ 中加载 .obj 文件的顶点。我只是从我下载的对象中复制了垂直点,所以我不必担心纹理映射或任何东西。我能够将其分成一行并摆脱 v,但无法隔离 x,y,z 坐标,因此我可以将其分配给三个单独的变量。

主.cpp


// ConsoleApplication3.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <iostream>
#include <memory>
#include <fstream>
#include <string>
using namespace std;
string pos1, pos2, pos3;
int main()
{
string line;
ifstream myfile("fox.txt");
if (myfile.is_open())
{
while (getline(myfile, line))
{

line.erase(std::remove(line.begin(), line.end(), 'v'), line.end());
cout << line << endl;
}
myfile.close();
}
else cout << "Unable to open file";
return 0;

}

狐狸.txt

v 10.693913 60.403057 33.765018
v -7.016389 46.160694 36.028797
v 9.998714 51.307644 35.496368
v -8.642366 49.095310 35.725204

一种简单的行中阅读方法

v 10.693913 60.403057 33.765018

并将其分成3个不同的变量是首先在char中读取,然后在三个doubles中读取:

ifstream fin("fox.txt");
vector <vector<double>> data; // holds sets of coordinates
double a, b, c;
char v;
while(fin >> v >> a >> b >> c){
data.push_back({a, b, c});
}

如果需要,还可以使用std::stringstream将输入解析为doubles

一个简单的方法是简单地使用std::stringstream并像对待任何其他流一样对待它。

#include <sstream>
...
std::string pos1, pos2, pos3;
std::stringstream lineStream;
...
while (getline(myfile, line))
{
/* Make a string stream out of the line we read */
lineStream.str(line);

char skip; // Temp var to skip the first 'v'
lineStream >> skip >> pos1 >> pos2 >> pos3;
/* Reset error state flags for next iteration */
lineStream.clear();
}

或者,您可以通过直接在myfile上使用>>运算符来避免所有这些。

std::string temp, pos1, pos2, pos3;
while (myfile >> temp >> pos1 >> pos2 >> pos3)
{
...
}

我会弄清楚你想把这些数据存储在std::vector之类的地方。这是一种方法。

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
const char* test_str = R"(
v 10.693913 60.403057 33.765018
v -7.016389 46.160694 36.028797
v 9.998714 51.307644 35.496368
v -8.642366 49.095310 35.725204
)";
struct data_item {
double x;
double y;
double z;
};
using data_set = std::vector<data_item>;
int main()
{
//std::ifstream myfile("fox.txt");
//if (!myfile.is_open()) {
//    std::cout << "Unable to open filen";
//    return -1;
//}
std::stringstream as_file;
as_file << test_str;
data_set set;
for (; ;) {
std::string dummy;
data_item item;
as_file >> dummy >> item.x >> item.y >> item.z;
if (!dummy.size())
break;
set.push_back(item);
}
for (auto& item : set)
std::cout << item.x << " " << item.y << " " << item.z << std::endl;
return 0;
}

不要做:using namespace std;它会为你省去很多麻烦。它还使您的代码更具可读性,以了解某些内容不在标准库中。

测试时,有时使用本地数据更简单,就像我对test_str一样。正如评论中指出的那样,您可以让流进行从文本到双精度的转换。

注意 我已经在一个地方处理了一个失败的文件错误,注释的文件内容。从失败中放下其他方法并不是那么清楚,并且会产生大量不必要的范围。