Skip to content

Commit

Permalink
更新
Browse files Browse the repository at this point in the history
更新配置文件写法、更新2种找点策略、更新禁止区域的写法
  • Loading branch information
Mizuki7fan committed Nov 2, 2019
1 parent 09f0b13 commit 63876b9
Show file tree
Hide file tree
Showing 10 changed files with 256 additions and 47 deletions.
10 changes: 8 additions & 2 deletions opt.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,18 @@ KPNewtonResultOutput=Yes

#==============PointFindingCfg=======
#如何度量顶点的优先级? Neighbourhood/Geodesic/RealDis
VertexPriorityMetric=RealDis
VertexPriorityMetric=Neighbourhood

#==============禁止区域的半径,测地距离
Dn=10


#论文中的流程对应的配置:
#从网格中随机选取一个点Vi
#即:SampleFirstPoint=Random
#对于网格上其他的所有点计算到Vi的dijkstra距离,找与其最远的点Vj,将Dij作为初始的割缝
#即:SampleMethod=Dijkstra
#即:SampleMethod=Dijkstra
#沿着割缝进行切割,做一个ACAP的参数化(KPNewton)
#计算每个顶点的等距扭曲,找所有局部极大值点(但不需要找顶点的等级)
#设定正数dn,计算禁止区域R,定义是距离极大值点和距离切缝距离都小于dn的区域为禁止区域
#即:Dn=10
4 changes: 4 additions & 0 deletions src/Auxiliary/OptionReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ Option::Option(std::string s,std::string ModelPath)
KPNewtonOutput = value;
else if (key == "VertexPriorityMetric")
VertexPriorityMetric = value;
else if (key == "Dn")
Dn = std::stoi(value);
else if (key == "BanAreaMethod")
BanAreaMethod = value;

}
}
2 changes: 2 additions & 0 deletions src/Auxiliary/OptionReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class Option
std::string MeshcutOutput = "Yes";
std::string KPNewtonOutput = "Yes";
std::string VertexPriorityMetric = "RealDis";
int Dn = 10;
std::string BanAreaMethod = "NonConnect";


double filtering_rate;
Expand Down
26 changes: 25 additions & 1 deletion src/MeshCut/MeshCut.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "MeshCut.h"
#include "MeshCut.h"
#include <string>

MeshCut::MeshCut(Mesh &mesh, MeshCache &MCache) :
Expand All @@ -12,6 +12,30 @@ void MeshCut::SetCondition(const std::vector<int> &lmk, const std::vector<int> &
this->initseam = initseam;
}

void MeshCut::SetBanCondition(const std::vector<int>& banV, const std::vector<int>& banE, const std::string BanMethod)
{
//设置Ban选的相关条件,根据BanMethod进行设置
if (BanMethod == "NonConnect")
{
//不进行连接,直接将所有点作为输入
std::set<int> ban;
for (auto a : banV)
ban.insert(a);
for (auto a : banE)
ban.insert(a);
for (auto a : ban)
ban_vertex.push_back(a);
}
else if (BanMethod == "Connect")
{
//将输入的点和边连起来得到ban_vertex;
}
}

void MeshCut::CalcBanArea(int Dn)
{
}

void MeshCut::Connect()
{
//如果初始没有割缝,则直接用Kruskal算法算割缝
Expand Down
12 changes: 7 additions & 5 deletions src/MeshCut/MeshCut.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#pragma once
#pragma once
#include <OpenMesh/Core/IO/MeshIO.hh>
#include "..//MeshDefinition/MeshDefinition.h"
#include "..//MeshDefinition/MeshCache.h"
Expand All @@ -10,15 +10,17 @@
class MeshCut
{
public:
//网格切割类,输入是原始网格以及其Cache
//网格切割类,输入是原始网格以及其Cache
MeshCut(Mesh& mesh, MeshCache& MCache);
//设置landmark点和已有的割缝点
//设置landmark点和已有的割缝点
void SetCondition(const std::vector<int>& lmk,const std::vector<int>& initseam=std::vector<int>());
//计算网格的割缝
void SetBanCondition(const std::vector<int>& banV, const std::vector<int>& banE, const std::string BanMethod);
void CalcBanArea(int Dn);
//计算网格的割缝
void Connect();
//Cut_to_Seam
void MakeSeam();
//返回切开后的网格
//返回切开后的网格
Mesh GetCutedMesh() const { return cuted_mesh; };
std::vector<int>& GetCutvertex() { return cutVertex; }
std::vector<int>& GetCutEdge() { return cutEdge; }
Expand Down
7 changes: 5 additions & 2 deletions src/MeshDefinition/MeshCache.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "MeshCache.h"
#include "MeshCache.h"

//¹¹ÔìMeshCacheÀà
//构造MeshCache类
MeshCache::MeshCache(Mesh& mesh)
{
n_vertices = mesh.n_vertices();
Expand Down Expand Up @@ -34,13 +34,16 @@ MeshCache::MeshCache(Mesh& mesh)
}
el.resize(n_edges);
ev.resize(n_edges, std::vector<int>(2));
avg_el = 0;
for (const auto& e : mesh.edges())
{
Mesh::HalfedgeHandle he = mesh.halfedge_handle(e, 0);
ev[e.idx()][0] = mesh.to_vertex_handle(he).idx();
ev[e.idx()][1] = mesh.from_vertex_handle(he).idx();
el[e.idx()] = mesh.calc_edge_length(e);
avg_el += el[e.idx()];
}
avg_el /= n_vertices;
}

MeshCache::~MeshCache()
Expand Down
19 changes: 10 additions & 9 deletions src/MeshDefinition/MeshCache.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#pragma once
#pragma once
#include "MeshDefinition.h"
#include <iostream>
#include <queue>
Expand All @@ -8,18 +8,18 @@ class MeshCache
public:
MeshCache(Mesh& mesh);
~MeshCache();
//存点的one-ring
//存点的one-ring
std::vector<std::vector<int>> vv;
//存点的邻边
//存点的邻边
std::vector<std::vector<int>> ve;
//两点之间的边id
//两点之间的边id
std::vector<std::map<int , int>> vve;
//边长
//边长
std::vector<double> el;
//边的两个顶点
//边的两个顶点
std::vector<std::vector<int>> ev;

//邻域
//邻域
std::vector<std::vector<std::vector<int>>> Neighbour;
std::vector<std::priority_queue<node>> dijkstra_cache;
std::vector<std::vector<int>> dijkstra_isvisited;
Expand All @@ -29,9 +29,10 @@ class MeshCache

int n_vertices;
int n_edges;
double avg_el;

//辅助用
//记录已经缓存了多少数据
//辅助用
//记录已经缓存了多少数据
int capacity;

void updataCapacity();
Expand Down
191 changes: 176 additions & 15 deletions src/PointFinding/PointFinding.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
#include "PointFinding.h"

PointFinding::PointFinding(const Mesh&m, const Mesh&pm):OriMesh(m),ParaedMesh(pm)
PointFinding::PointFinding(const Mesh&m, const Mesh&pm,MeshCache& MCache):OriMesh(m),ParaedMesh(pm),MC(MCache)
{
PrepareComputeDistortion();
ComputeFaceDistortion();
ComputeVertexDistortion();
}

PointFinding::~PointFinding()
Expand All @@ -15,23 +18,37 @@ void PointFinding::Set(std::string metric)

void PointFinding::Find(std::vector<std::pair<int, double>>& result)
{//主体函数,用于找点
PrepareComputeDistortion();
ComputeFaceDistortion();
ComputeVertexDistortion();
MC.updataCapacity();
if (Metric == "RealDis")
FindByRealDis(result);
else if (Metric == "Neighbourhood")
FindByNeighbourhood(result);
MC.updataCapacity();

}









void PointFinding::FindLocalMaximizer(std::vector<int>& Result)
{
//找局部极大值点
LocalMaximizer.resize(MC.n_vertices, 0);
for (int i = 0; i < MC.n_vertices; i++)
{
if (LocalMaximizer[i] == 1)
continue;
for (auto a : MC.vv[i])
{
if (vertex_distortion[a] < vertex_distortion[i])
LocalMaximizer[a] = 1;
else if (vertex_distortion[i] < vertex_distortion[a])
LocalMaximizer[i] = 1;
}
}
for (int i = 0; i < MC.n_vertices; i++)
if (LocalMaximizer[i] == 0)
Result.push_back(i);
}


void PointFinding::PrepareComputeDistortion()
{
facearea.resize(OriMesh.n_faces());
Expand Down Expand Up @@ -115,11 +132,155 @@ void PointFinding::ComputeVertexDistortion()
}
}

void PointFinding::FindByRealDis(std::vector<std::pair<int, double>>&)
void PointFinding::FindByRealDis(std::vector<std::pair<int, double>>&result)
{
//输入
std::vector<double> Priority(MC.n_vertices,0);

for (int i = 0; i<LocalMaximizer.size(); i++)
{
if (LocalMaximizer[i] == 1)
{
continue;
}
double v_dis = vertex_distortion[i];
std::vector<int>& is_visited = MC.dijkstra_isvisited[i];
std::vector<double>& distance = MC.V_D[i];
std::priority_queue<node>& que = MC.dijkstra_cache[i];
std::vector<int>& v_p = MC.V_VP[i];
if (is_visited.size() == 0)
{
is_visited.resize(MC.n_vertices, 0);
distance.resize(MC.n_vertices, DBL_MAX);
distance[i] = 0;
que.push(node(i, 0));
v_p.resize(MC.n_vertices, -1);
v_p[i] = i;
}
else
{
//发生概率应该不高,可能有问题
double level = MC.avg_el * MC.n_edges;
for (int j= 0; j < MC.V_D[i].size(); j++)
{
if (is_visited[j] == 0)
continue;
else if (v_dis<vertex_distortion[j])
{
if (level > MC.V_D[i][j])
level = MC.V_D[i][j];
}
}
if (level < MC.avg_el * MC.n_edges)
{
Priority[i] = level;
continue;
}
}
while (1)
{
if (que.empty())
{
Priority[i] = DBL_MAX;
break;
}
node tmp = que.top();
que.pop();
if (is_visited[tmp.id])
continue;
is_visited[tmp.id] = 1;
for (int u = 0; u < MC.vv[tmp.id].size(); u++)
{
int vid = MC.vv[tmp.id][u];
int eid = MC.ve[tmp.id][u];
if (distance[tmp.id] + MC.el[eid] < distance[vid])
{
distance[vid] = distance[tmp.id] + MC.el[eid];
que.push(node(vid, distance[vid]));
v_p[vid] = tmp.id;
}
}
if (vertex_distortion[tmp.id] > v_dis)
{
if (distance[tmp.id] > MC.avg_el)
{
Priority[i] = distance[tmp.id];
}
break;
}
}
}
for (int i = 0; i < Priority.size(); i++)
if (Priority[i] >= MC.avg_el)
result.push_back({ i,Priority[i] });
}

void PointFinding::FindByNeighbourhood(std::vector<std::pair<int, double>>&FeaturePoints)
{
FeaturePoints.clear();
std::vector<int> Priority(MC.n_vertices, 0);
for (int i = 0; i < OriMesh.n_vertices(); i++)
{
if (LocalMaximizer[i] == 1)
continue;
double v_dis = vertex_distortion[i];
std::vector<int> is_visited(MC.n_vertices, 0);
is_visited[i] = 1;
std::vector<int> now_competitor(0), next_competitor(0);
now_competitor = MC.vv[i];
for (int u = 0; u < now_competitor.size(); u++)
{
is_visited[now_competitor[u]] = 1;
}
int level = 1;
while (1)
{
if (level == 50)
{
Priority[i] = 50;
break;
}
next_competitor.clear();
for (auto a : now_competitor)
{
for (auto b : MC.vv[a])
{
if (!is_visited[b])
{
next_competitor.push_back(b);

}
}
}
}
std::sort(next_competitor.begin(), next_competitor.end());

next_competitor.erase(std::unique(next_competitor.begin(), next_competitor.end()), next_competitor.end());
now_competitor = next_competitor;
int mudeki = 1;
for (auto a : now_competitor)
{
if (v_dis < vertex_distortion[a])
{//我怎么会输?
mudeki = 0;
break;
}
else
{//彩笔,还有脸再来?
is_visited[a] = 1;
}
}
//挑战结束
if (mudeki == 0)
{
Priority[i] = level;
break;
}
else
{
level++;
}
}
}
for (int i = 0; i < Priority.size(); i++)
if (Priority[i] >= 1)
FeaturePoints.push_back({ i,Priority[i] });
}
Loading

0 comments on commit 63876b9

Please sign in to comment.