You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
183 lines
5.6 KiB
183 lines
5.6 KiB
#pragma once
|
|
#include "real.h"
|
|
#include "tinynurbs/util/array2.h"
|
|
#include <QFile>
|
|
#include <QList>
|
|
#include <QRegularExpression>
|
|
#include <QString>
|
|
#include <array>
|
|
#include <glm/glm.hpp>
|
|
#include <iostream>
|
|
#include <qcontainerfwd.h>
|
|
#include <tinynurbs/tinynurbs.h>
|
|
|
|
using namespace std;
|
|
using namespace tinynurbs;
|
|
|
|
class Reader {
|
|
public:
|
|
static std::array<tinynurbs::RationalSurface<real>, 2>
|
|
readSurfaces(const string &surfacesPath) {
|
|
tinynurbs::RationalSurface<real> s;
|
|
tinynurbs::RationalSurface<real> f;
|
|
|
|
ifstream fin;
|
|
fin.open(surfacesPath);
|
|
|
|
string str;
|
|
string tmp;
|
|
while (fin.good()) {
|
|
getline(fin, tmp);
|
|
str += tmp + "\n";
|
|
}
|
|
// cout << str << endl;
|
|
|
|
auto infos = QString(str.c_str()).split(";");
|
|
auto wData = infos[0];
|
|
auto srf1Data = infos[1];
|
|
auto srf2Data = infos[2];
|
|
|
|
auto points1 = getPtsFromStr(srf1Data);
|
|
auto points2 = getPtsFromStr(srf2Data);
|
|
|
|
wData = wData.remove(0, wData.indexOf("Matrix") + 6).trimmed();
|
|
wData.remove(0, 3);
|
|
wData.remove(wData.size() - 3, 3);
|
|
auto wInfos = wData.split(QRegularExpression("\\]( )*,( )*\\["));
|
|
|
|
array2<real> weights;
|
|
vector<real> wArray(points1.cols() * points1.rows());
|
|
for (int i = 0; i < points1.cols(); i++) {
|
|
auto wsInV = wInfos[i].split(QRegularExpression("( )*,( )*"));
|
|
for (int j = 0; j < points1.rows(); j++) {
|
|
wArray[i * points1.rows() + j] = real(wsInV[j].toDouble());
|
|
}
|
|
}
|
|
weights = {points1.cols(), points2.rows(), wArray};
|
|
|
|
// knot
|
|
std::vector<real> knot_u(2 * points1.cols(), 1.);
|
|
for (int i = 0; i < knot_u.size() / 2; i++)
|
|
knot_u[i] = 0;
|
|
std::vector<real> knot_v(2 * points1.rows(), 1.);
|
|
for (int i = 0; i < knot_v.size() / 2; i++)
|
|
knot_v[i] = 0;
|
|
|
|
s.degree_u = knot_u.size() / 2 - 1;
|
|
s.degree_v = knot_v.size() / 2 - 1;
|
|
s.knots_u = knot_u;
|
|
s.knots_v = knot_v;
|
|
s.control_points = points1;
|
|
s.weights = weights;
|
|
|
|
f.degree_u = knot_u.size() / 2 - 1;
|
|
f.degree_v = knot_v.size() / 2 - 1;
|
|
f.knots_u = knot_u;
|
|
f.knots_v = knot_v;
|
|
f.control_points = points2;
|
|
f.weights = weights;
|
|
|
|
fin.close();
|
|
|
|
printCtrPtsAsQuadruples(f);
|
|
return {s, f};
|
|
}
|
|
|
|
static void printCtrPtsAsQuadruples(const Surface<real> &s) {
|
|
cout << endl;
|
|
for (int i = 0; i < s.control_points.rows(); i++) {
|
|
for (int j = 0; j < s.control_points.cols(); j++) {
|
|
auto pt = s.control_points(i, j);
|
|
cout << pt.x << ", " << pt.y << ", " << pt.z << ", " << endl;
|
|
}
|
|
}
|
|
cout << s.control_points.rows() * s.control_points.cols() * 4 << endl;
|
|
}
|
|
|
|
static tinynurbs::RationalSurface<real> readSurface(const QString &path) {
|
|
QFile file(path);
|
|
file.open(QIODevice::ReadOnly | QIODevice::Text);
|
|
QByteArray byteArray = file.readAll();
|
|
auto infos = QString(byteArray).split("\n");
|
|
|
|
auto degreeInfos = infos[0].split(QRegularExpression("( )+"));
|
|
auto degreeU = degreeInfos[0].toInt(), degreeV = degreeInfos[1].toInt();
|
|
auto dimInfos = infos[1].split(QRegularExpression("( )+"));
|
|
auto dimU = dimInfos[0].toInt(), dimV = dimInfos[1].toInt();
|
|
auto knotInfos1 = infos[2].split(QRegularExpression("( )+"));
|
|
auto knotInfos2 = infos[3].split(QRegularExpression("( )+"));
|
|
auto knotU = std::vector<float>(knotInfos1.size());
|
|
auto knotV = std::vector<float>(knotInfos2.size());
|
|
for (int i = 0; i < knotInfos1.size(); i++) {
|
|
knotU[i] = knotInfos1[i].toFloat();
|
|
}
|
|
for (int i = 0; i < knotInfos2.size(); i++) {
|
|
knotV[i] = knotInfos2[i].toFloat();
|
|
}
|
|
array2<glm::vec3> points(dimU, dimV);
|
|
auto pts = infos[4].split(QRegularExpression("( )+"));
|
|
for (int i = 0; i < dimU; i++) {
|
|
for (int j = 0; j < dimV; j++) {
|
|
auto pt_coords = pts[i * dimV + j].split(QRegularExpression(",( )*"));
|
|
for (int k = 0; k < 3; k++) {
|
|
points(i, j)[k] = pt_coords[k].toFloat();
|
|
}
|
|
}
|
|
}
|
|
|
|
tinynurbs::RationalSurface<real> s;
|
|
s.degree_u = degreeU;
|
|
s.degree_v = degreeV;
|
|
s.knots_u = knotU;
|
|
s.knots_v = knotV;
|
|
s.control_points = points;
|
|
s.weights = array2<real>(dimU, dimV, 1.0);
|
|
|
|
file.close();
|
|
|
|
return s;
|
|
}
|
|
|
|
private:
|
|
static array2<glm::vec3> getPtsFromStr(QString srfData) {
|
|
srfData = srfData.remove(0, srfData.indexOf("Matrix") + 6).trimmed();
|
|
// 去掉首尾的括号
|
|
srfData.remove(0, 1);
|
|
srfData.remove(srfData.size() - 1, 1);
|
|
auto srfInfos = srfData.split("{");
|
|
auto srfDimInfos = srfInfos[0].split(QRegularExpression(",( )*"));
|
|
auto dimU = srfDimInfos[0].toInt();
|
|
auto dimV = srfDimInfos[1].toInt();
|
|
auto srfPtInfo = srfInfos[1].remove(srfInfos[1].indexOf("}"), 1);
|
|
auto srfPtsInfos = srfPtInfo.split(QRegularExpression(",( )*\\("));
|
|
std::vector<glm::vec3> points(dimU * dimV, glm::vec3());
|
|
for (int i = 0; i < srfPtsInfos.size(); i++) {
|
|
auto pt = srfPtsInfos[i].split("=")[1].trimmed();
|
|
// 去掉首尾的方括号
|
|
pt.remove(0, 1);
|
|
pt.remove(pt.size() - 1, 1);
|
|
// int iu = i / dimU;
|
|
// int iv = i % dimU;
|
|
auto coords = pt.split(QRegularExpression(",( )*"));
|
|
for (int k = 0; k < 3; k++) {
|
|
real num;
|
|
if (coords[k].contains("/")) {
|
|
auto nums = coords[k].split("/");
|
|
num =
|
|
real(nums[0].trimmed().toDouble() / nums[1].trimmed().toDouble());
|
|
} else {
|
|
|
|
num = real(coords[k].toDouble());
|
|
}
|
|
if (k == 0)
|
|
points[i].x = num;
|
|
else if (k == 1)
|
|
points[i].y = num;
|
|
else
|
|
points[i].z = num;
|
|
}
|
|
}
|
|
array2<glm::vec3> res = {(size_t)dimU, (size_t)dimV, points};
|
|
return res;
|
|
}
|
|
};
|