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 );
|
||||
|
||||
if( stricmp( text, "DEF" ) == 0 )
|
||||
if( stricmp( text, "DEF" ) == 0 || stricmp( text, "Group" ) == 0)
|
||||
{
|
||||
while( GetLine( file, line, &LineNum, 512 ) )
|
||||
{
|
||||
|
@ -144,7 +144,7 @@ int S3D_MASTER::ReadMaterial( FILE* file, int* LineNum )
|
|||
return 0;
|
||||
}
|
||||
|
||||
if( stricmp( command, "DEF" ) == 0 )
|
||||
if( stricmp( command, "DEF" ) == 0 || stricmp( command, "Material") == 0)
|
||||
{
|
||||
material = new S3D_MATERIAL( this, mat_name );
|
||||
|
||||
|
@ -478,6 +478,12 @@ int S3D_MASTER::ReadGeometry( FILE* file, int* LineNum )
|
|||
continue;
|
||||
}
|
||||
|
||||
if( stricmp( text, "solid" ) == 0 )
|
||||
{
|
||||
// ignore solid
|
||||
continue;
|
||||
}
|
||||
|
||||
if( stricmp( text, "colorIndex" ) == 0 )
|
||||
{
|
||||
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...
|
||||
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,
|
||||
FILE* aOutputFile, double aScalingFactor,
|
||||
FILE* aOutputFile,
|
||||
double aVRMLModelsToBiu,
|
||||
bool aExport3DFiles, const wxString & a3D_Subdir )
|
||||
{
|
||||
// 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, " scale %g %g %g\n",
|
||||
vrmlm->m_MatScale.x * aScalingFactor,
|
||||
vrmlm->m_MatScale.y * aScalingFactor,
|
||||
vrmlm->m_MatScale.z * aScalingFactor );
|
||||
|
||||
// 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;
|
||||
// adjust 3D shape offset position
|
||||
int offsetx = vrmlm->m_MatPosition.x;
|
||||
int offsety = vrmlm->m_MatPosition.y;
|
||||
double offsetz = vrmlm->m_MatPosition.z;
|
||||
|
||||
if ( isFlipped )
|
||||
NEGATE(offsetz);
|
||||
|
@ -1168,6 +1209,12 @@ static void export_vrml_module( BOARD* aPcb, MODULE* aModule,
|
|||
(double) (offsetx + aModule->m_Pos.x),
|
||||
- (double)(offsety + aModule->m_Pos.y), // Y axis is reversed in Pcbnew
|
||||
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,
|
||||
" children [\n Inline {\n url \"%s\"\n } ]\n",
|
||||
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
|
||||
* Creates the file(s) exporting current BOARD to a VRML file.
|
||||
* @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 a3D_Subdir = sub directory where 3D shapes files are copied
|
||||
* used only when aExport3DFiles == true
|
||||
* @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.
|
||||
* 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,
|
||||
double aScale, bool aExport3DFiles,
|
||||
double aMMtoWRMLunit, bool aExport3DFiles,
|
||||
const wxString & a3D_Subdir )
|
||||
{
|
||||
wxString msg;
|
||||
|
@ -1266,42 +1281,30 @@ bool PCB_EDIT_FRAME::ExportVRML_File( const wxString & aFullFileName,
|
|||
" title \"%s - Generated by Pcbnew\"\n"
|
||||
"}\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
|
||||
* fix it. For example here we build the world in inches...
|
||||
*/
|
||||
|
||||
/* scaling factor to convert internal units (decimils) to inches
|
||||
*/
|
||||
double board_scaling_factor = 0.001*MILS_PER_IU;
|
||||
|
||||
/* auxiliary scale to export to a different scale.
|
||||
*/
|
||||
double general_scaling_factor = board_scaling_factor * aScale;
|
||||
// Global VRML scale to export to a different scale.
|
||||
// (aMMtoWRMLScale = 1.0 to export in mm)
|
||||
double boardIU2WRML = aMMtoWRMLunit / MM_PER_IU;
|
||||
fprintf( output_file, "Transform {\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
|
||||
* more easy for rotations...
|
||||
*/
|
||||
EDA_RECT bbbox = pcb->ComputeBoundingBox();
|
||||
|
||||
double dx = board_scaling_factor * bbbox.Centre().x * aScale;
|
||||
double dy = board_scaling_factor * bbbox.Centre().y * aScale;
|
||||
double dx = boardIU2WRML * bbbox.Centre().x;
|
||||
double dy = boardIU2WRML * bbbox.Centre().y;
|
||||
|
||||
fprintf( output_file, " translation %g %g 0.0\n", -dx, dy );
|
||||
|
||||
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
|
||||
compute_layer_Zs( pcb );
|
||||
|
||||
|
@ -1315,6 +1318,13 @@ bool PCB_EDIT_FRAME::ExportVRML_File( const wxString & aFullFileName,
|
|||
/* 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
|
||||
for( MODULE* module = pcb->m_Modules; module != 0; module = module->Next() )
|
||||
export_vrml_module( pcb, module, output_file,
|
||||
|
|
Loading…
Reference in New Issue