使用目标文件读取三角形数据网格

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 中所做的那样。正如评论中指出的那样,您可以让流进行从文本到双精度的转换。

请注意,我已经处理了一处失败的文件错误,即注释文件内容。从失败中找出其他方法不是很清楚,并且会产生一个不需要的大范围。