Example #1
0
void CBBOX::ApplyTransformationAA( glm::mat4 aTransformMatrix )
{
    if( m_initialized == false )
        return;

    // apply the transformation matrix for each of vertices of the bounding box
    // and make a union with all vertices
    CBBOX tmpBBox = CBBOX(  S3D_VERTEX( aTransformMatrix * glm::vec4( m_min.x, m_min.y, m_min.z, 1.0f ) ) );
    tmpBBox.Union(          S3D_VERTEX( aTransformMatrix * glm::vec4( m_max.x, m_min.y, m_min.z, 1.0f ) ) );
    tmpBBox.Union(          S3D_VERTEX( aTransformMatrix * glm::vec4( m_min.x, m_max.y, m_min.z, 1.0f ) ) );
    tmpBBox.Union(          S3D_VERTEX( aTransformMatrix * glm::vec4( m_min.x, m_min.y, m_max.z, 1.0f ) ) );
    tmpBBox.Union(          S3D_VERTEX( aTransformMatrix * glm::vec4( m_min.x, m_max.y, m_max.z, 1.0f ) ) );
    tmpBBox.Union(          S3D_VERTEX( aTransformMatrix * glm::vec4( m_max.x, m_max.y, m_min.z, 1.0f ) ) );
    tmpBBox.Union(          S3D_VERTEX( aTransformMatrix * glm::vec4( m_max.x, m_min.y, m_max.z, 1.0f ) ) );
    tmpBBox.Union(          S3D_VERTEX( aTransformMatrix * glm::vec4( m_max.x, m_max.y, m_max.z, 1.0f ) ) );

    m_min = tmpBBox.m_min;
    m_max = tmpBBox.m_max;
}
Example #2
0
void EDA_3D_CANVAS::calcBBox()
{
    BOARD* pcb = GetBoard();

    m_fastAABBox.Reset();

    for( MODULE* module = pcb->m_Modules; module; module = module->Next() )
    {
        CBBOX tmpFastAABBox;

        // Compute the transformation matrix for this module based on translation, rotation and orientation.
        float  zpos = GetPrm3DVisu().GetModulesZcoord3DIU( module->IsFlipped() );
        wxPoint pos = module->GetPosition();

        glm::mat4 fullTransformMatrix;
        fullTransformMatrix = glm::translate( glm::mat4(),  S3D_VERTEX( (float)(pos.x * GetPrm3DVisu().m_BiuTo3Dunits),
                                                                        (float)(-pos.y * GetPrm3DVisu().m_BiuTo3Dunits),
                                                                        zpos ) );

        if( module->GetOrientation() )
            fullTransformMatrix = glm::rotate( fullTransformMatrix,
                                               glm::radians( (float)(module->GetOrientation() / 10.0f) ),
                                               S3D_VERTEX( 0.0f, 0.0f, 1.0f ) );

        if( module->IsFlipped() )
        {
            fullTransformMatrix = glm::rotate( fullTransformMatrix, glm::radians( 180.0f ), S3D_VERTEX( 0.0f, 1.0f, 0.0f ) );
            fullTransformMatrix = glm::rotate( fullTransformMatrix, glm::radians( 180.0f ), S3D_VERTEX( 0.0f, 0.0f, 1.0f ) );
        }

        // Compute a union bounding box for all the shapes of the model

        S3D_MASTER* shape3D = module->Models();

        for( ; shape3D; shape3D = shape3D->Next() )
        {
            if( shape3D->Is3DType( S3D_MASTER::FILE3D_VRML ) )
                tmpFastAABBox.Union( shape3D->getFastAABBox() );
        }

        tmpFastAABBox.ApplyTransformationAA( fullTransformMatrix );

        m_fastAABBox.Union( tmpFastAABBox );
    }

    // Create a board bounding box based on board size
    wxSize  brd_size = getBoardSize();
    wxPoint brd_center_pos = getBoardCenter();

    float xsize   = brd_size.x;
    float ysize   = brd_size.y;

    float scale   = GetPrm3DVisu().m_BiuTo3Dunits;
    float xmin    = (brd_center_pos.x - xsize / 2.0) * scale;
    float xmax    = (brd_center_pos.x + xsize / 2.0) * scale;
    float ymin    = (brd_center_pos.y - ysize / 2.0) * scale;
    float ymax    = (brd_center_pos.y + ysize / 2.0) * scale;

    float zmin = GetPrm3DVisu().GetLayerZcoordBIU( B_Adhes ) * scale;
    float zmax = GetPrm3DVisu().GetLayerZcoordBIU( F_Adhes ) * scale;

    m_boardAABBox = CBBOX(  S3D_VERTEX(xmin, ymin, zmin),
                            S3D_VERTEX(xmax, ymax, zmax) );

    // Add BB board with BB models and scale it a bit
    m_fastAABBox.Union( m_boardAABBox );
    m_fastAABBox_Shadow = m_fastAABBox;
    m_fastAABBox_Shadow.Scale( SHADOW_BOUNDING_BOX_SCALE );
}
Example #3
0
void CINFO3D_VISU::InitSettings( REPORTER *aStatusTextReporter )
{
    wxLogTrace( m_logTrace, wxT( "CINFO3D_VISU::InitSettings" ) );

    // Calculates the board bounding box
    // First, use only the board outlines
    EDA_RECT bbbox = m_board->ComputeBoundingBox( true );

    // If no outlines, use the board with items
    if( ( bbbox.GetWidth() == 0 ) && ( bbbox.GetHeight() == 0 ) )
        bbbox = m_board->ComputeBoundingBox( false );

    // Gives a non null size to avoid issues in zoom / scale calculations
    if( ( bbbox.GetWidth() == 0 ) && ( bbbox.GetHeight() == 0 ) )
        bbbox.Inflate( Millimeter2iu( 10 ) );

    m_boardSize = bbbox.GetSize();
    m_boardPos  = bbbox.Centre();

    wxASSERT( (m_boardSize.x > 0) && (m_boardSize.y > 0) );

    m_boardPos.y = -m_boardPos.y; // The y coord is inverted in 3D viewer

    m_copperLayersCount = m_board->GetCopperLayerCount();

    // Ensure the board has 2 sides for 3D views, because it is hard to find
    // a *really* single side board in the true life...
    if( m_copperLayersCount < 2 )
        m_copperLayersCount = 2;

    // Calculate the convertion to apply to all positions.
    m_biuTo3Dunits = RANGE_SCALE_3D / std::max( m_boardSize.x, m_boardSize.y );

    // Calculate factors for cicle segment approximation
    m_calc_seg_min_factor3DU = (float)( SEG_MIN_FACTOR_BIU * m_biuTo3Dunits );
    m_calc_seg_max_factor3DU = (float)( SEG_MAX_FACTOR_BIU * m_biuTo3Dunits );

    m_epoxyThickness3DU = m_board->GetDesignSettings().GetBoardThickness() *
                          m_biuTo3Dunits;

    // !TODO: use value defined by user (currently use default values by ctor
    m_copperThickness3DU         = COPPER_THICKNESS     * m_biuTo3Dunits;
    m_nonCopperLayerThickness3DU = TECH_LAYER_THICKNESS * m_biuTo3Dunits;

    // Init  Z position of each layer
    // calculate z position for each copper layer
    // Zstart = -m_epoxyThickness / 2.0 is the z position of the back (bottom layer) (layer id = 31)
    // Zstart = +m_epoxyThickness / 2.0 is the z position of the front (top layer) (layer id = 0)
    // all unused copper layer z position are set to 0

    //  ____==__________==________==______ <- Bottom = +m_epoxyThickness / 2.0,
    // |                                  |   Top = Bottom + m_copperThickness
    // |__________________________________|
    //   ==         ==         ==     ==   <- Bottom = -m_epoxyThickness / 2.0,
    //                                        Top = Bottom - m_copperThickness

    unsigned int layer;

    for( layer = 0; layer < m_copperLayersCount; ++layer )
    {
        m_layerZcoordBottom[layer] = m_epoxyThickness3DU / 2.0f -
                                     (m_epoxyThickness3DU * layer / (m_copperLayersCount - 1) );

        if( layer < (m_copperLayersCount / 2) )
            m_layerZcoordTop[layer] = m_layerZcoordBottom[layer] + m_copperThickness3DU;
        else
            m_layerZcoordTop[layer] = m_layerZcoordBottom[layer] - m_copperThickness3DU;
    }

    #define layerThicknessMargin 1.1
    const float zpos_offset = m_nonCopperLayerThickness3DU * layerThicknessMargin;

    // Fill remaining unused copper layers and back layer zpos
    // with -m_epoxyThickness / 2.0
    for( ; layer < MAX_CU_LAYERS; layer++ )
    {
        m_layerZcoordBottom[layer] = -(m_epoxyThickness3DU / 2.0f);
        m_layerZcoordTop[layer]    = -(m_epoxyThickness3DU / 2.0f) - m_copperThickness3DU;
    }

    // This is the top of the copper layer thickness.
    const float zpos_copperTop_back  = m_layerZcoordTop[B_Cu];
    const float zpos_copperTop_front = m_layerZcoordTop[F_Cu];

    // calculate z position for each non copper layer
    // Solder mask and Solder paste have the same Z position
    for( int layer_id = MAX_CU_LAYERS; layer_id < LAYER_ID_COUNT; ++layer_id )
    {
        float zposTop;
        float zposBottom;

        switch( layer_id )
        {
        case B_Adhes:
            zposBottom = zpos_copperTop_back - 2.0f * zpos_offset;
            zposTop    = zposBottom - m_nonCopperLayerThickness3DU;
            break;

        case F_Adhes:
            zposBottom = zpos_copperTop_front + 2.0f * zpos_offset;
            zposTop    = zposBottom + m_nonCopperLayerThickness3DU;
            break;

        case B_Mask:
        case B_Paste:
            zposBottom = zpos_copperTop_back;
            zposTop    = zpos_copperTop_back - m_nonCopperLayerThickness3DU;
            break;

        case F_Mask:
        case F_Paste:
            zposTop    = zpos_copperTop_front + m_nonCopperLayerThickness3DU;
            zposBottom = zpos_copperTop_front;
            break;

        case B_SilkS:
            zposBottom = zpos_copperTop_back - 1.0f * zpos_offset;
            zposTop    = zposBottom - m_nonCopperLayerThickness3DU;
            break;

        case F_SilkS:
            zposBottom = zpos_copperTop_front + 1.0f * zpos_offset;
            zposTop    = zposBottom + m_nonCopperLayerThickness3DU;
            break;

        // !TODO: review
        default:
            zposTop = zpos_copperTop_front + (layer_id - MAX_CU_LAYERS + 3.0f) * zpos_offset;
            zposBottom = zposTop - m_nonCopperLayerThickness3DU;
            break;
        }

        m_layerZcoordTop[layer_id]    = zposTop;
        m_layerZcoordBottom[layer_id] = zposBottom;
    }

    m_boardCenter = SFVEC3F( m_boardPos.x * m_biuTo3Dunits,
                             m_boardPos.y * m_biuTo3Dunits,
                             0.0f );

    SFVEC3F boardSize = SFVEC3F( m_boardSize.x * m_biuTo3Dunits,
                                 m_boardSize.y * m_biuTo3Dunits,
                                 0.0f );
            boardSize /= 2.0f;

    SFVEC3F boardMin = (m_boardCenter - boardSize);
    SFVEC3F boardMax = (m_boardCenter + boardSize);

    boardMin.z = m_layerZcoordTop[B_Adhes];
    boardMax.z = m_layerZcoordTop[F_Adhes];

    m_boardBoudingBox = CBBOX( boardMin, boardMax );

#ifdef PRINT_STATISTICS_3D_VIEWER
    unsigned stats_startCreateBoardPolyTime = GetRunningMicroSecs();
#endif

    if( aStatusTextReporter )
        aStatusTextReporter->Report( _( "Build board body" ) );

    createBoardPolygon();

#ifdef PRINT_STATISTICS_3D_VIEWER
    unsigned stats_stopCreateBoardPolyTime = GetRunningMicroSecs();
    unsigned stats_startCreateLayersTime = stats_stopCreateBoardPolyTime;
#endif

    if( aStatusTextReporter )
        aStatusTextReporter->Report( _( "Create layers" ) );

    createLayers( aStatusTextReporter );

#ifdef PRINT_STATISTICS_3D_VIEWER
    unsigned stats_stopCreateLayersTime = GetRunningMicroSecs();

    printf( "CINFO3D_VISU::InitSettings times\n" );
    printf( "  CreateBoardPoly:          %.3f ms\n",
            (float)( stats_stopCreateBoardPolyTime  - stats_startCreateBoardPolyTime  ) / 1e3 );
    printf( "  CreateLayers and holes:   %.3f ms\n",
            (float)( stats_stopCreateLayersTime     - stats_startCreateLayersTime     ) / 1e3 );
    printf( "\n" );
#endif
}