Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<iostream>
- #include<Eigen\Dense>
- #include<vector>
- #include"model.hpp"
- #include<set>
- #include<ctime>
- #include<map>
- #include"cross.hpp"
- using namespace std;
- const int maxn = 1e5 + 10;
- int in[maxn];
- bool checkColision() {
- return false;
- }
- auto cmpVector2i = [](const Eigen::Vector2i a, const Eigen::Vector2i b) {
- return a.x() < b.x();
- };
- map<Eigen::Vector2i, int, decltype(cmpVector2i)>edgeId(cmpVector2i);
- int ID = 0;
- vector<set<int>>edge2faces;
- bool judge(double a, double b, double c, double d) {
- if (a > b)swap(a, b);
- if (c > d)swap(c, d);
- if (a <= c && b >= c)return true;
- if (a <= d && b >= d)return true;
- if (a >= c && b <= d)return true;
- return false;
- }
- template<class cmp1,class cmp2>
- bool CrossCheckY(Eigen::Vector2i v,set<Eigen::Vector2i,cmp1>& SortedEdgeYbyFirstVert, set<Eigen::Vector2i,cmp2>& SortedEdgeYbyEndVert,const vector<Eigen::Vector3d>& verts, const vector<Eigen::Vector3i>&faces) {
- int stVert = v.x(), edVert = v.y();
- auto stY = SortedEdgeYbyFirstVert.lower_bound(Eigen::Vector2i(edVert, edVert));
- //cerr << "check st" << '\n';
- if (stY != SortedEdgeYbyFirstVert.begin()) {
- --stY;
- while (stY != SortedEdgeYbyFirstVert.begin() && verts[stY->x()].y() >= verts[stVert].y()) {
- //crossCheck(Eigen::Vector2i(vert,nxtVert),*stY);
- int ida = edgeId[Eigen::Vector2i(min(stVert, edVert), max(stVert, edVert))];
- int idb = edgeId[Eigen::Vector2i(min(stY->x(), stY->y()), max(stY->x(), stY->y()))];
- /*if (judge(verts[stVert].z(), verts[edVert].z(), verts[stY->x()].z(), verts[stY->y()].z()) == 0)
- {
- cerr << "cross " << '\n';
- cout << verts[stVert].z() << " " << verts[edVert].z() << '\n';
- cout << verts[stY->x()].z() << " " << verts[stY->y()].z() << '\n';
- }*/
- //for (int i = 0; i < edge2faces[ida].size(); ++i) {
- // for (int j = 0; j < edge2faces[idb].size(); ++j) {
- // if (ida != idb) {
- // /*float va[3][3] = { {verts[faces[ida].x()].x(),verts[faces[ida].x()].y(),verts[faces[ida].x()].y()},\
- // {verts[faces[ida].y()].x(), verts[faces[ida].y()].y(), verts[faces[ida].y()].y()},
- // { verts[faces[ida].z()].x(),verts[faces[ida].z()].y(),verts[faces[ida].z()].y() } };
- // float vb[3][3] = { {verts[faces[idb].x()].x(),verts[faces[idb].x()].y(),verts[faces[idb].x()].y()},\
- // {verts[faces[idb].y()].x(), verts[faces[idb].y()].y(), verts[faces[idb].y()].y()},
- // { verts[faces[idb].z()].x(),verts[faces[idb].z()].y(),verts[faces[idb].z()].y() } };
- // Triangle a(va), b(vb);*/
- // //if (judge_triangle_topologicalStructure(&a, &b)== INTERSECT) {
- // // /*cerr << " cross " << '\n';
- // // cerr << verts[stVert].z() << '\n';
- // // cerr << verts[edVert].z() << '\n';
- // // cerr << verts[stY->x()].z() << '\n';
- // // cerr << verts[stY->y()].z() << '\n';*/
- // // /*cerr << faces[ida].x() + 1 << " " << faces[ida].y() + 1 << " " << faces[ida].z() + 1 << '\n';
- // // cerr << faces[idb].x() + 1 << " " << faces[idb].y() + 1 << " " << faces[idb].z() + 1 << '\n';*/
- // //}
- // }
- // }
- //}
- --stY;
- }
- }
- auto edY = SortedEdgeYbyFirstVert.lower_bound(Eigen::Vector2i(stVert, stVert));
- while (edY != SortedEdgeYbyFirstVert.end() && verts[stY->y()].y() <= verts[edVert].y()) {
- //crossCheck(Eigen::Vector2i(vert, nxtVert), *edY);
- int ida = edgeId[Eigen::Vector2i(min(stVert, edVert), max(stVert, edVert))];
- int idb = edgeId[Eigen::Vector2i(min(edY->x(), edY->y()), max(edY->x(), edY->y()))];
- /*if (judge(verts[stVert].z(), verts[edVert].z(), verts[edY->x()].z(), verts[edY->y()].z()) == 0)
- {
- cerr << "cross " << '\n';
- cout << verts[stVert].z() << " " << verts[edVert].z() << '\n';
- cout << verts[edY->x()].z() << " " << verts[edY->y()].z() << '\n';
- }*/
- //for (int i = 0; i < edge2faces[ida].size(); ++i) {
- // for (int j = 0; j < edge2faces[idb].size(); ++j) {
- // if (ida != idb) {
- // /*float va[3][3] = { {verts[faces[ida].x()].x(),verts[faces[ida].x()].y(),verts[faces[ida].x()].y()},\
- // {verts[faces[ida].y()].x(), verts[faces[ida].y()].y(), verts[faces[ida].y()].y()},
- // { verts[faces[ida].z()].x(),verts[faces[ida].z()].y(),verts[faces[ida].z()].y() } };
- // float vb[3][3] = { {verts[faces[idb].x()].x(),verts[faces[idb].x()].y(),verts[faces[idb].x()].y()},\
- // {verts[faces[idb].y()].x(), verts[faces[idb].y()].y(), verts[faces[idb].y()].y()},
- // { verts[faces[idb].z()].x(),verts[faces[idb].z()].y(),verts[faces[idb].z()].y() } };
- // Triangle a(va), b(vb);*/
- // //if (judge_triangle_topologicalStructure(&a, &b) == INTERSECT) {
- // // /*cerr << " cross " << '\n';
- // // cerr << verts[stVert].z() << '\n';
- // // cerr << verts[edVert].z() << '\n';
- // // cerr << verts[edY->x()].z() << '\n';
- // // cerr << verts[edY->y()].z() << '\n';*/
- // // /*cerr << faces[ida].x()+1<<" "<< faces[ida].y()+1<<" "<< faces[ida].z()+1 << '\n';
- // // cerr << faces[idb].x()+1 << " " << faces[idb].y()+1 << " " << faces[idb].z()+1 << '\n';*/
- // //
- // //}
- // }
- // }
- //}
- ++edY;
- }
- //cerr << "check end" << '\n';
- return false;
- }
- int main() {
- Model model;
- time_t begin, end;
- model.ReadObjFile("C:\\Users\\admin\\Desktop\\model\\trumpet2.obj");
- vector<Eigen::Vector3d> verts = model.GetVertices();
- vector<Eigen::Vector3i> faces = model.GetFaces();
- vector<set<int>>nxtVerts(verts.size(), set<int>());
- vector<set<int>>preVerts(verts.size(), set<int>());
- begin = clock();
- for (int pos = 0;pos<faces.size();++pos) {
- auto face = faces[pos];
- if (verts[face.x()].z() > verts[face.y()].z()||(verts[face.x()].z() == verts[face.y()].z())&&face.x()<face.y())
- {
- nxtVerts[face.x()].insert(face.y());
- preVerts[face.y()].insert(face.x());
- in[face.y()] = 1;
- }
- else {
- nxtVerts[face.y()].insert(face.x());
- preVerts[face.x()].insert(face.y());
- in[face.x()] = 1;
- }
- if (edgeId.count(Eigen::Vector2i(min(face.x(), face.y()), max(face.x(), face.y())))) {
- edge2faces[edgeId[Eigen::Vector2i(min(face.x(), face.y()), max(face.x(), face.y()))]].insert(pos);
- }
- else {
- edgeId[Eigen::Vector2i(min(face.x(), face.y()), max(face.x(), face.y()))] = ID;
- edge2faces.push_back(set<int>());
- edge2faces[ID].insert(pos);
- ++ID;
- }
- if (verts[face.x()].z() > verts[face.z()].z() || (verts[face.x()].z() == verts[face.z()].z()) && face.x() < face.z())
- {
- nxtVerts[face.x()].insert(face.z());
- preVerts[face.z()].insert(face.x());
- in[face.z()] = 1;
- }
- else {
- nxtVerts[face.z()].insert(face.x());
- preVerts[face.x()].insert(face.z());
- in[face.x()] = 1;
- }
- if (edgeId.count(Eigen::Vector2i(min(face.x(), face.z()), max(face.x(), face.z())))) {
- edge2faces[edgeId[Eigen::Vector2i(min(face.x(), face.z()), max(face.x(), face.z()))]].insert(pos);
- }
- else {
- edgeId[Eigen::Vector2i(min(face.x(), face.z()), max(face.x(), face.z()))] = ID;
- edge2faces.push_back(set<int>());
- edge2faces[ID].insert(pos);
- ++ID;
- }
- if (verts[face.z()].z() > verts[face.y()].z() || (verts[face.z()].z() == verts[face.y()].z()) && face.z() < face.y())
- {
- nxtVerts[face.z()].insert(face.y());
- preVerts[face.y()].insert(face.z());
- in[face.y()] = 1;
- }
- else {
- nxtVerts[face.y()].insert(face.z());
- preVerts[face.z()].insert(face.y());
- in[face.z()] = 1;
- }
- if (edgeId.count(Eigen::Vector2i(min(face.z(), face.y()), max(face.z(), face.y())))) {
- edge2faces[edgeId[Eigen::Vector2i(min(face.z(), face.y()), max(face.z(), face.y()))]].insert(pos);
- }
- else {
- edgeId[Eigen::Vector2i(min(face.z(), face.y()), max(face.z(), face.y()))] = ID;
- edge2faces.push_back(set<int>());
- edge2faces[ID].insert(pos);
- ++ID;
- }
- }
- cerr << "size " << verts.size() << " " << faces.size() << '\n';
- //利用x和y交叉进行检查
- //存储当前准备扫描的边,将每条边的起点和终点的坐标记录下来,做比较函数,利用y值进行比较
- auto cmpEdgeYbyFirstVert = [&verts](const Eigen::Vector2i edgea, const Eigen::Vector2i edgeb) {
- return verts[edgea.x()].y() < verts[edgeb.x()].y();
- };
- //正在扫描的边和所有的点,将所有正在扫描的边组合在一起产生的数据结构
- set<Eigen::Vector2i,decltype(cmpEdgeYbyFirstVert)>SortedEdgeYbyFirstVert(cmpEdgeYbyFirstVert);
- auto cmpEdgeYbyEndVert = [&verts](const Eigen::Vector2i edgea, const Eigen::Vector2i edgeb) {
- return verts[edgea.y()].y() < verts[edgeb.y()].y();
- };
- set<Eigen::Vector2i, decltype(cmpEdgeYbyEndVert)>SortedEdgeYbyEndVert(cmpEdgeYbyEndVert);
- set<Eigen::Vector2i, decltype(cmpEdgeYbyEndVert)>allEdge(cmpEdgeYbyEndVert);
- /*auto cmpEdgeX = [&verts](const Eigen::Vector2i edgea, const Eigen::Vector2i edgeb) {
- return min(verts[edgea.x()].x(), verts[edgea.y()].x()) < \
- min(verts[edgeb.x()].x(), verts[edgeb.y()].x());
- };
- set<Eigen::Vector2i, decltype(cmpEdgeX)>SortedEdgeX(cmpEdgeX);*/
- //如果存在离散的点或者多个分开的数据结构的时候,所以需要单独建立一个点的数据结构,在不能利用边含入进来的时候
- //利用点的高度继续构建
- auto cmpVertZ = [&verts](const int verta, const int vertb) {
- return verts[verta].z() > verts[vertb].z();
- };
- set<int,decltype(cmpVertZ)>RemainVerts(cmpVertZ);
- //当前正在扫描中的点
- set<int,decltype(cmpVertZ)>CurVerts(cmpVertZ);
- for (int i = 0; i<int(verts.size()); ++i) {
- RemainVerts.insert(i);
- }
- int out = 0;
- while (!RemainVerts.empty() || !CurVerts.empty()) {
- //删除掉旧的边会产生新的边
- //在插入新的边的时候再判断这条边有没有和已有的边产生交叉
- //如果CurVerts是空的
- if (CurVerts.empty()||(!RemainVerts.empty()&&verts[*CurVerts.begin()].z()<verts[*RemainVerts.begin()].z())) {
- int vert = *RemainVerts.begin();
- //CurVerts.insert(vert);
- RemainVerts.erase(vert);
- for (auto nxtVert : nxtVerts[vert]) {
- CurVerts.insert(nxtVert);
- RemainVerts.erase(nxtVert);
- int stVert = (verts[nxtVert].y() < verts[vert].y() ? nxtVert : vert);
- int edVert = (stVert == vert ? nxtVert : vert);
- CrossCheckY(Eigen::Vector2i(stVert, edVert), SortedEdgeYbyFirstVert, SortedEdgeYbyEndVert, verts,faces);
- SortedEdgeYbyFirstVert.insert(Eigen::Vector2i(stVert, edVert));
- SortedEdgeYbyEndVert.insert(Eigen::Vector2i(stVert, edVert));
- allEdge.insert(Eigen::Vector2i(stVert, edVert));
- //cerr << "end 1 "<<nxtVert << '\n';
- }
- //cerr << "end 2" << '\n';
- }
- else {
- //cerr << "start 2" << '\n';
- cerr << ++out << '\n';
- int vert = *CurVerts.begin();
- //cerr << vert<< '\n';
- CurVerts.erase(vert);
- for (auto preVert : preVerts[vert]) {
- int stVert = (verts[vert].y() < verts[preVert].y() ? vert : preVert);
- int edVert = (vert == stVert ? preVert : vert);
- if (!allEdge.count(Eigen::Vector2i(stVert, edVert))) {
- cerr << "error " << endl;
- }
- SortedEdgeYbyFirstVert.erase(Eigen::Vector2i(stVert, edVert));
- SortedEdgeYbyEndVert.erase(Eigen::Vector2i(stVert, edVert));
- }
- for (auto nxtVert : nxtVerts[vert]) {
- //cerr << "nxt " << nxtVerts[vert].size() << endl;
- CurVerts.insert(nxtVert);
- RemainVerts.erase(nxtVert);
- int stVert = verts[nxtVert].y() < verts[vert].y() ? nxtVert : vert;
- int edVert = (stVert == vert ? nxtVert : vert);
- //CrossCheckY(Eigen::Vector2i(stVert, edVert), SortedEdgeYbyFirstVert, SortedEdgeYbyEndVert, verts,faces);
- SortedEdgeYbyFirstVert.insert(Eigen::Vector2i(stVert, edVert));
- SortedEdgeYbyEndVert.insert(Eigen::Vector2i(stVert, edVert));
- allEdge.insert(Eigen::Vector2i(stVert, edVert));
- }
- }
- }
- end = clock();
- std::cout << "runtime: " << double(end - begin) / CLOCKS_PER_SEC << endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement