DXFViewer进行中2 -> 直线 解析+渲染 ✅已完成
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;}}}// 解析 AcDbLineif (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.准备Shaderm_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 330uniform 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 330in 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;
};