|
|
@ -1,7 +1,12 @@ |
|
|
|
#include <iostream> |
|
|
|
#include "SingularityJudger.h" |
|
|
|
#include "fstream" |
|
|
|
#include "QString" |
|
|
|
#include "QList" |
|
|
|
#include "QRegularExpression" |
|
|
|
#include "gauss_map.h" |
|
|
|
|
|
|
|
SrfMesh getMesh(const RationalSurface<float>& s, int sampleLevel){ |
|
|
|
SrfMesh getMesh(const RationalSurface<float> &s, int sampleLevel) { |
|
|
|
SrfMesh res; |
|
|
|
res.sampleLevel = sampleLevel; |
|
|
|
res.sampleCntOnSingleDir = int(pow(2, sampleLevel - 1) + 1); |
|
|
@ -15,86 +20,193 @@ SrfMesh getMesh(const RationalSurface<float>& s, int sampleLevel){ |
|
|
|
auto s_step_u = (*(s.knots_u.end() - 1) - s_first_u) / float(res.sampleCntOnSingleDir - 1); |
|
|
|
auto s_step_v = (*(s.knots_v.end() - 1) - s_first_v) / float(res.sampleCntOnSingleDir - 1); |
|
|
|
|
|
|
|
for(int i = 0; i < res.sampleCntOnSingleDir; i++) { |
|
|
|
for (int i = 0; i < res.sampleCntOnSingleDir; i++) { |
|
|
|
auto u = s_first_u + s_step_u * float(i); |
|
|
|
for(int j = 0; j < res.sampleCntOnSingleDir; j++) { |
|
|
|
for (int j = 0; j < res.sampleCntOnSingleDir; j++) { |
|
|
|
auto v = s_first_v + s_step_v * float(j); |
|
|
|
res.evaluation[i][j] = tinynurbs::surfacePoint(s, u, v); |
|
|
|
auto der = tinynurbs::surfaceDerivatives(s, 1, u, v); |
|
|
|
res.tangent_u[i][j] = der(1, 0); |
|
|
|
res.tangent_v[i][j] = der(0, 1); |
|
|
|
res.normal[i][j] = glm::cross(res.tangent_u[i][j], res.tangent_v[i][j]); |
|
|
|
res.normal[i][j] = glm::normalize(glm::cross(res.tangent_u[i][j], res.tangent_v[i][j])); |
|
|
|
} |
|
|
|
} |
|
|
|
return res; |
|
|
|
} |
|
|
|
|
|
|
|
array2<glm::vec3> getPtsFromStr(QString srfData); |
|
|
|
|
|
|
|
int main() { |
|
|
|
RationalSurface<float> s; |
|
|
|
RationalSurface<float> f; |
|
|
|
s.degree_u = 3; |
|
|
|
s.degree_v = 3; |
|
|
|
s.knots_u = {0, 0, 0, 0, 1, 1, 1, 1}; |
|
|
|
s.knots_v = {0, 0, 0, 0, 1, 1, 1, 1}; |
|
|
|
s.control_points = {4, 4, { |
|
|
|
glm::vec3(0, 0.3, 0.9), glm::vec3(0, 0.6, 1), glm::vec3(0, 0.9, 1.1), glm::vec3(0, 1.2, 1), |
|
|
|
glm::vec3(0.33, 0.3, 0.12), glm::vec3(0.33, 0.6, 0.12), glm::vec3(0.33, 0.9, 0.12), |
|
|
|
glm::vec3(0.33, 1.2, 0.12), |
|
|
|
glm::vec3(0.66, 0.3, 0.12), glm::vec3(0.66, 0.6, 0.12), glm::vec3(0.66, 0.9, 0.12), |
|
|
|
glm::vec3(0.66, 1.2, 0.12), |
|
|
|
glm::vec3(1, 0.3, 0.8), glm::vec3(1, 0.6, 1), glm::vec3(1, 0.9, 1.1), glm::vec3(1, 1.2, 1) |
|
|
|
}}; |
|
|
|
s.weights = {4, 4, |
|
|
|
{ |
|
|
|
1, 1, 1, 1, |
|
|
|
1, 1, 1, 1, |
|
|
|
1, 1, 1, 1, |
|
|
|
1, 1, 1, 1, |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
f.degree_u = 3; |
|
|
|
f.degree_v = 3; |
|
|
|
f.knots_u = {0, 0, 0, 0, 1, 1, 1, 1}; |
|
|
|
f.knots_v = {0, 0, 0, 0, 1, 1, 1, 1}; |
|
|
|
f.control_points = {4, 4, { |
|
|
|
glm::vec3(0, 0.2, 0.9), glm::vec3(0, 0.5, 1.8), glm::vec3(0, 0.8, 1.1), glm::vec3(0, 1.2, 1), |
|
|
|
glm::vec3(0.33, 0.2, 0.12), glm::vec3(0.33, 0.5, 0.42), glm::vec3(0.33, 0.9, -0.62), |
|
|
|
glm::vec3(0.33, 1.1, -1.756), |
|
|
|
glm::vec3(0.66, 0.2, 0.12), glm::vec3(0.66, 0.5, 0.42), glm::vec3(0.66, 0.9, -0.62), |
|
|
|
glm::vec3(0.66, 1.0, -1.756), |
|
|
|
glm::vec3(1, 0.2, 0.8), glm::vec3(1, 0.5, 1), glm::vec3(1, 0.9, 1.1), glm::vec3(1, 1.2, 1) |
|
|
|
}}; |
|
|
|
f.weights = {4, 4, |
|
|
|
{ |
|
|
|
1, 1, 1, 1, |
|
|
|
1, 1, 1, 1, |
|
|
|
1, 1, 1, 1, |
|
|
|
1, 1, 1, 1, |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
vector<vector<glm::vec3>> s_evaluation; |
|
|
|
vector<vector<glm::vec3>> f_evaluation; |
|
|
|
// 曲面s和f的切向量。
|
|
|
|
vector<vector<glm::vec3>> s_tangent_u; |
|
|
|
vector<vector<glm::vec3>> s_tangent_v; |
|
|
|
vector<vector<glm::vec3>> f_tangent_u; |
|
|
|
const vector<vector<glm::vec3>> f_tangent_v; |
|
|
|
// s.degree_u = 3;
|
|
|
|
// s.degree_v = 3;
|
|
|
|
// s.knots_u = {0, 0, 0, 0, 1, 1, 1, 1};
|
|
|
|
// s.knots_v = {0, 0, 0, 0, 1, 1, 1, 1};
|
|
|
|
// s.control_points = {4, 4, {
|
|
|
|
// glm::vec3(0, 0.3, 0.9), glm::vec3(0, 0.6, 1), glm::vec3(0, 0.9, 1.1), glm::vec3(0, 1.2, 1),
|
|
|
|
// glm::vec3(0.33, 0.3, 0.12), glm::vec3(0.33, 0.6, 0.12), glm::vec3(0.33, 0.9, 0.12),
|
|
|
|
// glm::vec3(0.33, 1.2, 0.12),
|
|
|
|
// glm::vec3(0.66, 0.3, 0.12), glm::vec3(0.66, 0.6, 0.12), glm::vec3(0.66, 0.9, 0.12),
|
|
|
|
// glm::vec3(0.66, 1.2, 0.12),
|
|
|
|
// glm::vec3(1, 0.3, 0.8), glm::vec3(1, 0.6, 1), glm::vec3(1, 0.9, 1.1), glm::vec3(1, 1.2, 1)
|
|
|
|
// }};
|
|
|
|
// s.weights = {4, 4,
|
|
|
|
// {
|
|
|
|
// 1, 1, 1, 1,
|
|
|
|
// 1, 1, 1, 1,
|
|
|
|
// 1, 1, 1, 1,
|
|
|
|
// 1, 1, 1, 1,
|
|
|
|
// }
|
|
|
|
// };
|
|
|
|
//
|
|
|
|
// f.degree_u = 3;
|
|
|
|
// f.degree_v = 3;
|
|
|
|
// f.knots_u = {0, 0, 0, 0, 1, 1, 1, 1};
|
|
|
|
// f.knots_v = {0, 0, 0, 0, 1, 1, 1, 1};
|
|
|
|
// f.control_points = {4, 4, {
|
|
|
|
// glm::vec3(0, 0.2, 0.9), glm::vec3(0, 0.5, 1.8), glm::vec3(0, 0.8, 1.1), glm::vec3(0, 1.2, 1),
|
|
|
|
// glm::vec3(0.33, 0.2, 0.12), glm::vec3(0.33, 0.5, 0.42), glm::vec3(0.33, 0.9, -0.62),
|
|
|
|
// glm::vec3(0.33, 1.1, -1.756),
|
|
|
|
// glm::vec3(0.66, 0.2, 0.12), glm::vec3(0.66, 0.5, 0.42), glm::vec3(0.66, 0.9, -0.62),
|
|
|
|
// glm::vec3(0.66, 1.0, -1.756),
|
|
|
|
// glm::vec3(1, 0.2, 0.8), glm::vec3(1, 0.5, 1), glm::vec3(1, 0.9, 1.1), glm::vec3(1, 1.2, 1)
|
|
|
|
// }};
|
|
|
|
// f.weights = {4, 4,
|
|
|
|
// {
|
|
|
|
// 1, 1, 1, 1,
|
|
|
|
// 1, 1, 1, 1,
|
|
|
|
// 1, 1, 1, 1,
|
|
|
|
// 1, 1, 1, 1,
|
|
|
|
// }
|
|
|
|
// };
|
|
|
|
|
|
|
|
ifstream fin; |
|
|
|
fin.open(R"(E:\qt\OpenGLDemo\surfacePlayer\assets\intersectTest\casea3\surfaces.txt)"); |
|
|
|
|
|
|
|
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<float> weights; |
|
|
|
vector<float> 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] = wsInV[j].toFloat(); |
|
|
|
} |
|
|
|
} |
|
|
|
weights = {points1.cols(), points2.rows(), wArray}; |
|
|
|
|
|
|
|
// knot
|
|
|
|
std::vector<float> knot_u(2 * points1.cols(), 1.); |
|
|
|
for (int i = 0; i < knot_u.size() / 2; i++)knot_u[i] = 0; |
|
|
|
std::vector<float> 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(); |
|
|
|
|
|
|
|
// ====================== 测试 =======================
|
|
|
|
vector <vector<glm::vec3>> s_evaluation; |
|
|
|
vector <vector<glm::vec3>> f_evaluation; |
|
|
|
// 曲面s和f的切向量。zd*-sznmj
|
|
|
|
vector <vector<glm::vec3>> s_tangent_v; |
|
|
|
vector <vector<glm::vec3>> f_tangent_u; |
|
|
|
const vector <vector<glm::vec3>> f_tangent_v; |
|
|
|
// 曲面s和f的法向量
|
|
|
|
const vector<vector<glm::vec3>> s_normal; |
|
|
|
const vector<vector<glm::vec3>> f_normal; |
|
|
|
const vector <vector<glm::vec3>> s_normal; |
|
|
|
const vector <vector<glm::vec3>> f_normal; |
|
|
|
|
|
|
|
auto mesh1 = getMesh(s, 7); |
|
|
|
auto mesh1 = getMesh(s, 7); // [0, 63]
|
|
|
|
auto mesh2 = getMesh(f, 7); |
|
|
|
|
|
|
|
SingularityJudger singularityJudger(s, f, mesh1, mesh2); |
|
|
|
auto hasSingularity = singularityJudger.judge({2,7}, {4,12}, {3, 9}, {10, 16}); |
|
|
|
for(auto line: singularityJudger.judgeRes) { |
|
|
|
for(auto el: line) { |
|
|
|
cout<<el<<' '; |
|
|
|
// auto hasSingularity = singularityJudger.judge({2,7}, {4,12}, {3, 9}, {10, 16});
|
|
|
|
// for(auto line: singularityJudger.judgeRes) {
|
|
|
|
// for(auto el: line) {
|
|
|
|
// cout<<el<<' ';
|
|
|
|
// }
|
|
|
|
// cout<<endl;
|
|
|
|
// }
|
|
|
|
// singularityJudger.judge({12, 48}, {12, 48}, {12, 48}, {12, 48});
|
|
|
|
singularityJudger.judge({0, 63}, {0, 63}, {0, 63}, {0, 63}); |
|
|
|
|
|
|
|
// ================== 测试对整个曲面,gauss能排除多少(或保留多少)==================
|
|
|
|
GaussMap gaussMap1(mesh1.normal); |
|
|
|
GaussMap gaussMap2(mesh2.normal); |
|
|
|
gaussMap1.build(); |
|
|
|
gaussMap2.build(); |
|
|
|
auto pairs = getOverlapLeafNodes(gaussMap1, gaussMap2); |
|
|
|
printf("Gauss Map: keep %lld samples in totally %lld boxes\n", pairs.size(), |
|
|
|
mesh1.normal.size() * mesh1.normal[0].size() * mesh2.normal.size() * mesh2.normal[0].size()); |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
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++) { |
|
|
|
float num; |
|
|
|
if (coords[k].contains("/")) { |
|
|
|
auto nums = coords[k].split("/"); |
|
|
|
num = nums[0].trimmed().toFloat() / nums[1].trimmed().toFloat(); |
|
|
|
} else { |
|
|
|
num = coords[k].toFloat(); |
|
|
|
} |
|
|
|
if (k == 0) points[i].x = num; |
|
|
|
else if (k == 1) points[i].y = num; |
|
|
|
else points[i].z = num; |
|
|
|
} |
|
|
|
cout<<endl; |
|
|
|
} |
|
|
|
return 0; |
|
|
|
array2<glm::vec3> res = {(size_t) dimU, (size_t) dimV, points}; |
|
|
|
return res; |
|
|
|
} |