使用目标文件读取三角形数据网格
Reading Triangle Data Mesh With Object Files
我需要在 C++ 中加载 .obj 文件的顶点。我只是从我下载的对象中复制了顶点,所以我不必担心纹理贴图或任何东西。我能够将它分成一行并摆脱 v 但无法隔离 x、y、z 坐标,因此我可以将它分配给三个单独的变量。
main.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;
}
fox.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 file\n";
// 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
中所做的那样。正如评论中指出的那样,您可以让流进行从文本到双精度的转换。
请注意,我已经处理了一处失败的文件错误,即注释文件内容。从失败中找出其他方法不是很清楚,并且会产生一个不需要的大范围。
我需要在 C++ 中加载 .obj 文件的顶点。我只是从我下载的对象中复制了顶点,所以我不必担心纹理贴图或任何东西。我能够将它分成一行并摆脱 v 但无法隔离 x、y、z 坐标,因此我可以将它分配给三个单独的变量。
main.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;
}
fox.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 file\n";
// 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
中所做的那样。正如评论中指出的那样,您可以让流进行从文本到双精度的转换。
请注意,我已经处理了一处失败的文件错误,即注释文件内容。从失败中找出其他方法不是很清楚,并且会产生一个不需要的大范围。