实现解析svg path
parent
e849479236
commit
4f9611c385
|
@ -58,6 +58,16 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||||
|
@ -97,6 +107,7 @@
|
||||||
<ClCompile Include="RendererWidget.cpp" />
|
<ClCompile Include="RendererWidget.cpp" />
|
||||||
<ClCompile Include="ShortCutTree.cpp" />
|
<ClCompile Include="ShortCutTree.cpp" />
|
||||||
<ClCompile Include="StraightLine.cpp" />
|
<ClCompile Include="StraightLine.cpp" />
|
||||||
|
<ClCompile Include="SvgParser.cpp" />
|
||||||
<QtRcc Include="MainWindow.qrc" />
|
<QtRcc Include="MainWindow.qrc" />
|
||||||
<QtUic Include="MainWindow.ui" />
|
<QtUic Include="MainWindow.ui" />
|
||||||
<QtMoc Include="MainWindow.h" />
|
<QtMoc Include="MainWindow.h" />
|
||||||
|
@ -137,6 +148,7 @@
|
||||||
<ClInclude Include="PaintingMesh.h" />
|
<ClInclude Include="PaintingMesh.h" />
|
||||||
<ClInclude Include="ShortCutTree.h" />
|
<ClInclude Include="ShortCutTree.h" />
|
||||||
<ClInclude Include="StraightLine.h" />
|
<ClInclude Include="StraightLine.h" />
|
||||||
|
<ClInclude Include="SvgParser.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
|
<ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
|
||||||
|
|
|
@ -79,6 +79,9 @@
|
||||||
<ClCompile Include="StraightLine.cpp">
|
<ClCompile Include="StraightLine.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="SvgParser.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<QtMoc Include="RendererWidget.h">
|
<QtMoc Include="RendererWidget.h">
|
||||||
|
@ -172,5 +175,8 @@
|
||||||
<ClInclude Include="StraightLine.h">
|
<ClInclude Include="StraightLine.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="SvgParser.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -10,7 +10,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
using std::tr1::shared_ptr;
|
using std::shared_ptr;
|
||||||
|
|
||||||
struct BvhTreeData {
|
struct BvhTreeData {
|
||||||
QVector4D bound;
|
QVector4D bound;
|
||||||
|
@ -59,7 +59,7 @@ struct BvhNode {
|
||||||
~BvhNode() {}
|
~BvhNode() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::tr1::shared_ptr<BvhNode> BvhPtr;
|
typedef std::shared_ptr<BvhNode> BvhPtr;
|
||||||
|
|
||||||
class BvhTree
|
class BvhTree
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,11 +8,11 @@ float CubicBezier::getLineValueByT(float t, bool isY) {
|
||||||
return pt * pt * pt * p[0] + 3 * t * pt * pt * p[1] + 3 * t * t * pt * p[2] + t * t * t * p[3];
|
return pt * pt * pt * p[0] + 3 * t * pt * pt * p[1] + 3 * t * t * pt * p[2] + t * t * t * p[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
point CubicBezier::getPointByT(point a, point b, float t) {
|
Point CubicBezier::getPointByT(Point a, Point b, float t) {
|
||||||
return { a.x * (1 - t) + b.x * t, a.y * (1 - t) + b.y * t };
|
return { a.x * (1 - t) + b.x * t, a.y * (1 - t) + b.y * t };
|
||||||
}
|
}
|
||||||
|
|
||||||
point CubicBezier::calculateControlPoint(point a, point b) {
|
Point CubicBezier::calculateControlPoint(Point a, Point b) {
|
||||||
return {
|
return {
|
||||||
a.x + 2 * (b.x - a.x) / 3,
|
a.x + 2 * (b.x - a.x) / 3,
|
||||||
a.y + 2 * (b.y - a.y) / 3
|
a.y + 2 * (b.y - a.y) / 3
|
||||||
|
@ -47,7 +47,7 @@ void CubicBezier::findPointsOfDivison(vector<float> &p, vector<float>& res) {
|
||||||
|
|
||||||
void CubicBezier::transformToCubic() {
|
void CubicBezier::transformToCubic() {
|
||||||
if (siz == 4) return;
|
if (siz == 4) return;
|
||||||
point p[3] = {
|
Point p[3] = {
|
||||||
getPointByIndex(0),
|
getPointByIndex(0),
|
||||||
getPointByIndex(1),
|
getPointByIndex(1),
|
||||||
getPointByIndex(2)
|
getPointByIndex(2)
|
||||||
|
@ -61,10 +61,10 @@ void CubicBezier::transformToCubic() {
|
||||||
void CubicBezier::splitBezierCubic(float t, vector<LinePtr>& res) {
|
void CubicBezier::splitBezierCubic(float t, vector<LinePtr>& res) {
|
||||||
LinePtr Lf(new CubicBezier());
|
LinePtr Lf(new CubicBezier());
|
||||||
float pt = 1 - t;
|
float pt = 1 - t;
|
||||||
point pointE = { getLineValueByT(t, false), getLineValueByT(t, true) };
|
Point pointE = { getLineValueByT(t, false), getLineValueByT(t, true) };
|
||||||
point pointF = getPointByT(getPointByIndex(0), getPointByIndex(1), t);
|
Point pointF = getPointByT(getPointByIndex(0), getPointByIndex(1), t);
|
||||||
point pointG = getPointByT(getPointByIndex(1), getPointByIndex(2), t);
|
Point pointG = getPointByT(getPointByIndex(1), getPointByIndex(2), t);
|
||||||
point pointH = getPointByT(getPointByIndex(2), getPointByIndex(3), t);
|
Point pointH = getPointByT(getPointByIndex(2), getPointByIndex(3), t);
|
||||||
Lf->push_back(getPointByIndex(0));
|
Lf->push_back(getPointByIndex(0));
|
||||||
Lf->push_back(pointF);
|
Lf->push_back(pointF);
|
||||||
Lf->push_back(getPointByT(pointF, pointG, t));
|
Lf->push_back(getPointByT(pointF, pointG, t));
|
||||||
|
|
|
@ -6,8 +6,8 @@ class CubicBezier : public Line
|
||||||
{
|
{
|
||||||
using Line::Line;
|
using Line::Line;
|
||||||
private:
|
private:
|
||||||
static point getPointByT(point a, point b, float t);
|
static Point getPointByT(Point a, Point b, float t);
|
||||||
static point calculateControlPoint(point a, point b);
|
static Point calculateControlPoint(Point a, Point b);
|
||||||
static void findPointsOfDivison(vector<float> &p, vector<float>& res);
|
static void findPointsOfDivison(vector<float> &p, vector<float>& res);
|
||||||
void splitBezierCubic(float t, vector<LinePtr>& res);
|
void splitBezierCubic(float t, vector<LinePtr>& res);
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#include "Line.h"
|
#include "Line.h"
|
||||||
|
|
||||||
Line::Line(vector<point> Vp) {
|
Line::Line(vector<Point> Vp) {
|
||||||
siz = Vp.size();
|
siz = Vp.size();
|
||||||
for (point now : Vp) {
|
for (Point now : Vp) {
|
||||||
vX.push_back(now.x);
|
vX.push_back(now.x);
|
||||||
vY.push_back(now.y);
|
vY.push_back(now.y);
|
||||||
}
|
}
|
||||||
|
@ -12,23 +12,23 @@ int Line::size() {
|
||||||
return siz;
|
return siz;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<point> Line::toPointVector() const {
|
vector<Point> Line::toPointVector() const {
|
||||||
vector<point> vL;
|
vector<Point> vL;
|
||||||
for (int i = 0; i < siz; i++) {
|
for (int i = 0; i < siz; i++) {
|
||||||
vL.push_back({vX[i], vY[i]});
|
vL.push_back({vX[i], vY[i]});
|
||||||
}
|
}
|
||||||
return vL;
|
return vL;
|
||||||
}
|
}
|
||||||
|
|
||||||
point Line::operator[](int index) const {
|
Point Line::operator[](int index) const {
|
||||||
return { vX[index], vY[index] };
|
return { vX[index], vY[index] };
|
||||||
}
|
}
|
||||||
|
|
||||||
point Line::getPointByIndex(int index) const {
|
Point Line::getPointByIndex(int index) const {
|
||||||
return operator[](index);
|
return operator[](index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Line::setPointByIndex(int index, point now) {
|
void Line::setPointByIndex(int index, Point now) {
|
||||||
vX[index] = now.x;
|
vX[index] = now.x;
|
||||||
vY[index] = now.y;
|
vY[index] = now.y;
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ void Line::clear() {
|
||||||
vY.clear();
|
vY.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Line::push_back(point now) {
|
void Line::push_back(Point now) {
|
||||||
siz++;
|
siz++;
|
||||||
vX.push_back(now.x);
|
vX.push_back(now.x);
|
||||||
vY.push_back(now.y);
|
vY.push_back(now.y);
|
||||||
|
@ -52,11 +52,11 @@ bool Line::isLineContained(QVector4D bound) {
|
||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
point Line::getBegin() {
|
Point Line::getBegin() {
|
||||||
return { *vX.begin(), *vY.begin() };
|
return { *vX.begin(), *vY.begin() };
|
||||||
}
|
}
|
||||||
|
|
||||||
point Line::getEnd() {
|
Point Line::getEnd() {
|
||||||
return { *vX.rbegin(), *vY.rbegin() };
|
return { *vX.rbegin(), *vY.rbegin() };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,20 +12,20 @@ using std::pair;
|
||||||
using std::min;
|
using std::min;
|
||||||
using std::max;
|
using std::max;
|
||||||
using std::sort;
|
using std::sort;
|
||||||
using std::tr1::shared_ptr;
|
using std::shared_ptr;
|
||||||
using std::tr1::make_shared;
|
using std::make_shared;
|
||||||
using std::swap;
|
using std::swap;
|
||||||
|
|
||||||
const float eps = 1e-6;
|
const float eps = 1e-6;
|
||||||
|
|
||||||
struct point {
|
struct Point {
|
||||||
float x, y;
|
float x, y;
|
||||||
point operator - (const point a) { return { x - a.x, y - a.y }; }
|
Point operator - (const Point a) { return { x - a.x, y - a.y }; }
|
||||||
float operator * (const point a) { return x * a.y - y * a.x; }
|
float operator * (const Point a) { return x * a.y - y * a.x; }
|
||||||
bool operator== (const point& a) const {
|
bool operator== (const Point& a) const {
|
||||||
return fabs(x - a.x) <= eps && fabs(y - a.y) <= eps;
|
return fabs(x - a.x) <= eps && fabs(y - a.y) <= eps;
|
||||||
}
|
}
|
||||||
bool operator< (const point& a) const {
|
bool operator< (const Point& a) const {
|
||||||
return fabs(x - a.x) <= eps ? y < a.y : x < a.x;
|
return fabs(x - a.x) <= eps ? y < a.y : x < a.x;
|
||||||
}
|
}
|
||||||
void show() {
|
void show() {
|
||||||
|
@ -41,22 +41,22 @@ protected:
|
||||||
public:
|
public:
|
||||||
typedef shared_ptr<Line> LinePtr;
|
typedef shared_ptr<Line> LinePtr;
|
||||||
Line() :siz(0) {}
|
Line() :siz(0) {}
|
||||||
Line(vector<point> Vp);
|
Line(vector<Point> Vp);
|
||||||
int size();
|
int size();
|
||||||
void clear();
|
void clear();
|
||||||
point getBegin();
|
Point getBegin();
|
||||||
point getEnd();
|
Point getEnd();
|
||||||
int direction(bool isY);
|
int direction(bool isY);
|
||||||
virtual float getLineValueByT(float t, bool isY) = 0;
|
virtual float getLineValueByT(float t, bool isY) = 0;
|
||||||
virtual void monotonization(vector <LinePtr>& res) = 0;
|
virtual void monotonization(vector <LinePtr>& res) = 0;
|
||||||
virtual int judgeBoundIntersection(float xy, float l, float r, bool isY) = 0;
|
virtual int judgeBoundIntersection(float xy, float l, float r, bool isY) = 0;
|
||||||
virtual bool judgeIntersection(QVector4D bound);
|
virtual bool judgeIntersection(QVector4D bound);
|
||||||
bool isLineContained(QVector4D bound);
|
bool isLineContained(QVector4D bound);
|
||||||
point operator[](int index) const;
|
Point operator[](int index) const;
|
||||||
point getPointByIndex(int index) const;
|
Point getPointByIndex(int index) const;
|
||||||
vector<point> toPointVector() const;
|
vector<Point> toPointVector() const;
|
||||||
void setPointByIndex(int index, point now);
|
void setPointByIndex(int index, Point now);
|
||||||
void push_back(point now);
|
void push_back(Point now);
|
||||||
virtual ~Line() {}
|
virtual ~Line() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <QtMath>
|
#include <QtMath>
|
||||||
#include "BvhTree.h"
|
#include "BvhTree.h"
|
||||||
#include "ShortCutTree.h"
|
#include "ShortCutTree.h"
|
||||||
|
#include "SvgParser.h"
|
||||||
|
|
||||||
Model::Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram)
|
Model::Model(QString path, QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram)
|
||||||
: context(context)
|
: context(context)
|
||||||
|
@ -186,11 +187,20 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod
|
||||||
initBound.push_back(QVector4D(-0.8, 0.7, -0.7, 0.8));
|
initBound.push_back(QVector4D(-0.8, 0.7, -0.7, 0.8));
|
||||||
initBound.push_back(QVector4D(0.7, -0.8, 0.8, -0.7));
|
initBound.push_back(QVector4D(0.7, -0.8, 0.8, -0.7));
|
||||||
initBound.push_back(QVector4D(0.7, 0.7, 0.8, 0.8));*/
|
initBound.push_back(QVector4D(0.7, 0.7, 0.8, 0.8));*/
|
||||||
//bvhTree.buildBvhTree(initBound.data(), initBound.size());
|
//bvhTree.buildBvhTree(initBound.data(), initBound.size());
|
||||||
|
|
||||||
//vector<vector<point>> lineSet = { {point{-1,-1}, point{1,-1}},{point{1,-1}, point{1,1}}, {point{1,1}, point{-1,1}},{point{-1,1}, point{-1,-1}} };
|
|
||||||
vector<vector<point>> lineSet = { {point{-1,-1}, point{1,-1}},{point{1,-1}, point{1,1}}, {point{1,1}, point{-1,1}},{point{-1,1}, point{-1,-1}} };
|
vector<vector<Point>> lineSet = SvgParser::parse("M100,100C-.5,100,0,100.5,0,0L40,.07C40,59.5,39.5,60,100,60Z", 100,100);
|
||||||
ShortCutTree shortCutTree;
|
for (vector<Point> line : lineSet)
|
||||||
|
{
|
||||||
|
for (Point p : line)
|
||||||
|
p.show();
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
//vector<vector<Point>> lineSet = { {Point{-1,-1}, Point{1,-1}},{Point{1,-1}, Point{1,1}}, {Point{1,1}, Point{-1,1}},{Point{-1,1}, Point{-1,-1}} };
|
||||||
|
//vector<vector<Point>> lineSet = { {Point{-1,-1}, Point{1,-1}},{Point{1,-1}, Point{1,1}}, {Point{1,1}, Point{-1,1}},{Point{-1,1}, Point{-1,-1}} };
|
||||||
|
ShortCutTree shortCutTree(5);
|
||||||
shortCutTree.buildShortCutTree(lineSet);
|
shortCutTree.buildShortCutTree(lineSet);
|
||||||
vector<float> pointVector;
|
vector<float> pointVector;
|
||||||
vector<GLuint> lineVector;
|
vector<GLuint> lineVector;
|
||||||
|
@ -296,7 +306,7 @@ Drawable* Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 mod
|
||||||
3, 0,2,3,
|
3, 0,2,3,
|
||||||
//element1
|
//element1
|
||||||
//lines
|
//lines
|
||||||
0,1,1,2
|
0,1,1,2
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<GLfloat> elementData0 = {
|
std::vector<GLfloat> elementData0 = {
|
||||||
|
|
|
@ -8,7 +8,7 @@ void ShortCutTree::init() {
|
||||||
numLine = numPoint = 0;
|
numLine = numPoint = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ShortCutTree::getPointIndex(point nowPoint) {
|
int ShortCutTree::getPointIndex(Point nowPoint) {
|
||||||
auto iter = pointMap.find(nowPoint);
|
auto iter = pointMap.find(nowPoint);
|
||||||
if (iter != pointMap.end()) {
|
if (iter != pointMap.end()) {
|
||||||
return iter->second;
|
return iter->second;
|
||||||
|
@ -44,7 +44,7 @@ void ShortCutTree::monotonization(vector<PointVector>& inL, vector<LinePtr>& out
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShortCutTree::generateShortCutsegmentement(ShortCutNode& nowTreeNode) {
|
void ShortCutTree::generateShortCutsegmentement(ShortCutNode& nowTreeNode) {
|
||||||
point p = {0, 0};
|
Point p = {0, 0};
|
||||||
vector<int> v;
|
vector<int> v;
|
||||||
for (int & lineIndex : nowTreeNode.lineSet) {
|
for (int & lineIndex : nowTreeNode.lineSet) {
|
||||||
int type = allLine[lineIndex]->judgeBoundIntersection(nowTreeNode.bound.z(), nowTreeNode.bound.y(), nowTreeNode.bound.w(), false), be, en;
|
int type = allLine[lineIndex]->judgeBoundIntersection(nowTreeNode.bound.z(), nowTreeNode.bound.y(), nowTreeNode.bound.w(), false), be, en;
|
||||||
|
@ -112,7 +112,7 @@ void ShortCutTree::simplifyLineVector() {
|
||||||
numLine = allLine.size();
|
numLine = allLine.size();
|
||||||
for (auto& nowLine : allLine) {
|
for (auto& nowLine : allLine) {
|
||||||
PointVector pointVector = nowLine->toPointVector();
|
PointVector pointVector = nowLine->toPointVector();
|
||||||
for (point& p : pointVector) {
|
for (Point& p : pointVector) {
|
||||||
int pointIndex = getPointIndex(p);
|
int pointIndex = getPointIndex(p);
|
||||||
lineIndexs.push_back(pointIndex);
|
lineIndexs.push_back(pointIndex);
|
||||||
if (pointVector.size() == 2)
|
if (pointVector.size() == 2)
|
||||||
|
@ -216,7 +216,10 @@ void ShortCutTree::buildShortCutTree(vector<PointVector>& lineSet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<BvhTreeData> ShortCutTree::getPointLineAndBvhTree(vector<float>& resPoints, vector<GLuint>& resLines) {
|
vector<BvhTreeData> ShortCutTree::getPointLineAndBvhTree(vector<float>& resPoints, vector<GLuint>& resLines) {
|
||||||
vector<pair<GLuint, point> > tmpPoints; tmpPoints.clear();
|
vector<pair<GLuint, Point> > tmpPoints; tmpPoints.clear();
|
||||||
|
for (auto& now : restOfTreeNodes) {
|
||||||
|
std::cout << now.windingIncrement << ' ';
|
||||||
|
}
|
||||||
for (auto& mapIter : pointMap) {
|
for (auto& mapIter : pointMap) {
|
||||||
tmpPoints.push_back({ mapIter.second , mapIter.first});
|
tmpPoints.push_back({ mapIter.second , mapIter.first});
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ using std::map;
|
||||||
using std::for_each;
|
using std::for_each;
|
||||||
|
|
||||||
struct ShortCutNode {
|
struct ShortCutNode {
|
||||||
typedef vector<point> vectorPoint;
|
typedef vector<Point> vectorPoint;
|
||||||
int windingIncrement;
|
int windingIncrement;
|
||||||
bool divided;
|
bool divided;
|
||||||
/* type 代表进入广度优先搜索队列的节点种类:
|
/* type 代表进入广度优先搜索队列的节点种类:
|
||||||
|
@ -27,16 +27,16 @@ struct ShortCutNode {
|
||||||
};
|
};
|
||||||
class ShortCutTree
|
class ShortCutTree
|
||||||
{
|
{
|
||||||
typedef vector<point> PointVector;
|
typedef vector<Point> PointVector;
|
||||||
typedef vector<int> PointIndexVector;
|
typedef vector<int> PointIndexVector;
|
||||||
private:
|
private:
|
||||||
vector<ShortCutNode> restOfTreeNodes;
|
vector<ShortCutNode> restOfTreeNodes;
|
||||||
vector<LinePtr> allLine;
|
vector<LinePtr> allLine;
|
||||||
int RequiredLineMin, numPoint, numLine;
|
int RequiredLineMin, numPoint, numLine;
|
||||||
map<point, int> pointMap;
|
map<Point, int> pointMap;
|
||||||
vector<int> lineIndexs;
|
vector<int> lineIndexs;
|
||||||
|
|
||||||
int getPointIndex(point nowPoint);
|
int getPointIndex(Point nowPoint);
|
||||||
void generateShortCutsegmentement(ShortCutNode& nowTreeNode);
|
void generateShortCutsegmentement(ShortCutNode& nowTreeNode);
|
||||||
bool handleShortCutNode(ShortCutNode& fa, ShortCutNode& nowTreeNode, float yValue, vector<ShortCutNode>& v, int& sumIncrement);
|
bool handleShortCutNode(ShortCutNode& fa, ShortCutNode& nowTreeNode, float yValue, vector<ShortCutNode>& v, int& sumIncrement);
|
||||||
void spliteToShortCutTree();
|
void spliteToShortCutTree();
|
||||||
|
@ -48,7 +48,7 @@ public:
|
||||||
//lineMin最小线数目,即划分终止条件
|
//lineMin最小线数目,即划分终止条件
|
||||||
ShortCutTree(int lineMin = 3)
|
ShortCutTree(int lineMin = 3)
|
||||||
:RequiredLineMin(lineMin), numPoint(0), numLine(0) {}
|
:RequiredLineMin(lineMin), numPoint(0), numLine(0) {}
|
||||||
// 传入一个vector<vector<point> > 作为所有输入的线
|
// 传入一个vector<vector<Point> > 作为所有输入的线
|
||||||
void buildShortCutTree(vector<PointVector>& lineSet);
|
void buildShortCutTree(vector<PointVector>& lineSet);
|
||||||
// 获得点集合和线集合 返回输入BvhTree的数据集合
|
// 获得点集合和线集合 返回输入BvhTree的数据集合
|
||||||
vector<BvhTreeData> getPointLineAndBvhTree(vector<float> &pointSet, vector<GLuint> &lineSet);
|
vector<BvhTreeData> getPointLineAndBvhTree(vector<float> &pointSet, vector<GLuint> &lineSet);
|
||||||
|
|
|
@ -14,7 +14,7 @@ float StraightLine::getLineValueByT(float t, bool isY) {
|
||||||
}
|
}
|
||||||
|
|
||||||
float StraightLine::findTByValue(float value, bool isY) {
|
float StraightLine::findTByValue(float value, bool isY) {
|
||||||
point be = getPointByIndex(0), en = getPointByIndex(1);
|
Point be = getPointByIndex(0), en = getPointByIndex(1);
|
||||||
if (!isY) {
|
if (!isY) {
|
||||||
if(fabs(be.x - en.x) <= eps) return 0;
|
if(fabs(be.x - en.x) <= eps) return 0;
|
||||||
return (value - be.x) / (en.x - be.x);
|
return (value - be.x) / (en.x - be.x);
|
||||||
|
@ -26,7 +26,7 @@ float StraightLine::findTByValue(float value, bool isY) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int StraightLine::judgeBoundIntersection(float xy, float l, float r, bool isY) {
|
int StraightLine::judgeBoundIntersection(float xy, float l, float r, bool isY) {
|
||||||
point be = getBegin(), en = getEnd();
|
Point be = getBegin(), en = getEnd();
|
||||||
if (isY) {
|
if (isY) {
|
||||||
swap(be.x, be.y);
|
swap(be.x, be.y);
|
||||||
swap(en.x, en.y);
|
swap(en.x, en.y);
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
#include "SvgParser.h"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
vector<vector<Point>> SvgParser::parse(const std::string path, float width, float height)
|
||||||
|
{
|
||||||
|
std::string tmp;
|
||||||
|
vector<float> point;
|
||||||
|
vector<Point> line;
|
||||||
|
vector<vector<Point>> lines;
|
||||||
|
for (char c : path.substr(1))
|
||||||
|
{
|
||||||
|
if ((c >= '0' && c <= '9') || c == '.' || c == '-' || c == '+')
|
||||||
|
{
|
||||||
|
tmp += c;
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (tmp != "")
|
||||||
|
{
|
||||||
|
point.push_back(std::stof(tmp));
|
||||||
|
tmp = "";
|
||||||
|
if (point.size() == 2)
|
||||||
|
{
|
||||||
|
line.push_back(Point{ std::clamp(point[0] / width * 2 - 1, -1.f, 1.f) , std::clamp(1 - point[1] / height * 2 , -1.f, 1.f)});
|
||||||
|
point.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (c != ',' && c != ' ')
|
||||||
|
{
|
||||||
|
lines.push_back(line);
|
||||||
|
line.erase(line.begin(), line.end() - 1);
|
||||||
|
if (c == 'Z')
|
||||||
|
{
|
||||||
|
line.push_back(lines[0][0]);
|
||||||
|
lines.push_back(line);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lines.erase(lines.begin());
|
||||||
|
return lines;
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "Line.h"
|
||||||
|
class SvgParser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static vector<vector<Point>> parse(const std::string path, float width, float height);
|
||||||
|
};
|
||||||
|
|
19
README.md
19
README.md
|
@ -1,17 +1,20 @@
|
||||||
# ArchitectureColoredPainting
|
# ArchitectureColoredPainting
|
||||||
|
|
||||||
vs2022项目 qt5.15.2 msvc 2019 64-bit
|
古建筑彩绘计算机辅助设计系统
|
||||||
|
|
||||||
采用pbr材质,现在有一个随时间变化的方向光并添加了阴影
|
## 依赖
|
||||||
|
|
||||||
把一块布替换成了(待完成的)彩绘管线,见PaintingMesh类以及painting着色器
|
- Qt 5.15.2 (MSVC 2019 64-bit)
|
||||||
|
- Assimp (x64-windows)
|
||||||
|
|
||||||
TODO:
|
## 构建
|
||||||
|
|
||||||
- [x] 改用延迟渲染
|
使用 Visual Studio 2022 打开项目编译运行。
|
||||||
|
|
||||||
- [x] 指定一块材质使用独立管线进行纹理采样
|
## 进度
|
||||||
|
|
||||||
- [ ] 彩绘的表示、读取、采样...
|
采用 PBR (金属度-粗糙度) 材质模型,场景中存在一个方向光,可拖动滑动条调整光源方向观察材质效果。
|
||||||
|
|
||||||
- [x] PCF Shadow Map
|
已实现BVH加速结构的建立
|
||||||
|
|
||||||
|
基本实现单图元的拆分,即划分网格并生成快捷段和缠绕增量,尚未验证正确性
|
Loading…
Reference in New Issue