30#include <wx/filename.h> 
   36#include "idf_parser.h" 
   37#include "vrml_layer.h" 
   39#define PLUGIN_3D_IDF_MAJOR 1 
   40#define PLUGIN_3D_IDF_MINOR 0 
   41#define PLUGIN_3D_IDF_PATCH 0 
   42#define PLUGIN_3D_IDF_REVNO 0 
   83static bool getOutlineModel( VRML_LAYER& model, 
const std::list< IDF_OUTLINE* >* items );
 
   87static bool addSegment( VRML_LAYER& model, IDF_SEGMENT* seg, 
int icont, 
int iseg );
 
  100        setlocale( LC_NUMERIC, 
"C" );
 
 
  105        setlocale( LC_NUMERIC, 
"" );
 
 
 
  188    if( ( colorIdx == -1 ) && ( ++cidx > 
NCOLORS ) )
 
 
  197    return "PLUGIN_3D_IDF";
 
 
  202                       unsigned char* Revision )
 
 
  235    static char fil0[] = 
"IDF (*.idf)|*.idf";
 
  236    static char fil1[] = 
"IDF BRD v2/v3 (*.emn)|*.emn";
 
  240    static char fil0[] = 
"IDF (*.idf;*.IDF)|*.idf;*.IDF";
 
  241    static char fil1[] = 
"IDF BRD (*.emn;*.EMN)|*.emn;*.EMN";
 
  273    if( aIndex < 0 || aIndex >= 
NEXTS )
 
 
  288    if( aIndex < 0 || aIndex >= 
NFILS )
 
 
  304    if( 
nullptr == aFileName )
 
  308    fname.Assign( wxString::FromUTF8Unchecked( aFileName ) );
 
  310    wxString ext = fname.GetExt();
 
  314    if( !ext.Cmp( wxT( 
"idf" ) ) || !ext.Cmp( wxT( 
"IDF" ) ) )
 
  319    if( !ext.Cmp( wxT( 
"emn" ) ) || !ext.Cmp( wxT( 
"EMN" ) ) )
 
  325#if defined( DEBUG_IDF ) && DEBUG_IDF > 3 
  328        wxFileName fn( aFileName );
 
  329        wxString output = wxT( 
"_idf-" );
 
  330        output.append( fn.GetName() );
 
  331        output.append( wxT( 
".wrl" ) );
 
 
  340static bool getOutlineModel( VRML_LAYER& model, 
const std::list< IDF_OUTLINE* >* items )
 
  343    if( items->size() < 1 )
 
  349    std::list< IDF_OUTLINE* >::const_iterator scont = items->begin();
 
  350    std::list< IDF_OUTLINE* >::const_iterator econt = items->end();
 
  351    std::list<IDF_SEGMENT*>::iterator sseg;
 
  352    std::list<IDF_SEGMENT*>::iterator eseg;
 
  356    while( scont != econt )
 
  358        nvcont = model.NewContour();
 
  363                                             "* [INFO] cannot create an outline" ),
 
  364                        __FILE__, __FUNCTION__, __LINE__ );
 
  369        if( (*scont)->size() < 1 )
 
  372                                             "* [INFO] invalid contour: no vertices" ),
 
  373                        __FILE__, __FUNCTION__, __LINE__ );
 
  378        sseg = (*scont)->begin();
 
  379        eseg = (*scont)->end();
 
  383        while( sseg != eseg )
 
  387            if( !
addSegment( model, &lseg, nvcont, iseg ) )
 
  390                                                 "* [BUG] cannot add segment" ),
 
  391                            __FILE__, __FUNCTION__, __LINE__ );
 
 
  407static bool addSegment( VRML_LAYER& model, IDF_SEGMENT* seg, 
int icont, 
int iseg )
 
  412    if( seg->angle != 0.0 )
 
  414        if( seg->IsCircle() )
 
  420                                 "* [INFO] adding a circle to an existing vertex list" ),
 
  421                            __FILE__, __FUNCTION__, __LINE__ );
 
  426            return model.AppendCircle( seg->center.x, seg->center.y, seg->radius, icont );
 
  430            return model.AppendArc( seg->center.x, seg->center.y, seg->radius,
 
  431                                    seg->offsetAngle, seg->angle, icont );
 
  435    if( !model.AddVertex( icont, seg->startPoint.x, seg->startPoint.y ) )
 
 
  445    vpcb.Tesselate( 
nullptr );
 
  446    std::vector< double > vertices;
 
  447    std::vector< int > idxPlane;
 
  448    std::vector< int > idxSide;
 
  457    if( !vpcb.Get3DTriangles( vertices, idxPlane, idxSide, top, bottom ) )
 
  460                                         "* [INFO] no vertex data" ),
 
  461                    __FILE__, __FUNCTION__, __LINE__ );
 
  466    if( ( idxPlane.size() % 3 ) || ( idxSide.size() % 3 ) )
 
  470                         "* [BUG] index lists are not a multiple of 3 (not a triangle list)" ),
 
  471                    __FILE__, __FUNCTION__, __LINE__ );
 
  476    std::vector< SGPOINT > vlist;
 
  477    size_t nvert = vertices.size() / 3;
 
  480    for( 
size_t i = 0; i < nvert; ++i, j+= 3 )
 
  481        vlist.emplace_back( vertices[j], vertices[j+1], vertices[j+2] );
 
  498    coordIdx->
SetIndices( idxPlane.size(), &idxPlane[0] );
 
  507    for( 
size_t i = 0; i < j; ++i )
 
  511    for( 
size_t i = 0; i < j; ++i )
 
  527    std::vector< int >::iterator sI = idxSide.begin();
 
  528    std::vector< int >::iterator eI = idxSide.end();
 
 
  581                                         "* [INFO] no valid outline data" ),
 
  582                    __FILE__, __FUNCTION__, __LINE__ );
 
  587    vpcb.EnsureWinding( 0, 
false );
 
  589    double top = outline->GetThickness();
 
 
  608    IDF3_BOARD brd( IDF3::CAD_ELEC );
 
  609    IDF3_COMP_OUTLINE* outline = 
nullptr;
 
  611    outline = brd.GetComponentOutline( aFileName );
 
  613    if( 
nullptr == outline )
 
  616                                         "* [INFO] Failed to read IDF data:\n" 
  618                                         "* [INFO] no outline for file '%s'" ),
 
  619                    __FILE__, __FUNCTION__, __LINE__,
 
 
  635    IDF3_BOARD brd( IDF3::CAD_ELEC );
 
  638    if( !brd.ReadFile( aFileName, 
true ) )
 
  641                                         "* [INFO] Error '%s' occurred reading IDF file: %s" ),
 
  642                    __FILE__, __FUNCTION__, __LINE__,
 
  652    bool noBoard = 
false;
 
  654    bool noOther = 
false;
 
  656    if( 
nullptr == 
makeBoard( brd, topNode ) )
 
  665    if( noBoard && noComp && noOther )
 
 
  677    if( 
nullptr == aParent )
 
  683    if( brd.GetBoardOutlinesSize() < 1 )
 
  690    vpcb.EnsureWinding( 0, 
false );
 
  692    int nvcont = vpcb.GetNContours() - 1;
 
  695        vpcb.EnsureWinding( nvcont--, 
true );
 
  698    const std::list<IDF_DRILL_DATA*>* drills = &brd.GetBoardDrills();
 
  700    std::list<IDF_DRILL_DATA*>::const_iterator sd = drills->begin();
 
  701    std::list<IDF_DRILL_DATA*>::const_iterator ed = drills->end();
 
  705        vpcb.AddCircle( (*sd)->GetDrillXPos(), (*sd)->GetDrillYPos(),
 
  706            (*sd)->GetDrillDia() / 2.0, 
true );
 
  710    std::map< std::string, IDF3_COMPONENT* >*
const comp = brd.GetComponents();
 
  711    std::map< std::string, IDF3_COMPONENT* >::const_iterator sc = comp->begin();
 
  712    std::map< std::string, IDF3_COMPONENT* >::const_iterator ec = comp->end();
 
  716        drills = sc->second->GetDrills();
 
  717        sd = drills->begin();
 
  722            vpcb.AddCircle( (*sd)->GetDrillXPos(), (*sd)->GetDrillYPos(),
 
  723                (*sd)->GetDrillDia() / 2.0, 
true );
 
  730    double top = brd.GetBoardThickness();
 
 
  740    if( 
nullptr == aParent )
 
  745    double brdTop = brd.GetBoardThickness();
 
  748    const std::map< std::string, IDF3_COMPONENT* >*
const comp = brd.GetComponents();
 
  749    std::map< std::string, IDF3_COMPONENT* >::const_iterator sc = comp->begin();
 
  750    std::map< std::string, IDF3_COMPONENT* >::const_iterator ec = comp->end();
 
  752    std::list< IDF3_COMP_OUTLINE_DATA* >::const_iterator so;
 
  753    std::list< IDF3_COMP_OUTLINE_DATA* >::const_iterator eo;
 
  756    double tX, tY, tZ, tA;
 
  760    std::map< std::string, SGNODE* > dataMap;    
 
  761    std::map< std::string, SGNODE* >::iterator dataItem;
 
  762    IDF3_COMP_OUTLINE* pout;
 
  766        sc->second->GetPosition( vX, vY, vA, lyr );
 
  768        if( lyr == IDF3::LYR_BOTTOM )
 
  773        so = sc->second->GetOutlinesData()->begin();
 
  774        eo = sc->second->GetOutlinesData()->end();
 
  778            if( 
std::abs( (*so)->GetOutline()->GetThickness() ) < 0.001 )
 
  784            (*so)->GetOffsets( tX, tY, tZ, tA );
 
  789            pout = (IDF3_COMP_OUTLINE*)((*so)->GetOutline());
 
  791            if( 
nullptr == pout  )
 
  797            dataItem = dataMap.find( pout->GetUID() );
 
  800            if( dataItem == dataMap.end() )
 
  811                dataMap.insert( std::pair< std::string, SGNODE* >( pout->GetUID(), (
SGNODE*)sg ) );
 
  835                double ang = -tA * 
M_PI / 360.0;
 
  836                double sinA = sin( ang );
 
  837                double cosA = cos( ang );
 
  852    if( 0 == ncomponents )
 
 
  861    if( 
nullptr == aParent )
 
  867    double brdTop = brd.GetBoardThickness();
 
  871    const std::map< std::string, OTHER_OUTLINE* >*
const comp = brd.GetOtherOutlines();
 
  872    std::map< std::string, OTHER_OUTLINE* >::const_iterator sc = comp->begin();
 
  873    std::map< std::string, OTHER_OUTLINE* >::const_iterator ec = comp->end();
 
  883        if( 
std::abs( pout->GetThickness() ) < 0.001 )
 
  896        vpcb.EnsureWinding( 0, 
false );
 
  898        nvcont = vpcb.GetNContours() - 1;
 
  901            vpcb.EnsureWinding( nvcont--, 
true );
 
  903        if( pout->GetSide() == IDF3::LYR_BOTTOM )
 
  906            bot = -pout->GetThickness();
 
  911            top = bot + pout->GetThickness();
 
  914        if( 
nullptr == 
vrmlToSG( vpcb, -1, aParent, top, bot ) )
 
  927    if( 0 == ncomponents )
 
 
Describe the runtime-loadable interface to support loading and parsing of 3D models.
 
bool SetDiffuse(float aRVal, float aGVal, float aBVal)
 
bool SetSpecular(float aRVal, float aGVal, float aBVal)
 
bool SetShininess(float aShininess) noexcept
 
The wrapper for SGCOORDINDEX.
 
bool NewNode(SGNODE *aParent) override
Create a new node to associate with this wrapper.
 
The wrapper for SGCOORDS.
 
bool NewNode(SGNODE *aParent) override
Create a new node to associate with this wrapper.
 
bool SetCoordsList(size_t aListSize, const SGPOINT *aCoordsList)
 
bool AddCoord(double aXValue, double aYValue, double aZValue)
 
The wrapper for the SGFACESET class.
 
bool NewNode(SGNODE *aParent) override
Create a new node to associate with this wrapper.
 
bool AddIndex(int aIndex)
Add a single index to the list.
 
bool SetIndices(size_t nIndices, int *aIndexList)
Set the number of indices and creates a copy of the given index data.
 
SGNODE * GetParent(void) const
Return a pointer to the parent SGNODE of this object or NULL if the object has no parent (ie.
 
SGNODE * GetRawPtr(void) noexcept
Return the raw internal SGNODE pointer.
 
void Destroy(void)
Delete the object held by this wrapper.
 
bool AddChildNode(SGNODE *aNode)
Add a node as a child owned by this node.
 
bool AddRefNode(SGNODE *aNode)
Add a reference to an existing node which is not owned by (not a child of) this node.
 
The wrapper for the SGNORMALS class.
 
bool NewNode(SGNODE *aParent) override
Create a new node to associate with this wrapper.
 
bool AddNormal(double aXValue, double aYValue, double aZValue)
 
The wrapper for the SGSHAPE class.
 
bool NewNode(SGNODE *aParent) override
Create a new node to associate with this wrapper.
 
Define the basic data set required to represent a 3D model.
 
The base class of all Scene Graph nodes.
 
void SetVector(double aXVal, double aYVal, double aZVal)
 
const wxChar *const traceIdfPlugin
Flag to enable IDF plugin trace output.
 
collects header files for all SG* wrappers and the API
 
SGLIB_API bool WriteVRML(const char *filename, bool overwrite, SGNODE *aTopNode, bool reuse, bool renameNodes)
Write out the given node and its subnodes to a VRML2 file.
 
SGLIB_API SGVECTOR CalcTriNorm(const SGPOINT &p1, const SGPOINT &p2, const SGPOINT &p3)
Return the normal vector of a triangle described by vertices p1, p2, p3.
 
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
 
static bool addSegment(VRML_LAYER &model, IDF_SEGMENT *seg, int icont, int iseg)
 
static bool makeComponents(IDF3_BOARD &brd, SGNODE *aParent)
 
static bool getOutlineModel(VRML_LAYER &model, const std::list< IDF_OUTLINE * > *items)
 
static struct FILE_DATA file_data
 
char const * GetModelExtension(int aIndex)
 
#define PLUGIN_3D_IDF_MAJOR
 
#define PLUGIN_3D_IDF_PATCH
 
SCENEGRAPH * Load(char const *aFileName)
Read a model file and creates a generic display structure.
 
char const * GetFileFilter(int aIndex)
 
static SCENEGRAPH * makeBoard(IDF3_BOARD &brd, SGNODE *aParent)
 
#define PLUGIN_3D_IDF_MINOR
 
static SCENEGRAPH * loadIDFOutline(const wxString &aFileName)
 
void GetPluginVersion(unsigned char *Major, unsigned char *Minor, unsigned char *Patch, unsigned char *Revision)
Retrieve the version of the instantiated plugin for informational purposes.
 
#define PLUGIN_3D_IDF_REVNO
 
const char * GetKicadPluginName(void)
Return the name of the plugin instance, for example IDFv3.
 
static SCENEGRAPH * loadIDFBoard(const wxString &aFileName)
 
static bool makeOtherOutlines(IDF3_BOARD &brd, SGNODE *aParent)
 
static SCENEGRAPH * addOutline(IDF3_COMP_OUTLINE *outline, int idxColor, SGNODE *aParent)
 
static SGNODE * getColor(IFSG_SHAPE &shape, int colorIdx)
 
static SCENEGRAPH * vrmlToSG(VRML_LAYER &vpcb, int idxColor, SGNODE *aParent, double top, double bottom)
 
char const  * extensions[NEXTS]
 
char const  * filters[NFILS]