3D viewer: allows import of models created with openscad and convertedvia meshconv to wrl (thanks to Georg Gast <georg@schorsch-tech.de>)
Export VRML: fix scaling issue for pcbnew - nanometers.
This commit is contained in:
parent
0fedf6b3eb
commit
5c2efcbf3e
|
@ -93,7 +93,7 @@ int S3D_MASTER::ReadData()
|
||||||
{
|
{
|
||||||
text = strtok( line, sep_chars );
|
text = strtok( line, sep_chars );
|
||||||
|
|
||||||
if( stricmp( text, "DEF" ) == 0 )
|
if( stricmp( text, "DEF" ) == 0 || stricmp( text, "Group" ) == 0)
|
||||||
{
|
{
|
||||||
while( GetLine( file, line, &LineNum, 512 ) )
|
while( GetLine( file, line, &LineNum, 512 ) )
|
||||||
{
|
{
|
||||||
|
@ -144,7 +144,7 @@ int S3D_MASTER::ReadMaterial( FILE* file, int* LineNum )
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( stricmp( command, "DEF" ) == 0 )
|
if( stricmp( command, "DEF" ) == 0 || stricmp( command, "Material") == 0)
|
||||||
{
|
{
|
||||||
material = new S3D_MATERIAL( this, mat_name );
|
material = new S3D_MATERIAL( this, mat_name );
|
||||||
|
|
||||||
|
@ -478,6 +478,12 @@ int S3D_MASTER::ReadGeometry( FILE* file, int* LineNum )
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( stricmp( text, "solid" ) == 0 )
|
||||||
|
{
|
||||||
|
// ignore solid
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if( stricmp( text, "colorIndex" ) == 0 )
|
if( stricmp( text, "colorIndex" ) == 0 )
|
||||||
{
|
{
|
||||||
while( GetLine( file, line, LineNum, 512 ) )
|
while( GetLine( file, line, LineNum, 512 ) )
|
||||||
|
|
|
@ -96,6 +96,52 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function OnExportVRML
|
||||||
|
* will export the current BOARD to a VRML file.
|
||||||
|
*/
|
||||||
|
void PCB_EDIT_FRAME::OnExportVRML( wxCommandEvent& event )
|
||||||
|
{
|
||||||
|
wxFileName fn;
|
||||||
|
static wxString subDirFor3Dshapes = wxT("shapes3D");
|
||||||
|
|
||||||
|
// The general VRML scale factor
|
||||||
|
// Assuming the VRML default unit is the mm
|
||||||
|
// this is the mm to VRML scaling factor for inch, mm and meter
|
||||||
|
double scaleList[3] = { 1.0/25.4, 1, 0.001 };
|
||||||
|
|
||||||
|
// Build default file name
|
||||||
|
wxString ext = wxT( "wrl" );
|
||||||
|
fn = GetBoard()->GetFileName();
|
||||||
|
fn.SetExt( ext );
|
||||||
|
|
||||||
|
DIALOG_EXPORT_3DFILE dlg( this );
|
||||||
|
dlg.FilePicker()->SetPath( fn.GetFullPath() );
|
||||||
|
dlg.SetSubdir( subDirFor3Dshapes );
|
||||||
|
|
||||||
|
if( dlg.ShowModal() != wxID_OK )
|
||||||
|
return;
|
||||||
|
|
||||||
|
double scale = scaleList[dlg.GetUnits( )]; // final scale export
|
||||||
|
bool export3DFiles = dlg.Get3DFilesOption( ) == 0;
|
||||||
|
|
||||||
|
wxBusyCursor dummy;
|
||||||
|
|
||||||
|
wxString fullFilename = dlg.FilePicker()->GetPath();
|
||||||
|
subDirFor3Dshapes = dlg.GetSubdir();
|
||||||
|
|
||||||
|
if( ! wxDirExists( subDirFor3Dshapes ) )
|
||||||
|
wxMkdir( subDirFor3Dshapes );
|
||||||
|
|
||||||
|
if( ! ExportVRML_File( fullFilename, scale, export3DFiles, subDirFor3Dshapes ) )
|
||||||
|
{
|
||||||
|
wxString msg = _( "Unable to create " ) + fullFilename;
|
||||||
|
wxMessageBox( msg );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// I use this a lot...
|
// I use this a lot...
|
||||||
static const double PI2 = M_PI / 2;
|
static const double PI2 = M_PI / 2;
|
||||||
|
|
||||||
|
@ -1050,7 +1096,8 @@ static void compose_quat( double q1[4], double q2[4], double qr[4] )
|
||||||
|
|
||||||
|
|
||||||
static void export_vrml_module( BOARD* aPcb, MODULE* aModule,
|
static void export_vrml_module( BOARD* aPcb, MODULE* aModule,
|
||||||
FILE* aOutputFile, double aScalingFactor,
|
FILE* aOutputFile,
|
||||||
|
double aVRMLModelsToBiu,
|
||||||
bool aExport3DFiles, const wxString & a3D_Subdir )
|
bool aExport3DFiles, const wxString & a3D_Subdir )
|
||||||
{
|
{
|
||||||
// Reference and value
|
// Reference and value
|
||||||
|
@ -1146,16 +1193,10 @@ static void export_vrml_module( BOARD* aPcb, MODULE* aModule,
|
||||||
fprintf( aOutputFile, " rotation %g %g %g %g\n", rot[0], rot[1], rot[2], rot[3] );
|
fprintf( aOutputFile, " rotation %g %g %g %g\n", rot[0], rot[1], rot[2], rot[3] );
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf( aOutputFile, " scale %g %g %g\n",
|
// adjust 3D shape offset position
|
||||||
vrmlm->m_MatScale.x * aScalingFactor,
|
int offsetx = vrmlm->m_MatPosition.x;
|
||||||
vrmlm->m_MatScale.y * aScalingFactor,
|
int offsety = vrmlm->m_MatPosition.y;
|
||||||
vrmlm->m_MatScale.z * aScalingFactor );
|
double offsetz = vrmlm->m_MatPosition.z;
|
||||||
|
|
||||||
// adjust 3D shape offset position (offset is given in inch)
|
|
||||||
#define UNITS_3D_TO_PCB_UNITS (IU_PER_MILS*1000)
|
|
||||||
int offsetx = KiROUND( vrmlm->m_MatPosition.x * UNITS_3D_TO_PCB_UNITS );
|
|
||||||
int offsety = KiROUND( vrmlm->m_MatPosition.y * UNITS_3D_TO_PCB_UNITS );
|
|
||||||
double offsetz = vrmlm->m_MatPosition.z * UNITS_3D_TO_PCB_UNITS;
|
|
||||||
|
|
||||||
if ( isFlipped )
|
if ( isFlipped )
|
||||||
NEGATE(offsetz);
|
NEGATE(offsetz);
|
||||||
|
@ -1168,6 +1209,12 @@ static void export_vrml_module( BOARD* aPcb, MODULE* aModule,
|
||||||
(double) (offsetx + aModule->m_Pos.x),
|
(double) (offsetx + aModule->m_Pos.x),
|
||||||
- (double)(offsety + aModule->m_Pos.y), // Y axis is reversed in Pcbnew
|
- (double)(offsety + aModule->m_Pos.y), // Y axis is reversed in Pcbnew
|
||||||
offsetz + layer_z[aModule->GetLayer()] );
|
offsetz + layer_z[aModule->GetLayer()] );
|
||||||
|
|
||||||
|
fprintf( aOutputFile, " scale %g %g %g\n",
|
||||||
|
vrmlm->m_MatScale.x * aVRMLModelsToBiu,
|
||||||
|
vrmlm->m_MatScale.y * aVRMLModelsToBiu,
|
||||||
|
vrmlm->m_MatScale.z * aVRMLModelsToBiu );
|
||||||
|
|
||||||
fprintf( aOutputFile,
|
fprintf( aOutputFile,
|
||||||
" children [\n Inline {\n url \"%s\"\n } ]\n",
|
" children [\n Inline {\n url \"%s\"\n } ]\n",
|
||||||
TO_UTF8( fname ) );
|
TO_UTF8( fname ) );
|
||||||
|
@ -1185,64 +1232,32 @@ static void write_and_empty_triangle_bag( FILE* output_file, TriangleBag& triang
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function OnExportVRML
|
|
||||||
* will export the current BOARD to a VRML file.
|
|
||||||
*/
|
|
||||||
void PCB_EDIT_FRAME::OnExportVRML( wxCommandEvent& event )
|
|
||||||
{
|
|
||||||
wxFileName fn;
|
|
||||||
static wxString subDirFor3Dshapes = wxT("shapes3D");
|
|
||||||
double scaleList[3] = { 1.0, 25.4, 25.4/1000 };
|
|
||||||
|
|
||||||
// Build default file name
|
|
||||||
wxString ext = wxT( "wrl" );
|
|
||||||
fn = GetBoard()->GetFileName();
|
|
||||||
fn.SetExt( ext );
|
|
||||||
|
|
||||||
DIALOG_EXPORT_3DFILE dlg( this );
|
|
||||||
dlg.FilePicker()->SetPath( fn.GetFullPath() );
|
|
||||||
dlg.SetSubdir( subDirFor3Dshapes );
|
|
||||||
|
|
||||||
if( dlg.ShowModal() != wxID_OK )
|
|
||||||
return;
|
|
||||||
|
|
||||||
double scale = scaleList[dlg.GetUnits( )]; // final scale export
|
|
||||||
bool export3DFiles = dlg.Get3DFilesOption( ) == 0;
|
|
||||||
|
|
||||||
wxBusyCursor dummy;
|
|
||||||
|
|
||||||
wxString fullFilename = dlg.FilePicker()->GetPath();
|
|
||||||
subDirFor3Dshapes = dlg.GetSubdir();
|
|
||||||
|
|
||||||
if( ! wxDirExists( subDirFor3Dshapes ) )
|
|
||||||
wxMkdir( subDirFor3Dshapes );
|
|
||||||
|
|
||||||
if( ! ExportVRML_File( fullFilename, scale, export3DFiles, subDirFor3Dshapes ) )
|
|
||||||
{
|
|
||||||
wxString msg = _( "Unable to create " ) + fullFilename;
|
|
||||||
wxMessageBox( msg );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function ExportVRML_File
|
* Function ExportVRML_File
|
||||||
* Creates the file(s) exporting current BOARD to a VRML file.
|
* Creates the file(s) exporting current BOARD to a VRML file.
|
||||||
* @param aFullFileName = the full filename of the file to create
|
* @param aFullFileName = the full filename of the file to create
|
||||||
* @param aScale = the general scaling factor. 1.0 to export in inch
|
* @param aMMtoWRMLunit = the general scaling factor. 1.0 to export in mm
|
||||||
* @param aExport3DFiles = true to copy 3D shapes in the subdir a3D_Subdir
|
* @param aExport3DFiles = true to copy 3D shapes in the subdir a3D_Subdir
|
||||||
* @param a3D_Subdir = sub directory where 3D shapes files are copied
|
* @param a3D_Subdir = sub directory where 3D shapes files are copied
|
||||||
* used only when aExport3DFiles == true
|
* used only when aExport3DFiles == true
|
||||||
* @return true if Ok.
|
* @return true if Ok.
|
||||||
*/
|
*/
|
||||||
/* When copying 3D shapes files, the new filename is build from
|
/* Note1:
|
||||||
|
* When copying 3D shapes files, the new filename is build from
|
||||||
* the full path name, changing the separators by underscore.
|
* the full path name, changing the separators by underscore.
|
||||||
* this is needed because files with the same shortname can exist in different directories
|
* this is needed because files with the same shortname can exist in different directories
|
||||||
|
* Note 2:
|
||||||
|
* ExportVRML_File generates coordinates in board units (BIU) inside the file.
|
||||||
|
* (TODO: use mm inside the file)
|
||||||
|
* A general scale transform is applied to the whole file
|
||||||
|
* (1.0 to have the actual WRML unit im mm, 0.001 to have the actual WRML unit im meter
|
||||||
|
* Note 3:
|
||||||
|
* For 3D models built by a 3D modeler, the unit is 0,1 inch
|
||||||
|
* A specfic scale is applied to 3D models to convert them to BIU
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
bool PCB_EDIT_FRAME::ExportVRML_File( const wxString & aFullFileName,
|
bool PCB_EDIT_FRAME::ExportVRML_File( const wxString & aFullFileName,
|
||||||
double aScale, bool aExport3DFiles,
|
double aMMtoWRMLunit, bool aExport3DFiles,
|
||||||
const wxString & a3D_Subdir )
|
const wxString & a3D_Subdir )
|
||||||
{
|
{
|
||||||
wxString msg;
|
wxString msg;
|
||||||
|
@ -1266,42 +1281,30 @@ bool PCB_EDIT_FRAME::ExportVRML_File( const wxString & aFullFileName,
|
||||||
" title \"%s - Generated by Pcbnew\"\n"
|
" title \"%s - Generated by Pcbnew\"\n"
|
||||||
"}\n", TO_UTF8( name ) );
|
"}\n", TO_UTF8( name ) );
|
||||||
|
|
||||||
/* The would be in decimils and not in meters, as the standard wants.
|
/* The would be in BIU and not in meters, as the standard wants.
|
||||||
* It is trivial to embed everything in a transform node to
|
* It is trivial to embed everything in a transform node to
|
||||||
* fix it. For example here we build the world in inches...
|
* fix it. For example here we build the world in inches...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* scaling factor to convert internal units (decimils) to inches
|
// Global VRML scale to export to a different scale.
|
||||||
*/
|
// (aMMtoWRMLScale = 1.0 to export in mm)
|
||||||
double board_scaling_factor = 0.001*MILS_PER_IU;
|
double boardIU2WRML = aMMtoWRMLunit / MM_PER_IU;
|
||||||
|
|
||||||
/* auxiliary scale to export to a different scale.
|
|
||||||
*/
|
|
||||||
double general_scaling_factor = board_scaling_factor * aScale;
|
|
||||||
fprintf( output_file, "Transform {\n" );
|
fprintf( output_file, "Transform {\n" );
|
||||||
fprintf( output_file, " scale %g %g %g\n",
|
fprintf( output_file, " scale %g %g %g\n",
|
||||||
general_scaling_factor, general_scaling_factor, general_scaling_factor );
|
boardIU2WRML , boardIU2WRML, boardIU2WRML );
|
||||||
|
|
||||||
/* Define the translation to have the board centre to the 2D axis origin
|
/* Define the translation to have the board centre to the 2D axis origin
|
||||||
* more easy for rotations...
|
* more easy for rotations...
|
||||||
*/
|
*/
|
||||||
EDA_RECT bbbox = pcb->ComputeBoundingBox();
|
EDA_RECT bbbox = pcb->ComputeBoundingBox();
|
||||||
|
|
||||||
double dx = board_scaling_factor * bbbox.Centre().x * aScale;
|
double dx = boardIU2WRML * bbbox.Centre().x;
|
||||||
double dy = board_scaling_factor * bbbox.Centre().y * aScale;
|
double dy = boardIU2WRML * bbbox.Centre().y;
|
||||||
|
|
||||||
fprintf( output_file, " translation %g %g 0.0\n", -dx, dy );
|
fprintf( output_file, " translation %g %g 0.0\n", -dx, dy );
|
||||||
|
|
||||||
fprintf( output_file, " children [\n" );
|
fprintf( output_file, " children [\n" );
|
||||||
|
|
||||||
/* scaling factor to convert 3D models to board units (decimils)
|
|
||||||
* Usually we use Wings3D to create thems.
|
|
||||||
* One can consider the 3D units is 0.1 inch
|
|
||||||
* So the scaling factor from 0.1 inch to board units
|
|
||||||
* is 0.1 / board_scaling_factor
|
|
||||||
*/
|
|
||||||
|
|
||||||
double wrml_3D_models_scaling_factor = 0.1 / board_scaling_factor;
|
|
||||||
// Preliminary computation: the z value for each layer
|
// Preliminary computation: the z value for each layer
|
||||||
compute_layer_Zs( pcb );
|
compute_layer_Zs( pcb );
|
||||||
|
|
||||||
|
@ -1315,6 +1318,13 @@ bool PCB_EDIT_FRAME::ExportVRML_File( const wxString & aFullFileName,
|
||||||
/* TODO export_vrml_zones(pcb);
|
/* TODO export_vrml_zones(pcb);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* scaling factor to convert 3D models to board units (decimils)
|
||||||
|
* Usually we use Wings3D to create thems.
|
||||||
|
* One can consider the 3D units is 0.1 inch (2.54 mm)
|
||||||
|
* So the scaling factor from 0.1 inch to board units
|
||||||
|
* is 0.1 / general_scaling_factor
|
||||||
|
*/
|
||||||
|
double wrml_3D_models_scaling_factor = 2.54 / boardIU2WRML;
|
||||||
// Export footprints
|
// Export footprints
|
||||||
for( MODULE* module = pcb->m_Modules; module != 0; module = module->Next() )
|
for( MODULE* module = pcb->m_Modules; module != 0; module = module->Next() )
|
||||||
export_vrml_module( pcb, module, output_file,
|
export_vrml_module( pcb, module, output_file,
|
||||||
|
|
Loading…
Reference in New Issue