From 0e42cb19f21d96aecb954124a28ba6fc7700ae25 Mon Sep 17 00:00:00 2001 From: Marek Roszko Date: Wed, 4 Jan 2023 20:42:56 -0500 Subject: [PATCH] Realize we can just describe the dxf arb axis with our MATRIX3x3 class --- libs/kimath/include/math/matrix3x3.h | 40 +++++++++++++++++++ pcbnew/import_gfx/dxf_import_plugin.cpp | 53 ++++++++++--------------- pcbnew/import_gfx/dxf_import_plugin.h | 16 ++------ 3 files changed, 65 insertions(+), 44 deletions(-) diff --git a/libs/kimath/include/math/matrix3x3.h b/libs/kimath/include/math/matrix3x3.h index 49230dc2fa..b8bc98763a 100644 --- a/libs/kimath/include/math/matrix3x3.h +++ b/libs/kimath/include/math/matrix3x3.h @@ -28,6 +28,7 @@ #define MATRIX3X3_H_ #include +#include /** * MATRIX3x3 describes a general 3x3 matrix. @@ -68,6 +69,11 @@ public: */ MATRIX3x3(); + /** + * Initialize with 3 vectors + */ + MATRIX3x3( VECTOR3 a1, VECTOR3 a2, VECTOR3 a3 ); + /** * Initialize with given matrix members * @@ -168,6 +174,8 @@ template MATRIX3x3 const operator*( MATRIX3x3 const& aA, MATRIX3 //! Multiplication with a 2D vector, the 3rd z-component is assumed to be 1 template VECTOR2 const operator*( MATRIX3x3 const& aA, VECTOR2 const& aB ); +template VECTOR3 const operator*( MATRIX3x3 const& aA, VECTOR3 const& aB ); + //! Multiplication with a scalar template MATRIX3x3 const operator*( MATRIX3x3 const& aA, T aScalar ); template MATRIX3x3 const operator*( T aScalar, MATRIX3x3 const& aMatrix ); @@ -189,6 +197,23 @@ MATRIX3x3::MATRIX3x3() } +template +MATRIX3x3::MATRIX3x3( VECTOR3 a1, VECTOR3 a2, VECTOR3 a3 ) +{ + m_data[0][0] = a1.x; + m_data[0][1] = a1.y; + m_data[0][2] = a1.z; + + m_data[1][0] = a2.x; + m_data[1][1] = a2.y; + m_data[1][2] = a2.z; + + m_data[2][0] = a3.x; + m_data[2][1] = a3.y; + m_data[2][2] = a3.z; +} + + template MATRIX3x3::MATRIX3x3( T a00, T a01, T a02, T a10, T a11, T a12, T a20, T a21, T a22 ) { @@ -302,6 +327,21 @@ VECTOR2 const operator*( MATRIX3x3 const& aMatrix, VECTOR2 const& aVect } +template +VECTOR3 const operator*( MATRIX3x3 const& aMatrix, VECTOR3 const& aVector ) +{ + VECTOR3 result( 0, 0, 0 ); + result.x = aMatrix.m_data[0][0] * aVector.x + aMatrix.m_data[0][1] * aVector.y + + aMatrix.m_data[0][2] * aVector.z; + result.y = aMatrix.m_data[1][0] * aVector.x + aMatrix.m_data[1][1] * aVector.y + + aMatrix.m_data[1][2] * aVector.z; + result.y = aMatrix.m_data[2][0] * aVector.x + aMatrix.m_data[2][1] * aVector.y + + aMatrix.m_data[2][2] * aVector.z; + + return result; +} + + template T MATRIX3x3::Determinant() const { diff --git a/pcbnew/import_gfx/dxf_import_plugin.cpp b/pcbnew/import_gfx/dxf_import_plugin.cpp index 359609cc45..b0f738f8d4 100644 --- a/pcbnew/import_gfx/dxf_import_plugin.cpp +++ b/pcbnew/import_gfx/dxf_import_plugin.cpp @@ -406,7 +406,7 @@ void DXF_IMPORT_PLUGIN::addVertex( const DL_VertexData& aData ) const DL_VertexData* vertex = &aData; - DXF_ARBITRARY_AXIS arbAxis = getArbitraryAxis( getExtrusion() ); + MATRIX3x3D arbAxis = getArbitraryAxis( getExtrusion() ); VECTOR3D vertexCoords = ocsToWcs( arbAxis, VECTOR3D( vertex->x, vertex->y, vertex->z ) ); if( m_curr_entity.m_EntityParseStatus == 1 ) // This is the first vertex of an entity @@ -486,7 +486,7 @@ void DXF_IMPORT_PLUGIN::addInsert( const DL_InsertData& aData ) if( block == nullptr ) return; - DXF_ARBITRARY_AXIS arbAxis = getArbitraryAxis( getExtrusion() ); + MATRIX3x3D arbAxis = getArbitraryAxis( getExtrusion() ); VECTOR3D insertCoords = ocsToWcs( arbAxis, VECTOR3D( aData.ipx, aData.ipy, aData.ipz ) ); VECTOR2D translation( mapX( insertCoords.x ), mapY( insertCoords.y ) ); @@ -507,7 +507,7 @@ void DXF_IMPORT_PLUGIN::addInsert( const DL_InsertData& aData ) void DXF_IMPORT_PLUGIN::addCircle( const DL_CircleData& aData ) { - DXF_ARBITRARY_AXIS arbAxis = getArbitraryAxis( getExtrusion() ); + MATRIX3x3D arbAxis = getArbitraryAxis( getExtrusion() ); VECTOR3D centerCoords = ocsToWcs( arbAxis, VECTOR3D( aData.cx, aData.cy, aData.cz ) ); VECTOR2D center( mapX( centerCoords.x ), mapY( centerCoords.y ) ); @@ -527,8 +527,8 @@ void DXF_IMPORT_PLUGIN::addCircle( const DL_CircleData& aData ) void DXF_IMPORT_PLUGIN::addArc( const DL_ArcData& aData ) { - DXF_ARBITRARY_AXIS arbAxis = getArbitraryAxis( getExtrusion() ); - VECTOR3D centerCoords = ocsToWcs( arbAxis, VECTOR3D( aData.cx, aData.cy, aData.cz ) ); + MATRIX3x3D arbAxis = getArbitraryAxis( getExtrusion() ); + VECTOR3D centerCoords = ocsToWcs( arbAxis, VECTOR3D( aData.cx, aData.cy, aData.cz ) ); // Init arc centre: VECTOR2D center( mapX( centerCoords.x ), mapY( centerCoords.y ) ); @@ -565,9 +565,9 @@ void DXF_IMPORT_PLUGIN::addArc( const DL_ArcData& aData ) void DXF_IMPORT_PLUGIN::addEllipse( const DL_EllipseData& aData ) { - DXF_ARBITRARY_AXIS arbAxis = getArbitraryAxis( getExtrusion() ); - VECTOR3D centerCoords = ocsToWcs( arbAxis, VECTOR3D( aData.cx, aData.cy, aData.cz ) ); - VECTOR3D majorCoords = ocsToWcs( arbAxis, VECTOR3D( aData.mx, aData.my, aData.mz ) ); + MATRIX3x3D arbAxis = getArbitraryAxis( getExtrusion() ); + VECTOR3D centerCoords = ocsToWcs( arbAxis, VECTOR3D( aData.cx, aData.cy, aData.cz ) ); + VECTOR3D majorCoords = ocsToWcs( arbAxis, VECTOR3D( aData.mx, aData.my, aData.mz ) ); // DXF ellipses store the minor axis length as a ratio to the major axis. // The major coords are relative to the center point. @@ -631,7 +631,7 @@ void DXF_IMPORT_PLUGIN::addEllipse( const DL_EllipseData& aData ) void DXF_IMPORT_PLUGIN::addText( const DL_TextData& aData ) { - DXF_ARBITRARY_AXIS arbAxis = getArbitraryAxis( getExtrusion() ); + MATRIX3x3D arbAxis = getArbitraryAxis( getExtrusion() ); VECTOR3D refPointCoords = ocsToWcs( arbAxis, VECTOR3D( aData.ipx, aData.ipy, aData.ipz ) ); VECTOR3D secPointCoords = ocsToWcs( arbAxis, VECTOR3D( std::isnan( aData.apx ) ? 0 : aData.apx, std::isnan( aData.apy ) ? 0 : aData.apy, @@ -830,8 +830,8 @@ void DXF_IMPORT_PLUGIN::addMText( const DL_MTextData& aData ) text = tmp; } - DXF_ARBITRARY_AXIS arbAxis = getArbitraryAxis( getExtrusion() ); - VECTOR3D textposCoords = ocsToWcs( arbAxis, VECTOR3D( aData.ipx, aData.ipy, aData.ipz ) ); + MATRIX3x3D arbAxis = getArbitraryAxis( getExtrusion() ); + VECTOR3D textposCoords = ocsToWcs( arbAxis, VECTOR3D( aData.ipx, aData.ipy, aData.ipz ) ); VECTOR2D textpos( mapX( textposCoords.x ), mapY( textposCoords.y ) ); @@ -1266,10 +1266,10 @@ void DXF_IMPORT_PLUGIN::addTextStyle( const DL_StyleData& aData ) void DXF_IMPORT_PLUGIN::addPoint( const DL_PointData& aData ) { - DXF_ARBITRARY_AXIS arbAxis = getArbitraryAxis( getExtrusion() ); - VECTOR3D centerCoords = ocsToWcs( arbAxis, VECTOR3D( aData.x, aData.y, aData.z ) ); + MATRIX3x3D arbAxis = getArbitraryAxis( getExtrusion() ); + VECTOR3D centerCoords = ocsToWcs( arbAxis, VECTOR3D( aData.x, aData.y, aData.z ) ); - VECTOR2D center( mapX( centerCoords.x ), mapY( centerCoords.y ) ); + VECTOR2D center( mapX( centerCoords.x ), mapY( centerCoords.y ) ); // we emulate points with filled circles // set the linewidth to something that even small circles look good with @@ -1499,7 +1499,7 @@ void DXF_IMPORT_PLUGIN::updateImageLimits( const VECTOR2D& aPoint ) } -DXF_ARBITRARY_AXIS DXF_IMPORT_PLUGIN::getArbitraryAxis( DL_Extrusion* aData ) +MATRIX3x3D DXF_IMPORT_PLUGIN::getArbitraryAxis( DL_Extrusion* aData ) { VECTOR3D arbZ, arbX, arbY; @@ -1519,34 +1519,23 @@ DXF_ARBITRARY_AXIS DXF_IMPORT_PLUGIN::getArbitraryAxis( DL_Extrusion* aData ) arbY = arbZ.Cross( arbX ).Normalize(); - return DXF_ARBITRARY_AXIS{ arbX, arbY, arbZ }; + return MATRIX3x3D{ arbX, arbY, arbZ }; } -VECTOR3D DXF_IMPORT_PLUGIN::wcsToOcs( const DXF_ARBITRARY_AXIS& arbitraryAxis, VECTOR3D point ) +VECTOR3D DXF_IMPORT_PLUGIN::wcsToOcs( const MATRIX3x3D& arbitraryAxis, VECTOR3D point ) { - double x, y, z; - x = point.x * arbitraryAxis.vecX.x + point.y * arbitraryAxis.vecX.y - + point.z * arbitraryAxis.vecX.z; - y = point.x * arbitraryAxis.vecY.x + point.y * arbitraryAxis.vecY.y - + point.z * arbitraryAxis.vecY.z; - z = point.x * arbitraryAxis.vecZ.x + point.y * arbitraryAxis.vecZ.y - + point.z * arbitraryAxis.vecZ.z; - - return VECTOR3D( x, y, z ); + return arbitraryAxis * point; } -VECTOR3D DXF_IMPORT_PLUGIN::ocsToWcs( const DXF_ARBITRARY_AXIS& arbitraryAxis, VECTOR3D point ) +VECTOR3D DXF_IMPORT_PLUGIN::ocsToWcs( const MATRIX3x3D& arbitraryAxis, VECTOR3D point ) { VECTOR3D worldX = wcsToOcs( arbitraryAxis, VECTOR3D( 1, 0, 0 ) ); VECTOR3D worldY = wcsToOcs( arbitraryAxis, VECTOR3D( 0, 1, 0 ) ); VECTOR3D worldZ = wcsToOcs( arbitraryAxis, VECTOR3D( 0, 0, 1 ) ); - double x, y, z; - x = point.x * worldX.x + point.y * worldX.y + point.z * worldX.z; - y = point.x * worldY.x + point.y * worldY.y + point.z * worldY.z; - z = point.x * worldZ.x + point.y * worldZ.y + point.z * worldZ.z; + MATRIX3x3 world( worldX, worldY, worldZ ); - return VECTOR3D( x, y, z ); + return world * point; } diff --git a/pcbnew/import_gfx/dxf_import_plugin.h b/pcbnew/import_gfx/dxf_import_plugin.h index c78749c89d..61d5cc93f6 100644 --- a/pcbnew/import_gfx/dxf_import_plugin.h +++ b/pcbnew/import_gfx/dxf_import_plugin.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -200,15 +201,6 @@ enum class DXF_IMPORT_UNITS PARSECS = 20 }; -/** - * Helper class representing the DXF specification's "arbitrary axis" - */ -struct DXF_ARBITRARY_AXIS -{ - VECTOR3D vecX; - VECTOR3D vecY; - VECTOR3D vecZ; -}; /** * This class import DXF ASCII files and convert basic entities to board entities. @@ -334,19 +326,19 @@ private: double lineWeightToWidth( int lw, DXF_IMPORT_LAYER* aLayer ); double getCurrentUnitScale(); - DXF_ARBITRARY_AXIS getArbitraryAxis( DL_Extrusion* aData ); + MATRIX3x3D getArbitraryAxis( DL_Extrusion* aData ); /** * Converts a given world coordinate point to object coordinate using the given arbitrary * axis vectors. */ - VECTOR3D wcsToOcs( const DXF_ARBITRARY_AXIS& arbitraryAxis, VECTOR3D point ); + VECTOR3D wcsToOcs( const MATRIX3x3D& arbitraryAxis, VECTOR3D point ); /** * Converts a given object coordinate point to world coordinate using the given arbitrary * axis vectors. */ - VECTOR3D ocsToWcs( const DXF_ARBITRARY_AXIS& arbitraryAxis, VECTOR3D point ); + VECTOR3D ocsToWcs( const MATRIX3x3D& arbitraryAxis, VECTOR3D point ); /** * Return the import layer data.