进行了简单的代码重构

dev-VirtualTexture
yang.yongquan 2022-10-06 14:50:07 +08:00
parent 09f2a32fc6
commit e849479236
4 changed files with 127 additions and 127 deletions

View File

@ -12,7 +12,7 @@ int Line::size() {
return siz;
}
vector<point> Line::toVectorPoint() const {
vector<point> Line::toPointVector() const {
vector<point> vL;
for (int i = 0; i < siz; i++) {
vL.push_back({vX[i], vY[i]});

View File

@ -54,7 +54,7 @@ public:
bool isLineContained(QVector4D bound);
point operator[](int index) const;
point getPointByIndex(int index) const;
vector<point> toVectorPoint() const;
vector<point> toPointVector() const;
void setPointByIndex(int index, point now);
void push_back(point now);
virtual ~Line() {}

View File

@ -1,27 +1,27 @@
#include "ShortCutTree.h"
void ShortCutTree::init() {
outTree.clear();
restOfTreeNodes.clear();
allLine.clear();
pointMap.clear();
lineIndexSet.clear();
lineIndexs.clear();
numLine = numPoint = 0;
}
int ShortCutTree::getPointIndex(point now) {
auto iter = pointMap.find(now);
int ShortCutTree::getPointIndex(point nowPoint) {
auto iter = pointMap.find(nowPoint);
if (iter != pointMap.end()) {
return iter->second;
}
else {
int res = numPoint;
pointMap.insert({ now, numPoint });
pointMap.insert({ nowPoint, numPoint });
++numPoint;
return res;
}
}
bool ShortCutTree::isLineEqual(LineIndex& a, LineIndex& b) const {
bool ShortCutTree::isLineEqual(PointIndexVector& a, PointIndexVector& b) const {
if (a.size() != b.size())
return false;
for (int i = 0; i < a.size(); i++)
@ -30,79 +30,79 @@ bool ShortCutTree::isLineEqual(LineIndex& a, LineIndex& b) const {
return true;
}
void ShortCutTree::monotonization(vector<vLine>& inL, vector<LinePtr>& outL) {
for (vLine &l: inL) {
LinePtr now;
void ShortCutTree::monotonization(vector<PointVector>& inL, vector<LinePtr>& outL) {
for (PointVector&l: inL) {
LinePtr nowLine;
switch(l.size()) {
case 2: now.reset(new StraightLine(l)); break;
case 3: case 4: now.reset(new CubicBezier(l)); break;
case 2: nowLine.reset(new StraightLine(l)); break;
case 3: case 4: nowLine.reset(new CubicBezier(l)); break;
default: break;
}
now->monotonization(outL);
outL.push_back(now);
nowLine->monotonization(outL);
outL.push_back(nowLine);
}
}
void ShortCutTree::generateShortCutSegement(ShortCutNode& now) {
point p;
void ShortCutTree::generateShortCutsegmentement(ShortCutNode& nowTreeNode) {
point p = {0, 0};
vector<int> v;
for (int &index : now.lineSet) {
int type = allLine[index]->judgeBoundIntersection(now.bound.z(), now.bound.y(), now.bound.w(), false), be, en;
for (int & lineIndex : nowTreeNode.lineSet) {
int type = allLine[lineIndex]->judgeBoundIntersection(nowTreeNode.bound.z(), nowTreeNode.bound.y(), nowTreeNode.bound.w(), false), be, en;
if (type >= 2) {
v.push_back(numLine);
if (type == 2) {
p = allLine[index]->getEnd();
p = allLine[lineIndex]->getEnd();
}
if (type == 3) {
p = allLine[index]->getBegin();
p = allLine[lineIndex]->getBegin();
}
be = getPointIndex({ p.x, now.bound.w() });
be = getPointIndex({ p.x, nowTreeNode.bound.w() });
en = getPointIndex(p);
lineIndexSet.push_back(be);
lineIndexSet.push_back(be);
lineIndexSet.push_back(en);
lineIndexSet.push_back(en);
lineIndexs.push_back(be);
lineIndexs.push_back(be);
lineIndexs.push_back(en);
lineIndexs.push_back(en);
numLine++;
}
}
if (now.windingIncrement != 0) {
if (nowTreeNode.windingIncrement != 0) {
v.push_back(numLine);
int be = getPointIndex({now.bound.z(), now.bound.y()});
int en = getPointIndex({ now.bound.z(), now.bound.w() });
lineIndexSet.push_back(be);
lineIndexSet.push_back(be);
lineIndexSet.push_back(en);
lineIndexSet.push_back(en);
int be = getPointIndex({ nowTreeNode.bound.z(), nowTreeNode.bound.y()});
int en = getPointIndex({ nowTreeNode.bound.z(), nowTreeNode.bound.w() });
lineIndexs.push_back(be);
lineIndexs.push_back(be);
lineIndexs.push_back(en);
lineIndexs.push_back(en);
numLine++;
}
for (int& index : v) {
now.lineSet.push_back(index);
for (int& lineIndex : v) {
nowTreeNode.lineSet.push_back(lineIndex);
}
}
bool ShortCutTree::handleShortCutNode(ShortCutNode& fa, ShortCutNode& now, float yValue, vector<ShortCutNode>& v, int& sumIncrement) {
now.windingIncrement = sumIncrement;
for (int &index : fa.lineSet) {
int type = allLine[index]->judgeBoundIntersection(yValue, now.bound.x(), now.bound.z(), true);
bool ShortCutTree::handleShortCutNode(ShortCutNode& fa, ShortCutNode& nowTreeNode, float yValue, vector<ShortCutNode>& v, int& sumIncrement) {
nowTreeNode.windingIncrement = sumIncrement;
for (int & lineIndex : fa.lineSet) {
int type = allLine[lineIndex]->judgeBoundIntersection(yValue, nowTreeNode.bound.x(), nowTreeNode.bound.z(), true);
if (type == 2)
sumIncrement++;
if (type == 3)
sumIncrement--;
if (allLine[index]->judgeIntersection(now.bound)) {
now.lineSet.push_back(index);
if (allLine[lineIndex]->judgeIntersection(nowTreeNode.bound)) {
nowTreeNode.lineSet.push_back(lineIndex);
}
}
if (now.lineSet.size() <= RequiredLineMin) {
if (now.lineSet.empty() && now.windingIncrement == 0)
if (nowTreeNode.lineSet.size() <= RequiredLineMin) {
if (nowTreeNode.lineSet.empty() && nowTreeNode.windingIncrement == 0)
return false;
outTree.push_back(now);
now.divided = false;
v.push_back(now);
restOfTreeNodes.push_back(nowTreeNode);
nowTreeNode.divided = false;
v.push_back(nowTreeNode);
return false;
}
else {
v.push_back(now);
v.push_back(nowTreeNode);
return true;
}
@ -110,17 +110,17 @@ bool ShortCutTree::handleShortCutNode(ShortCutNode& fa, ShortCutNode& now, float
void ShortCutTree::simplifyLineVector() {
numLine = allLine.size();
for (auto& l : allLine) {
vLine vl = l->toVectorPoint();
for (point& p : vl) {
int index = getPointIndex(p);
lineIndexSet.push_back(index);
if (vl.size() == 2)
lineIndexSet.push_back(index);
for (auto& nowLine : allLine) {
PointVector pointVector = nowLine->toPointVector();
for (point& p : pointVector) {
int pointIndex = getPointIndex(p);
lineIndexs.push_back(pointIndex);
if (pointVector.size() == 2)
lineIndexs.push_back(pointIndex);
}
}
for (auto& now : outTree) {
generateShortCutSegement(now);
for (auto& nowTreeNode : restOfTreeNodes) {
generateShortCutsegmentement(nowTreeNode);
}
}
@ -134,16 +134,16 @@ void ShortCutTree::spliteToShortCutTree() {
}
Q.push(root);
lineBound.push({ -1, 1 });
vector<ShortCutNode> v, vn;
vector<ShortCutNode> tmpTreeNodes, generatedTreeNodes;
while (!lineBound.empty()) {
// 取出一行的所有可行方格
auto seg = lineBound.front();
float yMid = (seg.first + seg.second) / 2;
auto segment = lineBound.front();
float yMid = (segment.first + segment.second) / 2;
lineBound.pop();
while (!Q.empty()) {
auto now = Q.front();
if (now.bound.y() <= seg.first && seg.second <= now.bound.w()) {
v.push_back(now);
auto nowTreeNode = Q.front();
if (nowTreeNode.bound.y() <= segment.first && segment.second <= nowTreeNode.bound.w()) {
tmpTreeNodes.push_back(nowTreeNode);
Q.pop();
}
else {
@ -152,99 +152,99 @@ void ShortCutTree::spliteToShortCutTree() {
}
int sumIncrement = 0;
bool isDivided = false;
vn.clear();
generatedTreeNodes.clear();
// 上部分;
for (auto& now : v) {
if (!now.divided) {
for (int& index : now.lineSet) {
int type = allLine[index]->judgeBoundIntersection(yMid, now.bound.x(), now.bound.z(), true);
for (auto& nowTreeNode : tmpTreeNodes) {
if (!nowTreeNode.divided) {
for (int& lineIndex : nowTreeNode.lineSet) {
int type = allLine[lineIndex]->judgeBoundIntersection(yMid, nowTreeNode.bound.x(), nowTreeNode.bound.z(), true);
if (type == 2)
sumIncrement++;
if (type == 3)
sumIncrement--;
}
vn.push_back(now);
generatedTreeNodes.push_back(nowTreeNode);
}
else {
ShortCutNode nw, ne;
float xMid = (now.bound.x() + now.bound.z()) / 2;
ne.bound = QVector4D(xMid, yMid, now.bound.z(), now.bound.w());
isDivided |= handleShortCutNode(now, ne, yMid, vn, sumIncrement);
nw.bound = QVector4D(now.bound.x(), yMid, xMid, now.bound.w());
isDivided |= handleShortCutNode(now, nw, yMid, vn, sumIncrement);
ShortCutNode nwTreeNode, neTreeNode;
float xMid = (nowTreeNode.bound.x() + nowTreeNode.bound.z()) / 2;
neTreeNode.bound = QVector4D(xMid, yMid, nowTreeNode.bound.z(), nowTreeNode.bound.w());
isDivided |= handleShortCutNode(nowTreeNode, neTreeNode, yMid, generatedTreeNodes, sumIncrement);
nwTreeNode.bound = QVector4D(nowTreeNode.bound.x(), yMid, xMid, nowTreeNode.bound.w());
isDivided |= handleShortCutNode(nowTreeNode, nwTreeNode, yMid, generatedTreeNodes, sumIncrement);
}
}
if (isDivided) {
lineBound.push({yMid, seg.second});
for (auto& now : vn) {
Q.push(now);
lineBound.push({yMid, segment.second});
for (auto& nowTreeNode : generatedTreeNodes) {
Q.push(nowTreeNode);
}
}
// 下部分
vn.clear();
generatedTreeNodes.clear();
sumIncrement = 0;
isDivided = false;
for (auto& now : v) {
if (!now.divided) {
sumIncrement += now.windingIncrement;
vn.push_back(now);
for (auto& nowTreeNode : tmpTreeNodes) {
if (!nowTreeNode.divided) {
sumIncrement += nowTreeNode.windingIncrement;
generatedTreeNodes.push_back(nowTreeNode);
}
else {
ShortCutNode se, sw;
float xMid = (now.bound.x() + now.bound.z()) / 2;
yMid = (now.bound.y() + now.bound.w()) / 2;
se.bound = QVector4D(xMid, now.bound.y(), now.bound.z(), yMid);
isDivided |= handleShortCutNode(now, se, seg.first, vn, sumIncrement);
sw.bound = QVector4D(now.bound.x(), now.bound.y(), xMid, yMid);
isDivided |= handleShortCutNode(now, sw, seg.first, vn, sumIncrement);
ShortCutNode seTreeNode, swTreeNode;
float xMid = (nowTreeNode.bound.x() + nowTreeNode.bound.z()) / 2;
yMid = (nowTreeNode.bound.y() + nowTreeNode.bound.w()) / 2;
seTreeNode.bound = QVector4D(xMid, nowTreeNode.bound.y(), nowTreeNode.bound.z(), yMid);
isDivided |= handleShortCutNode(nowTreeNode, seTreeNode, segment.first, generatedTreeNodes, sumIncrement);
swTreeNode.bound = QVector4D(nowTreeNode.bound.x(), nowTreeNode.bound.y(), xMid, yMid);
isDivided |= handleShortCutNode(nowTreeNode, swTreeNode, segment.first, generatedTreeNodes, sumIncrement);
}
}
if (isDivided) {
lineBound.push({seg.first, yMid});
for (auto& now : vn) {
Q.push(now);
lineBound.push({segment.first, yMid});
for (auto& nowTreeNode : generatedTreeNodes) {
Q.push(nowTreeNode);
}
}
}
}
void ShortCutTree::buildShortCutTree(vector<vLine>& lineSet) {
void ShortCutTree::buildShortCutTree(vector<PointVector>& lineSet) {
init();
monotonization(lineSet, allLine);
spliteToShortCutTree();
simplifyLineVector();
}
vector<BvhTreeData> ShortCutTree::getPointLineAndBvhTree(vector<float>& pointSet, vector<GLuint>& lineSet) {
vector<pair<GLuint, point> > vp; vp.clear();
for (auto& now : pointMap) {
vp.push_back({ now.second , now.first});
vector<BvhTreeData> ShortCutTree::getPointLineAndBvhTree(vector<float>& resPoints, vector<GLuint>& resLines) {
vector<pair<GLuint, point> > tmpPoints; tmpPoints.clear();
for (auto& mapIter : pointMap) {
tmpPoints.push_back({ mapIter.second , mapIter.first});
}
sort(vp.begin(), vp.end());
for (auto& now : vp) {
pointSet.push_back(now.second.x);
pointSet.push_back(now.second.y);
now.second.show();
sort(tmpPoints.begin(), tmpPoints.end());
for (auto& vectorIter : tmpPoints) {
resPoints.push_back(vectorIter.second.x);
resPoints.push_back(vectorIter.second.y);
vectorIter.second.show();
std::cout << '\n';
}
for (auto& now : lineIndexSet) {
lineSet.push_back(now);
std::cout << now << ' ';
for (auto& nowLineIndex : lineIndexs) {
resLines.push_back(nowLineIndex);
std::cout << nowLineIndex << ' ';
}
std::cout << '\n';
vector<BvhTreeData> v;
for (auto& now : outTree) {
vector<BvhTreeData> resBvhTreeData;
for (auto& nowTreeNode : restOfTreeNodes) {
BvhTreeData oneData;
oneData.leftSon = lineSet.size();
oneData.bound = now.bound;
std::cout << now.lineSet.size() << ' ';
lineSet.push_back(now.lineSet.size());
for (auto& index : now.lineSet) {
lineSet.push_back(index);
std::cout << index << ' ';
oneData.leftSon = resLines.size();
oneData.bound = nowTreeNode.bound;
std::cout << nowTreeNode.lineSet.size() << ' ';
resLines.push_back(nowTreeNode.lineSet.size());
for (auto& lineIndex : nowTreeNode.lineSet) {
resLines.push_back(lineIndex);
std::cout << lineIndex << ' ';
}
std::cout << '\n';
v.push_back(oneData);
resBvhTreeData.push_back(oneData);
}
return v;
return resBvhTreeData;
}

View File

@ -9,7 +9,7 @@ using std::map;
using std::for_each;
struct ShortCutNode {
typedef vector<point> vLine;
typedef vector<point> vectorPoint;
int windingIncrement;
bool divided;
/* type 代表进入广度优先搜索队列的节点种类:
@ -27,21 +27,21 @@ struct ShortCutNode {
};
class ShortCutTree
{
typedef vector<point> vLine;
typedef vector<int> LineIndex;
typedef vector<point> PointVector;
typedef vector<int> PointIndexVector;
private:
vector<ShortCutNode> outTree;
vector<ShortCutNode> restOfTreeNodes;
vector<LinePtr> allLine;
int RequiredLineMin, numPoint, numLine;
map<point, int> pointMap;
vector<int> lineIndexSet;
vector<int> lineIndexs;
int getPointIndex(point now);
void generateShortCutSegement(ShortCutNode& now);
bool handleShortCutNode(ShortCutNode& fa, ShortCutNode& now, float yValue, vector<ShortCutNode>& v, int& sumIncrement);
int getPointIndex(point nowPoint);
void generateShortCutsegmentement(ShortCutNode& nowTreeNode);
bool handleShortCutNode(ShortCutNode& fa, ShortCutNode& nowTreeNode, float yValue, vector<ShortCutNode>& v, int& sumIncrement);
void spliteToShortCutTree();
static void monotonization(vector<vLine>& inL, vector<LinePtr> &outL);
bool isLineEqual(LineIndex& a, LineIndex& b) const;
static void monotonization(vector<PointVector>& inL, vector<LinePtr> &outL);
bool isLineEqual(PointIndexVector& a, PointIndexVector& b) const;
void simplifyLineVector();
public:
void init();
@ -49,7 +49,7 @@ public:
ShortCutTree(int lineMin = 3)
:RequiredLineMin(lineMin), numPoint(0), numLine(0) {}
// 传入一个vector<vector<point> > 作为所有输入的线
void buildShortCutTree(vector<vLine>& lineSet);
void buildShortCutTree(vector<PointVector>& lineSet);
// 获得点集合和线集合 返回输入BvhTree的数据集合
vector<BvhTreeData> getPointLineAndBvhTree(vector<float> &pointSet, vector<GLuint> &lineSet);
~ShortCutTree() {}