Integration of gauss map, osculating toroidal patches, loop detection and C2 judgement to figure out the singular or loop intersection.
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

#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;
}
};