DXFViewer进行中 : ->封装OpenGL -> 解析DXF直线-CSDN博客
https://blog.csdn.net/qq_25547755/article/details/147723906
上篇博文
解析dxf直线635条
1. DXFViewer.h
#pragma once
#include "Application.h"
#include <stdio.h>
#include <iostream>
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/string_cast.hpp>
#include "../Entity/Line.h"
#include <fstream>
#include <string>
#include <vector>
#include <map>
#include <Windows.h>
class DXFViewer :public Application
{
public:
std::string UTF8ToGB(const char* str)
{
std::string result;
WCHAR* strSrc;
LPSTR szRes;
//获得临时变量的大小
int i = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
strSrc = new WCHAR[i + 1];
MultiByteToWideChar(CP_UTF8, 0, str, -1, strSrc, i);
//获得临时变量的大小
i = WideCharToMultiByte(CP_ACP, 0, strSrc, -1, NULL, 0, NULL, NULL);
szRes = new CHAR[i + 1];
WideCharToMultiByte(CP_ACP, 0, strSrc, -1, szRes, i, NULL, NULL);
result = szRes;
delete[]strSrc;
delete[]szRes;
return result;
}
// 去除前后空格
std::string trim(const std::string& str) {
auto first = str.find_first_not_of(" \t\r\n");
auto last = str.find_last_not_of(" \t\r\n");
return (first == std::string::npos) ? "" : str.substr(first, last - first + 1);
}
// 读取组码-值对
bool ReadCodes(std::ifstream& file, std::string& code, std::string& value) {
if (!std::getline(file, code)) return false;
if (!std::getline(file, value)) return false;
std::string strCode = UTF8ToGB(code.c_str()).c_str();
std::string strValue = UTF8ToGB(value.c_str()).c_str();
code = trim(strCode);
value = trim(strValue);
return true;
}
glm::vec3 GetColorByLayer(const std::string& layer)
{
static std::map<std::string, glm::vec3> layerColors = {
{ "0", {1.0f, 1.0f, 1.0f} },
{ "WALL", {1.0f, 0.0f, 0.0f} },
{ "DOOR", {0.0f, 1.0f, 0.0f} },
{ "WINDOW",{0.0f, 0.5f, 1.0f} }
};
auto it = layerColors.find(layer);
return (it != layerColors.end()) ? it->second : glm::vec3(1.0); // 默认为白色
}
/// <summary>
/// 读取直线
/// </summary>
void ReadLine(const std::string& filename)
{
std::ifstream file(filename, std::ios::binary);
if (!file.is_open()) {
std::cerr << "无法打开文件: " << filename << std::endl;
return;
}
std::string code, value;
std::string currentLayer;
std::map<std::string, std::string> lineEntity;
const std::map<std::string, std::string> codeToKey = {
{ "10", "StartX" }, { "20", "StartY" }, { "30", "StartZ" },
{ "11", "EndX" }, { "21", "EndY" }, { "31", "EndZ" }
};
while (ReadCodes(file, code, value)) {
// 记录当前图层(可用于后续颜色处理)
if (code == "100" && value == "AcDbEntity") {
while (ReadCodes(file, code, value)) {
if (code == "8") {
currentLayer = value;
break;
}
}
}
// 解析 AcDbLine
if (code == "100" && value == "AcDbLine") {
lineEntity.clear();
while (ReadCodes(file, code, value)) {
auto it = codeToKey.find(code);
if (it != codeToKey.end()) {
lineEntity[it->second] = value;
}
if (lineEntity.size() == 6) {
// 读取完毕后再解析 + 添加直线
glm::vec3 start(
std::stof(lineEntity["StartX"]),
std::stof(lineEntity["StartY"]),
std::stof(lineEntity["StartZ"])
);
glm::vec3 end(
std::stof(lineEntity["EndX"]),
std::stof(lineEntity["EndY"]),
std::stof(lineEntity["EndZ"])
);
glm::vec3 color = GetColorByLayer(currentLayer); // 可选
m_line.AddLine(start, end, color);
break;
}
}
}
}
file.close();
}
virtual void Startup()
{
std::string filename = R"(C:\Users\ml\Desktop\Drawing1.dxf)";
// 解析文件
ReadLine(filename);
printf("读取了直线 %d 条\r\n",(m_line.GetSize()/2));
m_line.Init();
};
virtual void Render()
{
m_line.Render(m_camera);
};
virtual void Shutdown()
{
printf("Shutdown\r\n");
};
private:
Line m_line;
};
2. Line.h
#pragma once
#include "Entity.h"
#include "glm/glm.hpp"
#include "../Shader/Shader_P3_C3.h"
#include "../Core/OrthoCamera.h"
#include <vector>
class Line
{
public:
Line()
{
m_vao = -1;
m_vbo = -1;
};
~Line()
{
glDeleteVertexArrays(1, &m_vao);
glDeleteBuffers(1, &m_vbo);
};
virtual void Init() // 数据准备
{
// 1.准备Shader
m_shader.Initialize();
// Shader应用绑定顶点缓冲区数据
glGenVertexArrays(1, &m_vao);
glBindVertexArray(m_vao);
// 创建显存并向顶点缓冲填充数据
glGenBuffers(1, &m_vbo);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, m_vertices.size() * sizeof(Vertex), m_vertices.data(), GL_STATIC_DRAW);
glVertexAttribPointer(m_shader.m_position, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);
glEnableVertexAttribArray(m_shader.m_position);
glVertexAttribPointer(m_shader.m_color, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(m_shader.m_color);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
void AddLine(glm::vec3 start, glm::vec3 end, glm::vec3 color) {
m_vertices.push_back({ start.x, start.y, start.z, color.r, color.g, color.b });
m_vertices.push_back({ end.x, end.y, end.z, color.r, color.g, color.b });
}
virtual void Render(const OrthoCamera& camera) // 绘制
{
m_shader.Begin();
glBindVertexArray(m_vao);
glUniformMatrix4fv(m_shader.m_mvp, 1, GL_FALSE, (const GLfloat*)&camera.GetViewProjectionMatrix());
glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(m_vertices.size()));
m_shader.End();
}
typedef struct Vertex
{
float x, y, z;
float r, g, b;
} Vertex;
unsigned int GetSize()
{
return m_vertices.size();
}
private:
GLuint m_vao;
GLuint m_vbo;
Shader_P3_C3 m_shader;
std::vector<Vertex> m_vertices;
};
3.Shader_P3_C3.h
#pragma once
#include "Shader.h"
class Shader_P3_C3:public Shader
{
public:
Shader_P3_C3()
{
m_mvp = -1;
m_position = -1;
m_color = -1;
};
~Shader_P3_C3()
{
};
virtual bool Initialize()
{
const char* vs = R"(
#version 330
uniform mat4 MVP;
in vec3 vPos;
in vec3 vCol;
out vec3 color;
void main()
{
gl_Position = MVP * vec4(vPos, 1.0);
color = vCol;
}
)";
const char* ps = R"(
#version 330
in vec3 color;
out vec4 fragment;
void main()
{
fragment = vec4(color, 1.0);
}
)";
bool res = CreateShader(vs, ps);
if (res)
{
m_mvp = glGetUniformLocation(m_shaderId, "MVP");
m_position = glGetAttribLocation(m_shaderId, "vPos");
m_color = glGetAttribLocation(m_shaderId, "vCol");;
}
return true;
}
public:
int m_mvp;
int m_position;
int m_color;
};