Fixes for 3D model offset

- Display offset units in 3D preview window (inches or mm)
- Fix offset in 3D renderer
- Fix offset in Raytracing renderer
- Fix offset in STEP export
- Fix offset in VRML export
This commit is contained in:
Oliver 2017-11-08 20:56:57 +11:00 committed by Wayne Stambaugh
parent 422b7dd551
commit b80449b069
10 changed files with 89 additions and 54 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Aug 4 2017) // C++ code generated with wxFormBuilder (version Mar 22 2017)
// http://www.wxformbuilder.org/ // http://www.wxformbuilder.org/
// //
// PLEASE DO "NOT" EDIT THIS FILE! // PLEASE DO "NOT" EDIT THIS FILE!
@ -40,7 +40,7 @@ PANEL_PREV_3D_BASE::PANEL_PREV_3D_BASE( wxWindow* parent, wxWindowID id, const w
fgSizerScale->Add( m_staticText2, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); fgSizerScale->Add( m_staticText2, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
yscale = new wxTextCtrl( vbScale->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); yscale = new wxTextCtrl( vbScale->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerScale->Add( yscale, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); fgSizerScale->Add( yscale, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP, 5 );
m_spinYscale = new wxSpinButton( vbScale->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_VERTICAL ); m_spinYscale = new wxSpinButton( vbScale->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_VERTICAL );
fgSizerScale->Add( m_spinYscale, 0, wxALIGN_CENTER_VERTICAL, 5 ); fgSizerScale->Add( m_spinYscale, 0, wxALIGN_CENTER_VERTICAL, 5 );
@ -53,7 +53,7 @@ PANEL_PREV_3D_BASE::PANEL_PREV_3D_BASE( wxWindow* parent, wxWindowID id, const w
fgSizerScale->Add( zscale, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 5 ); fgSizerScale->Add( zscale, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 5 );
m_spinZscale = new wxSpinButton( vbScale->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_VERTICAL ); m_spinZscale = new wxSpinButton( vbScale->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_VERTICAL );
fgSizerScale->Add( m_spinZscale, 0, wxALIGN_CENTER_VERTICAL, 5 ); fgSizerScale->Add( m_spinZscale, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM, 5 );
vbScale->Add( fgSizerScale, 1, wxEXPAND, 5 ); vbScale->Add( fgSizerScale, 1, wxEXPAND, 5 );
@ -100,7 +100,7 @@ PANEL_PREV_3D_BASE::PANEL_PREV_3D_BASE( wxWindow* parent, wxWindowID id, const w
#else #else
yrot->SetMaxLength( 9 ); yrot->SetMaxLength( 9 );
#endif #endif
fgSizerRotate->Add( yrot, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); fgSizerRotate->Add( yrot, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP, 5 );
m_spinYrot = new wxSpinButton( vbRotate->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_VERTICAL ); m_spinYrot = new wxSpinButton( vbRotate->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_VERTICAL );
fgSizerRotate->Add( m_spinYrot, 0, wxALIGN_CENTER_VERTICAL, 5 ); fgSizerRotate->Add( m_spinYrot, 0, wxALIGN_CENTER_VERTICAL, 5 );
@ -121,7 +121,7 @@ PANEL_PREV_3D_BASE::PANEL_PREV_3D_BASE( wxWindow* parent, wxWindowID id, const w
fgSizerRotate->Add( zrot, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 5 ); fgSizerRotate->Add( zrot, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 5 );
m_spinZrot = new wxSpinButton( vbRotate->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_VERTICAL ); m_spinZrot = new wxSpinButton( vbRotate->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_VERTICAL );
fgSizerRotate->Add( m_spinZrot, 0, wxALIGN_CENTER_VERTICAL, 5 ); fgSizerRotate->Add( m_spinZrot, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM, 5 );
vbRotate->Add( fgSizerRotate, 1, wxEXPAND, 5 ); vbRotate->Add( fgSizerRotate, 1, wxEXPAND, 5 );
@ -129,7 +129,6 @@ PANEL_PREV_3D_BASE::PANEL_PREV_3D_BASE( wxWindow* parent, wxWindowID id, const w
bSizerLeft->Add( vbRotate, 0, wxEXPAND, 5 ); bSizerLeft->Add( vbRotate, 0, wxEXPAND, 5 );
wxStaticBoxSizer* vbOffset;
vbOffset = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Offset") ), wxVERTICAL ); vbOffset = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Offset") ), wxVERTICAL );
wxFlexGridSizer* fgSizerOffset; wxFlexGridSizer* fgSizerOffset;
@ -152,7 +151,7 @@ PANEL_PREV_3D_BASE::PANEL_PREV_3D_BASE( wxWindow* parent, wxWindowID id, const w
fgSizerOffset->Add( m_staticText22, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); fgSizerOffset->Add( m_staticText22, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
yoff = new wxTextCtrl( vbOffset->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); yoff = new wxTextCtrl( vbOffset->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerOffset->Add( yoff, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); fgSizerOffset->Add( yoff, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP, 5 );
m_spinYoffset = new wxSpinButton( vbOffset->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_VERTICAL ); m_spinYoffset = new wxSpinButton( vbOffset->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_VERTICAL );
fgSizerOffset->Add( m_spinYoffset, 0, wxALIGN_CENTER_VERTICAL, 5 ); fgSizerOffset->Add( m_spinYoffset, 0, wxALIGN_CENTER_VERTICAL, 5 );
@ -165,7 +164,7 @@ PANEL_PREV_3D_BASE::PANEL_PREV_3D_BASE( wxWindow* parent, wxWindowID id, const w
fgSizerOffset->Add( zoff, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 5 ); fgSizerOffset->Add( zoff, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 5 );
m_spinZoffset = new wxSpinButton( vbOffset->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_VERTICAL ); m_spinZoffset = new wxSpinButton( vbOffset->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS|wxSP_VERTICAL );
fgSizerOffset->Add( m_spinZoffset, 0, wxALIGN_CENTER_VERTICAL, 5 ); fgSizerOffset->Add( m_spinZoffset, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM, 5 );
vbOffset->Add( fgSizerOffset, 1, wxEXPAND, 5 ); vbOffset->Add( fgSizerOffset, 1, wxEXPAND, 5 );

View File

@ -464,7 +464,7 @@
</object> </object>
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="1">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT</property> <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP</property>
<property name="proportion">0</property> <property name="proportion">0</property>
<object class="wxTextCtrl" expanded="1"> <object class="wxTextCtrl" expanded="1">
<property name="BottomDockable">1</property> <property name="BottomDockable">1</property>
@ -813,7 +813,7 @@
</object> </object>
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="1">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL</property> <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM</property>
<property name="proportion">0</property> <property name="proportion">0</property>
<object class="wxSpinButton" expanded="1"> <object class="wxSpinButton" expanded="1">
<property name="BottomDockable">1</property> <property name="BottomDockable">1</property>
@ -1271,7 +1271,7 @@
</object> </object>
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="1">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT</property> <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP</property>
<property name="proportion">0</property> <property name="proportion">0</property>
<object class="wxTextCtrl" expanded="1"> <object class="wxTextCtrl" expanded="1">
<property name="BottomDockable">1</property> <property name="BottomDockable">1</property>
@ -1620,7 +1620,7 @@
</object> </object>
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="1">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL</property> <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM</property>
<property name="proportion">0</property> <property name="proportion">0</property>
<object class="wxSpinButton" expanded="1"> <object class="wxSpinButton" expanded="1">
<property name="BottomDockable">1</property> <property name="BottomDockable">1</property>
@ -1717,7 +1717,7 @@
<property name="name">vbOffset</property> <property name="name">vbOffset</property>
<property name="orient">wxVERTICAL</property> <property name="orient">wxVERTICAL</property>
<property name="parent">1</property> <property name="parent">1</property>
<property name="permission">none</property> <property name="permission">protected</property>
<event name="OnUpdateUI"></event> <event name="OnUpdateUI"></event>
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="1">
<property name="border">5</property> <property name="border">5</property>
@ -2078,7 +2078,7 @@
</object> </object>
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="1">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT</property> <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT|wxTOP</property>
<property name="proportion">0</property> <property name="proportion">0</property>
<object class="wxTextCtrl" expanded="1"> <object class="wxTextCtrl" expanded="1">
<property name="BottomDockable">1</property> <property name="BottomDockable">1</property>
@ -2120,7 +2120,7 @@
<property name="pane_border">1</property> <property name="pane_border">1</property>
<property name="pane_position"></property> <property name="pane_position"></property>
<property name="pane_size"></property> <property name="pane_size"></property>
<property name="permission">protected</property> <property name="permission">public</property>
<property name="pin_button">1</property> <property name="pin_button">1</property>
<property name="pos"></property> <property name="pos"></property>
<property name="resize">Resizable</property> <property name="resize">Resizable</property>
@ -2427,7 +2427,7 @@
</object> </object>
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="1">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL</property> <property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM</property>
<property name="proportion">0</property> <property name="proportion">0</property>
<object class="wxSpinButton" expanded="1"> <object class="wxSpinButton" expanded="1">
<property name="BottomDockable">1</property> <property name="BottomDockable">1</property>

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Aug 4 2017) // C++ code generated with wxFormBuilder (version Mar 22 2017)
// http://www.wxformbuilder.org/ // http://www.wxformbuilder.org/
// //
// PLEASE DO "NOT" EDIT THIS FILE! // PLEASE DO "NOT" EDIT THIS FILE!
@ -57,11 +57,11 @@ class PANEL_PREV_3D_BASE : public wxPanel
wxStaticText* m_staticText31; wxStaticText* m_staticText31;
wxTextCtrl* zrot; wxTextCtrl* zrot;
wxSpinButton* m_spinZrot; wxSpinButton* m_spinZrot;
wxStaticBoxSizer* vbOffset;
wxStaticText* m_staticText12; wxStaticText* m_staticText12;
wxTextCtrl* xoff; wxTextCtrl* xoff;
wxSpinButton* m_spinXoffset; wxSpinButton* m_spinXoffset;
wxStaticText* m_staticText22; wxStaticText* m_staticText22;
wxTextCtrl* yoff;
wxSpinButton* m_spinYoffset; wxSpinButton* m_spinYoffset;
wxStaticText* m_staticText32; wxStaticText* m_staticText32;
wxTextCtrl* zoff; wxTextCtrl* zoff;
@ -99,6 +99,7 @@ class PANEL_PREV_3D_BASE : public wxPanel
public: public:
wxTextCtrl* yoff;
PANEL_PREV_3D_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 503,371 ), long style = wxTAB_TRAVERSAL ); PANEL_PREV_3D_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 503,371 ), long style = wxTAB_TRAVERSAL );
~PANEL_PREV_3D_BASE(); ~PANEL_PREV_3D_BASE();

View File

@ -125,7 +125,29 @@ void PANEL_PREV_3D::initPanel()
}; };
for( int ii = 0; ii < 9; ii++ ) for( int ii = 0; ii < 9; ii++ )
{
spinButtonList[ii]->SetRange( INT_MIN, INT_MAX ); spinButtonList[ii]->SetRange( INT_MIN, INT_MAX );
}
wxString units;
switch( g_UserUnit )
{
case INCHES:
units = _( "inches" );
break;
case MILLIMETRES:
units = _( "mm" );
break;
default:
break;
}
if( !units.IsEmpty() )
{
units = wxString::Format( _( "Offset (%s)" ), units );
vbOffset->GetStaticBox()->SetLabel( units );
}
} }
@ -214,26 +236,26 @@ void PANEL_PREV_3D::SetModelDataIdx( int idx, bool aReloadPreviewModule )
yrot->SetValue( wxString::Format( "%.2f", aModel->m_Rotation.y ) ); yrot->SetValue( wxString::Format( "%.2f", aModel->m_Rotation.y ) );
zrot->SetValue( wxString::Format( "%.2f", aModel->m_Rotation.z ) ); zrot->SetValue( wxString::Format( "%.2f", aModel->m_Rotation.z ) );
// Convert from internal units (mm) to user units
double scaler = 1;
switch( g_UserUnit ) switch( g_UserUnit )
{ {
case MILLIMETRES: case MILLIMETRES:
xoff->SetValue( wxString::Format( "%.4f", aModel->m_Offset.x * 25.4 ) ); scaler = 1.0f;
yoff->SetValue( wxString::Format( "%.4f", aModel->m_Offset.y * 25.4 ) );
zoff->SetValue( wxString::Format( "%.4f", aModel->m_Offset.z * 25.4 ) );
break; break;
case INCHES: case INCHES:
xoff->SetValue( wxString::Format( "%.4f", aModel->m_Offset.x ) ); scaler = 25.4f;
yoff->SetValue( wxString::Format( "%.4f", aModel->m_Offset.y ) );
zoff->SetValue( wxString::Format( "%.4f", aModel->m_Offset.z ) );
break; break;
case DEGREES:
case UNSCALED_UNITS:
default: default:
wxASSERT(0); wxASSERT( 0 );
} }
xoff->SetValue( wxString::Format( "%.4f", aModel->m_Offset.x / scaler ) );
yoff->SetValue( wxString::Format( "%.4f", aModel->m_Offset.y / scaler ) );
zoff->SetValue( wxString::Format( "%.4f", aModel->m_Offset.z / scaler ) );
UpdateModelName( aModel->m_Filename ); UpdateModelName( aModel->m_Filename );
if( aReloadPreviewModule && m_previewPane ) if( aReloadPreviewModule && m_previewPane )
@ -249,7 +271,9 @@ void PANEL_PREV_3D::SetModelDataIdx( int idx, bool aReloadPreviewModule )
} }
if( m_previewPane ) if( m_previewPane )
{
m_previewPane->SetFocus(); m_previewPane->SetFocus();
}
return; return;
} }
@ -565,25 +589,26 @@ void PANEL_PREV_3D::getOrientationVars( SGPOINT& aScale, SGPOINT& aRotation, SGP
yoff->GetValue().ToDouble( &aOffset.y ); yoff->GetValue().ToDouble( &aOffset.y );
zoff->GetValue().ToDouble( &aOffset.z ); zoff->GetValue().ToDouble( &aOffset.z );
// Convert from user units to internal units (mm)
double scaler = 1.0f;
switch( g_UserUnit ) switch( g_UserUnit )
{ {
case MILLIMETRES: case MILLIMETRES:
// Convert to Inches. Offset is stored in inches. scaler = 1.0f;
aOffset.x = aOffset.x / 25.4;
aOffset.y = aOffset.y / 25.4;
aOffset.z = aOffset.z / 25.4;
break; break;
case INCHES: case INCHES:
// It is already in Inches scaler = 25.4f;
break; break;
case DEGREES:
case UNSCALED_UNITS:
default: default:
wxASSERT(0); wxASSERT( 0 );
} }
aOffset.x *= scaler;
aOffset.y *= scaler;
aOffset.z *= scaler;
return; return;
} }

View File

@ -1046,9 +1046,7 @@ void C3D_RENDER_OGL_LEGACY::render_3D_module( const MODULE* module,
{ {
glPushMatrix(); glPushMatrix();
glTranslatef( sM->m_Offset.x * 25.4f, glTranslatef( sM->m_Offset.x, sM->m_Offset.y, sM->m_Offset.z );
sM->m_Offset.y * 25.4f,
sM->m_Offset.z * 25.4f );
glRotatef( -sM->m_Rotation.z, 0.0f, 0.0f, 1.0f ); glRotatef( -sM->m_Rotation.z, 0.0f, 0.0f, 1.0f );
glRotatef( -sM->m_Rotation.y, 0.0f, 1.0f, 0.0f ); glRotatef( -sM->m_Rotation.y, 0.0f, 1.0f, 0.0f );

View File

@ -1263,9 +1263,9 @@ void C3D_RENDER_RAYTRACING::load_3D_models()
glm::mat4 modelMatrix = moduleMatrix; glm::mat4 modelMatrix = moduleMatrix;
modelMatrix = glm::translate( modelMatrix, modelMatrix = glm::translate( modelMatrix,
SFVEC3F( sM->m_Offset.x * 25.4f, SFVEC3F( sM->m_Offset.x,
sM->m_Offset.y * 25.4f, sM->m_Offset.y,
sM->m_Offset.z * 25.4f ) ); sM->m_Offset.z ) );
modelMatrix = glm::rotate( modelMatrix, modelMatrix = glm::rotate( modelMatrix,
(float)-( sM->m_Rotation.z / 180.0f ) * (float)-( sM->m_Rotation.z / 180.0f ) *

View File

@ -82,6 +82,14 @@ enum MODULE_ATTR_T
class MODULE_3D_SETTINGS class MODULE_3D_SETTINGS
{ {
public: public:
MODULE_3D_SETTINGS() :
// Initialize with sensible values
m_Scale { 1, 1, 1 },
m_Rotation { 0, 0, 0 },
m_Offset { 0, 0, 0 }
{
}
struct VECTOR3D struct VECTOR3D
{ {
double x, y, z; double x, y, z;

View File

@ -1349,11 +1349,13 @@ static void export_vrml_module( MODEL_VRML& aModel, BOARD* aPcb,
compose_quat( q1, q2, q1 ); compose_quat( q1, q2, q1 );
from_quat( q1, rot ); from_quat( q1, rot );
double offsetFactor = 1000.0f * IU_PER_MILS / 25.4f;
// adjust 3D shape local offset position // adjust 3D shape local offset position
// they are given in inch, so they are converted in board IU. // they are given in mm, so they are converted in board IU.
double offsetx = sM->m_Offset.x * IU_PER_MILS * 1000.0; double offsetx = sM->m_Offset.x * offsetFactor;
double offsety = sM->m_Offset.y * IU_PER_MILS * 1000.0; double offsety = sM->m_Offset.y * offsetFactor;
double offsetz = sM->m_Offset.z * IU_PER_MILS * 1000.0; double offsetz = sM->m_Offset.z * offsetFactor;
if( isFlipped ) if( isFlipped )
offsetz = -offsetz; offsetz = -offsetz;

View File

@ -28,7 +28,10 @@
#include "kicadmodel.h" #include "kicadmodel.h"
KICADMODEL::KICADMODEL() : m_scale( 1.0, 1.0, 1.0 ) KICADMODEL::KICADMODEL() :
m_scale( 1.0, 1.0, 1.0 ),
m_offset( 0.0, 0.0, 0.0 ),
m_rotation( 0.0, 0.0, 0.0 )
{ {
return; return;
} }

View File

@ -996,10 +996,9 @@ bool PCBMODEL::getModelLocation( bool aBottom, DOUBLET aPosition, double aRotati
gp_Trsf lPos; gp_Trsf lPos;
lPos.SetTranslation( gp_Vec( aPosition.x, -aPosition.y, 0.0 ) ); lPos.SetTranslation( gp_Vec( aPosition.x, -aPosition.y, 0.0 ) );
// offset (inches) // Offset board thickness
aOffset.x *= 25.4; aOffset.z += BOARD_OFFSET;
aOffset.y *= 25.4;
aOffset.z *= 25.4 + BOARD_OFFSET;
gp_Trsf lRot; gp_Trsf lRot;
if( aBottom ) if( aBottom )