Esempio n. 1
0
// ------------------------------------------------------------------------------------------------
void DXFImporter::ParseBlocks(DXF::LineReader& reader, DXF::FileData& output) {
    while( !reader.End() && !reader.Is(0,"ENDSEC")) {
        if (reader.Is(0,"BLOCK")) {
            ParseBlock(++reader,output);
            continue;
        }
        ++reader;
    }

    ASSIMP_LOG_DEBUG_F("DXF: got ", output.blocks.size()," entries in BLOCKS" );
}
Esempio n. 2
0
// ------------------------------------------------------------------------------------------------
void DXFImporter::ParseBlocks(DXF::LineReader& reader, DXF::FileData& output)
{
    while( !reader.End() && !reader.Is(0,"ENDSEC")) {
        if (reader.Is(0,"BLOCK")) {
            ParseBlock(++reader,output);
            continue;
        }
        ++reader;
    }

    DefaultLogger::get()->debug((Formatter::format("DXF: got "),
        output.blocks.size()," entries in BLOCKS"
    ));
}
Esempio n. 3
0
// ------------------------------------------------------------------------------------------------
void DXFImporter::ParseEntities(DXF::LineReader& reader, DXF::FileData& output)
{
    // push a new block onto the stack.
    output.blocks.push_back( DXF::Block() );
    DXF::Block& block = output.blocks.back();

    block.name = AI_DXF_ENTITIES_MAGIC_BLOCK;

    while( !reader.End() && !reader.Is(0,"ENDSEC")) {
        if (reader.Is(0,"POLYLINE")) {
            ParsePolyLine(++reader,output);
            continue;
        }

        else if (reader.Is(0,"INSERT")) {
            ParseInsertion(++reader,output);
            continue;
        }

        else if (reader.Is(0,"3DFACE") || reader.Is(0,"LINE") || reader.Is(0,"3DLINE")) {
            //http://sourceforge.net/tracker/index.php?func=detail&aid=2970566&group_id=226462&atid=1067632
            Parse3DFace(++reader, output);
            continue;
        }

        ++reader;
    }

    DefaultLogger::get()->debug((Formatter::format("DXF: got "),
        block.lines.size()," polylines and ", block.insertions.size() ," inserted blocks in ENTITIES"
    ));
}
Esempio n. 4
0
// ------------------------------------------------------------------------------------------------
void DXFImporter::Parse3DFace(DXF::LineReader& reader, DXF::FileData& output)
{
    // (note) this is also used for for parsing line entities, so we
    // must handle the vertex_count == 2 case as well.

    output.blocks.back().lines.push_back( std::shared_ptr<DXF::PolyLine>( new DXF::PolyLine() )  );
    DXF::PolyLine& line = *output.blocks.back().lines.back();

    aiVector3D vip[4];
    aiColor4D  clr = AI_DXF_DEFAULT_COLOR;

    bool b[4] = {false,false,false,false};
    while( !reader.End() ) {

        // next entity with a groupcode == 0 is probably already the next vertex or polymesh entity
        if (reader.GroupCode() == 0) {
            break;
        }
        switch (reader.GroupCode())
        {

        // 8 specifies the layer
        case 8:
            line.layer = reader.Value();
            break;

        // x position of the first corner
        case 10: vip[0].x = reader.ValueAsFloat();
            b[2] = true;
            break;

        // y position of the first corner
        case 20: vip[0].y = reader.ValueAsFloat();
            b[2] = true;
            break;

        // z position of the first corner
        case 30: vip[0].z = reader.ValueAsFloat();
            b[2] = true;
            break;

        // x position of the second corner
        case 11: vip[1].x = reader.ValueAsFloat();
            b[3] = true;
            break;

        // y position of the second corner
        case 21: vip[1].y = reader.ValueAsFloat();
            b[3] = true;
            break;

        // z position of the second corner
        case 31: vip[1].z = reader.ValueAsFloat();
            b[3] = true;
            break;

        // x position of the third corner
        case 12: vip[2].x = reader.ValueAsFloat();
            b[0] = true;
            break;

        // y position of the third corner
        case 22: vip[2].y = reader.ValueAsFloat();
            b[0] = true;
            break;

        // z position of the third corner
        case 32: vip[2].z = reader.ValueAsFloat();
            b[0] = true;
            break;

        // x position of the fourth corner
        case 13: vip[3].x = reader.ValueAsFloat();
            b[1] = true;
            break;

        // y position of the fourth corner
        case 23: vip[3].y = reader.ValueAsFloat();
            b[1] = true;
            break;

        // z position of the fourth corner
        case 33: vip[3].z = reader.ValueAsFloat();
            b[1] = true;
            break;

        // color
        case 62:
            clr = g_aclrDxfIndexColors[reader.ValueAsUnsignedInt() % AI_DXF_NUM_INDEX_COLORS];
            break;
        };

        ++reader;
    }

    // the fourth corner may even be identical to the third,
    // in this case we treat it as if it didn't exist.
    if (vip[3] == vip[2]) {
        b[1] = false;
    }

    // sanity checks to see if we got something meaningful
    if ((b[1] && !b[0]) || !b[2] || !b[3]) {
        DefaultLogger::get()->warn("DXF: unexpected vertex setup in 3DFACE/LINE/FACE entity; ignoring");
        output.blocks.back().lines.pop_back();
        return;
    }

    const unsigned int cnt = (2+(b[0]?1:0)+(b[1]?1:0));
    line.counts.push_back(cnt);

    for (unsigned int i = 0; i < cnt; ++i) {
        line.indices.push_back(static_cast<unsigned int>(line.positions.size()));
        line.positions.push_back(vip[i]);
        line.colors.push_back(clr);
    }
}
Esempio n. 5
0
// ------------------------------------------------------------------------------------------------
void DXFImporter::ParsePolyLineVertex(DXF::LineReader& reader, DXF::PolyLine& line)
{
    unsigned int cnti = 0, flags = 0;
    unsigned int indices[4];

    aiVector3D out;
    aiColor4D clr = AI_DXF_DEFAULT_COLOR;

    while( !reader.End() ) {

        if (reader.Is(0)) { // SEQEND or another VERTEX
            break;
        }

        switch (reader.GroupCode())
        {
        case 8:
                // layer to which the vertex belongs to - assume that
                // this is always the layer the top-level polyline
                // entity resides on as well.
                if(reader.Value() != line.layer) {
                    DefaultLogger::get()->warn("DXF: expected vertex to be part of a polyface but the 0x128 flag isn't set");
                }
                break;

        case 70:
                flags = reader.ValueAsUnsignedInt();
                break;

        // VERTEX COORDINATES
        case 10: out.x = reader.ValueAsFloat();break;
        case 20: out.y = reader.ValueAsFloat();break;
        case 30: out.z = reader.ValueAsFloat();break;

        // POLYFACE vertex indices
        case 71:
        case 72:
        case 73:
        case 74:
            if (cnti == 4) {
                DefaultLogger::get()->warn("DXF: more than 4 indices per face not supported; ignoring");
                break;
            }
            indices[cnti++] = reader.ValueAsUnsignedInt();
            break;

        // color
        case 62:
            clr = g_aclrDxfIndexColors[reader.ValueAsUnsignedInt() % AI_DXF_NUM_INDEX_COLORS];
            break;
        };

        reader++;
    }

    if (line.flags & DXF_POLYLINE_FLAG_POLYFACEMESH && !(flags & DXF_VERTEX_FLAG_PART_OF_POLYFACE)) {
        DefaultLogger::get()->warn("DXF: expected vertex to be part of a polyface but the 0x128 flag isn't set");
    }

    if (cnti) {
        line.counts.push_back(cnti);
        for (unsigned int i = 0; i < cnti; ++i) {
            // IMPORTANT NOTE: POLYMESH indices are ONE-BASED
            if (indices[i] == 0) {
                DefaultLogger::get()->warn("DXF: invalid vertex index, indices are one-based.");
                --line.counts.back();
                continue;
            }
            line.indices.push_back(indices[i]-1);
        }
    }
    else {
        line.positions.push_back(out);
        line.colors.push_back(clr);
    }
}
Esempio n. 6
0
// ------------------------------------------------------------------------------------------------
void DXFImporter::ParsePolyLine(DXF::LineReader& reader, DXF::FileData& output)
{
    output.blocks.back().lines.push_back( std::shared_ptr<DXF::PolyLine>( new DXF::PolyLine() ) );
    DXF::PolyLine& line = *output.blocks.back().lines.back();

    unsigned int iguess = 0, vguess = 0;
    while( !reader.End() && !reader.Is(0,"ENDSEC")) {

        if (reader.Is(0,"VERTEX")) {
            ParsePolyLineVertex(++reader,line);
            if (reader.Is(0,"SEQEND")) {
                break;
            }
            continue;
        }

        switch(reader.GroupCode())
        {
        // flags --- important that we know whether it is a
        // polyface mesh or 'just' a line.
        case 70:
            if (!line.flags)    {
                line.flags = reader.ValueAsSignedInt();
            }
            break;

        // optional number of vertices
        case 71:
            vguess = reader.ValueAsSignedInt();
            line.positions.reserve(vguess);
            break;

        // optional number of faces
        case 72:
            iguess = reader.ValueAsSignedInt();
            line.indices.reserve(iguess);
            break;

        // 8 specifies the layer on which this line is placed on
        case 8:
            line.layer = reader.Value();
            break;
        }

        reader++;
    }

    //if (!(line.flags & DXF_POLYLINE_FLAG_POLYFACEMESH))   {
    //  DefaultLogger::get()->warn((Formatter::format("DXF: polyline not currently supported: "),line.flags));
    //  output.blocks.back().lines.pop_back();
    //  return;
    //}

    if (vguess && line.positions.size() != vguess) {
        DefaultLogger::get()->warn((Formatter::format("DXF: unexpected vertex count in polymesh: "),
            line.positions.size(),", expected ", vguess
        ));
    }

    if (line.flags & DXF_POLYLINE_FLAG_POLYFACEMESH ) {
        if (line.positions.size() < 3 || line.indices.size() < 3)   {
                DefaultLogger::get()->warn("DXF: not enough vertices for polymesh; ignoring");
                output.blocks.back().lines.pop_back();
                return;
        }

        // if these numbers are wrong, parsing might have gone wild.
        // however, the docs state that applications are not required
        // to set the 71 and 72 fields, respectively, to valid values.
        // So just fire a warning.
        if (iguess && line.counts.size() != iguess) {
            DefaultLogger::get()->warn((Formatter::format("DXF: unexpected face count in polymesh: "),
                line.counts.size(),", expected ", iguess
            ));
        }
    }
    else if (!line.indices.size() && !line.counts.size()) {
        // a polyline - so there are no indices yet.
        size_t guess = line.positions.size() + (line.flags & DXF_POLYLINE_FLAG_CLOSED ? 1 : 0);
        line.indices.reserve(guess);

        line.counts.reserve(guess/2);
        for (unsigned int i = 0; i < line.positions.size()/2; ++i) {
            line.indices.push_back(i*2);
            line.indices.push_back(i*2+1);
            line.counts.push_back(2);
        }

        // closed polyline?
        if (line.flags & DXF_POLYLINE_FLAG_CLOSED) {
            line.indices.push_back(static_cast<unsigned int>(line.positions.size()-1));
            line.indices.push_back(0);
            line.counts.push_back(2);
        }
    }
}
Esempio n. 7
0
void DXFImporter::ParseInsertion(DXF::LineReader& reader, DXF::FileData& output)
{
    output.blocks.back().insertions.push_back( DXF::InsertBlock() );
    DXF::InsertBlock& bl = output.blocks.back().insertions.back();

    while( !reader.End() && !reader.Is(0)) {

        switch(reader.GroupCode())
        {
            // name of referenced block
        case 2:
            bl.name = reader.Value();
            break;

            // translation
        case 10:
            bl.pos.x = reader.ValueAsFloat();
            break;
        case 20:
            bl.pos.y = reader.ValueAsFloat();
            break;
        case 30:
            bl.pos.z = reader.ValueAsFloat();
            break;

            // scaling
        case 41:
            bl.scale.x = reader.ValueAsFloat();
            break;
        case 42:
            bl.scale.y = reader.ValueAsFloat();
            break;
        case 43:
            bl.scale.z = reader.ValueAsFloat();
            break;

            // rotation angle
        case 50:
            bl.angle = reader.ValueAsFloat();
            break;
        }
        reader++;
    }
}
Esempio n. 8
0
// ------------------------------------------------------------------------------------------------
void DXFImporter::ParseBlock(DXF::LineReader& reader, DXF::FileData& output)
{
    // push a new block onto the stack.
    output.blocks.push_back( DXF::Block() );
    DXF::Block& block = output.blocks.back();

    while( !reader.End() && !reader.Is(0,"ENDBLK")) {

        switch(reader.GroupCode()) {
            case 2:
                block.name = reader.Value();
                break;

            case 10:
                block.base.x = reader.ValueAsFloat();
                break;
            case 20:
                block.base.y = reader.ValueAsFloat();
                break;
            case 30:
                block.base.z = reader.ValueAsFloat();
                break;
        }

        if (reader.Is(0,"POLYLINE")) {
            ParsePolyLine(++reader,output);
            continue;
        }

        // XXX is this a valid case?
        if (reader.Is(0,"INSERT")) {
            DefaultLogger::get()->warn("DXF: INSERT within a BLOCK not currently supported; skipping");
            for( ;!reader.End() && !reader.Is(0,"ENDBLK"); ++reader);
            break;
        }

        else if (reader.Is(0,"3DFACE") || reader.Is(0,"LINE") || reader.Is(0,"3DLINE")) {
            //http://sourceforge.net/tracker/index.php?func=detail&aid=2970566&group_id=226462&atid=1067632
            Parse3DFace(++reader, output);
            continue;
        }
        ++reader;
    }
}
Esempio n. 9
0
// ------------------------------------------------------------------------------------------------
void DXFImporter::ParseHeader(DXF::LineReader& reader, DXF::FileData& /*output*/)
{
    for( ;!reader.End() && !reader.Is(0,"ENDSEC"); reader++);
}
Esempio n. 10
0
// ------------------------------------------------------------------------------------------------
void DXFImporter::SkipSection(DXF::LineReader& reader)
{
    for( ;!reader.End() && !reader.Is(0,"ENDSEC"); reader++);
}
Esempio n. 11
0
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
void DXFImporter::InternReadFile( const std::string& pFile,
    aiScene* pScene,
    IOSystem* pIOHandler)
{
    std::shared_ptr<IOStream> file = std::shared_ptr<IOStream>( pIOHandler->Open( pFile) );

    // Check whether we can read the file
    if( file.get() == NULL) {
        throw DeadlyImportError( "Failed to open DXF file " + pFile + "");
    }

    // check whether this is a binaray DXF file - we can't read binary DXF files :-(
    char buff[AI_DXF_BINARY_IDENT_LEN+1] = {0};
    file->Read(buff,AI_DXF_BINARY_IDENT_LEN,1);

    if (!strncmp(AI_DXF_BINARY_IDENT,buff,AI_DXF_BINARY_IDENT_LEN)) {
        throw DeadlyImportError("DXF: Binary files are not supported at the moment");
    }

    // DXF files can grow very large, so read them via the StreamReader,
    // which will choose a suitable strategy.
    file->Seek(0,aiOrigin_SET);
    StreamReaderLE stream( file );

    DXF::LineReader reader (stream);
    DXF::FileData output;

    // now get all lines of the file and process top-level sections
    bool eof = false;
    while(!reader.End()) {

        // blocks table - these 'build blocks' are later (in ENTITIES)
        // referenced an included via INSERT statements.
        if (reader.Is(2,"BLOCKS")) {
            ParseBlocks(reader,output);
            continue;
        }

        // primary entity table
        if (reader.Is(2,"ENTITIES")) {
            ParseEntities(reader,output);
            continue;
        }

        // skip unneeded sections entirely to avoid any problems with them
        // altogether.
        else if (reader.Is(2,"CLASSES") || reader.Is(2,"TABLES")) {
            SkipSection(reader);
            continue;
        }

        else if (reader.Is(2,"HEADER")) {
            ParseHeader(reader,output);
            continue;
        }

        // comments
        else if (reader.Is(999)) {
            DefaultLogger::get()->info("DXF Comment: " + reader.Value());
        }

        // don't read past the official EOF sign
        else if (reader.Is(0,"EOF")) {
            eof = true;
            break;
        }

        ++reader;
    }
    if (!eof) {
        DefaultLogger::get()->warn("DXF: EOF reached, but did not encounter DXF EOF marker");
    }

    ConvertMeshes(pScene,output);

    // Now rotate the whole scene by 90 degrees around the x axis to convert from AutoCAD's to Assimp's coordinate system
    pScene->mRootNode->mTransformation = aiMatrix4x4(
        1.f,0.f,0.f,0.f,
        0.f,0.f,1.f,0.f,
        0.f,-1.f,0.f,0.f,
        0.f,0.f,0.f,1.f) * pScene->mRootNode->mTransformation;
}