KiCad PCB EDA Suite
export_vrml.cpp File Reference
#include <exception>
#include <fstream>
#include <iomanip>
#include <vector>
#include <wx/dir.h>
#include "3d_cache/3d_cache.h"
#include "3d_cache/3d_info.h"
#include "board.h"
#include "fp_shape.h"
#include "footprint.h"
#include "pcb_text.h"
#include "track.h"
#include "zone.h"
#include "convert_to_biu.h"
#include <core/arraydim.h>
#include <filename_resolver.h>
#include "plugins/3dapi/ifsg_all.h"
#include "streamwrapper.h"
#include "vrml_layer.h"
#include "pcb_edit_frame.h"
#include <convert_basic_shapes_to_polygon.h>
#include <geometry/geometry_utils.h>
#include <zone_filler.h>

Go to the source code of this file.

Classes

struct  VRML_COLOR
 
class  MODEL_VRML
 

Macros

#define MIN_VRML_LINEWIDTH   0.05
 
#define ART_OFFSET   0.025
 
#define PLATE_OFFSET   0.005
 

Enumerations

enum  VRML_COLOR_INDEX {
  VRML_COLOR_NONE = -1, VRML_COLOR_PCB = 0, VRML_COLOR_TRACK, VRML_COLOR_SILK,
  VRML_COLOR_TIN, VRML_COLOR_LAST
}
 

Functions

static bool GetLayer (MODEL_VRML &aModel, LAYER_NUM layer, VRML_LAYER **vlayer)
 
static void create_vrml_shell (IFSG_TRANSFORM &PcbOutput, VRML_COLOR_INDEX colorID, VRML_LAYER *layer, double top_z, double bottom_z)
 
static void create_vrml_plane (IFSG_TRANSFORM &PcbOutput, VRML_COLOR_INDEX colorID, VRML_LAYER *layer, double aHeight, bool aTopPlane)
 
static void write_triangle_bag (std::ostream &aOut_file, const VRML_COLOR &aColor, VRML_LAYER *aLayer, bool aPlane, bool aTop, double aTop_z, double aBottom_z)
 
static void write_layers (MODEL_VRML &aModel, BOARD *aPcb, const char *aFileName, OSTREAM *aOutputFile)
 
static void compute_layer_Zs (MODEL_VRML &aModel, BOARD *pcb)
 
static void export_vrml_line (MODEL_VRML &aModel, LAYER_NUM layer, double startx, double starty, double endx, double endy, double width)
 
static void export_vrml_circle (MODEL_VRML &aModel, LAYER_NUM layer, double startx, double starty, double endx, double endy, double width)
 
static void export_vrml_arc (MODEL_VRML &aModel, LAYER_NUM layer, double centerx, double centery, double arc_startx, double arc_starty, double width, double arc_angle)
 
static void export_vrml_polygon (MODEL_VRML &aModel, LAYER_NUM layer, PCB_SHAPE *aOutline, double aOrientation, wxPoint aPos)
 
static void export_vrml_drawsegment (MODEL_VRML &aModel, PCB_SHAPE *drawseg)
 
static void vrml_text_callback (int x0, int y0, int xf, int yf, void *aData)
 
static void export_vrml_pcbtext (MODEL_VRML &aModel, PCB_TEXT *text)
 
static void export_vrml_drawings (MODEL_VRML &aModel, BOARD *pcb)
 
static void export_vrml_board (MODEL_VRML &aModel, BOARD *aPcb)
 
static void export_round_padstack (MODEL_VRML &aModel, BOARD *pcb, double x, double y, double r, LAYER_NUM bottom_layer, LAYER_NUM top_layer, double hole)
 
static void export_vrml_via (MODEL_VRML &aModel, BOARD *aPcb, const VIA *aVia)
 
static void export_vrml_tracks (MODEL_VRML &aModel, BOARD *pcb)
 
static void export_vrml_zones (MODEL_VRML &aModel, BOARD *aPcb, COMMIT *aCommit)
 
static void export_vrml_fp_text (FP_TEXT *item)
 
static void export_vrml_fp_shape (MODEL_VRML &aModel, FP_SHAPE *aOutline, FOOTPRINT *aFootprint)
 
static void export_vrml_padshape (MODEL_VRML &aModel, VRML_LAYER *aTinLayer, PAD *aPad)
 
static void export_vrml_pad (MODEL_VRML &aModel, BOARD *aPcb, PAD *aPad)
 
static void build_quat (double x, double y, double z, double a, double q[4])
 
static void from_quat (double q[4], double rot[4])
 
static void compose_quat (double q1[4], double q2[4], double qr[4])
 
static void export_vrml_footprint (MODEL_VRML &aModel, BOARD *aPcb, FOOTPRINT *aFootprint, std::ostream *aOutputFile)
 
static SGNODEgetSGColor (VRML_COLOR_INDEX colorIdx)
 

Variables

static S3D_CACHEcache
 
static bool USE_INLINES
 
static bool USE_DEFS
 
static bool USE_RELPATH
 
static double WORLD_SCALE = 1.0
 
static double BOARD_SCALE
 
static const int PRECISION = 6
 
static wxString SUBDIR_3D
 
static wxString PROJ_DIR
 
static VRML_COLOR colors [VRML_COLOR_LAST]
 
static SGNODEsgmaterial [VRML_COLOR_LAST] = { NULL }
 
static MODEL_VRMLmodel_vrml
 

Macro Definition Documentation

◆ ART_OFFSET

#define ART_OFFSET   0.025

Definition at line 56 of file export_vrml.cpp.

◆ MIN_VRML_LINEWIDTH

#define MIN_VRML_LINEWIDTH   0.05

Definition at line 53 of file export_vrml.cpp.

◆ PLATE_OFFSET

#define PLATE_OFFSET   0.005

Definition at line 58 of file export_vrml.cpp.

Enumeration Type Documentation

◆ VRML_COLOR_INDEX

Enumerator
VRML_COLOR_NONE 
VRML_COLOR_PCB 
VRML_COLOR_TRACK 
VRML_COLOR_SILK 
VRML_COLOR_TIN 
VRML_COLOR_LAST 

Definition at line 127 of file export_vrml.cpp.

Function Documentation

◆ build_quat()

static void build_quat ( double  x,
double  y,
double  z,
double  a,
double  q[4] 
)
static

Definition at line 1320 of file export_vrml.cpp.

1321 {
1322  double sina = sin( a / 2 );
1323 
1324  q[0] = x * sina;
1325  q[1] = y * sina;
1326  q[2] = z * sina;
1327  q[3] = cos( a / 2 );
1328 }

Referenced by export_vrml_footprint().

◆ compose_quat()

static void compose_quat ( double  q1[4],
double  q2[4],
double  qr[4] 
)
static

Definition at line 1342 of file export_vrml.cpp.

1343 {
1344  double tmp[4];
1345 
1346  tmp[0] = q2[3] * q1[0] + q2[0] * q1[3] + q2[1] * q1[2] - q2[2] * q1[1];
1347  tmp[1] = q2[3] * q1[1] + q2[1] * q1[3] + q2[2] * q1[0] - q2[0] * q1[2];
1348  tmp[2] = q2[3] * q1[2] + q2[2] * q1[3] + q2[0] * q1[1] - q2[1] * q1[0];
1349  tmp[3] = q2[3] * q1[3] - q2[0] * q1[0] - q2[1] * q1[1] - q2[2] * q1[2];
1350 
1351  qr[0] = tmp[0];
1352  qr[1] = tmp[1];
1353  qr[2] = tmp[2];
1354  qr[3] = tmp[3];
1355 }

Referenced by export_vrml_footprint().

◆ compute_layer_Zs()

static void compute_layer_Zs ( MODEL_VRML aModel,
BOARD pcb 
)
static

Definition at line 544 of file export_vrml.cpp.

545 {
546  int copper_layers = pcb->GetCopperLayerCount();
547 
548  // We call it 'layer' thickness, but it's the whole board thickness!
550  double half_thickness = aModel.m_brd_thickness / 2;
551 
552  // Compute each layer's Z value, more or less like the 3d view
553  for( LSEQ seq = LSET::AllCuMask().Seq(); seq; ++seq )
554  {
555  PCB_LAYER_ID i = *seq;
556 
557  if( i < copper_layers )
558  aModel.SetLayerZ( i, half_thickness - aModel.m_brd_thickness * i / (copper_layers - 1) );
559  else
560  aModel.SetLayerZ( i, - half_thickness ); // bottom layer
561  }
562 
563  /* To avoid rounding interference, we apply an epsilon to each
564  * successive layer */
565  double epsilon_z = Millimeter2iu( ART_OFFSET ) * BOARD_SCALE;
566  aModel.SetLayerZ( B_Paste, -half_thickness - epsilon_z * 4 );
567  aModel.SetLayerZ( B_Adhes, -half_thickness - epsilon_z * 3 );
568  aModel.SetLayerZ( B_SilkS, -half_thickness - epsilon_z * 2 );
569  aModel.SetLayerZ( B_Mask, -half_thickness - epsilon_z );
570  aModel.SetLayerZ( F_Mask, half_thickness + epsilon_z );
571  aModel.SetLayerZ( F_SilkS, half_thickness + epsilon_z * 2 );
572  aModel.SetLayerZ( F_Adhes, half_thickness + epsilon_z * 3 );
573  aModel.SetLayerZ( F_Paste, half_thickness + epsilon_z * 4 );
574  aModel.SetLayerZ( Dwgs_User, half_thickness + epsilon_z * 5 );
575  aModel.SetLayerZ( Cmts_User, half_thickness + epsilon_z * 6 );
576  aModel.SetLayerZ( Eco1_User, half_thickness + epsilon_z * 7 );
577  aModel.SetLayerZ( Eco2_User, half_thickness + epsilon_z * 8 );
578  aModel.SetLayerZ( Edge_Cuts, 0 );
579 }
void SetLayerZ(LAYER_NUM aLayer, double aValue)
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:750
static double BOARD_SCALE
Definition: export_vrml.cpp:65
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.h:559
PCB_LAYER_ID
A quick note on layer IDs:
LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
int GetCopperLayerCount() const
Definition: board.cpp:425
double m_brd_thickness
static constexpr int Millimeter2iu(double mm)
#define ART_OFFSET
Definition: export_vrml.cpp:56

References LSET::AllCuMask(), ART_OFFSET, B_Adhes, B_Mask, B_Paste, B_SilkS, BOARD_SCALE, Cmts_User, Dwgs_User, Eco1_User, Eco2_User, Edge_Cuts, F_Adhes, F_Mask, F_Paste, F_SilkS, BOARD_DESIGN_SETTINGS::GetBoardThickness(), BOARD::GetCopperLayerCount(), BOARD::GetDesignSettings(), MODEL_VRML::m_brd_thickness, Millimeter2iu(), and MODEL_VRML::SetLayerZ().

Referenced by PCB_EDIT_FRAME::ExportVRML_File().

◆ create_vrml_plane()

static void create_vrml_plane ( IFSG_TRANSFORM PcbOutput,
VRML_COLOR_INDEX  colorID,
VRML_LAYER *  layer,
double  aHeight,
bool  aTopPlane 
)
static

Definition at line 1714 of file export_vrml.cpp.

1716 {
1717  std::vector< double > vertices;
1718  std::vector< int > idxPlane;
1719 
1720  if( !( *layer ).Get2DTriangles( vertices, idxPlane, top_z, aTopPlane ) )
1721  {
1722  return;
1723  }
1724 
1725  if( ( idxPlane.size() % 3 ) )
1726  {
1727  throw( std::runtime_error( "[BUG] index lists are not a multiple of 3 (not a triangle list)" ) );
1728  }
1729 
1730  std::vector< SGPOINT > vlist;
1731  size_t nvert = vertices.size() / 3;
1732  size_t j = 0;
1733 
1734  for( size_t i = 0; i < nvert; ++i, j+= 3 )
1735  vlist.emplace_back( vertices[j], vertices[j+1], vertices[j+2] );
1736 
1737  // create the intermediate scenegraph
1738  IFSG_TRANSFORM tx0( PcbOutput.GetRawPtr() ); // tx0 = Transform for this outline
1739  IFSG_SHAPE shape( tx0 ); // shape will hold (a) all vertices and (b) a local list of normals
1740  IFSG_FACESET face( shape ); // this face shall represent the top and bottom planes
1741  IFSG_COORDS cp( face ); // coordinates for all faces
1742  cp.SetCoordsList( nvert, &vlist[0] );
1743  IFSG_COORDINDEX coordIdx( face ); // coordinate indices for top and bottom planes only
1744  coordIdx.SetIndices( idxPlane.size(), &idxPlane[0] );
1745  IFSG_NORMALS norms( face ); // normals for the top and bottom planes
1746 
1747  // set the normals
1748  if( aTopPlane )
1749  {
1750  for( size_t i = 0; i < nvert; ++i )
1751  norms.AddNormal( 0.0, 0.0, 1.0 );
1752  }
1753  else
1754  {
1755  for( size_t i = 0; i < nvert; ++i )
1756  norms.AddNormal( 0.0, 0.0, -1.0 );
1757  }
1758 
1759  // assign a color from the palette
1760  SGNODE* modelColor = getSGColor( colorID );
1761 
1762  if( NULL != modelColor )
1763  {
1764  if( NULL == S3D::GetSGNodeParent( modelColor ) )
1765  shape.AddChildNode( modelColor );
1766  else
1767  shape.AddRefNode( modelColor );
1768  }
1769 }
IFSG_COORDS is the wrapper for SGCOORDS.
Definition: ifsg_coords.h:40
IFSG_COORDINDEX is the wrapper for SGCOORDINDEX.
SGLIB_API SGNODE * GetSGNodeParent(SGNODE *aNode)
Definition: ifsg_api.cpp:636
SGNODE represents the base class of all Scene Graph nodes.
Definition: sg_node.h:76
SGNODE * GetRawPtr(void) noexcept
Function GetRawPtr() returns the raw internal SGNODE pointer.
Definition: ifsg_node.cpp:66
IFSG_NORMALS is the wrapper for the SGNORMALS class.
Definition: ifsg_normals.h:40
#define NULL
static SGNODE * getSGColor(VRML_COLOR_INDEX colorIdx)
IFSG_FACESET is the wrapper for the SGFACESET class.
Definition: ifsg_faceset.h:40
IFSG_TRANSFORM is the wrapper for the VRML compatible TRANSFORM block class SCENEGRAPH.
IFSG_SHAPE is the wrapper for the SGSHAPE class.
Definition: ifsg_shape.h:40

References IFSG_NORMALS::AddNormal(), IFSG_NODE::GetRawPtr(), getSGColor(), S3D::GetSGNodeParent(), NULL, IFSG_COORDS::SetCoordsList(), and IFSG_INDEX::SetIndices().

Referenced by write_layers().

◆ create_vrml_shell()

static void create_vrml_shell ( IFSG_TRANSFORM PcbOutput,
VRML_COLOR_INDEX  colorID,
VRML_LAYER *  layer,
double  top_z,
double  bottom_z 
)
static

Definition at line 1772 of file export_vrml.cpp.

1774 {
1775  std::vector< double > vertices;
1776  std::vector< int > idxPlane;
1777  std::vector< int > idxSide;
1778 
1779  if( top_z < bottom_z )
1780  {
1781  double tmp = top_z;
1782  top_z = bottom_z;
1783  bottom_z = tmp;
1784  }
1785 
1786  if( !( *layer ).Get3DTriangles( vertices, idxPlane, idxSide, top_z, bottom_z )
1787  || idxPlane.empty() || idxSide.empty() )
1788  {
1789  return;
1790  }
1791 
1792  if( ( idxPlane.size() % 3 ) || ( idxSide.size() % 3 ) )
1793  {
1794  throw( std::runtime_error( "[BUG] index lists are not a multiple of 3 (not a "
1795  "triangle list)" ) );
1796  }
1797 
1798  std::vector< SGPOINT > vlist;
1799  size_t nvert = vertices.size() / 3;
1800  size_t j = 0;
1801 
1802  for( size_t i = 0; i < nvert; ++i, j+= 3 )
1803  vlist.emplace_back( vertices[j], vertices[j+1], vertices[j+2] );
1804 
1805  // create the intermediate scenegraph
1806  IFSG_TRANSFORM tx0( PcbOutput.GetRawPtr() ); // tx0 = Transform for this outline
1807  IFSG_SHAPE shape( tx0 ); // shape will hold (a) all vertices and (b) a local list of normals
1808  IFSG_FACESET face( shape ); // this face shall represent the top and bottom planes
1809  IFSG_COORDS cp( face ); // coordinates for all faces
1810  cp.SetCoordsList( nvert, &vlist[0] );
1811  IFSG_COORDINDEX coordIdx( face ); // coordinate indices for top and bottom planes only
1812  coordIdx.SetIndices( idxPlane.size(), &idxPlane[0] );
1813  IFSG_NORMALS norms( face ); // normals for the top and bottom planes
1814 
1815  // number of TOP (and bottom) vertices
1816  j = nvert / 2;
1817 
1818  // set the TOP normals
1819  for( size_t i = 0; i < j; ++i )
1820  norms.AddNormal( 0.0, 0.0, 1.0 );
1821 
1822  // set the BOTTOM normals
1823  for( size_t i = 0; i < j; ++i )
1824  norms.AddNormal( 0.0, 0.0, -1.0 );
1825 
1826  // assign a color from the palette
1827  SGNODE* modelColor = getSGColor( colorID );
1828 
1829  if( NULL != modelColor )
1830  {
1831  if( NULL == S3D::GetSGNodeParent( modelColor ) )
1832  shape.AddChildNode( modelColor );
1833  else
1834  shape.AddRefNode( modelColor );
1835  }
1836 
1837  // create a second shape describing the vertical walls of the extrusion
1838  // using per-vertex-per-face-normals
1839  shape.NewNode( tx0 );
1840  shape.AddRefNode( modelColor ); // set the color to be the same as the top/bottom
1841  face.NewNode( shape );
1842  cp.NewNode( face ); // new vertex list
1843  norms.NewNode( face ); // new normals list
1844  coordIdx.NewNode( face ); // new index list
1845 
1846  // populate the new per-face vertex list and its indices and normals
1847  std::vector< int >::iterator sI = idxSide.begin();
1848  std::vector< int >::iterator eI = idxSide.end();
1849 
1850  size_t sidx = 0; // index to the new coord set
1851  SGPOINT p1, p2, p3;
1852  SGVECTOR vnorm;
1853 
1854  while( sI != eI )
1855  {
1856  p1 = vlist[*sI];
1857  cp.AddCoord( p1 );
1858  ++sI;
1859 
1860  p2 = vlist[*sI];
1861  cp.AddCoord( p2 );
1862  ++sI;
1863 
1864  p3 = vlist[*sI];
1865  cp.AddCoord( p3 );
1866  ++sI;
1867 
1868  vnorm.SetVector( S3D::CalcTriNorm( p1, p2, p3 ) );
1869  norms.AddNormal( vnorm );
1870  norms.AddNormal( vnorm );
1871  norms.AddNormal( vnorm );
1872 
1873  coordIdx.AddIndex( (int)sidx );
1874  ++sidx;
1875  coordIdx.AddIndex( (int)sidx );
1876  ++sidx;
1877  coordIdx.AddIndex( (int)sidx );
1878  ++sidx;
1879  }
1880 }
IFSG_COORDS is the wrapper for SGCOORDS.
Definition: ifsg_coords.h:40
IFSG_COORDINDEX is the wrapper for SGCOORDINDEX.
void SetVector(double aXVal, double aYVal, double aZVal)
Definition: sg_base.cpp:292
SGLIB_API SGNODE * GetSGNodeParent(SGNODE *aNode)
Definition: ifsg_api.cpp:636
SGNODE represents the base class of all Scene Graph nodes.
Definition: sg_node.h:76
SGNODE * GetRawPtr(void) noexcept
Function GetRawPtr() returns the raw internal SGNODE pointer.
Definition: ifsg_node.cpp:66
IFSG_NORMALS is the wrapper for the SGNORMALS class.
Definition: ifsg_normals.h:40
#define NULL
static SGNODE * getSGColor(VRML_COLOR_INDEX 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:606
IFSG_FACESET is the wrapper for the SGFACESET class.
Definition: ifsg_faceset.h:40
IFSG_TRANSFORM is the wrapper for the VRML compatible TRANSFORM block class SCENEGRAPH.
IFSG_SHAPE is the wrapper for the SGSHAPE class.
Definition: ifsg_shape.h:40

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

Referenced by write_layers().

◆ export_round_padstack()

static void export_round_padstack ( MODEL_VRML aModel,
BOARD pcb,
double  x,
double  y,
double  r,
LAYER_NUM  bottom_layer,
LAYER_NUM  top_layer,
double  hole 
)
static

Definition at line 880 of file export_vrml.cpp.

884 {
885  LAYER_NUM layer = top_layer;
886  bool thru = true;
887 
888  // if not a thru hole do not put a hole in the board
889  if( top_layer != F_Cu || bottom_layer != B_Cu )
890  thru = false;
891 
892  if( thru && hole > 0 )
893  aModel.m_holes.AddCircle( x, -y, hole, true );
894 
895  if( aModel.m_plainPCB )
896  return;
897 
898  while( true )
899  {
900  if( layer == B_Cu )
901  {
902  aModel.m_bot_copper.AddCircle( x, -y, r );
903 
904  if( hole > 0 && !thru )
905  aModel.m_bot_copper.AddCircle( x, -y, hole, true );
906 
907  }
908  else if( layer == F_Cu )
909  {
910  aModel.m_top_copper.AddCircle( x, -y, r );
911 
912  if( hole > 0 && !thru )
913  aModel.m_top_copper.AddCircle( x, -y, hole, true );
914 
915  }
916 
917  if( layer == bottom_layer )
918  break;
919 
920  layer = bottom_layer;
921  }
922 }
VRML_LAYER m_holes
VRML_LAYER m_bot_copper
int LAYER_NUM
This can be replaced with int and removed.
VRML_LAYER m_top_copper

References B_Cu, F_Cu, MODEL_VRML::m_bot_copper, MODEL_VRML::m_holes, MODEL_VRML::m_plainPCB, and MODEL_VRML::m_top_copper.

Referenced by export_vrml_via().

◆ export_vrml_arc()

static void export_vrml_arc ( MODEL_VRML aModel,
LAYER_NUM  layer,
double  centerx,
double  centery,
double  arc_startx,
double  arc_starty,
double  width,
double  arc_angle 
)
static

Definition at line 638 of file export_vrml.cpp.

642 {
643  VRML_LAYER* vlayer;
644 
645  if( !GetLayer( aModel, layer, &vlayer ) )
646  return;
647 
648  if( width < aModel.m_minLineWidth )
649  width = aModel.m_minLineWidth;
650 
651  centery = -centery;
652  arc_starty = -arc_starty;
653 
654  if( !vlayer->AddArc( centerx, centery, arc_startx, arc_starty, width, -arc_angle, false ) )
655  throw( std::runtime_error( vlayer->GetError() ) );
656 
657 }
static bool GetLayer(MODEL_VRML &aModel, LAYER_NUM layer, VRML_LAYER **vlayer)
double m_minLineWidth

References GetLayer(), and MODEL_VRML::m_minLineWidth.

Referenced by export_vrml_drawsegment(), export_vrml_fp_shape(), and export_vrml_tracks().

◆ export_vrml_board()

static void export_vrml_board ( MODEL_VRML aModel,
BOARD aPcb 
)
static

Definition at line 829 of file export_vrml.cpp.

830 {
831  SHAPE_POLY_SET pcbOutlines; // stores the board main outlines
832 
833  if( !aPcb->GetBoardPolygonOutlines( pcbOutlines ) )
834  {
835  wxLogWarning( _( "Board outline is malformed. Run DRC for a full analysis." ) );
836  }
837 
838  int seg;
839 
840  for( int cnt = 0; cnt < pcbOutlines.OutlineCount(); cnt++ )
841  {
842  const SHAPE_LINE_CHAIN& outline = pcbOutlines.COutline( cnt );
843 
844  seg = aModel.m_board.NewContour();
845 
846  for( int j = 0; j < outline.PointCount(); j++ )
847  {
848  aModel.m_board.AddVertex( seg, (double)outline.CPoint(j).x * BOARD_SCALE,
849  -((double)outline.CPoint(j).y * BOARD_SCALE ) );
850 
851  }
852 
853  aModel.m_board.EnsureWinding( seg, false );
854 
855  // Generate holes:
856  for( int ii = 0; ii < pcbOutlines.HoleCount( cnt ); ii++ )
857  {
858  const SHAPE_LINE_CHAIN& hole = pcbOutlines.Hole( cnt, ii );
859 
860  seg = aModel.m_holes.NewContour();
861 
862  if( seg < 0 )
863  {
864  wxLogError( _( "VRML Export Failed: Could not add holes to contours." ) );
865  return;
866  }
867 
868  for( int j = 0; j < hole.PointCount(); j++ )
869  {
870  aModel.m_holes.AddVertex( seg, (double) hole.CPoint(j).x * BOARD_SCALE,
871  -( (double) hole.CPoint(j).y * BOARD_SCALE ) );
872  }
873 
874  aModel.m_holes.EnsureWinding( seg, true );
875  }
876  }
877 }
static double BOARD_SCALE
Definition: export_vrml.cpp:65
int OutlineCount() const
Returns the number of outlines in the set
bool GetBoardPolygonOutlines(SHAPE_POLY_SET &aOutlines, OUTLINE_ERROR_HANDLER *aErrorHandler=nullptr)
Extract the board outlines and build a closed polygon from lines, arcs and circle items on edge cut l...
Definition: board.cpp:1845
VRML_LAYER m_holes
SHAPE_LINE_CHAIN & Hole(int aOutline, int aHole)
Returns the reference to aHole-th hole in the aIndex-th outline
int PointCount() const
Function PointCount()
const VECTOR2I & CPoint(int aIndex) const
Function Point()
SHAPE_POLY_SET.
VRML_LAYER m_board
int HoleCount(int aOutline) const
Returns the number of holes in a given outline
#define _(s)
Definition: 3d_actions.cpp:33
SHAPE_LINE_CHAIN.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const

References _, BOARD_SCALE, SHAPE_POLY_SET::COutline(), SHAPE_LINE_CHAIN::CPoint(), BOARD::GetBoardPolygonOutlines(), SHAPE_POLY_SET::Hole(), SHAPE_POLY_SET::HoleCount(), MODEL_VRML::m_board, MODEL_VRML::m_holes, SHAPE_POLY_SET::OutlineCount(), SHAPE_LINE_CHAIN::PointCount(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by PCB_EDIT_FRAME::ExportVRML_File().

◆ export_vrml_circle()

static void export_vrml_circle ( MODEL_VRML aModel,
LAYER_NUM  layer,
double  startx,
double  starty,
double  endx,
double  endy,
double  width 
)
static

Definition at line 607 of file export_vrml.cpp.

610 {
611  VRML_LAYER* vlayer;
612 
613  if( !GetLayer( aModel, layer, &vlayer ) )
614  return;
615 
616  if( width < aModel.m_minLineWidth )
617  width = aModel.m_minLineWidth;
618 
619  starty = -starty;
620  endy = -endy;
621 
622  double hole, radius;
623 
624  radius = Distance( startx, starty, endx, endy ) + ( width / 2);
625  hole = radius - width;
626 
627  if( !vlayer->AddCircle( startx, starty, radius, false ) )
628  throw( std::runtime_error( vlayer->GetError() ) );
629 
630  if( hole > 0.0001 )
631  {
632  if( !vlayer->AddCircle( startx, starty, hole, true ) )
633  throw( std::runtime_error( vlayer->GetError() ) );
634  }
635 }
static bool GetLayer(MODEL_VRML &aModel, LAYER_NUM layer, VRML_LAYER **vlayer)
double m_minLineWidth

References GetLayer(), and MODEL_VRML::m_minLineWidth.

Referenced by export_vrml_fp_shape().

◆ export_vrml_drawings()

static void export_vrml_drawings ( MODEL_VRML aModel,
BOARD pcb 
)
static

Definition at line 801 of file export_vrml.cpp.

802 {
803  // draw graphic items
804  for( auto drawing : pcb->Drawings() )
805  {
806  PCB_LAYER_ID layer = drawing->GetLayer();
807 
808  if( layer != F_Cu && layer != B_Cu && layer != B_SilkS && layer != F_SilkS )
809  continue;
810 
811  switch( drawing->Type() )
812  {
813  case PCB_SHAPE_T:
814  export_vrml_drawsegment( aModel, (PCB_SHAPE*) drawing );
815  break;
816 
817  case PCB_TEXT_T:
818  export_vrml_pcbtext( aModel, (PCB_TEXT*) drawing );
819  break;
820 
821  default:
822  break;
823  }
824  }
825 }
class PCB_TEXT, text on a layer
Definition: typeinfo.h:92
static void export_vrml_drawsegment(MODEL_VRML &aModel, PCB_SHAPE *drawseg)
PCB_LAYER_ID
A quick note on layer IDs:
static void export_vrml_pcbtext(MODEL_VRML &aModel, PCB_TEXT *text)
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:91
DRAWINGS & Drawings()
Definition: board.h:286

References B_Cu, B_SilkS, BOARD::Drawings(), export_vrml_drawsegment(), export_vrml_pcbtext(), F_Cu, F_SilkS, PCB_SHAPE_T, and PCB_TEXT_T.

Referenced by PCB_EDIT_FRAME::ExportVRML_File().

◆ export_vrml_drawsegment()

static void export_vrml_drawsegment ( MODEL_VRML aModel,
PCB_SHAPE drawseg 
)
static

Definition at line 696 of file export_vrml.cpp.

697 {
698  LAYER_NUM layer = drawseg->GetLayer();
699  double w = drawseg->GetWidth() * BOARD_SCALE;
700  double x = drawseg->GetStart().x * BOARD_SCALE;
701  double y = drawseg->GetStart().y * BOARD_SCALE;
702  double xf = drawseg->GetEnd().x * BOARD_SCALE;
703  double yf = drawseg->GetEnd().y * BOARD_SCALE;
704  double r = sqrt( pow( x - xf, 2 ) + pow( y - yf, 2 ) );
705 
706  // Items on the edge layer are handled elsewhere; just return
707  if( layer == Edge_Cuts )
708  return;
709 
710  switch( drawseg->GetShape() )
711  {
712  case S_ARC:
713  export_vrml_arc( aModel, layer,
714  (double) drawseg->GetCenter().x * BOARD_SCALE,
715  (double) drawseg->GetCenter().y * BOARD_SCALE,
716  (double) drawseg->GetArcStart().x * BOARD_SCALE,
717  (double) drawseg->GetArcStart().y * BOARD_SCALE,
718  w, drawseg->GetAngle() / 10 );
719  break;
720 
721  case S_CIRCLE:
722  // Break circles into two 180 arcs to prevent the vrml hole from obscuring objects
723  // within the hole area of the circle.
724  export_vrml_arc( aModel, layer, x, y, x, y-r, w, 180.0 );
725  export_vrml_arc( aModel, layer, x, y, x, y+r, w, 180.0 );
726  break;
727 
728  case S_POLYGON:
729  export_vrml_polygon( aModel, layer, drawseg, 0.0, wxPoint( 0, 0 ) );
730  break;
731 
732  case S_SEGMENT:
733  export_vrml_line( aModel, layer, x, y, xf, yf, w );
734  break;
735 
736  case S_RECT:
737  export_vrml_line( aModel, layer, x, y, xf, y, w );
738  export_vrml_line( aModel, layer, xf, y, xf, yf, w );
739  export_vrml_line( aModel, layer, xf, yf, x, yf, w );
740  export_vrml_line( aModel, layer, x, yf, x, y, w );
741  break;
742 
743  default:
744  break;
745  }
746 }
static double BOARD_SCALE
Definition: export_vrml.cpp:65
const wxPoint & GetEnd() const
Function GetEnd returns the ending point of the graphic.
Definition: pcb_shape.h:155
int GetWidth() const
Definition: pcb_shape.h:118
polygon (not yet used for tracks, but could be in microwave apps)
Definition: board_item.h:56
usual segment : line with rounded ends
Definition: board_item.h:52
Arcs (with rounded ends)
Definition: board_item.h:54
segment with non rounded ends
Definition: board_item.h:53
wxPoint GetArcStart() const
Definition: pcb_shape.h:178
wxPoint GetCenter() const override
Function GetCenter()
Definition: pcb_shape.cpp:343
const wxPoint & GetStart() const
Function GetStart returns the starting point of the graphic.
Definition: pcb_shape.h:144
static void export_vrml_arc(MODEL_VRML &aModel, LAYER_NUM layer, double centerx, double centery, double arc_startx, double arc_starty, double width, double arc_angle)
int LAYER_NUM
This can be replaced with int and removed.
double GetAngle() const
Definition: pcb_shape.h:126
ring
Definition: board_item.h:55
PCB_SHAPE_TYPE_T GetShape() const
Definition: pcb_shape.h:129
static void export_vrml_line(MODEL_VRML &aModel, LAYER_NUM layer, double startx, double starty, double endx, double endy, double width)
static void export_vrml_polygon(MODEL_VRML &aModel, LAYER_NUM layer, PCB_SHAPE *aOutline, double aOrientation, wxPoint aPos)
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
Definition: board_item.h:185

References BOARD_SCALE, Edge_Cuts, export_vrml_arc(), export_vrml_line(), export_vrml_polygon(), PCB_SHAPE::GetAngle(), PCB_SHAPE::GetArcStart(), PCB_SHAPE::GetCenter(), PCB_SHAPE::GetEnd(), BOARD_ITEM::GetLayer(), PCB_SHAPE::GetShape(), PCB_SHAPE::GetStart(), PCB_SHAPE::GetWidth(), S_ARC, S_CIRCLE, S_POLYGON, S_RECT, and S_SEGMENT.

Referenced by export_vrml_drawings().

◆ export_vrml_footprint()

static void export_vrml_footprint ( MODEL_VRML aModel,
BOARD aPcb,
FOOTPRINT aFootprint,
std::ostream *  aOutputFile 
)
static

Definition at line 1358 of file export_vrml.cpp.

1360 {
1361  if( !aModel.m_plainPCB )
1362  {
1363  // Reference and value
1364  if( aFootprint->Reference().IsVisible() )
1365  export_vrml_fp_text( &aFootprint->Reference() );
1366 
1367  if( aFootprint->Value().IsVisible() )
1368  export_vrml_fp_text( &aFootprint->Value() );
1369 
1370  // Export footprint graphics
1371 
1372  for( BOARD_ITEM* item : aFootprint->GraphicalItems() )
1373  {
1374  switch( item->Type() )
1375  {
1376  case PCB_FP_TEXT_T:
1377  export_vrml_fp_text( static_cast<FP_TEXT*>( item ) );
1378  break;
1379 
1380  case PCB_FP_SHAPE_T:
1381  export_vrml_fp_shape( aModel, static_cast<FP_SHAPE*>( item ), aFootprint );
1382  break;
1383 
1384  default:
1385  break;
1386  }
1387  }
1388  }
1389 
1390  // Export pads
1391  for( PAD* pad : aFootprint->Pads() )
1392  export_vrml_pad( aModel, aPcb, pad );
1393 
1394  bool isFlipped = aFootprint->GetLayer() == B_Cu;
1395 
1396  // Export the object VRML model(s)
1397  auto sM = aFootprint->Models().begin();
1398  auto eM = aFootprint->Models().end();
1399 
1400  wxFileName subdir( SUBDIR_3D, "" );
1401 
1402  while( sM != eM )
1403  {
1404  SGNODE* mod3d = (SGNODE*) cache->Load( sM->m_Filename );
1405 
1406  if( NULL == mod3d )
1407  {
1408  ++sM;
1409  continue;
1410  }
1411 
1412  /* Calculate 3D shape rotation:
1413  * this is the rotation parameters, with an additional 180 deg rotation
1414  * for footprints that are flipped
1415  * When flipped, axis rotation is the horizontal axis (X axis)
1416  */
1417  double rotx = -sM->m_Rotation.x;
1418  double roty = -sM->m_Rotation.y;
1419  double rotz = -sM->m_Rotation.z;
1420 
1421  if( isFlipped )
1422  {
1423  rotx += 180.0;
1424  roty = -roty;
1425  rotz = -rotz;
1426  }
1427 
1428  // Do some quaternion munching
1429  double q1[4], q2[4], rot[4];
1430  build_quat( 1, 0, 0, DEG2RAD( rotx ), q1 );
1431  build_quat( 0, 1, 0, DEG2RAD( roty ), q2 );
1432  compose_quat( q1, q2, q1 );
1433  build_quat( 0, 0, 1, DEG2RAD( rotz ), q2 );
1434  compose_quat( q1, q2, q1 );
1435 
1436  // Note here aFootprint->GetOrientation() is in 0.1 degrees, so footprint rotation
1437  // has to be converted to radians
1438  build_quat( 0, 0, 1, DECIDEG2RAD( aFootprint->GetOrientation() ), q2 );
1439  compose_quat( q1, q2, q1 );
1440  from_quat( q1, rot );
1441 
1442  double offsetFactor = 1000.0f * IU_PER_MILS / 25.4f;
1443 
1444  // adjust 3D shape local offset position
1445  // they are given in mm, so they are converted in board IU.
1446  double offsetx = sM->m_Offset.x * offsetFactor;
1447  double offsety = sM->m_Offset.y * offsetFactor;
1448  double offsetz = sM->m_Offset.z * offsetFactor;
1449 
1450  if( isFlipped )
1451  offsetz = -offsetz;
1452  else // In normal mode, Y axis is reversed in Pcbnew.
1453  offsety = -offsety;
1454 
1455  RotatePoint( &offsetx, &offsety, aFootprint->GetOrientation() );
1456 
1457  SGPOINT trans;
1458  trans.x = ( offsetx + aFootprint->GetPosition().x ) * BOARD_SCALE + aModel.m_tx;
1459  trans.y = -( offsety + aFootprint->GetPosition().y) * BOARD_SCALE - aModel.m_ty;
1460  trans.z = (offsetz * BOARD_SCALE ) + aModel.GetLayerZ( aFootprint->GetLayer() );
1461 
1462  if( USE_INLINES )
1463  {
1464  wxFileName srcFile = cache->GetResolver()->ResolvePath( sM->m_Filename );
1465  wxFileName dstFile;
1466  dstFile.SetPath( SUBDIR_3D );
1467  dstFile.SetName( srcFile.GetName() );
1468  dstFile.SetExt( "wrl" );
1469 
1470  // copy the file if necessary
1471  wxDateTime srcModTime = srcFile.GetModificationTime();
1472  wxDateTime destModTime = srcModTime;
1473 
1474  destModTime.SetToCurrent();
1475 
1476  if( dstFile.FileExists() )
1477  destModTime = dstFile.GetModificationTime();
1478 
1479  if( srcModTime != destModTime )
1480  {
1481  wxString fileExt = srcFile.GetExt();
1482  fileExt.LowerCase();
1483 
1484  // copy VRML models and use the scenegraph library to
1485  // translate other model types
1486  if( fileExt == "wrl" )
1487  {
1488  if( !wxCopyFile( srcFile.GetFullPath(), dstFile.GetFullPath() ) )
1489  continue;
1490  }
1491  else
1492  {
1493  if( !S3D::WriteVRML( dstFile.GetFullPath().ToUTF8(), true, mod3d, USE_DEFS, true ) )
1494  continue;
1495  }
1496  }
1497 
1498  (*aOutputFile) << "Transform {\n";
1499 
1500  // only write a rotation if it is >= 0.1 deg
1501  if( std::abs( rot[3] ) > 0.0001745 )
1502  {
1503  (*aOutputFile) << " rotation " << std::setprecision( 5 );
1504  (*aOutputFile) << rot[0] << " " << rot[1] << " " << rot[2] << " " << rot[3] << "\n";
1505  }
1506 
1507  (*aOutputFile) << " translation " << std::setprecision( PRECISION );
1508  (*aOutputFile) << trans.x << " ";
1509  (*aOutputFile) << trans.y << " ";
1510  (*aOutputFile) << trans.z << "\n";
1511 
1512  (*aOutputFile) << " scale ";
1513  (*aOutputFile) << sM->m_Scale.x << " ";
1514  (*aOutputFile) << sM->m_Scale.y << " ";
1515  (*aOutputFile) << sM->m_Scale.z << "\n";
1516 
1517  (*aOutputFile) << " children [\n Inline {\n url \"";
1518 
1519  if( USE_RELPATH )
1520  {
1521  wxFileName tmp = dstFile;
1522  tmp.SetExt( "" );
1523  tmp.SetName( "" );
1524  tmp.RemoveLastDir();
1525  dstFile.MakeRelativeTo( tmp.GetPath() );
1526  }
1527 
1528  wxString fn = dstFile.GetFullPath();
1529  fn.Replace( "\\", "/" );
1530  (*aOutputFile) << TO_UTF8( fn ) << "\"\n } ]\n";
1531  (*aOutputFile) << " }\n";
1532  }
1533  else
1534  {
1535  IFSG_TRANSFORM* modelShape = new IFSG_TRANSFORM( aModel.m_OutputPCB.GetRawPtr() );
1536 
1537  // only write a rotation if it is >= 0.1 deg
1538  if( std::abs( rot[3] ) > 0.0001745 )
1539  modelShape->SetRotation( SGVECTOR( rot[0], rot[1], rot[2] ), rot[3] );
1540 
1541  modelShape->SetTranslation( trans );
1542  modelShape->SetScale( SGPOINT( sM->m_Scale.x, sM->m_Scale.y, sM->m_Scale.z ) );
1543 
1544  if( NULL == S3D::GetSGNodeParent( mod3d ) )
1545  {
1546  aModel.m_components.push_back( mod3d );
1547  modelShape->AddChildNode( mod3d );
1548  }
1549  else
1550  {
1551  modelShape->AddRefNode( mod3d );
1552  }
1553 
1554  }
1555 
1556  ++sM;
1557  }
1558 }
static double BOARD_SCALE
Definition: export_vrml.cpp:65
static S3D_CACHE * cache
Definition: export_vrml.cpp:60
double x
Definition: sg_base.h:70
class FP_TEXT, text in a footprint
Definition: typeinfo.h:93
std::list< FP_3DMODEL > & Models()
Definition: footprint.h:196
static void compose_quat(double q1[4], double q2[4], double qr[4])
static void export_vrml_fp_text(FP_TEXT *item)
static bool USE_INLINES
Definition: export_vrml.cpp:61
BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class,...
Definition: board_item.h:86
bool IsVisible() const
Definition: eda_text.h:192
static void export_vrml_pad(MODEL_VRML &aModel, BOARD *aPcb, PAD *aPad)
double GetOrientation() const
Definition: footprint.h:204
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:199
SGLIB_API SGNODE * GetSGNodeParent(SGNODE *aNode)
Definition: ifsg_api.cpp:636
class FP_SHAPE, a footprint edge
Definition: typeinfo.h:94
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:208
SGNODE represents the base class of all Scene Graph nodes.
Definition: sg_node.h:76
IFSG_TRANSFORM m_OutputPCB
SGNODE * GetRawPtr(void) noexcept
Function GetRawPtr() returns the raw internal SGNODE pointer.
Definition: ifsg_node.cpp:66
bool AddChildNode(SGNODE *aNode)
Function AddChildNode adds a node as a child owned by this node.
Definition: ifsg_node.cpp:249
PADS & Pads()
Definition: footprint.h:182
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:81
FP_TEXT & Value()
read/write accessors:
Definition: footprint.h:473
FP_TEXT & Reference()
Definition: footprint.h:474
static void build_quat(double x, double y, double z, double a, double q[4])
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:95
static void export_vrml_fp_shape(MODEL_VRML &aModel, FP_SHAPE *aOutline, FOOTPRINT *aFootprint)
#define NULL
static bool USE_RELPATH
Definition: export_vrml.cpp:63
bool SetRotation(const SGVECTOR &aRotationAxis, double aAngle)
DRAWINGS & GraphicalItems()
Definition: footprint.h:185
static wxString SUBDIR_3D
Definition: export_vrml.cpp:67
std::list< SGNODE * > m_components
wxString ResolvePath(const wxString &aFileName)
Function ResolvePath determines the full path of the given file name.
double DEG2RAD(double deg)
Definition: trigo.h:217
FILENAME_RESOLVER * GetResolver() noexcept
Definition: 3d_cache.cpp:626
IFSG_TRANSFORM is the wrapper for the VRML compatible TRANSFORM block class SCENEGRAPH.
double DECIDEG2RAD(double deg)
Definition: trigo.h:221
static void from_quat(double q[4], double rot[4])
#define IU_PER_MILS
Definition: plotter.cpp:137
bool SetTranslation(const SGPOINT &aTranslation) noexcept
wxPoint GetPosition() const override
Definition: footprint.h:200
bool SetScale(const SGPOINT &aScale) noexcept
static const int PRECISION
Definition: export_vrml.cpp:66
static bool USE_DEFS
Definition: export_vrml.cpp:62
SCENEGRAPH * Load(const wxString &aModelFile)
Function Load attempts to load the scene data for a model; it will consult the internal cache list an...
Definition: 3d_cache.cpp:284
Definition: pad.h:59
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
Definition: board_item.h:185
double GetLayerZ(LAYER_NUM aLayer)

References IFSG_NODE::AddChildNode(), IFSG_NODE::AddRefNode(), B_Cu, BOARD_SCALE, build_quat(), cache, compose_quat(), DECIDEG2RAD(), DEG2RAD(), export_vrml_fp_shape(), export_vrml_fp_text(), export_vrml_pad(), from_quat(), BOARD_ITEM::GetLayer(), MODEL_VRML::GetLayerZ(), FOOTPRINT::GetOrientation(), FOOTPRINT::GetPosition(), IFSG_NODE::GetRawPtr(), S3D_CACHE::GetResolver(), S3D::GetSGNodeParent(), FOOTPRINT::GraphicalItems(), EDA_TEXT::IsVisible(), IU_PER_MILS, S3D_CACHE::Load(), MODEL_VRML::m_components, MODEL_VRML::m_OutputPCB, MODEL_VRML::m_plainPCB, MODEL_VRML::m_tx, MODEL_VRML::m_ty, FOOTPRINT::Models(), NULL, FOOTPRINT::Pads(), PCB_FP_SHAPE_T, PCB_FP_TEXT_T, PRECISION, FOOTPRINT::Reference(), FILENAME_RESOLVER::ResolvePath(), RotatePoint(), IFSG_TRANSFORM::SetRotation(), IFSG_TRANSFORM::SetScale(), IFSG_TRANSFORM::SetTranslation(), SUBDIR_3D, TO_UTF8, USE_DEFS, USE_INLINES, USE_RELPATH, FOOTPRINT::Value(), S3D::WriteVRML(), and SGPOINT::x.

Referenced by PCB_EDIT_FRAME::ExportVRML_File().

◆ export_vrml_fp_shape()

static void export_vrml_fp_shape ( MODEL_VRML aModel,
FP_SHAPE aOutline,
FOOTPRINT aFootprint 
)
static

Definition at line 1066 of file export_vrml.cpp.

1067 {
1068  LAYER_NUM layer = aOutline->GetLayer();
1069  double x = aOutline->GetStart().x * BOARD_SCALE;
1070  double y = aOutline->GetStart().y * BOARD_SCALE;
1071  double xf = aOutline->GetEnd().x * BOARD_SCALE;
1072  double yf = aOutline->GetEnd().y * BOARD_SCALE;
1073  double w = aOutline->GetWidth() * BOARD_SCALE;
1074 
1075  switch( aOutline->GetShape() )
1076  {
1077  case S_SEGMENT:
1078  export_vrml_line( aModel, layer, x, y, xf, yf, w );
1079  break;
1080 
1081  case S_ARC:
1082  export_vrml_arc( aModel, layer, x, y, xf, yf, w, aOutline->GetAngle() / 10 );
1083  break;
1084 
1085  case S_CIRCLE:
1086  export_vrml_circle( aModel, layer, x, y, xf, yf, w );
1087  break;
1088 
1089  case S_POLYGON:
1090  export_vrml_polygon( aModel, layer, aOutline, aFootprint->GetOrientationRadians(),
1091  aFootprint->GetPosition() );
1092  break;
1093 
1094  case S_RECT:
1095  export_vrml_line( aModel, layer, x, y, xf, y, w );
1096  export_vrml_line( aModel, layer, xf, y, xf, yf, w );
1097  export_vrml_line( aModel, layer, xf, yf, x, yf, w );
1098  export_vrml_line( aModel, layer, x, yf, x, y, w );
1099  break;
1100 
1101  default:
1102  break;
1103  }
1104 }
static double BOARD_SCALE
Definition: export_vrml.cpp:65
double GetOrientationRadians() const
Definition: footprint.h:206
const wxPoint & GetEnd() const
Function GetEnd returns the ending point of the graphic.
Definition: pcb_shape.h:155
int GetWidth() const
Definition: pcb_shape.h:118
polygon (not yet used for tracks, but could be in microwave apps)
Definition: board_item.h:56
usual segment : line with rounded ends
Definition: board_item.h:52
Arcs (with rounded ends)
Definition: board_item.h:54
segment with non rounded ends
Definition: board_item.h:53
static void export_vrml_circle(MODEL_VRML &aModel, LAYER_NUM layer, double startx, double starty, double endx, double endy, double width)
const wxPoint & GetStart() const
Function GetStart returns the starting point of the graphic.
Definition: pcb_shape.h:144
static void export_vrml_arc(MODEL_VRML &aModel, LAYER_NUM layer, double centerx, double centery, double arc_startx, double arc_starty, double width, double arc_angle)
int LAYER_NUM
This can be replaced with int and removed.
double GetAngle() const
Definition: pcb_shape.h:126
wxPoint GetPosition() const override
Definition: footprint.h:200
ring
Definition: board_item.h:55
PCB_SHAPE_TYPE_T GetShape() const
Definition: pcb_shape.h:129
static void export_vrml_line(MODEL_VRML &aModel, LAYER_NUM layer, double startx, double starty, double endx, double endy, double width)
static void export_vrml_polygon(MODEL_VRML &aModel, LAYER_NUM layer, PCB_SHAPE *aOutline, double aOrientation, wxPoint aPos)
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
Definition: board_item.h:185

References BOARD_SCALE, export_vrml_arc(), export_vrml_circle(), export_vrml_line(), export_vrml_polygon(), PCB_SHAPE::GetAngle(), PCB_SHAPE::GetEnd(), BOARD_ITEM::GetLayer(), FOOTPRINT::GetOrientationRadians(), FOOTPRINT::GetPosition(), PCB_SHAPE::GetShape(), PCB_SHAPE::GetStart(), PCB_SHAPE::GetWidth(), S_ARC, S_CIRCLE, S_POLYGON, S_RECT, and S_SEGMENT.

Referenced by export_vrml_footprint().

◆ export_vrml_fp_text()

static void export_vrml_fp_text ( FP_TEXT item)
static

Definition at line 1044 of file export_vrml.cpp.

1045 {
1046  if( item->IsVisible() )
1047  {
1048  wxSize size = item->GetTextSize();
1049 
1050  if( item->IsMirrored() )
1051  size.x = -size.x; // Text is mirrored
1052 
1053  bool forceBold = true;
1054  int penWidth = item->GetEffectiveTextPenWidth();
1055 
1056  model_vrml->m_text_layer = item->GetLayer();
1057  model_vrml->m_text_width = penWidth;
1058 
1059  GRText( NULL, item->GetTextPos(), BLACK, item->GetShownText(), item->GetDrawRotation(),
1060  size, item->GetHorizJustify(), item->GetVertJustify(), penWidth, item->IsItalic(),
1061  forceBold, vrml_text_callback );
1062  }
1063 }
virtual double GetDrawRotation() const override
Definition: fp_text.cpp:247
static void vrml_text_callback(int x0, int y0, int xf, int yf, void *aData)
EDA_TEXT_VJUSTIFY_T GetVertJustify() const
Definition: eda_text.h:206
bool IsMirrored() const
Definition: eda_text.h:195
bool IsVisible() const
Definition: eda_text.h:192
static MODEL_VRML * model_vrml
Definition: color4d.h:45
int GetEffectiveTextPenWidth(int aDefaultWidth=0) const
The EffectiveTextPenWidth uses the text thickness if > 1 or aDefaultWidth.
Definition: eda_text.cpp:157
bool IsItalic() const
Definition: eda_text.h:186
EDA_TEXT_HJUSTIFY_T GetHorizJustify() const
Definition: eda_text.h:205
#define NULL
const wxSize & GetTextSize() const
Definition: eda_text.h:245
LAYER_NUM m_text_layer
void GRText(wxDC *aDC, const wxPoint &aPos, COLOR4D aColor, const wxString &aText, double aOrient, const wxSize &aSize, enum EDA_TEXT_HJUSTIFY_T aH_justify, enum EDA_TEXT_VJUSTIFY_T aV_justify, int aWidth, bool aItalic, bool aBold, void(*aCallback)(int x0, int y0, int xf, int yf, void *aData), void *aCallbackData, PLOTTER *aPlotter)
Function GRText Draw a graphic text (like footprint texts)
Definition: gr_text.cpp:131
const wxPoint & GetTextPos() const
Definition: eda_text.h:254
virtual wxString GetShownText(int aDepth=0) const override
Return the string actually shown after processing of the base text.
Definition: fp_text.cpp:422
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
Definition: board_item.h:185

References BLACK, FP_TEXT::GetDrawRotation(), EDA_TEXT::GetEffectiveTextPenWidth(), EDA_TEXT::GetHorizJustify(), BOARD_ITEM::GetLayer(), FP_TEXT::GetShownText(), EDA_TEXT::GetTextPos(), EDA_TEXT::GetTextSize(), EDA_TEXT::GetVertJustify(), GRText(), EDA_TEXT::IsItalic(), EDA_TEXT::IsMirrored(), EDA_TEXT::IsVisible(), MODEL_VRML::m_text_layer, MODEL_VRML::m_text_width, model_vrml, NULL, and vrml_text_callback().

Referenced by export_vrml_footprint().

◆ export_vrml_line()

static void export_vrml_line ( MODEL_VRML aModel,
LAYER_NUM  layer,
double  startx,
double  starty,
double  endx,
double  endy,
double  width 
)
static

Definition at line 582 of file export_vrml.cpp.

585 {
586  VRML_LAYER* vlayer;
587 
588  if( !GetLayer( aModel, layer, &vlayer ) )
589  return;
590 
591  if( width < aModel.m_minLineWidth)
592  width = aModel.m_minLineWidth;
593 
594  starty = -starty;
595  endy = -endy;
596 
597  double angle = atan2( endy - starty, endx - startx ) * 180.0 / M_PI;
598  double length = Distance( startx, starty, endx, endy ) + width;
599  double cx = ( startx + endx ) / 2.0;
600  double cy = ( starty + endy ) / 2.0;
601 
602  if( !vlayer->AddSlot( cx, cy, length, width, angle, false ) )
603  throw( std::runtime_error( vlayer->GetError() ) );
604 }
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
static bool GetLayer(MODEL_VRML &aModel, LAYER_NUM layer, VRML_LAYER **vlayer)
double m_minLineWidth

References PNS::angle(), GetLayer(), and MODEL_VRML::m_minLineWidth.

Referenced by export_vrml_drawsegment(), export_vrml_fp_shape(), export_vrml_tracks(), and vrml_text_callback().

◆ export_vrml_pad()

static void export_vrml_pad ( MODEL_VRML aModel,
BOARD aPcb,
PAD aPad 
)
static

Definition at line 1240 of file export_vrml.cpp.

1241 {
1242  double hole_drill_w = (double) aPad->GetDrillSize().x * BOARD_SCALE / 2.0;
1243  double hole_drill_h = (double) aPad->GetDrillSize().y * BOARD_SCALE / 2.0;
1244  double hole_drill = std::min( hole_drill_w, hole_drill_h );
1245  double hole_x = aPad->GetPosition().x * BOARD_SCALE;
1246  double hole_y = aPad->GetPosition().y * BOARD_SCALE;
1247 
1248  // Export the hole on the edge layer
1249  if( hole_drill > 0 )
1250  {
1251  bool pth = false;
1252 
1253  if( ( aPad->GetAttribute() != PAD_ATTRIB_NPTH )
1254  && !aModel.m_plainPCB )
1255  pth = true;
1256 
1257  if( aPad->GetDrillShape() == PAD_DRILL_SHAPE_OBLONG )
1258  {
1259  // Oblong hole (slot)
1260 
1261  if( pth )
1262  {
1263  aModel.m_holes.AddSlot( hole_x, -hole_y, hole_drill_w * 2.0 + PLATE_OFFSET,
1264  hole_drill_h * 2.0 + PLATE_OFFSET,
1265  aPad->GetOrientation()/10.0, true, true );
1266 
1267  aModel.m_plated_holes.AddSlot( hole_x, -hole_y,
1268  hole_drill_w * 2.0, hole_drill_h * 2.0,
1269  aPad->GetOrientation()/10.0, true, false );
1270  }
1271  else
1272  {
1273  aModel.m_holes.AddSlot( hole_x, -hole_y, hole_drill_w * 2.0, hole_drill_h * 2.0,
1274  aPad->GetOrientation()/10.0, true, false );
1275 
1276  }
1277  }
1278  else
1279  {
1280  // Drill a round hole
1281 
1282  if( pth )
1283  {
1284  aModel.m_holes.AddCircle( hole_x, -hole_y, hole_drill + PLATE_OFFSET, true, true );
1285  aModel.m_plated_holes.AddCircle( hole_x, -hole_y, hole_drill, true, false );
1286  }
1287  else
1288  {
1289  aModel.m_holes.AddCircle( hole_x, -hole_y, hole_drill, true, false );
1290  }
1291 
1292  }
1293  }
1294 
1295  if( aModel.m_plainPCB )
1296  return;
1297 
1298  // The pad proper, on the selected layers
1299  LSET layer_mask = aPad->GetLayerSet();
1300 
1301  if( layer_mask[B_Cu] )
1302  {
1303  if( layer_mask[B_Mask] )
1304  export_vrml_padshape( aModel, &aModel.m_bot_tin, aPad );
1305  else
1306  export_vrml_padshape( aModel, &aModel.m_bot_copper, aPad );
1307  }
1308  if( layer_mask[F_Cu] )
1309  {
1310  if( layer_mask[F_Mask] )
1311  export_vrml_padshape( aModel, &aModel.m_top_tin, aPad );
1312  else
1313  export_vrml_padshape( aModel, &aModel.m_top_copper, aPad );
1314  }
1315 
1316 }
static double BOARD_SCALE
Definition: export_vrml.cpp:65
static void export_vrml_padshape(MODEL_VRML &aModel, VRML_LAYER *aTinLayer, PAD *aPad)
VRML_LAYER m_bot_tin
VRML_LAYER m_plated_holes
VRML_LAYER m_holes
like PAD_PTH, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:85
PAD_ATTR_T GetAttribute() const
Definition: pad.h:348
const wxSize & GetDrillSize() const
Definition: pad.h:236
LSET is a set of PCB_LAYER_IDs.
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in a variety of units (the basic call r...
Definition: pad.h:334
LSET GetLayerSet() const override
Function GetLayerSet returns a std::bitset of all layers on which the item physically resides.
Definition: pad.h:345
VRML_LAYER m_bot_copper
wxPoint GetPosition() const override
Definition: pad.h:167
PAD_DRILL_SHAPE_T GetDrillShape() const
Definition: pad.h:339
#define PLATE_OFFSET
Definition: export_vrml.cpp:58
VRML_LAYER m_top_copper
VRML_LAYER m_top_tin

References B_Cu, B_Mask, BOARD_SCALE, export_vrml_padshape(), F_Cu, F_Mask, PAD::GetAttribute(), PAD::GetDrillShape(), PAD::GetDrillSize(), PAD::GetLayerSet(), PAD::GetOrientation(), PAD::GetPosition(), MODEL_VRML::m_bot_copper, MODEL_VRML::m_bot_tin, MODEL_VRML::m_holes, MODEL_VRML::m_plainPCB, MODEL_VRML::m_plated_holes, MODEL_VRML::m_top_copper, MODEL_VRML::m_top_tin, PAD_ATTRIB_NPTH, PAD_DRILL_SHAPE_OBLONG, and PLATE_OFFSET.

Referenced by export_vrml_footprint().

◆ export_vrml_padshape()

static void export_vrml_padshape ( MODEL_VRML aModel,
VRML_LAYER *  aTinLayer,
PAD aPad 
)
static

Definition at line 1107 of file export_vrml.cpp.

1108 {
1109  // The (maybe offset) pad position
1110  wxPoint pad_pos = aPad->ShapePos();
1111  double pad_x = pad_pos.x * BOARD_SCALE;
1112  double pad_y = pad_pos.y * BOARD_SCALE;
1113  wxSize pad_delta = aPad->GetDelta();
1114 
1115  double pad_dx = pad_delta.x * BOARD_SCALE / 2.0;
1116  double pad_dy = pad_delta.y * BOARD_SCALE / 2.0;
1117 
1118  double pad_w = aPad->GetSize().x * BOARD_SCALE / 2.0;
1119  double pad_h = aPad->GetSize().y * BOARD_SCALE / 2.0;
1120 
1121  switch( aPad->GetShape() )
1122  {
1123  case PAD_SHAPE_CIRCLE:
1124 
1125  if( !aTinLayer->AddCircle( pad_x, -pad_y, pad_w, false ) )
1126  throw( std::runtime_error( aTinLayer->GetError() ) );
1127 
1128  break;
1129 
1130  case PAD_SHAPE_OVAL:
1131 
1132  if( !aTinLayer->AddSlot( pad_x, -pad_y, pad_w * 2.0, pad_h * 2.0,
1133  aPad->GetOrientation()/10.0, false ) )
1134  throw( std::runtime_error( aTinLayer->GetError() ) );
1135 
1136  break;
1137 
1138  case PAD_SHAPE_ROUNDRECT:
1140  {
1141  SHAPE_POLY_SET polySet;
1142  const int corner_radius = aPad->GetRoundRectCornerRadius();
1143  TransformRoundChamferedRectToPolygon( polySet, wxPoint( 0, 0 ), aPad->GetSize(), 0.0,
1144  corner_radius, 0.0, 0, ARC_HIGH_DEF, ERROR_INSIDE );
1145  std::vector< wxRealPoint > cornerList;
1146  // TransformRoundChamferedRectToPolygon creates only one convex polygon
1147  SHAPE_LINE_CHAIN poly( polySet.Outline( 0 ) );
1148 
1149  cornerList.reserve( poly.PointCount() );
1150  for( int ii = 0; ii < poly.PointCount(); ++ii )
1151  cornerList.emplace_back(
1152  poly.CPoint( ii ).x * BOARD_SCALE, -poly.CPoint( ii ).y * BOARD_SCALE );
1153 
1154  // Close polygon
1155  cornerList.push_back( cornerList[0] );
1156  if( !aTinLayer->AddPolygon( cornerList, pad_x, -pad_y, aPad->GetOrientation() ) )
1157  throw( std::runtime_error( aTinLayer->GetError() ) );
1158 
1159  break;
1160  }
1161 
1162  case PAD_SHAPE_CUSTOM:
1163  {
1164  SHAPE_POLY_SET polySet;
1165  std::vector< wxRealPoint > cornerList;
1166  aPad->MergePrimitivesAsPolygon( &polySet, UNDEFINED_LAYER );
1167 
1168  for( int cnt = 0; cnt < polySet.OutlineCount(); ++cnt )
1169  {
1170  SHAPE_LINE_CHAIN& poly = polySet.Outline( cnt );
1171  cornerList.clear();
1172 
1173  for( int ii = 0; ii < poly.PointCount(); ++ii )
1174  cornerList.emplace_back(
1175  poly.CPoint( ii ).x * BOARD_SCALE, -poly.CPoint( ii ).y * BOARD_SCALE );
1176 
1177  // Close polygon
1178  cornerList.push_back( cornerList[0] );
1179 
1180  if( !aTinLayer->AddPolygon( cornerList, pad_x, -pad_y, aPad->GetOrientation() ) )
1181  throw( std::runtime_error( aTinLayer->GetError() ) );
1182  }
1183 
1184  break;
1185  }
1186 
1187  case PAD_SHAPE_RECT:
1188  // Just to be sure :D
1189  pad_dx = 0;
1190  pad_dy = 0;
1191 
1192  // Intentionally fall through and treat a rectangle as a trapezoid with no sloped sides
1194 
1195  case PAD_SHAPE_TRAPEZOID:
1196  {
1197  double coord[8] =
1198  {
1199  -pad_w + pad_dy, -pad_h - pad_dx,
1200  -pad_w - pad_dy, pad_h + pad_dx,
1201  +pad_w - pad_dy, -pad_h + pad_dx,
1202  +pad_w + pad_dy, pad_h - pad_dx
1203  };
1204 
1205  for( int i = 0; i < 4; i++ )
1206  {
1207  RotatePoint( &coord[i * 2], &coord[i * 2 + 1], aPad->GetOrientation() );
1208  coord[i * 2] += pad_x;
1209  coord[i * 2 + 1] += pad_y;
1210  }
1211 
1212  int lines;
1213 
1214  lines = aTinLayer->NewContour();
1215 
1216  if( lines < 0 )
1217  throw( std::runtime_error( aTinLayer->GetError() ) );
1218 
1219  if( !aTinLayer->AddVertex( lines, coord[0], -coord[1] ) )
1220  throw( std::runtime_error( aTinLayer->GetError() ) );
1221 
1222  if( !aTinLayer->AddVertex( lines, coord[4], -coord[5] ) )
1223  throw( std::runtime_error( aTinLayer->GetError() ) );
1224 
1225  if( !aTinLayer->AddVertex( lines, coord[6], -coord[7] ) )
1226  throw( std::runtime_error( aTinLayer->GetError() ) );
1227 
1228  if( !aTinLayer->AddVertex( lines, coord[2], -coord[3] ) )
1229  throw( std::runtime_error( aTinLayer->GetError() ) );
1230 
1231  if( !aTinLayer->EnsureWinding( lines, false ) )
1232  throw( std::runtime_error( aTinLayer->GetError() ) );
1233 
1234  break;
1235  }
1236  }
1237 }
static double BOARD_SCALE
Definition: export_vrml.cpp:65
int OutlineCount() const
Returns the number of outlines in the set
void TransformRoundChamferedRectToPolygon(SHAPE_POLY_SET &aCornerBuffer, const wxPoint &aPosition, const wxSize &aSize, double aRotation, int aCornerRadius, double aChamferRatio, int aChamferCorners, int aError, ERROR_LOC aErrorLoc)
convert a rectangle with rounded corners and/or chamfered corners to a polygon Convert rounded corner...
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
Definition: macros.h:83
PAD_SHAPE_T GetShape() const
Definition: pad.h:159
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:208
int PointCount() const
Function PointCount()
const VECTOR2I & CPoint(int aIndex) const
Function Point()
wxPoint ShapePos() const
Definition: pcbnew/pad.cpp:609
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in a variety of units (the basic call r...
Definition: pad.h:334
SHAPE_POLY_SET.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Returns the reference to aIndex-th outline in the set
const wxSize & GetSize() const
Definition: pad.h:226
int GetRoundRectCornerRadius() const
Definition: pcbnew/pad.cpp:221
const wxSize & GetDelta() const
Definition: pad.h:233
void MergePrimitivesAsPolygon(SHAPE_POLY_SET *aMergedPolygon, PCB_LAYER_ID aLayer) const
Merge all basic shapes to a SHAPE_POLY_SET Note: The results are relative to the pad position,...
SHAPE_LINE_CHAIN.

References BOARD_SCALE, SHAPE_LINE_CHAIN::CPoint(), ERROR_INSIDE, PAD::GetDelta(), PAD::GetOrientation(), PAD::GetRoundRectCornerRadius(), PAD::GetShape(), PAD::GetSize(), KI_FALLTHROUGH, PAD::MergePrimitivesAsPolygon(), SHAPE_POLY_SET::Outline(), SHAPE_POLY_SET::OutlineCount(), PAD_SHAPE_CHAMFERED_RECT, PAD_SHAPE_CIRCLE, PAD_SHAPE_CUSTOM, PAD_SHAPE_OVAL, PAD_SHAPE_RECT, PAD_SHAPE_ROUNDRECT, PAD_SHAPE_TRAPEZOID, SHAPE_LINE_CHAIN::PointCount(), RotatePoint(), PAD::ShapePos(), TransformRoundChamferedRectToPolygon(), UNDEFINED_LAYER, VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by export_vrml_pad().

◆ export_vrml_pcbtext()

static void export_vrml_pcbtext ( MODEL_VRML aModel,
PCB_TEXT text 
)
static

Definition at line 763 of file export_vrml.cpp.

764 {
765  wxSize size = text->GetTextSize();
766 
767  if( text->IsMirrored() )
768  size.x = -size.x;
769 
770  bool forceBold = true;
771  int penWidth = text->GetEffectiveTextPenWidth();
772  COLOR4D color = COLOR4D::BLACK; // not actually used, but needed by GRText
773 
774  model_vrml->m_text_layer = text->GetLayer();
775  model_vrml->m_text_width = penWidth;
776 
777  if( text->IsMultilineAllowed() )
778  {
779  wxArrayString strings_list;
780  wxStringSplit( text->GetShownText(), strings_list, '\n' );
781  std::vector<wxPoint> positions;
782  positions.reserve( strings_list.Count() );
783  text->GetLinePositions( positions, strings_list.Count() );
784 
785  for( unsigned ii = 0; ii < strings_list.Count(); ii++ )
786  {
787  GRText( nullptr, positions[ii], color, strings_list[ii], text->GetTextAngle(), size,
788  text->GetHorizJustify(), text->GetVertJustify(), penWidth, text->IsItalic(),
789  forceBold, vrml_text_callback );
790  }
791  }
792  else
793  {
794  GRText( nullptr, text->GetTextPos(), color, text->GetShownText(), text->GetTextAngle(),
795  size, text->GetHorizJustify(), text->GetVertJustify(), penWidth, text->IsItalic(),
796  forceBold, vrml_text_callback );
797  }
798 }
static void vrml_text_callback(int x0, int y0, int xf, int yf, void *aData)
EDA_TEXT_VJUSTIFY_T GetVertJustify() const
Definition: eda_text.h:206
bool IsMirrored() const
Definition: eda_text.h:195
int color
Definition: DXF_plotter.cpp:60
double GetTextAngle() const
Definition: eda_text.h:180
static MODEL_VRML * model_vrml
Definition: color4d.h:45
int GetEffectiveTextPenWidth(int aDefaultWidth=0) const
The EffectiveTextPenWidth uses the text thickness if > 1 or aDefaultWidth.
Definition: eda_text.cpp:157
bool IsItalic() const
Definition: eda_text.h:186
wxString GetShownText(int aDepth=0) const override
Return the string actually shown after processing of the base text.
Definition: pcb_text.cpp:52
EDA_TEXT_HJUSTIFY_T GetHorizJustify() const
Definition: eda_text.h:205
const wxSize & GetTextSize() const
Definition: eda_text.h:245
bool IsMultilineAllowed() const
Definition: eda_text.h:203
void wxStringSplit(const wxString &aText, wxArrayString &aStrings, wxChar aSplitter)
Split aString to a string list separated at aSplitter.
Definition: string.cpp:796
LAYER_NUM m_text_layer
void GRText(wxDC *aDC, const wxPoint &aPos, COLOR4D aColor, const wxString &aText, double aOrient, const wxSize &aSize, enum EDA_TEXT_HJUSTIFY_T aH_justify, enum EDA_TEXT_VJUSTIFY_T aV_justify, int aWidth, bool aItalic, bool aBold, void(*aCallback)(int x0, int y0, int xf, int yf, void *aData), void *aCallbackData, PLOTTER *aPlotter)
Function GRText Draw a graphic text (like footprint texts)
Definition: gr_text.cpp:131
void GetLinePositions(std::vector< wxPoint > &aPositions, int aLineCount) const
Populate aPositions with the position of each line of a multiline text, according to the vertical jus...
Definition: eda_text.cpp:424
const wxPoint & GetTextPos() const
Definition: eda_text.h:254
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
Definition: board_item.h:185
COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:100

References BLACK, color, EDA_TEXT::GetEffectiveTextPenWidth(), EDA_TEXT::GetHorizJustify(), BOARD_ITEM::GetLayer(), EDA_TEXT::GetLinePositions(), PCB_TEXT::GetShownText(), EDA_TEXT::GetTextAngle(), EDA_TEXT::GetTextPos(), EDA_TEXT::GetTextSize(), EDA_TEXT::GetVertJustify(), GRText(), EDA_TEXT::IsItalic(), EDA_TEXT::IsMirrored(), EDA_TEXT::IsMultilineAllowed(), MODEL_VRML::m_text_layer, MODEL_VRML::m_text_width, model_vrml, vrml_text_callback(), and wxStringSplit().

Referenced by export_vrml_drawings().

◆ export_vrml_polygon()

static void export_vrml_polygon ( MODEL_VRML aModel,
LAYER_NUM  layer,
PCB_SHAPE aOutline,
double  aOrientation,
wxPoint  aPos 
)
static

Definition at line 660 of file export_vrml.cpp.

662 {
663  if( aOutline->IsPolyShapeValid() )
664  {
665  SHAPE_POLY_SET shape = aOutline->GetPolyShape();
666  VRML_LAYER* vlayer;
667 
668  if( !GetLayer( aModel, layer, &vlayer ) )
669  return;
670 
671  if( aOutline->GetWidth() )
672  {
673  int numSegs = GetArcToSegmentCount( aOutline->GetWidth() / 2, ARC_HIGH_DEF, 360.0 );
674  shape.Inflate( aOutline->GetWidth() / 2, numSegs );
676  }
677 
678  shape.Rotate( -aOrientation, VECTOR2I( 0, 0 ) );
679  shape.Move( aPos );
680  const SHAPE_LINE_CHAIN& outline = shape.COutline( 0 );
681 
682  int seg = vlayer->NewContour();
683 
684  for( int j = 0; j < outline.PointCount(); j++ )
685  {
686  if( !vlayer->AddVertex( seg, outline.CPoint( j ).x * BOARD_SCALE,
687  -outline.CPoint( j ).y * BOARD_SCALE ) )
688  throw( std::runtime_error( vlayer->GetError() ) );
689  }
690 
691  vlayer->EnsureWinding( seg, false );
692  }
693 }
bool IsPolyShapeValid() const
Definition: pcb_shape.cpp:1194
static double BOARD_SCALE
Definition: export_vrml.cpp:65
SHAPE_POLY_SET & GetPolyShape()
Definition: pcb_shape.h:259
int GetWidth() const
Definition: pcb_shape.h:118
void Rotate(double aAngle, const VECTOR2I &aCenter={ 0, 0 }) override
Function Rotate rotates all vertices by a given angle.
void Inflate(int aAmount, int aCircleSegmentsCount, CORNER_STRATEGY aCornerStrategy=ROUND_ALL_CORNERS)
Performs outline inflation/deflation.
VECTOR2< int > VECTOR2I
Definition: vector2d.h:594
int PointCount() const
Function PointCount()
const VECTOR2I & CPoint(int aIndex) const
Function Point()
void Move(const VECTOR2I &aVector) override
SHAPE_POLY_SET.
void Fracture(POLYGON_MODE aFastMode)
Converts a set of polygons with holes to a singe outline with "slits"/"fractures" connecting the oute...
SHAPE_LINE_CHAIN.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
static bool GetLayer(MODEL_VRML &aModel, LAYER_NUM layer, VRML_LAYER **vlayer)
int GetArcToSegmentCount(int aRadius, int aErrorMax, double aArcAngleDegree)

References BOARD_SCALE, SHAPE_POLY_SET::COutline(), SHAPE_LINE_CHAIN::CPoint(), SHAPE_POLY_SET::Fracture(), GetArcToSegmentCount(), GetLayer(), PCB_SHAPE::GetPolyShape(), PCB_SHAPE::GetWidth(), SHAPE_POLY_SET::Inflate(), PCB_SHAPE::IsPolyShapeValid(), SHAPE_POLY_SET::Move(), SHAPE_POLY_SET::PM_STRICTLY_SIMPLE, SHAPE_LINE_CHAIN::PointCount(), SHAPE_POLY_SET::Rotate(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by export_vrml_drawsegment(), and export_vrml_fp_shape().

◆ export_vrml_tracks()

static void export_vrml_tracks ( MODEL_VRML aModel,
BOARD pcb 
)
static

Definition at line 945 of file export_vrml.cpp.

946 {
947  for( TRACK* track : pcb->Tracks() )
948  {
949  if( track->Type() == PCB_VIA_T )
950  {
951  export_vrml_via( aModel, pcb, (const VIA*) track );
952  }
953  else if( ( track->GetLayer() == B_Cu || track->GetLayer() == F_Cu )
954  && !aModel.m_plainPCB )
955  {
956  if( track->Type() == PCB_ARC_T )
957  {
958  ARC* arc = static_cast<ARC*>( track );
959  VECTOR2D center( arc->GetCenter() );
960  double arc_angle_degree = arc->GetAngle()/10;
961 
962  // Vrml exporter does not export arcs with angle < 1.0 degree
963  // ( to avoid issues with vrml viewers).
964  // The best way is to convert them to a small straight line
965  if( arc_angle_degree < -1.0 || arc_angle_degree > 1.0 )
966  {
967  export_vrml_arc( aModel, track->GetLayer(),
968  center.x * BOARD_SCALE, center.y * BOARD_SCALE,
969  arc->GetStart().x * BOARD_SCALE,
970  arc->GetStart().y * BOARD_SCALE,
971  arc->GetWidth() * BOARD_SCALE, arc_angle_degree );
972  }
973  else
974  {
975  export_vrml_line( aModel, arc->GetLayer(),
976  arc->GetStart().x * BOARD_SCALE,
977  arc->GetStart().y * BOARD_SCALE,
978  arc->GetEnd().x * BOARD_SCALE,
979  arc->GetEnd().y * BOARD_SCALE,
980  arc->GetWidth() * BOARD_SCALE );
981  }
982  }
983  else
984  {
985  export_vrml_line( aModel, track->GetLayer(),
986  track->GetStart().x * BOARD_SCALE,
987  track->GetStart().y * BOARD_SCALE,
988  track->GetEnd().x * BOARD_SCALE,
989  track->GetEnd().y * BOARD_SCALE,
990  track->GetWidth() * BOARD_SCALE );
991  }
992  }
993  }
994 }
static double BOARD_SCALE
Definition: export_vrml.cpp:65
Definition: track.h:354
virtual wxPoint GetCenter() const override
Function GetCenter()
Definition: track.h:312
const wxPoint & GetStart() const
Definition: track.h:116
class ARC, an arc track segment on a copper layer
Definition: typeinfo.h:98
static void export_vrml_arc(MODEL_VRML &aModel, LAYER_NUM layer, double centerx, double centery, double arc_startx, double arc_starty, double width, double arc_angle)
double GetAngle() const
Definition: track.cpp:924
int GetWidth() const
Definition: track.h:110
Definition: track.h:272
const wxPoint & GetEnd() const
Definition: track.h:113
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:97
static void export_vrml_via(MODEL_VRML &aModel, BOARD *aPcb, const VIA *aVia)
static void export_vrml_line(MODEL_VRML &aModel, LAYER_NUM layer, double startx, double starty, double endx, double endy, double width)
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
Definition: board_item.h:185
TRACKS & Tracks()
Definition: board.h:280
Definition: track.h:83

References B_Cu, BOARD_SCALE, export_vrml_arc(), export_vrml_line(), export_vrml_via(), F_Cu, ARC::GetAngle(), ARC::GetCenter(), TRACK::GetEnd(), BOARD_ITEM::GetLayer(), TRACK::GetStart(), TRACK::GetWidth(), MODEL_VRML::m_plainPCB, PCB_ARC_T, PCB_VIA_T, and BOARD::Tracks().

Referenced by PCB_EDIT_FRAME::ExportVRML_File().

◆ export_vrml_via()

static void export_vrml_via ( MODEL_VRML aModel,
BOARD aPcb,
const VIA aVia 
)
static

Definition at line 925 of file export_vrml.cpp.

926 {
927  double x, y, r, hole;
928  PCB_LAYER_ID top_layer, bottom_layer;
929 
930  hole = aVia->GetDrillValue() * BOARD_SCALE / 2.0;
931  r = aVia->GetWidth() * BOARD_SCALE / 2.0;
932  x = aVia->GetStart().x * BOARD_SCALE;
933  y = aVia->GetStart().y * BOARD_SCALE;
934  aVia->LayerPair( &top_layer, &bottom_layer );
935 
936  // do not render a buried via
937  if( top_layer != F_Cu && bottom_layer != B_Cu )
938  return;
939 
940  // Export the via padstack
941  export_round_padstack( aModel, aPcb, x, y, r, bottom_layer, top_layer, hole );
942 }
static double BOARD_SCALE
Definition: export_vrml.cpp:65
void LayerPair(PCB_LAYER_ID *top_layer, PCB_LAYER_ID *bottom_layer) const
Function LayerPair Return the 2 layers used by the via (the via actually uses all layers between thes...
Definition: track.cpp:422
const wxPoint & GetStart() const
Definition: track.h:116
PCB_LAYER_ID
A quick note on layer IDs:
int GetDrillValue() const
Function GetDrillValue "calculates" the drill value for vias (m-Drill if > 0, or default drill value ...
Definition: track.cpp:170
static void export_round_padstack(MODEL_VRML &aModel, BOARD *pcb, double x, double y, double r, LAYER_NUM bottom_layer, LAYER_NUM top_layer, double hole)
int GetWidth() const
Definition: track.h:110

References B_Cu, BOARD_SCALE, export_round_padstack(), F_Cu, VIA::GetDrillValue(), TRACK::GetStart(), TRACK::GetWidth(), and VIA::LayerPair().

Referenced by export_vrml_tracks().

◆ export_vrml_zones()

static void export_vrml_zones ( MODEL_VRML aModel,
BOARD aPcb,
COMMIT aCommit 
)
static

Definition at line 997 of file export_vrml.cpp.

998 {
999  for( ZONE* zone : aPcb->Zones() )
1000  {
1001  for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() )
1002  {
1003  VRML_LAYER* vl;
1004 
1005  if( !GetLayer( aModel, layer, &vl ) )
1006  continue;
1007 
1008  if( !zone->IsFilled() )
1009  {
1010  ZONE_FILLER filler( aPcb, aCommit );
1011  zone->SetFillMode( ZONE_FILL_MODE::POLYGONS ); // use filled polygons
1012 
1013  // If the zone fill failed, don't try adding it to the export
1014  std::vector<ZONE*> toFill = { zone };
1015 
1016  if( !filler.Fill( toFill ) )
1017  continue;
1018  }
1019 
1020  const SHAPE_POLY_SET& poly = zone->GetFilledPolysList( layer );
1021 
1022  for( int i = 0; i < poly.OutlineCount(); i++ )
1023  {
1024  const SHAPE_LINE_CHAIN& outline = poly.COutline( i );
1025 
1026  int seg = vl->NewContour();
1027 
1028  for( int j = 0; j < outline.PointCount(); j++ )
1029  {
1030  if( !vl->AddVertex( seg, (double) outline.CPoint( j ).x * BOARD_SCALE,
1031  -( (double) outline.CPoint( j ).y * BOARD_SCALE ) ) )
1032  {
1033  throw( std::runtime_error( vl->GetError() ) );
1034  }
1035  }
1036 
1037  vl->EnsureWinding( seg, false );
1038  }
1039  }
1040  }
1041 }
static double BOARD_SCALE
Definition: export_vrml.cpp:65
int OutlineCount() const
Returns the number of outlines in the set
ZONES & Zones()
Definition: board.h:289
int PointCount() const
Function PointCount()
const VECTOR2I & CPoint(int aIndex) const
Function Point()
PCB_LAYER_ID
A quick note on layer IDs:
SHAPE_POLY_SET.
ZONE handles a list of polygons defining a copper zone.
Definition: zone.h:57
SHAPE_LINE_CHAIN.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
static bool GetLayer(MODEL_VRML &aModel, LAYER_NUM layer, VRML_LAYER **vlayer)

References BOARD_SCALE, SHAPE_POLY_SET::COutline(), SHAPE_LINE_CHAIN::CPoint(), ZONE_FILLER::Fill(), GetLayer(), SHAPE_POLY_SET::OutlineCount(), SHAPE_LINE_CHAIN::PointCount(), POLYGONS, VECTOR2< T >::x, VECTOR2< T >::y, and BOARD::Zones().

Referenced by PCB_EDIT_FRAME::ExportVRML_File().

◆ from_quat()

static void from_quat ( double  q[4],
double  rot[4] 
)
static

Definition at line 1332 of file export_vrml.cpp.

1333 {
1334  rot[3] = acos( q[3] ) * 2;
1335 
1336  for( int i = 0; i < 3; i++ )
1337  rot[i] = q[i] / sin( rot[3] / 2 );
1338 }

Referenced by export_vrml_footprint().

◆ GetLayer()

static bool GetLayer ( MODEL_VRML aModel,
LAYER_NUM  layer,
VRML_LAYER **  vlayer 
)
static

◆ getSGColor()

static SGNODE* getSGColor ( VRML_COLOR_INDEX  colorIdx)
static

Definition at line 1687 of file export_vrml.cpp.

1688 {
1689  if( colorIdx == -1 )
1690  colorIdx = VRML_COLOR_PCB;
1691  else if( colorIdx == VRML_COLOR_LAST )
1692  return NULL;
1693 
1694  if( sgmaterial[colorIdx] )
1695  return sgmaterial[colorIdx];
1696 
1697  IFSG_APPEARANCE vcolor( (SGNODE*) NULL );
1698  VRML_COLOR* cp = &colors[colorIdx];
1699 
1700  vcolor.SetSpecular( cp->spec_red, cp->spec_grn, cp->spec_blu );
1701  vcolor.SetDiffuse( cp->diffuse_red, cp->diffuse_grn, cp->diffuse_blu );
1702  vcolor.SetShininess( cp->shiny );
1703  // NOTE: XXX - replace with a better equation; using this definition
1704  // of ambient will not yield the best results
1705  vcolor.SetAmbient( cp->ambient, cp->ambient, cp->ambient );
1706  vcolor.SetTransparency( cp->transp );
1707 
1708  sgmaterial[colorIdx] = vcolor.GetRawPtr();
1709 
1710  return sgmaterial[colorIdx];
1711 }
float transp
Definition: export_vrml.cpp:85
static SGNODE * sgmaterial[VRML_COLOR_LAST]
SGNODE represents the base class of all Scene Graph nodes.
Definition: sg_node.h:76
float spec_blu
Definition: export_vrml.cpp:78
float ambient
Definition: export_vrml.cpp:84
float diffuse_grn
Definition: export_vrml.cpp:73
#define NULL
float spec_red
Definition: export_vrml.cpp:76
float spec_grn
Definition: export_vrml.cpp:77
float diffuse_red
Definition: export_vrml.cpp:72
float diffuse_blu
Definition: export_vrml.cpp:74
static VRML_COLOR colors[VRML_COLOR_LAST]

References VRML_COLOR::ambient, colors, VRML_COLOR::diffuse_blu, VRML_COLOR::diffuse_grn, VRML_COLOR::diffuse_red, IFSG_NODE::GetRawPtr(), NULL, IFSG_APPEARANCE::SetAmbient(), IFSG_APPEARANCE::SetDiffuse(), IFSG_APPEARANCE::SetShininess(), IFSG_APPEARANCE::SetSpecular(), IFSG_APPEARANCE::SetTransparency(), sgmaterial, VRML_COLOR::shiny, VRML_COLOR::spec_blu, VRML_COLOR::spec_grn, VRML_COLOR::spec_red, VRML_COLOR::transp, VRML_COLOR_LAST, and VRML_COLOR_PCB.

Referenced by create_vrml_plane(), and create_vrml_shell().

◆ vrml_text_callback()

static void vrml_text_callback ( int  x0,
int  y0,
int  xf,
int  yf,
void *  aData 
)
static

Definition at line 751 of file export_vrml.cpp.

752 {
753  LAYER_NUM m_text_layer = model_vrml->m_text_layer;
754  int m_text_width = model_vrml->m_text_width;
755 
756  export_vrml_line( *model_vrml, m_text_layer,
757  x0 * BOARD_SCALE, y0 * BOARD_SCALE,
758  xf * BOARD_SCALE, yf * BOARD_SCALE,
759  m_text_width * BOARD_SCALE );
760 }
static double BOARD_SCALE
Definition: export_vrml.cpp:65
static MODEL_VRML * model_vrml
int LAYER_NUM
This can be replaced with int and removed.
LAYER_NUM m_text_layer
static void export_vrml_line(MODEL_VRML &aModel, LAYER_NUM layer, double startx, double starty, double endx, double endy, double width)

References BOARD_SCALE, export_vrml_line(), MODEL_VRML::m_text_layer, MODEL_VRML::m_text_width, and model_vrml.

Referenced by export_vrml_fp_text(), and export_vrml_pcbtext().

◆ write_layers()

static void write_layers ( MODEL_VRML aModel,
BOARD aPcb,
const char *  aFileName,
OSTREAM aOutputFile 
)
static

Definition at line 403 of file export_vrml.cpp.

405 {
406  // VRML_LAYER board;
407  aModel.m_board.Tesselate( &aModel.m_holes );
408  double brdz = aModel.m_brd_thickness / 2.0
409  - ( Millimeter2iu( ART_OFFSET / 2.0 ) ) * BOARD_SCALE;
410 
411  if( USE_INLINES )
412  {
413  write_triangle_bag( *aOutputFile, aModel.GetColor( VRML_COLOR_PCB ),
414  &aModel.m_board, false, false, brdz, -brdz );
415  }
416  else
417  {
418  create_vrml_shell( aModel.m_OutputPCB, VRML_COLOR_PCB, &aModel.m_board, brdz, -brdz );
419  }
420 
421  if( aModel.m_plainPCB )
422  {
423  if( !USE_INLINES )
424  S3D::WriteVRML( aFileName, true, aModel.m_OutputPCB.GetRawPtr(), USE_DEFS, true );
425 
426  return;
427  }
428 
429  // VRML_LAYER m_top_copper;
430  aModel.m_top_copper.Tesselate( &aModel.m_holes );
431 
432  if( USE_INLINES )
433  {
434  write_triangle_bag( *aOutputFile, aModel.GetColor( VRML_COLOR_TRACK ),
435  &aModel.m_top_copper, true, true,
436  aModel.GetLayerZ( F_Cu ), 0 );
437  }
438  else
439  {
441  aModel.GetLayerZ( F_Cu ), true );
442  }
443 
444  // VRML_LAYER m_top_tin;
445  aModel.m_top_tin.Tesselate( &aModel.m_holes );
446 
447  if( USE_INLINES )
448  {
449  write_triangle_bag( *aOutputFile, aModel.GetColor( VRML_COLOR_TIN ),
450  &aModel.m_top_tin, true, true,
451  aModel.GetLayerZ( F_Cu ) + Millimeter2iu( ART_OFFSET / 2.0 ) * BOARD_SCALE,
452  0 );
453  }
454  else
455  {
457  aModel.GetLayerZ( F_Cu ) + Millimeter2iu( ART_OFFSET / 2.0 ) * BOARD_SCALE,
458  true );
459  }
460 
461  // VRML_LAYER m_bot_copper;
462  aModel.m_bot_copper.Tesselate( &aModel.m_holes );
463 
464  if( USE_INLINES )
465  {
466  write_triangle_bag( *aOutputFile, aModel.GetColor( VRML_COLOR_TRACK ),
467  &aModel.m_bot_copper, true, false,
468  aModel.GetLayerZ( B_Cu ), 0 );
469  }
470  else
471  {
473  aModel.GetLayerZ( B_Cu ), false );
474  }
475 
476  // VRML_LAYER m_bot_tin;
477  aModel.m_bot_tin.Tesselate( &aModel.m_holes );
478 
479  if( USE_INLINES )
480  {
481  write_triangle_bag( *aOutputFile, aModel.GetColor( VRML_COLOR_TIN ),
482  &aModel.m_bot_tin, true, false,
483  aModel.GetLayerZ( B_Cu )
484  - Millimeter2iu( ART_OFFSET / 2.0 ) * BOARD_SCALE,
485  0 );
486  }
487  else
488  {
490  aModel.GetLayerZ( B_Cu ) - Millimeter2iu( ART_OFFSET / 2.0 ) * BOARD_SCALE,
491  false );
492  }
493 
494  // VRML_LAYER PTH;
495  aModel.m_plated_holes.Tesselate( NULL, true );
496 
497  if( USE_INLINES )
498  {
499  write_triangle_bag( *aOutputFile, aModel.GetColor( VRML_COLOR_TIN ),
500  &aModel.m_plated_holes, false, false,
501  aModel.GetLayerZ( F_Cu ) + Millimeter2iu( ART_OFFSET / 2.0 ) * BOARD_SCALE,
502  aModel.GetLayerZ( B_Cu ) - Millimeter2iu( ART_OFFSET / 2.0 ) * BOARD_SCALE );
503  }
504  else
505  {
507  aModel.GetLayerZ( F_Cu ) + Millimeter2iu( ART_OFFSET / 2.0 ) * BOARD_SCALE,
508  aModel.GetLayerZ( B_Cu ) - Millimeter2iu( ART_OFFSET / 2.0 ) * BOARD_SCALE );
509  }
510 
511  // VRML_LAYER m_top_silk;
512  aModel.m_top_silk.Tesselate( &aModel.m_holes );
513 
514  if( USE_INLINES )
515  {
516  write_triangle_bag( *aOutputFile, aModel.GetColor( VRML_COLOR_SILK ), &aModel.m_top_silk,
517  true, true, aModel.GetLayerZ( F_SilkS ), 0 );
518  }
519  else
520  {
522  aModel.GetLayerZ( F_SilkS ), true );
523  }
524 
525  // VRML_LAYER m_bot_silk;
526  aModel.m_bot_silk.Tesselate( &aModel.m_holes );
527 
528  if( USE_INLINES )
529  {
530  write_triangle_bag( *aOutputFile, aModel.GetColor( VRML_COLOR_SILK ), &aModel.m_bot_silk,
531  true, false, aModel.GetLayerZ( B_SilkS ), 0 );
532  }
533  else
534  {
536  aModel.GetLayerZ( B_SilkS ), false );
537  }
538 
539  if( !USE_INLINES )
540  S3D::WriteVRML( aFileName, true, aModel.m_OutputPCB.GetRawPtr(), true, true );
541 }
static double BOARD_SCALE
Definition: export_vrml.cpp:65
static bool USE_INLINES
Definition: export_vrml.cpp:61
VRML_LAYER m_bot_tin
VRML_LAYER m_plated_holes
VRML_LAYER m_holes
static void create_vrml_plane(IFSG_TRANSFORM &PcbOutput, VRML_COLOR_INDEX colorID, VRML_LAYER *layer, double aHeight, bool aTopPlane)
IFSG_TRANSFORM m_OutputPCB
SGNODE * GetRawPtr(void) noexcept
Function GetRawPtr() returns the raw internal SGNODE pointer.
Definition: ifsg_node.cpp:66
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:81
VRML_LAYER m_bot_silk
VRML_LAYER m_top_silk
#define NULL
VRML_LAYER m_board
VRML_LAYER m_bot_copper
static void create_vrml_shell(IFSG_TRANSFORM &PcbOutput, VRML_COLOR_INDEX colorID, VRML_LAYER *layer, double top_z, double bottom_z)
static void write_triangle_bag(std::ostream &aOut_file, const VRML_COLOR &aColor, VRML_LAYER *aLayer, bool aPlane, bool aTop, double aTop_z, double aBottom_z)
double m_brd_thickness
static bool USE_DEFS
Definition: export_vrml.cpp:62
VRML_LAYER m_top_copper
VRML_LAYER m_top_tin
static constexpr int Millimeter2iu(double mm)
VRML_COLOR & GetColor(VRML_COLOR_INDEX aIndex)
double GetLayerZ(LAYER_NUM aLayer)
#define ART_OFFSET
Definition: export_vrml.cpp:56

References ART_OFFSET, B_Cu, B_SilkS, BOARD_SCALE, create_vrml_plane(), create_vrml_shell(), F_Cu, F_SilkS, MODEL_VRML::GetColor(), MODEL_VRML::GetLayerZ(), IFSG_NODE::GetRawPtr(), MODEL_VRML::m_board, MODEL_VRML::m_bot_copper, MODEL_VRML::m_bot_silk, MODEL_VRML::m_bot_tin, MODEL_VRML::m_brd_thickness, MODEL_VRML::m_holes, MODEL_VRML::m_OutputPCB, MODEL_VRML::m_plainPCB, MODEL_VRML::m_plated_holes, MODEL_VRML::m_top_copper, MODEL_VRML::m_top_silk, MODEL_VRML::m_top_tin, Millimeter2iu(), NULL, USE_DEFS, USE_INLINES, VRML_COLOR_PCB, VRML_COLOR_SILK, VRML_COLOR_TIN, VRML_COLOR_TRACK, write_triangle_bag(), and S3D::WriteVRML().

Referenced by PCB_EDIT_FRAME::ExportVRML_File().

◆ write_triangle_bag()

static void write_triangle_bag ( std::ostream &  aOut_file,
const VRML_COLOR aColor,
VRML_LAYER *  aLayer,
bool  aPlane,
bool  aTop,
double  aTop_z,
double  aBottom_z 
)
static

Definition at line 303 of file export_vrml.cpp.

306 {
307  /* A lot of nodes are not required, but blender sometimes chokes
308  * without them */
309  static const char* shape_boiler[] =
310  {
311  "Transform {\n",
312  " children [\n",
313  " Group {\n",
314  " children [\n",
315  " Shape {\n",
316  " appearance Appearance {\n",
317  " material Material {\n",
318  0, // Material marker
319  " }\n",
320  " }\n",
321  " geometry IndexedFaceSet {\n",
322  " solid TRUE\n",
323  " coord Coordinate {\n",
324  " point [\n",
325  0, // Coordinates marker
326  " ]\n",
327  " }\n",
328  " coordIndex [\n",
329  0, // Index marker
330  " ]\n",
331  " }\n",
332  " }\n",
333  " ]\n",
334  " }\n",
335  " ]\n",
336  "}\n",
337  0 // End marker
338  };
339 
340  int marker_found = 0, lineno = 0;
341 
342  while( marker_found < 4 )
343  {
344  if( shape_boiler[lineno] )
345  aOut_file << shape_boiler[lineno];
346  else
347  {
348  marker_found++;
349 
350  switch( marker_found )
351  {
352  case 1: // Material marker
353  aOut_file << " diffuseColor " << std::setprecision(3);
354  aOut_file << aColor.diffuse_red << " ";
355  aOut_file << aColor.diffuse_grn << " ";
356  aOut_file << aColor.diffuse_blu << "\n";
357 
358  aOut_file << " specularColor ";
359  aOut_file << aColor.spec_red << " ";
360  aOut_file << aColor.spec_grn << " ";
361  aOut_file << aColor.spec_blu << "\n";
362 
363  aOut_file << " emissiveColor ";
364  aOut_file << aColor.emit_red << " ";
365  aOut_file << aColor.emit_grn << " ";
366  aOut_file << aColor.emit_blu << "\n";
367 
368  aOut_file << " ambientIntensity " << aColor.ambient << "\n";
369  aOut_file << " transparency " << aColor.transp << "\n";
370  aOut_file << " shininess " << aColor.shiny << "\n";
371  break;
372 
373  case 2:
374 
375  if( aPlane )
376  aLayer->WriteVertices( aTop_z, aOut_file, PRECISION );
377  else
378  aLayer->Write3DVertices( aTop_z, aBottom_z, aOut_file, PRECISION );
379 
380  aOut_file << "\n";
381  break;
382 
383  case 3:
384 
385  if( aPlane )
386  aLayer->WriteIndices( aTop, aOut_file );
387  else
388  aLayer->Write3DIndices( aOut_file );
389 
390  aOut_file << "\n";
391  break;
392 
393  default:
394  break;
395  }
396  }
397 
398  lineno++;
399  }
400 }
float transp
Definition: export_vrml.cpp:85
float spec_blu
Definition: export_vrml.cpp:78
float ambient
Definition: export_vrml.cpp:84
float diffuse_grn
Definition: export_vrml.cpp:73
float spec_red
Definition: export_vrml.cpp:76
float spec_grn
Definition: export_vrml.cpp:77
float emit_grn
Definition: export_vrml.cpp:81
float emit_blu
Definition: export_vrml.cpp:82
float diffuse_red
Definition: export_vrml.cpp:72
static const int PRECISION
Definition: export_vrml.cpp:66
float emit_red
Definition: export_vrml.cpp:80
float diffuse_blu
Definition: export_vrml.cpp:74

References VRML_COLOR::ambient, VRML_COLOR::diffuse_blu, VRML_COLOR::diffuse_grn, VRML_COLOR::diffuse_red, VRML_COLOR::emit_blu, VRML_COLOR::emit_grn, VRML_COLOR::emit_red, PRECISION, VRML_COLOR::shiny, VRML_COLOR::spec_blu, VRML_COLOR::spec_grn, VRML_COLOR::spec_red, and VRML_COLOR::transp.

Referenced by write_layers().

Variable Documentation

◆ BOARD_SCALE

◆ cache

◆ colors

◆ model_vrml

◆ PRECISION

const int PRECISION = 6
static

◆ PROJ_DIR

wxString PROJ_DIR
static

Definition at line 68 of file export_vrml.cpp.

Referenced by PCB_EDIT_FRAME::ExportVRML_File().

◆ sgmaterial

SGNODE* sgmaterial[VRML_COLOR_LAST] = { NULL }
static

Definition at line 138 of file export_vrml.cpp.

Referenced by getSGColor(), and MODEL_VRML::~MODEL_VRML().

◆ SUBDIR_3D

wxString SUBDIR_3D
static

Definition at line 67 of file export_vrml.cpp.

Referenced by export_vrml_footprint(), and PCB_EDIT_FRAME::ExportVRML_File().

◆ USE_DEFS

bool USE_DEFS
static

◆ USE_INLINES

bool USE_INLINES
static

◆ USE_RELPATH

bool USE_RELPATH
static

Definition at line 63 of file export_vrml.cpp.

Referenced by export_vrml_footprint(), and PCB_EDIT_FRAME::ExportVRML_File().

◆ WORLD_SCALE

double WORLD_SCALE = 1.0
static

Definition at line 64 of file export_vrml.cpp.

Referenced by PCB_EDIT_FRAME::ExportVRML_File(), and MODEL_VRML::SetScale().