📄 dxfrenderer.cpp
字号:
}// deallocate all the dynamic datavoid DXFRenderer::Clear(){ m_loaded = false; { for (DXFLayerList::compatibility_iterator node = m_layers.GetFirst(); node; node = node->GetNext()) { DXFLayer *current = node->GetData(); delete current; } } m_layers.Clear(); { for (DXFEntityList::compatibility_iterator node = m_entities.GetFirst(); node; node = node->GetNext()) { DXFEntity *current = node->GetData(); delete current; } m_entities.Clear(); }}int DXFRenderer::GetLayerColour(const wxString& layer) const{ for (DXFLayerList::compatibility_iterator node = m_layers.GetFirst(); node; node = node->GetNext()) { DXFLayer *current = node->GetData(); if (current->name == layer) return current->colour; } return 7; // white}// read two sequential linesinline void GetLines(wxTextInputStream& text, wxString& line1, wxString& line2){ line1 = text.ReadLine().Trim().Trim(false); line2 = text.ReadLine().Trim().Trim(false);}// parse header section: just skip everythingbool DXFRenderer::ParseHeader(wxInputStream& stream){ wxTextInputStream text(stream); wxString line1, line2; while (stream.CanRead()) { GetLines(text, line1, line2); if (line1 == wxT("0") && line2 == wxT("ENDSEC")) return true; } return false;}// parse tables section: save layers name and colourbool DXFRenderer::ParseTables(wxInputStream& stream){ wxTextInputStream text(stream); wxString line1, line2; bool inlayer=false; DXFLayer layer; while (stream.CanRead()) { GetLines(text, line1, line2); if (line1 == wxT("0") && inlayer) { // flush layer if (!layer.name.IsEmpty() && layer.colour != -1) { DXFLayer *p = new DXFLayer; p->name = layer.name; p->colour = layer.colour; m_layers.Append(p); } layer = DXFLayer(); inlayer = false; } if (line1 == wxT("0") && line2 == wxT("ENDSEC")) return true; else if (line1 == wxT("0") && line2 == wxT("LAYER")) inlayer = true; else if (inlayer) { if (line1 == wxT("2")) // layer name layer.name = line2; else if (line1 == wxT("62")) // ACI colour { long l; line2.ToLong(&l); layer.colour = l; } } } return false;}// parse entities section: save 3DFACE and LINE entitiesbool DXFRenderer::ParseEntities(wxInputStream& stream){ wxTextInputStream text(stream); wxString line1, line2; int state = 0; // 0: none, 1: 3DFACE, 2: LINE DXFVector v[4]; int colour = -1; wxString layer; while (stream.CanRead()) { GetLines(text, line1, line2); if (line1 == wxT("0") && state > 0) { // flush entity if (state == 1) // 3DFACE { DXFFace *p = new DXFFace; p->v0 = v[0]; p->v1 = v[1]; p->v2 = v[2]; p->v3 = v[3]; p->CalculateNormal(); if (colour != -1) p->colour = colour; else p->colour = GetLayerColour(layer); m_entities.Append(p); colour = -1; layer = wxEmptyString; v[0] = v[1] = v[2] = v[3] = DXFVector(); state = 0; } else if (state == 2) // LINE { DXFLine *p = new DXFLine; p->v0 = v[0]; p->v1 = v[1]; if (colour != -1) p->colour = colour; else p->colour = GetLayerColour(layer); m_entities.Append(p); colour = -1; layer = wxEmptyString; v[0] = v[1] = v[2] = v[3] = DXFVector(); state = 0; } } if (line1 == wxT("0") && line2 == wxT("ENDSEC")) return true; else if (line1 == wxT("0") && line2 == wxT("3DFACE")) state = 1; else if (line1 == wxT("0") && line2 == wxT("LINE")) state = 2; else if (state > 0) { double d; line2.ToDouble(&d); if (line1 == wxT("10")) v[0].x = d; else if (line1 == wxT("20")) v[0].y = d; else if (line1 == wxT("30")) v[0].z = d; else if (line1 == wxT("11")) v[1].x = d; else if (line1 == wxT("21")) v[1].y = d; else if (line1 == wxT("31")) v[1].z = d; else if (line1 == wxT("12")) v[2].x = d; else if (line1 == wxT("22")) v[2].y = d; else if (line1 == wxT("32")) v[2].z = d; else if (line1 == wxT("13")) v[3].x = d; else if (line1 == wxT("23")) v[3].y = d; else if (line1 == wxT("33")) v[3].z = d; else if (line1 == wxT("8")) // layer layer = line2; else if (line1 == wxT("62")) // colour { long l; line2.ToLong(&l); colour = l; } } } return false;}// parse and load a DXF file// currently pretty limited, but knows enought do handle 3DFACEs and LINEsbool DXFRenderer::Load(wxInputStream& stream){ Clear(); wxTextInputStream text(stream); wxString line1, line2; while (stream.CanRead()) { GetLines(text, line1, line2); if (line1 == wxT("999")) // comment continue; else if (line1 == wxT("0") && line2 == wxT("SECTION")) { GetLines(text, line1, line2); if (line1 == wxT("2")) { if (line2 == wxT("HEADER")) { if (!ParseHeader(stream)) return false; } else if (line2 == wxT("TABLES")) { if (!ParseTables(stream)) return false; } else if (line2 == wxT("ENTITIES")) { if (!ParseEntities(stream)) return false; } } } } NormalizeEntities(); m_loaded = true; return true;}inline float mymin(float x, float y) { return x < y ? x : y; }inline float mymax(float x, float y) { return x > y ? x : y; }// Scale object boundings to [-5,5]void DXFRenderer::NormalizeEntities(){ // calculate current min and max boundings of object DXFVector minv(10e20f, 10e20f, 10e20f); DXFVector maxv(-10e20f, -10e20f, -10e20f); for (DXFEntityList::compatibility_iterator node = m_entities.GetFirst(); node; node = node->GetNext()) { DXFEntity *p = node->GetData(); if (p->type == DXFEntity::Line) { DXFLine *line = (DXFLine *)p; const DXFVector *v[2] = { &line->v0, &line->v1 }; for (int i = 0; i < 2; ++i) { minv.x = mymin(v[i]->x, minv.x); minv.y = mymin(v[i]->y, minv.y); minv.z = mymin(v[i]->z, minv.z); maxv.x = mymax(v[i]->x, maxv.x); maxv.y = mymax(v[i]->y, maxv.y); maxv.z = mymax(v[i]->z, maxv.z); } } else if (p->type == DXFEntity::Face) { DXFFace *face = (DXFFace *)p; const DXFVector *v[4] = { &face->v0, &face->v1, &face->v2, &face->v3 }; for (int i = 0; i < 4; ++i) { minv.x = mymin(v[i]->x, minv.x); minv.y = mymin(v[i]->y, minv.y); minv.z = mymin(v[i]->z, minv.z); maxv.x = mymax(v[i]->x, maxv.x); maxv.y = mymax(v[i]->y, maxv.y); maxv.z = mymax(v[i]->z, maxv.z); } } } // rescale object down to [-5,5] DXFVector span(maxv.x - minv.x, maxv.y - minv.y, maxv.z - minv.z); float factor = mymin(mymin(10.0f / span.x, 10.0f / span.y), 10.0f / span.z); for (DXFEntityList::compatibility_iterator node2 = m_entities.GetFirst(); node2; node2 = node2->GetNext()) { DXFEntity *p = node2->GetData(); if (p->type == DXFEntity::Line) { DXFLine *line = (DXFLine *)p; DXFVector *v[2] = { &line->v0, &line->v1 }; for (int i = 0; i < 2; ++i) { v[i]->x -= minv.x + span.x/2; v[i]->x *= factor; v[i]->y -= minv.y + span.y/2; v[i]->y *= factor; v[i]->z -= minv.z + span.z/2; v[i]->z *= factor; } } else if (p->type == DXFEntity::Face) { DXFFace *face = (DXFFace *)p; DXFVector *v[4] = { &face->v0, &face->v1, &face->v2, &face->v3 }; for (int i = 0; i < 4; ++i) { v[i]->x -= minv.x + span.x/2; v[i]->x *= factor; v[i]->y -= minv.y + span.y/2; v[i]->y *= factor; v[i]->z -= minv.z + span.z/2; v[i]->z *= factor; } } }}// OpenGL renderer for DXF entitiesvoid DXFRenderer::Render() const{ if (!m_loaded) return; for (DXFEntityList::compatibility_iterator node = m_entities.GetFirst(); node; node = node->GetNext()) { DXFEntity *p = node->GetData(); wxColour c = ACIColourToRGB(p->colour); if (p->type == DXFEntity::Line) { DXFLine *line = (DXFLine *)p; glBegin(GL_LINES); glColor3f(c.Red()/255.0,c.Green()/255.0,c.Blue()/255.0); glVertex3f(line->v0.x, line->v0.y, line->v0.z); glVertex3f(line->v1.x, line->v1.y, line->v1.z); glEnd(); } else if (p->type == DXFEntity::Face) { DXFFace *face = (DXFFace *)p; glBegin(GL_TRIANGLES); glColor3f(c.Red()/255.0,c.Green()/255.0,c.Blue()/255.0); glNormal3f(face->n.x, face->n.y, face->n.z); glVertex3f(face->v0.x, face->v0.y, face->v0.z); glVertex3f(face->v1.x, face->v1.y, face->v1.z); glVertex3f(face->v2.x, face->v2.y, face->v2.z); glEnd(); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -