⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dxfrenderer.cpp

📁 Wxpython Implemented on Windows CE, Source code
💻 CPP
📖 第 1 页 / 共 2 页
字号:
{
    Clear();
}

// deallocate all the dynamic data
void DXFRenderer::Clear()
{
    m_loaded = false;
    {
        for (DXFLayerList::Node *node = m_layers.GetFirst(); node; node = node->GetNext())
        {
            DXFLayer *current = node->GetData();
            delete current;
        }
    }
    m_layers.Clear();
    {
        for (DXFEntityList::Node *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::Node *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 lines
inline 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 everything
bool 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 colour
bool 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 entities
bool 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 LINEs
bool 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::Node *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::Node *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 entities
void DXFRenderer::Render() const
{
    if (!m_loaded)
        return;

    for (DXFEntityList::Node *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 + -