KiCad PCB EDA Suite
s3d_plugin_idf.cpp File Reference
#include <iostream>
#include <sstream>
#include <cmath>
#include <string>
#include <map>
#include <wx/filename.h>
#include <wx/log.h>
#include <wx/string.h>
#include "plugins/3d/3d_plugin.h"
#include "plugins/3dapi/ifsg_all.h"
#include "idf_parser.h"
#include "vrml_layer.h"

Go to the source code of this file.

Classes

class  LOCALESWITCH
 
struct  FILE_DATA
 

Macros

#define PLUGIN_3D_IDF_MAJOR   1
 
#define PLUGIN_3D_IDF_MINOR   0
 
#define PLUGIN_3D_IDF_PATCH   0
 
#define PLUGIN_3D_IDF_REVNO   0
 
#define NCOLORS   6
 
#define MASK_IDF   "PLUGIN_IDF"
 
#define NEXTS   4
 
#define NFILS   2
 

Functions

static SCENEGRAPHloadIDFOutline (const wxString &aFileName)
 
static SCENEGRAPHloadIDFBoard (const wxString &aFileName)
 
static SCENEGRAPHaddOutline (IDF3_COMP_OUTLINE *outline, int idxColor, SGNODE *aParent)
 
static SCENEGRAPHmakeBoard (IDF3_BOARD &brd, SGNODE *aParent)
 
static bool makeComponents (IDF3_BOARD &brd, SGNODE *aParent)
 
static bool makeOtherOutlines (IDF3_BOARD &brd, SGNODE *aParent)
 
static bool getOutlineModel (VRML_LAYER &model, const std::list< IDF_OUTLINE * > *items)
 
static bool addSegment (VRML_LAYER &model, IDF_SEGMENT *seg, int icont, int iseg)
 
static SCENEGRAPHvrmlToSG (VRML_LAYER &vpcb, int idxColor, SGNODE *aParent, double top, double bottom)
 
static SGNODEgetColor (IFSG_SHAPE &shape, int colorIdx)
 
const char * GetKicadPluginName (void)
 Function GetKicadPluginName returns the name of the plugin instance; for example IDFv3. More...
 
void GetPluginVersion (unsigned char *Major, unsigned char *Minor, unsigned char *Patch, unsigned char *Revision)
 Function GetPluginVersion retrieves the version of the instantiated plugin for informational purposes. More...
 
int GetNExtensions (void)
 Function GetNExtensions. More...
 
char const * GetModelExtension (int aIndex)
 Function GetModelExtension. More...
 
int GetNFilters (void)
 Function GetNFilters. More...
 
char const * GetFileFilter (int aIndex)
 Function GetFileFilter. More...
 
bool CanRender (void)
 Function CanRender. More...
 
SCENEGRAPHLoad (char const *aFileName)
 reads a model file and creates a generic display structure More...
 

Variables

static char ext0 [] = "idf"
 
static char ext1 [] = "emn"
 
static char ext2 [] = "IDF"
 
static char ext3 [] = "EMN"
 
static char fil0 [] = "IDF (*.idf;*.IDF)|*.idf;*.IDF"
 
static char fil1 [] = "IDF BRD (*.emn;*.EMN)|*.emn;*.EMN"
 
static struct FILE_DATA file_data
 

Macro Definition Documentation

◆ MASK_IDF

#define MASK_IDF   "PLUGIN_IDF"

Definition at line 50 of file s3d_plugin_idf.cpp.

◆ NCOLORS

#define NCOLORS   6

Definition at line 47 of file s3d_plugin_idf.cpp.

◆ NEXTS

#define NEXTS   4

Definition at line 203 of file s3d_plugin_idf.cpp.

◆ NFILS

#define NFILS   2

Definition at line 207 of file s3d_plugin_idf.cpp.

◆ PLUGIN_3D_IDF_MAJOR

#define PLUGIN_3D_IDF_MAJOR   1

Definition at line 40 of file s3d_plugin_idf.cpp.

◆ PLUGIN_3D_IDF_MINOR

#define PLUGIN_3D_IDF_MINOR   0

Definition at line 41 of file s3d_plugin_idf.cpp.

◆ PLUGIN_3D_IDF_PATCH

#define PLUGIN_3D_IDF_PATCH   0

Definition at line 42 of file s3d_plugin_idf.cpp.

◆ PLUGIN_3D_IDF_REVNO

#define PLUGIN_3D_IDF_REVNO   0

Definition at line 43 of file s3d_plugin_idf.cpp.

Function Documentation

◆ addOutline()

static SCENEGRAPH * addOutline ( IDF3_COMP_OUTLINE *  outline,
int  idxColor,
SGNODE aParent 
)
static

Definition at line 570 of file s3d_plugin_idf.cpp.

571 {
572  VRML_LAYER vpcb;
573 
574  if( !getOutlineModel( vpcb, outline->GetOutlines() ) )
575  {
576  #ifdef DEBUG
577  do {
578  std::ostringstream ostr;
579  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
580  ostr << " * [INFO] no valid outline data";
581  wxLogTrace( MASK_IDF, "%s\n", ostr.str().c_str() );
582  } while( 0 );
583  #endif
584 
585  return NULL;
586  }
587 
588  vpcb.EnsureWinding( 0, false );
589 
590  double top = outline->GetThickness();
591  double bot = 0.0;
592 
593  // note: some IDF entities permit negative heights
594  if( top < bot )
595  {
596  bot = top;
597  top = 0.0;
598  }
599 
600  SCENEGRAPH* data = vrmlToSG( vpcb, idxColor, aParent, top, bot );
601 
602  return data;
603 }
static SCENEGRAPH * vrmlToSG(VRML_LAYER &vpcb, int idxColor, SGNODE *aParent, double top, double bottom)
static bool getOutlineModel(VRML_LAYER &model, const std::list< IDF_OUTLINE * > *items)
#define NULL
Define the basic data set required to represent a 3D model.
Definition: scenegraph.h:44
#define MASK_IDF

References getOutlineModel(), MASK_IDF, NULL, and vrmlToSG().

Referenced by loadIDFOutline(), and makeComponents().

◆ addSegment()

static bool addSegment ( VRML_LAYER &  model,
IDF_SEGMENT *  seg,
int  icont,
int  iseg 
)
static

Definition at line 401 of file s3d_plugin_idf.cpp.

402 {
403  // note: in all cases we must add all but the last point in the segment
404  // to avoid redundant points
405 
406  if( seg->angle != 0.0 )
407  {
408  if( seg->IsCircle() )
409  {
410  if( iseg != 0 )
411  {
412  #ifdef DEBUG
413  do {
414  std::ostringstream ostr;
415  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
416  ostr << " * [INFO] adding a circle to an existing vertex list";
417  wxLogTrace( MASK_IDF, "%s\n", ostr.str().c_str() );
418  } while( 0 );
419  #endif
420 
421  return false;
422  }
423 
424  return model.AppendCircle( seg->center.x, seg->center.y, seg->radius, icont );
425  }
426  else
427  {
428  return model.AppendArc( seg->center.x, seg->center.y, seg->radius,
429  seg->offsetAngle, seg->angle, icont );
430  }
431  }
432 
433  if( !model.AddVertex( icont, seg->startPoint.x, seg->startPoint.y ) )
434  return false;
435 
436  return true;
437 }
#define MASK_IDF

References MASK_IDF.

Referenced by getOutlineModel().

◆ CanRender()

bool CanRender ( void  )

Function CanRender.

Returns
true if the plugin can render a model, that is the Load() function is implemented

Definition at line 275 of file s3d_plugin_idf.cpp.

276 {
277  // this plugin supports rendering of IDF component outlines
278  return true;
279 }

◆ getColor()

static SGNODE* getColor ( IFSG_SHAPE shape,
int  colorIdx 
)
static

Definition at line 90 of file s3d_plugin_idf.cpp.

91 {
92  IFSG_APPEARANCE material( shape );
93 
94  static int cidx = 1;
95  int idx;
96 
97  if( colorIdx == -1 )
98  idx = cidx;
99  else
100  idx = colorIdx;
101 
102  switch( idx )
103  {
104  case 0:
105  // green for PCB
106  material.SetSpecular( 0.13f, 0.81f, 0.22f );
107  material.SetDiffuse( 0.13f, 0.81f, 0.22f );
108  // default ambient intensity
109  material.SetShininess( 0.3f );
110 
111  break;
112 
113  case 1:
114  // magenta
115  material.SetSpecular( 0.8f, 0.0f, 0.8f );
116  material.SetDiffuse( 0.6f, 0.0f, 0.6f );
117  // default ambient intensity
118  material.SetShininess( 0.3f );
119 
120  break;
121 
122  case 2:
123  // red
124  material.SetSpecular( 0.69f, 0.14f, 0.14f );
125  material.SetDiffuse( 0.69f, 0.14f, 0.14f );
126  // default ambient intensity
127  material.SetShininess( 0.3f );
128 
129  break;
130 
131  case 3:
132  // orange
133  material.SetSpecular( 1.0f, 0.44f, 0.0f );
134  material.SetDiffuse( 1.0f, 0.44f, 0.0f );
135  // default ambient intensity
136  material.SetShininess( 0.3f );
137 
138  break;
139 
140  case 4:
141  // yellow
142  material.SetSpecular( 0.93f, 0.94f, 0.16f );
143  material.SetDiffuse( 0.93f, 0.94f, 0.16f );
144  // default ambient intensity
145  material.SetShininess( 0.3f );
146 
147  break;
148 
149  case 5:
150  // blue
151  material.SetSpecular( 0.1f, 0.11f, 0.88f );
152  material.SetDiffuse( 0.1f, 0.11f, 0.88f );
153  // default ambient intensity
154  material.SetShininess( 0.3f );
155 
156  break;
157 
158  default:
159  // violet
160  material.SetSpecular( 0.32f, 0.07f, 0.64f );
161  material.SetDiffuse( 0.32f, 0.07f, 0.64f );
162  // default ambient intensity
163  material.SetShininess( 0.3f );
164 
165  break;
166  }
167 
168  if( ( colorIdx == -1 ) && ( ++cidx > NCOLORS ) )
169  cidx = 1;
170 
171  return material.GetRawPtr();
172 }
#define NCOLORS

References IFSG_NODE::GetRawPtr(), NCOLORS, IFSG_APPEARANCE::SetDiffuse(), IFSG_APPEARANCE::SetShininess(), and IFSG_APPEARANCE::SetSpecular().

Referenced by vrmlToSG().

◆ GetFileFilter()

char const* GetFileFilter ( int  aIndex)

Function GetFileFilter.

Returns
the file filter string for the given index

Definition at line 266 of file s3d_plugin_idf.cpp.

267 {
268  if( aIndex < 0 || aIndex >= NFILS )
269  return NULL;
270 
271  return file_data.filters[aIndex];
272 }
#define NULL
#define NFILS
char const * filters[NFILS]
static struct FILE_DATA file_data

References file_data, FILE_DATA::filters, NFILS, and NULL.

◆ GetKicadPluginName()

const char* GetKicadPluginName ( void  )

Function GetKicadPluginName returns the name of the plugin instance; for example IDFv3.

This string may be used to check for name conflicts or to display informational messages about loaded plugins. This method must be implemented in specific instantiations of a plugin class.

Returns
is the NULL-terminated UTF-8 string representing the plugin name

Definition at line 175 of file s3d_plugin_idf.cpp.

176 {
177  return "PLUGIN_3D_IDF";
178 }

◆ GetModelExtension()

char const* GetModelExtension ( int  aIndex)

Function GetModelExtension.

Parameters
aIndexis the extension to return; valid values are 0 to GetNExtensions() - 1.
Returns
the requested extension or a null string if aIndex was invalid.

Definition at line 251 of file s3d_plugin_idf.cpp.

252 {
253  if( aIndex < 0 || aIndex >= NEXTS )
254  return NULL;
255 
256  return file_data.extensions[aIndex];
257 }
#define NEXTS
char const * extensions[NEXTS]
#define NULL
static struct FILE_DATA file_data

References FILE_DATA::extensions, file_data, NEXTS, and NULL.

◆ GetNExtensions()

int GetNExtensions ( void  )

Function GetNExtensions.

Returns
the number of extensions supported by the plugin

Definition at line 245 of file s3d_plugin_idf.cpp.

246 {
247  return NEXTS;
248 }
#define NEXTS

References NEXTS.

◆ GetNFilters()

int GetNFilters ( void  )

Function GetNFilters.

Returns
the number of file filters

Definition at line 260 of file s3d_plugin_idf.cpp.

261 {
262  return NFILS;
263 }
#define NFILS

References NFILS.

◆ getOutlineModel()

static bool getOutlineModel ( VRML_LAYER &  model,
const std::list< IDF_OUTLINE * > *  items 
)
static

Definition at line 320 of file s3d_plugin_idf.cpp.

321 {
322  // empty outlines are not unusual so we fail quietly
323  if( items->size() < 1 )
324  return false;
325 
326  int nvcont = 0;
327  int iseg = 0;
328 
329  std::list< IDF_OUTLINE* >::const_iterator scont = items->begin();
330  std::list< IDF_OUTLINE* >::const_iterator econt = items->end();
331  std::list<IDF_SEGMENT*>::iterator sseg;
332  std::list<IDF_SEGMENT*>::iterator eseg;
333 
334  IDF_SEGMENT lseg;
335 
336  while( scont != econt )
337  {
338  nvcont = model.NewContour();
339 
340  if( nvcont < 0 )
341  {
342  #ifdef DEBUG
343  do {
344  std::ostringstream ostr;
345  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
346  ostr << " * [INFO] cannot create an outline";
347  wxLogTrace( MASK_IDF, "%s\n", ostr.str().c_str() );
348  } while( 0 );
349  #endif
350 
351  return false;
352  }
353 
354  if( (*scont)->size() < 1 )
355  {
356  #ifdef DEBUG
357  do {
358  std::ostringstream ostr;
359  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
360  ostr << " * [INFO] invalid contour: no vertices";
361  wxLogTrace( MASK_IDF, "%s\n", ostr.str().c_str() );
362  } while( 0 );
363  #endif
364 
365  return false;
366  }
367 
368  sseg = (*scont)->begin();
369  eseg = (*scont)->end();
370 
371  iseg = 0;
372  while( sseg != eseg )
373  {
374  lseg = **sseg;
375 
376  if( !addSegment( model, &lseg, nvcont, iseg ) )
377  {
378  #ifdef DEBUG
379  do {
380  std::ostringstream ostr;
381  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
382  ostr << " * [BUG] cannot add segment";
383  wxLogTrace( MASK_IDF, "%s\n", ostr.str().c_str() );
384  } while( 0 );
385  #endif
386 
387  return false;
388  }
389 
390  ++iseg;
391  ++sseg;
392  }
393 
394  ++scont;
395  }
396 
397  return true;
398 }
#define MASK_IDF
static bool addSegment(VRML_LAYER &model, IDF_SEGMENT *seg, int icont, int iseg)

References addSegment(), and MASK_IDF.

Referenced by addOutline(), makeBoard(), and makeOtherOutlines().

◆ GetPluginVersion()

void GetPluginVersion ( unsigned char *  Major,
unsigned char *  Minor,
unsigned char *  Patch,
unsigned char *  Revision 
)

Function GetPluginVersion retrieves the version of the instantiated plugin for informational purposes.

Do not confuse this with GetClassVersion which is used to determine API compatibility.

Parameters
Majorwill hold the Plugin Major version
Minorwill hold the Plugin Minor version
Patchwill hold the Plugin Patch level
Revisionwill hold the Plugin Revision

Definition at line 181 of file s3d_plugin_idf.cpp.

183 {
184  if( Major )
185  *Major = PLUGIN_3D_IDF_MAJOR;
186 
187  if( Minor )
188  *Minor = PLUGIN_3D_IDF_MINOR;
189 
190  if( Patch )
191  *Patch = PLUGIN_3D_IDF_PATCH;
192 
193  if( Revision )
194  *Revision = PLUGIN_3D_IDF_REVNO;
195 
196  return;
197 }
#define PLUGIN_3D_IDF_REVNO
#define PLUGIN_3D_IDF_MINOR
#define PLUGIN_3D_IDF_PATCH
#define PLUGIN_3D_IDF_MAJOR

References PLUGIN_3D_IDF_MAJOR, PLUGIN_3D_IDF_MINOR, PLUGIN_3D_IDF_PATCH, and PLUGIN_3D_IDF_REVNO.

◆ Load()

SCENEGRAPH* Load ( char const *  aFileName)

reads a model file and creates a generic display structure

Parameters
aFileNameis the full path of the model file
Returns
a SCENEGRAPH pointer to the display structure if the model was successfully loaded and NULL if there is no rendering support for the model or there were problems reading the model

Definition at line 282 of file s3d_plugin_idf.cpp.

283 {
284  if( NULL == aFileName )
285  return NULL;
286 
287  wxFileName fname;
288  fname.Assign( wxString::FromUTF8Unchecked( aFileName ) );
289 
290  wxString ext = fname.GetExt();
291 
292  SCENEGRAPH* data = NULL;
293 
294  if( !ext.Cmp( wxT( "idf" ) ) || !ext.Cmp( wxT( "IDF" ) ) )
295  {
296  data = loadIDFOutline( fname.GetFullPath() );
297  }
298 
299  if( !ext.Cmp( wxT( "emn" ) ) || !ext.Cmp( wxT( "EMN" ) ) )
300  {
301  data = loadIDFBoard( fname.GetFullPath() );
302  }
303 
304  // DEBUG: WRITE OUT IDF FILE TO CONFIRM NORMALS
305  #if defined( DEBUG_IDF ) && DEBUG_IDF > 3
306  if( data )
307  {
308  wxFileName fn( aFileName );
309  wxString output = wxT( "_idf-" );
310  output.append( fn.GetName() );
311  output.append( wxT(".wrl") );
312  S3D::WriteVRML( output.ToUTF8(), true, (SGNODE*)(data), true, true );
313  }
314  #endif
315 
316  return data;
317 }
static SCENEGRAPH * loadIDFOutline(const wxString &aFileName)
The base class of all Scene Graph nodes.
Definition: sg_node.h:74
SGLIB_API bool WriteVRML(const char *filename, bool overwrite, SGNODE *aTopNode, bool reuse, bool renameNodes)
Function WriteVRML writes out the given node and its subnodes to a VRML2 file.
Definition: ifsg_api.cpp:76
static SCENEGRAPH * loadIDFBoard(const wxString &aFileName)
#define NULL
Define the basic data set required to represent a 3D model.
Definition: scenegraph.h:44

References loadIDFBoard(), loadIDFOutline(), NULL, and S3D::WriteVRML().

◆ loadIDFBoard()

static SCENEGRAPH * loadIDFBoard ( const wxString &  aFileName)
static

Definition at line 637 of file s3d_plugin_idf.cpp.

638 {
639  LOCALESWITCH switcher;
640  IDF3_BOARD brd( IDF3::CAD_ELEC );
641 
642  // note: if the IDF model is defective no outline substitutes shall be made
643  if( !brd.ReadFile( aFileName, true ) )
644  {
645  #ifdef DEBUG
646  do {
647  std::ostringstream ostr;
648  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
649  ostr << " * [INFO] Failed to read IDF file:\n";
650  ostr << brd.GetError() << "\n\n";
651  ostr << " * [INFO] IDF file '" << aFileName.ToUTF8() << "'";
652  wxLogTrace( MASK_IDF, "%s\n", ostr.str().c_str() );
653  } while( 0 );
654  #endif
655 
656  return NULL;
657  }
658 
659  IFSG_TRANSFORM tx0( true );
660  SGNODE* topNode = tx0.GetRawPtr();
661 
662  bool noBoard = false;
663  bool noComp = false;
664  bool noOther = false;
665 
666  if( NULL == makeBoard( brd, topNode ) )
667  noBoard = true;
668 
669  if( !makeComponents( brd, topNode ) )
670  noComp = true;
671 
672  if( !makeOtherOutlines( brd, topNode ) )
673  noOther = true;
674 
675  if( noBoard && noComp && noOther )
676  {
677  tx0.Destroy();
678  return NULL;
679  }
680 
681  return (SCENEGRAPH*) topNode;
682 }
static bool makeOtherOutlines(IDF3_BOARD &brd, SGNODE *aParent)
static SCENEGRAPH * makeBoard(IDF3_BOARD &brd, SGNODE *aParent)
The base class of all Scene Graph nodes.
Definition: sg_node.h:74
#define NULL
IFSG_TRANSFORM is the wrapper for the VRML compatible TRANSFORM block class SCENEGRAPH.
Define the basic data set required to represent a 3D model.
Definition: scenegraph.h:44
#define MASK_IDF
static bool makeComponents(IDF3_BOARD &brd, SGNODE *aParent)

References IFSG_NODE::Destroy(), IFSG_NODE::GetRawPtr(), makeBoard(), makeComponents(), makeOtherOutlines(), MASK_IDF, and NULL.

Referenced by Load().

◆ loadIDFOutline()

static SCENEGRAPH * loadIDFOutline ( const wxString &  aFileName)
static

Definition at line 606 of file s3d_plugin_idf.cpp.

607 {
608  LOCALESWITCH switcher;
609  IDF3_BOARD brd( IDF3::CAD_ELEC );
610  IDF3_COMP_OUTLINE* outline = NULL;
611 
612  outline = brd.GetComponentOutline( aFileName );
613 
614  if( NULL == outline )
615  {
616  #ifdef DEBUG
617  do {
618  std::ostringstream ostr;
619  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
620  ostr << " * [INFO] Failed to read IDF data:\n";
621  ostr << brd.GetError() << "\n\n";
622  ostr << " * [INFO] no outline for file '";
623  ostr << aFileName << "'";
624  wxLogTrace( MASK_IDF, "%s\n", ostr.str().c_str() );
625  } while( 0 );
626  #endif
627 
628  return NULL;
629  }
630 
631  SCENEGRAPH* data = addOutline( outline, -1, NULL );
632 
633  return data;
634 }
static SCENEGRAPH * addOutline(IDF3_COMP_OUTLINE *outline, int idxColor, SGNODE *aParent)
#define NULL
Define the basic data set required to represent a 3D model.
Definition: scenegraph.h:44
#define MASK_IDF

References addOutline(), MASK_IDF, and NULL.

Referenced by Load().

◆ makeBoard()

static SCENEGRAPH * makeBoard ( IDF3_BOARD &  brd,
SGNODE aParent 
)
static

Definition at line 685 of file s3d_plugin_idf.cpp.

686 {
687  if( NULL == aParent )
688  return NULL;
689 
690  VRML_LAYER vpcb;
691 
692  // check if no board outline
693  if( brd.GetBoardOutlinesSize() < 1 )
694  return NULL;
695 
696 
697  if( !getOutlineModel( vpcb, brd.GetBoardOutline()->GetOutlines() ) )
698  return NULL;
699 
700  vpcb.EnsureWinding( 0, false );
701 
702  int nvcont = vpcb.GetNContours() - 1;
703 
704  while( nvcont > 0 )
705  vpcb.EnsureWinding( nvcont--, true );
706 
707  // Add the drill holes
708  const std::list<IDF_DRILL_DATA*>* drills = &brd.GetBoardDrills();
709 
710  std::list<IDF_DRILL_DATA*>::const_iterator sd = drills->begin();
711  std::list<IDF_DRILL_DATA*>::const_iterator ed = drills->end();
712 
713  while( sd != ed )
714  {
715  vpcb.AddCircle( (*sd)->GetDrillXPos(), (*sd)->GetDrillYPos(),
716  (*sd)->GetDrillDia() / 2.0, true );
717  ++sd;
718  }
719 
720  std::map< std::string, IDF3_COMPONENT* >*const comp = brd.GetComponents();
721  std::map< std::string, IDF3_COMPONENT* >::const_iterator sc = comp->begin();
722  std::map< std::string, IDF3_COMPONENT* >::const_iterator ec = comp->end();
723 
724  while( sc != ec )
725  {
726  drills = sc->second->GetDrills();
727  sd = drills->begin();
728  ed = drills->end();
729 
730  while( sd != ed )
731  {
732  vpcb.AddCircle( (*sd)->GetDrillXPos(), (*sd)->GetDrillYPos(),
733  (*sd)->GetDrillDia() / 2.0, true );
734  ++sd;
735  }
736 
737  ++sc;
738  }
739 
740  double top = brd.GetBoardThickness();
741 
742  SCENEGRAPH* data = vrmlToSG( vpcb, 0, aParent, top, 0.0 );
743 
744  return data;
745 }
static SCENEGRAPH * vrmlToSG(VRML_LAYER &vpcb, int idxColor, SGNODE *aParent, double top, double bottom)
static bool getOutlineModel(VRML_LAYER &model, const std::list< IDF_OUTLINE * > *items)
#define NULL
Define the basic data set required to represent a 3D model.
Definition: scenegraph.h:44

References getOutlineModel(), NULL, and vrmlToSG().

Referenced by loadIDFBoard().

◆ makeComponents()

static bool makeComponents ( IDF3_BOARD &  brd,
SGNODE aParent 
)
static

Definition at line 748 of file s3d_plugin_idf.cpp.

749 {
750  if( NULL == aParent )
751  return false;
752 
753  int ncomponents = 0;
754 
755  double brdTop = brd.GetBoardThickness();
756 
757  // Add the component outlines
758  const std::map< std::string, IDF3_COMPONENT* >*const comp = brd.GetComponents();
759  std::map< std::string, IDF3_COMPONENT* >::const_iterator sc = comp->begin();
760  std::map< std::string, IDF3_COMPONENT* >::const_iterator ec = comp->end();
761 
762  std::list< IDF3_COMP_OUTLINE_DATA* >::const_iterator so;
763  std::list< IDF3_COMP_OUTLINE_DATA* >::const_iterator eo;
764 
765  double vX, vY, vA;
766  double tX, tY, tZ, tA;
767  bool bottom;
768  IDF3::IDF_LAYER lyr;
769 
770  std::map< std::string, SGNODE* > dataMap; // map data by UID
771  std::map< std::string, SGNODE* >::iterator dataItem;
772  IDF3_COMP_OUTLINE* pout;
773 
774  while( sc != ec )
775  {
776  sc->second->GetPosition( vX, vY, vA, lyr );
777 
778  if( lyr == IDF3::LYR_BOTTOM )
779  bottom = true;
780  else
781  bottom = false;
782 
783  so = sc->second->GetOutlinesData()->begin();
784  eo = sc->second->GetOutlinesData()->end();
785 
786  while( so != eo )
787  {
788  if( std::abs( (*so)->GetOutline()->GetThickness() ) < 0.001 )
789  {
790  ++so;
791  continue;
792  }
793 
794  (*so)->GetOffsets( tX, tY, tZ, tA );
795  tX += vX;
796  tY += vY;
797  tA += vA;
798 
799  pout = (IDF3_COMP_OUTLINE*)((*so)->GetOutline());
800 
801  if( NULL == pout )
802  {
803  ++so;
804  continue;
805  }
806 
807  dataItem = dataMap.find( pout->GetUID() );
808  SCENEGRAPH* sg = NULL;
809 
810  if( dataItem == dataMap.end() )
811  {
812  sg = addOutline( pout, -1, NULL );
813 
814  if( NULL == sg )
815  {
816  ++so;
817  continue;
818  }
819 
820  ++ncomponents;
821  dataMap.insert( std::pair< std::string, SGNODE* >
822  ( pout->GetUID(), (SGNODE*)sg ) );
823  }
824  else
825  {
826  sg = (SCENEGRAPH*) dataItem->second;
827  }
828 
829  IFSG_TRANSFORM tx0( aParent );
830  IFSG_TRANSFORM txN( false );
831  txN.Attach( (SGNODE*)sg );
832 
833  if( NULL == txN.GetParent() )
834  tx0.AddChildNode( txN );
835  else
836  tx0.AddRefNode( txN );
837 
838  if( bottom )
839  {
840  tx0.SetTranslation( SGPOINT( tX, tY, -tZ ) );
841  // for an item on the back of the board we have a compounded rotation,
842  // first a flip on the Y axis as per the IDF spec and then a rotation
843  // of -tA degrees on the Z axis. The resultant rotation axis is an
844  // XY vector equivalent to (0,1) rotated by -(tA/2) degrees
845  //
846  double ang = -tA * M_PI / 360.0;
847  double sinA = sin( ang );
848  double cosA = cos( ang );
849  tx0.SetRotation( SGVECTOR( -sinA, cosA , 0 ), M_PI );
850  }
851  else
852  {
853  tx0.SetTranslation( SGPOINT( tX, tY, tZ + brdTop ) );
854  tx0.SetRotation( SGVECTOR( 0, 0, 1 ), tA * M_PI / 180.0 );
855  }
856 
857  ++so;
858  }
859 
860  ++sc;
861  }
862 
863  if( 0 == ncomponents )
864  return false;
865 
866  return true;
867 }
static SCENEGRAPH * addOutline(IDF3_COMP_OUTLINE *outline, int idxColor, SGNODE *aParent)
The base class of all Scene Graph nodes.
Definition: sg_node.h:74
#define NULL
IFSG_TRANSFORM is the wrapper for the VRML compatible TRANSFORM block class SCENEGRAPH.
Define the basic data set required to represent a 3D model.
Definition: scenegraph.h:44

References IFSG_NODE::AddChildNode(), addOutline(), IFSG_NODE::AddRefNode(), IFSG_TRANSFORM::Attach(), IFSG_NODE::GetParent(), NULL, IFSG_TRANSFORM::SetRotation(), and IFSG_TRANSFORM::SetTranslation().

Referenced by loadIDFBoard().

◆ makeOtherOutlines()

static bool makeOtherOutlines ( IDF3_BOARD &  brd,
SGNODE aParent 
)
static

Definition at line 870 of file s3d_plugin_idf.cpp.

871 {
872  if( NULL == aParent )
873  return false;
874 
875  VRML_LAYER vpcb;
876  int ncomponents = 0;
877 
878  double brdTop = brd.GetBoardThickness();
879  double top, bot;
880 
881  // Add the component outlines
882  const std::map< std::string, OTHER_OUTLINE* >*const comp = brd.GetOtherOutlines();
883  std::map< std::string, OTHER_OUTLINE* >::const_iterator sc = comp->begin();
884  std::map< std::string, OTHER_OUTLINE* >::const_iterator ec = comp->end();
885 
886  int nvcont;
887 
888  OTHER_OUTLINE* pout;
889 
890  while( sc != ec )
891  {
892  pout = sc->second;
893 
894  if( std::abs( pout->GetThickness() ) < 0.001 )
895  {
896  ++sc;
897  continue;
898  }
899 
900  if( !getOutlineModel( vpcb, pout->GetOutlines() ) )
901  {
902  vpcb.Clear();
903  ++sc;
904  continue;
905  }
906 
907  vpcb.EnsureWinding( 0, false );
908 
909  nvcont = vpcb.GetNContours() - 1;
910 
911  while( nvcont > 0 )
912  vpcb.EnsureWinding( nvcont--, true );
913 
914  if( pout->GetSide() == IDF3::LYR_BOTTOM )
915  {
916  top = 0.0;
917  bot = -pout->GetThickness();
918  }
919  else
920  {
921  bot = brdTop;
922  top = bot + pout->GetThickness();
923  }
924 
925  if( NULL == vrmlToSG( vpcb, -1, aParent, top, bot ) )
926  {
927  vpcb.Clear();
928  ++sc;
929  continue;
930  }
931 
932  ++ncomponents;
933 
934  vpcb.Clear();
935  ++sc;
936  }
937 
938  if( 0 == ncomponents )
939  return false;
940 
941  return true;
942 }
static SCENEGRAPH * vrmlToSG(VRML_LAYER &vpcb, int idxColor, SGNODE *aParent, double top, double bottom)
static bool getOutlineModel(VRML_LAYER &model, const std::list< IDF_OUTLINE * > *items)
#define NULL

References getOutlineModel(), NULL, and vrmlToSG().

Referenced by loadIDFBoard().

◆ vrmlToSG()

static SCENEGRAPH * vrmlToSG ( VRML_LAYER &  vpcb,
int  idxColor,
SGNODE aParent,
double  top,
double  bottom 
)
static

Definition at line 440 of file s3d_plugin_idf.cpp.

441 {
442  vpcb.Tesselate( NULL );
443  std::vector< double > vertices;
444  std::vector< int > idxPlane;
445  std::vector< int > idxSide;
446 
447  if( top < bottom )
448  {
449  double tmp = top;
450  top = bottom;
451  bottom = tmp;
452  }
453 
454  if( !vpcb.Get3DTriangles( vertices, idxPlane, idxSide, top, bottom ) )
455  {
456  #ifdef DEBUG
457  do {
458  std::ostringstream ostr;
459  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
460  ostr << " * [INFO] no vertex data";
461  wxLogTrace( MASK_IDF, "%s\n", ostr.str().c_str() );
462  } while( 0 );
463  #endif
464 
465  return NULL;
466  }
467 
468  if( ( idxPlane.size() % 3 ) || ( idxSide.size() % 3 ) )
469  {
470  #ifdef DEBUG
471  do {
472  std::ostringstream ostr;
473  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
474  ostr << " * [BUG] index lists are not a multiple of 3 (not a triangle list)";
475  wxLogTrace( MASK_IDF, "%s\n", ostr.str().c_str() );
476  } while( 0 );
477  #endif
478 
479  return NULL;
480  }
481 
482  std::vector< SGPOINT > vlist;
483  size_t nvert = vertices.size() / 3;
484  size_t j = 0;
485 
486  for( size_t i = 0; i < nvert; ++i, j+= 3 )
487  vlist.emplace_back( vertices[j], vertices[j+1], vertices[j+2] );
488 
489  // create the intermediate scenegraph
490  IFSG_TRANSFORM* tx0 = new IFSG_TRANSFORM( aParent ); // tx0 = Transform for this outline
491  IFSG_SHAPE* shape = new IFSG_SHAPE( *tx0 ); // shape will hold (a) all vertices and (b) a local list of normals
492  IFSG_FACESET* face = new IFSG_FACESET( *shape ); // this face shall represent the top and bottom planes
493  IFSG_COORDS* cp = new IFSG_COORDS( *face ); // coordinates for all faces
494  cp->SetCoordsList( nvert, &vlist[0] );
495  IFSG_COORDINDEX* coordIdx = new IFSG_COORDINDEX( *face ); // coordinate indices for top and bottom planes only
496  coordIdx->SetIndices( idxPlane.size(), &idxPlane[0] );
497  IFSG_NORMALS* norms = new IFSG_NORMALS( *face ); // normals for the top and bottom planes
498 
499  // number of TOP (and bottom) vertices
500  j = nvert / 2;
501 
502  // set the TOP normals
503  for( size_t i = 0; i < j; ++i )
504  norms->AddNormal( 0.0, 0.0, 1.0 );
505 
506  // set the BOTTOM normals
507  for( size_t i = 0; i < j; ++i )
508  norms->AddNormal( 0.0, 0.0, -1.0 );
509 
510  // assign a color from the palette
511  SGNODE* modelColor = getColor( *shape, idxColor );
512 
513  // create a second shape describing the vertical walls of the IDF extrusion
514  // using per-vertex-per-face-normals
515  shape->NewNode( *tx0 );
516  shape->AddRefNode( modelColor ); // set the color to be the same as the top/bottom
517  face->NewNode( *shape );
518  cp->NewNode( *face ); // new vertex list
519  norms->NewNode( *face ); // new normals list
520  coordIdx->NewNode( *face ); // new index list
521 
522  // populate the new per-face vertex list and its indices and normals
523  std::vector< int >::iterator sI = idxSide.begin();
524  std::vector< int >::iterator eI = idxSide.end();
525 
526  size_t sidx = 0; // index to the new coord set
527  SGPOINT p1, p2, p3;
528  SGVECTOR vnorm;
529 
530  while( sI != eI )
531  {
532  p1 = vlist[*sI];
533  cp->AddCoord( p1 );
534  ++sI;
535 
536  p2 = vlist[*sI];
537  cp->AddCoord( p2 );
538  ++sI;
539 
540  p3 = vlist[*sI];
541  cp->AddCoord( p3 );
542  ++sI;
543 
544  vnorm.SetVector( S3D::CalcTriNorm( p1, p2, p3 ) );
545  norms->AddNormal( vnorm );
546  norms->AddNormal( vnorm );
547  norms->AddNormal( vnorm );
548 
549  coordIdx->AddIndex( (int)sidx );
550  ++sidx;
551  coordIdx->AddIndex( (int)sidx );
552  ++sidx;
553  coordIdx->AddIndex( (int)sidx );
554  ++sidx;
555  }
556 
557  SCENEGRAPH* data = (SCENEGRAPH*)tx0->GetRawPtr();
558 
559  // delete the API wrappers
560  delete shape;
561  delete face;
562  delete coordIdx;
563  delete cp;
564  delete tx0;
565 
566  return data;
567 }
bool NewNode(SGNODE *aParent) override
Function NewNode creates a new node to associate with this wrapper.
IFSG_COORDS is the wrapper for SGCOORDS.
Definition: ifsg_coords.h:40
IFSG_COORDINDEX is the wrapper for SGCOORDINDEX.
bool AddRefNode(SGNODE *aNode)
Function AddRefNode adds a reference to an existing node which is not owned by (not a child of) this ...
Definition: ifsg_node.cpp:128
void SetVector(double aXVal, double aYVal, double aZVal)
Definition: sg_base.cpp:233
The base class of all Scene Graph nodes.
Definition: sg_node.h:74
SGNODE * GetRawPtr(void) noexcept
Function GetRawPtr() returns the raw internal SGNODE pointer.
Definition: ifsg_node.cpp:65
bool AddIndex(int aIndex)
Function AddIndex adds a single index to the list.
Definition: ifsg_index.cpp:57
bool AddNormal(double aXValue, double aYValue, double aZValue)
IFSG_NORMALS is the wrapper for the SGNORMALS class.
Definition: ifsg_normals.h:40
#define NULL
bool NewNode(SGNODE *aParent) override
Function NewNode creates a new node to associate with this wrapper.
bool SetIndices(size_t nIndices, int *aIndexList)
Function SetIndices sets the number of indices and creates a copy of the given index data.
Definition: ifsg_index.cpp:47
static SGNODE * getColor(IFSG_SHAPE &shape, int colorIdx)
SGLIB_API SGVECTOR CalcTriNorm(const SGPOINT &p1, const SGPOINT &p2, const SGPOINT &p3)
Function CalcTriNorm returns the normal vector of a triangle described by vertices p1,...
Definition: ifsg_api.cpp:462
bool SetCoordsList(size_t aListSize, const SGPOINT *aCoordsList)
IFSG_FACESET is the wrapper for the SGFACESET class.
Definition: ifsg_faceset.h:40
bool NewNode(SGNODE *aParent) override
Function NewNode creates a new node to associate with this wrapper.
IFSG_TRANSFORM is the wrapper for the VRML compatible TRANSFORM block class SCENEGRAPH.
Define the basic data set required to represent a 3D model.
Definition: scenegraph.h:44
#define MASK_IDF
bool AddCoord(double aXValue, double aYValue, double aZValue)
bool NewNode(SGNODE *aParent) override
Function NewNode creates a new node to associate with this wrapper.
Definition: ifsg_shape.cpp:118
IFSG_SHAPE is the wrapper for the SGSHAPE class.
Definition: ifsg_shape.h:40
bool NewNode(SGNODE *aParent) override
Function NewNode creates a new node to associate with this wrapper.

References IFSG_COORDS::AddCoord(), IFSG_INDEX::AddIndex(), IFSG_NORMALS::AddNormal(), IFSG_NODE::AddRefNode(), S3D::CalcTriNorm(), getColor(), IFSG_NODE::GetRawPtr(), MASK_IDF, IFSG_NORMALS::NewNode(), IFSG_FACESET::NewNode(), IFSG_COORDS::NewNode(), IFSG_SHAPE::NewNode(), IFSG_COORDINDEX::NewNode(), NULL, IFSG_COORDS::SetCoordsList(), IFSG_INDEX::SetIndices(), and SGVECTOR::SetVector().

Referenced by addOutline(), makeBoard(), and makeOtherOutlines().

Variable Documentation

◆ ext0

char ext0[] = "idf"
static

Definition at line 209 of file s3d_plugin_idf.cpp.

Referenced by FILE_DATA::FILE_DATA().

◆ ext1

char ext1[] = "emn"
static

Definition at line 210 of file s3d_plugin_idf.cpp.

Referenced by FILE_DATA::FILE_DATA().

◆ ext2

char ext2[] = "IDF"
static

Definition at line 216 of file s3d_plugin_idf.cpp.

Referenced by FILE_DATA::FILE_DATA().

◆ ext3

char ext3[] = "EMN"
static

Definition at line 217 of file s3d_plugin_idf.cpp.

Referenced by FILE_DATA::FILE_DATA().

◆ fil0

char fil0[] = "IDF (*.idf;*.IDF)|*.idf;*.IDF"
static

Definition at line 218 of file s3d_plugin_idf.cpp.

Referenced by FILE_DATA::FILE_DATA().

◆ fil1

char fil1[] = "IDF BRD (*.emn;*.EMN)|*.emn;*.EMN"
static

Definition at line 219 of file s3d_plugin_idf.cpp.

Referenced by FILE_DATA::FILE_DATA().

◆ file_data

struct FILE_DATA file_data
static

Referenced by GetFileFilter(), and GetModelExtension().