From af218a5dc0c47aa0cf283c78b9aff99c53e100d6 Mon Sep 17 00:00:00 2001 From: "Reece R. Pollack" Date: Sat, 4 Jul 2020 22:06:21 -0400 Subject: [PATCH] Add the PCB_ORIGIN_TRANSFORMS class This commit adds the PCB_ORIGIN_TRANSFORMS class, which is derived from the ORIGIN_TRANSFORMS class, and provides a set of templated functions to convert PCB coordinates between internal representation and display representation. It extends the ORIGIN_TRANSFORMS class to understand the three user-selectable display origins and the coordinate direction display options. --- common/CMakeLists.txt | 1 + pcbnew/pcb_origin_transforms.cpp | 123 ++++++++++++++++++ pcbnew/pcb_origin_transforms.h | 211 +++++++++++++++++++++++++++++++ 3 files changed, 335 insertions(+) create mode 100644 pcbnew/pcb_origin_transforms.cpp create mode 100644 pcbnew/pcb_origin_transforms.h diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index d579745802..fb88353faa 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -517,6 +517,7 @@ set( PCB_COMMON_SRCS ${CMAKE_SOURCE_DIR}/pcbnew/pcb_display_options.cpp ${CMAKE_SOURCE_DIR}/pcbnew/pcb_draw_panel_gal.cpp ${CMAKE_SOURCE_DIR}/pcbnew/netlist_reader/pcb_netlist.cpp + ${CMAKE_SOURCE_DIR}/pcbnew/pcb_origin_transforms.cpp ${CMAKE_SOURCE_DIR}/pcbnew/pcb_painter.cpp ${CMAKE_SOURCE_DIR}/pcbnew/pcb_parser.cpp ${CMAKE_SOURCE_DIR}/pcbnew/pcb_plot_params.cpp diff --git a/pcbnew/pcb_origin_transforms.cpp b/pcbnew/pcb_origin_transforms.cpp new file mode 100644 index 0000000000..f491ffd6c2 --- /dev/null +++ b/pcbnew/pcb_origin_transforms.cpp @@ -0,0 +1,123 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2019-2020 Reece R. Pollack + * Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include // for wxASSERT +#include +#include +#include + +using COORD_TYPE = ORIGIN_TRANSFORMS::COORD_TYPES_T; + +PCB_ORIGIN_TRANSFORMS::PCB_ORIGIN_TRANSFORMS( PCB_BASE_FRAME& aPcbBaseFrame ) + : m_pcbBaseFrame( aPcbBaseFrame ), + m_invertXAxis( aPcbBaseFrame.GetDisplayOptions().m_DisplayInvertXAxis ), + m_invertYAxis( aPcbBaseFrame.GetDisplayOptions().m_DisplayInvertYAxis ) +{} + +PCB_ORIGIN_TRANSFORMS::~PCB_ORIGIN_TRANSFORMS() +{} + +long long int PCB_ORIGIN_TRANSFORMS::ToDisplay( long long int aValue, + COORD_TYPES_T aCoordType ) +{ + long long int value = aValue; + + switch( aCoordType ) + { + case COORD_TYPE::ABS_X_COORD: value = ToDisplayAbsX( value ); break; + case COORD_TYPE::ABS_Y_COORD: value = ToDisplayAbsY( value ); break; + case COORD_TYPE::REL_X_COORD: value = ToDisplayRelX( value ); break; + case COORD_TYPE::REL_Y_COORD: value = ToDisplayRelY( value ); break; + case COORD_TYPE::NOT_A_COORD: /* do nothing */ ; break; + default: wxASSERT( false ); break; + }; + + return value; +} + +double PCB_ORIGIN_TRANSFORMS::ToDisplay( double aValue, + COORD_TYPES_T aCoordType ) +{ + double value = aValue; + + switch( aCoordType ) + { + case COORD_TYPE::ABS_X_COORD: value = ToDisplayAbsX( value ); break; + case COORD_TYPE::ABS_Y_COORD: value = ToDisplayAbsY( value ); break; + case COORD_TYPE::REL_X_COORD: value = ToDisplayRelX( value ); break; + case COORD_TYPE::REL_Y_COORD: value = ToDisplayRelY( value ); break; + case COORD_TYPE::NOT_A_COORD: /* do nothing */ ; break; + default: wxASSERT( false ); break; + }; + + return value; +} + +long long int PCB_ORIGIN_TRANSFORMS::FromDisplay( long long int aValue, + COORD_TYPES_T aCoordType ) +{ + long long value = aValue; + + switch( aCoordType ) + { + case COORD_TYPE::ABS_X_COORD: value = FromDisplayAbsX( value ); break; + case COORD_TYPE::ABS_Y_COORD: value = FromDisplayAbsY( value ); break; + case COORD_TYPE::REL_X_COORD: value = FromDisplayRelX( value ); break; + case COORD_TYPE::REL_Y_COORD: value = FromDisplayRelY( value ); break; + case COORD_TYPE::NOT_A_COORD: /* do nothing */ ; break; + default: wxASSERT( false ); break; + }; + + return value; +} + +double PCB_ORIGIN_TRANSFORMS::FromDisplay( double aValue, + COORD_TYPES_T aCoordType ) +{ + double value = aValue; + + switch( aCoordType ) + { + case COORD_TYPE::ABS_X_COORD: value = FromDisplayAbsX( value ); break; + case COORD_TYPE::ABS_Y_COORD: value = FromDisplayAbsY( value ); break; + case COORD_TYPE::REL_X_COORD: value = FromDisplayRelX( value ); break; + case COORD_TYPE::REL_Y_COORD: value = FromDisplayRelY( value ); break; + case COORD_TYPE::NOT_A_COORD: /* do nothing */ ; break; + default: wxASSERT( false ); break; + }; + + return value; +} + + +int PCB_ORIGIN_TRANSFORMS::GetUserXOrigin() const +{ + return m_pcbBaseFrame.GetUserOrigin().x; +} + +int PCB_ORIGIN_TRANSFORMS::GetUserYOrigin() const +{ + return m_pcbBaseFrame.GetUserOrigin().y; +} + diff --git a/pcbnew/pcb_origin_transforms.h b/pcbnew/pcb_origin_transforms.h new file mode 100644 index 0000000000..5857dc98d6 --- /dev/null +++ b/pcbnew/pcb_origin_transforms.h @@ -0,0 +1,211 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2019-2020 Reece R. Pollack + * Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef PCB_ORIGIN_TRANSFORM_H_ +#define PCB_ORIGIN_TRANSFORM_H_ 1 + +#include + +class PCB_BASE_FRAME; + +class PCB_ORIGIN_TRANSFORMS : public ORIGIN_TRANSFORMS +{ +public: + PCB_ORIGIN_TRANSFORMS( PCB_BASE_FRAME& aPcbBaseFrame ); + + virtual ~PCB_ORIGIN_TRANSFORMS() override; + + + using ORIGIN_TRANSFORMS::ToDisplay; + + virtual long long int ToDisplay( long long int aValue, + COORD_TYPES_T aCoordType ) override; + + virtual double ToDisplay( double aValue, + COORD_TYPES_T aCoordType ) override; + + + using ORIGIN_TRANSFORMS::FromDisplay; + + virtual long long int FromDisplay( long long int aValue, + COORD_TYPES_T aCoordType ) override; + + virtual double FromDisplay( double aValue, + COORD_TYPES_T aCoordType ) override; + + + /** + * Transform a 2-D coordinate point referenced to the internal origin + * to the equivalent point referenced to the user-selected display origin. + * + * @param aValue a point referenced to the internal origin + * @returns the point re-referenced to the user-selected display origin + */ + + /** + * Transform a 2-D coordinate point referenced to the user-selected + * display origin to the equivalent point referenced to the internal origin. + * + * @param aValue a point referenced to the user-selected display origin + * @returns the point re-referenced to the internal origin + */ + + /** + * Transform a relative 2-D coordinate delta referenced to the user-selected + * display origin to the equivalent delta referenced to the internal origin. + * + * This is initially intended to handle axis inversion of a delta between + * two display points, but could be extended to handle other transforms. + * + * @param aValue a delta referenced to the internal origin + * @returns the delta re-referenced to the user-selected display origin + */ + + /** + * Transform a relative 2-D coordinate delta referenced to the user-selected + * display origin to the equivalent delta referenced to the internal origin. + * + * This is initially intended to handle axis inversion of a delta between + * two display points, but could be extended to handle other transforms. + * + * @param aValue a delta referenced to the user-selected display origin + * @returns the delta re-referenced to the internal origin + */ + + + // =============== Single-axis Relative Transforms =============== + + template + T ToDisplayRelX( T aInternalValue ) const + { + return ORIGIN_TRANSFORMS::ToDisplayRel( aInternalValue, m_invertXAxis ); + } + + template + T ToDisplayRelY( T aInternalValue ) const + { + return ORIGIN_TRANSFORMS::ToDisplayRel( aInternalValue, m_invertYAxis ); + } + + template + T FromDisplayRelX( T aDisplayValue ) const + { + return ORIGIN_TRANSFORMS::FromDisplayRel( aDisplayValue, m_invertXAxis ); + } + + template + T FromDisplayRelY( T aDisplayValue ) const + { + return ORIGIN_TRANSFORMS::FromDisplayRel( aDisplayValue, m_invertYAxis ); + } + + + // =============== Single-axis Absolute Transforms =============== + + template + T ToDisplayAbsX( T aInternalValue ) const + { + return ORIGIN_TRANSFORMS::ToDisplayAbs( aInternalValue, GetUserXOrigin(), m_invertXAxis ); + } + + template + T ToDisplayAbsY( T aInternalValue ) const + { + return ORIGIN_TRANSFORMS::ToDisplayAbs( aInternalValue, GetUserYOrigin(), m_invertYAxis ); + } + + template + T FromDisplayAbsX( T aDisplayValue ) const + { + return ORIGIN_TRANSFORMS::FromDisplayAbs( aDisplayValue, GetUserXOrigin(), m_invertXAxis ); + } + + template + T FromDisplayAbsY( T aDisplayValue ) const + { + return ORIGIN_TRANSFORMS::FromDisplayAbs( aDisplayValue, GetUserYOrigin(), m_invertYAxis ); + } + + + // =============== Two-axis Transforms =============== + + template + T ToDisplayAbs( T aInternalValue ) const + { + T displayValue; + + displayValue.x = ToDisplayAbsX( aInternalValue.x ); + displayValue.y = ToDisplayAbsY( aInternalValue.y ); + + return displayValue; + } + + + template + T FromDisplayAbs( T aDisplayValue ) const + { + T internalValue; + + internalValue.x = FromDisplayAbsX( aDisplayValue.x ); + internalValue.y = FromDisplayAbsY( aDisplayValue.y ); + + return internalValue; + } + + + template + T ToDisplayRel( T aInternalValue ) const + { + T displayValue; + + displayValue.x = ToDisplayRelX( aInternalValue.x ); + displayValue.y = ToDisplayRelY( aInternalValue.y ); + + return displayValue; + } + + + template + T FromDisplayRel( T aDisplayValue ) const + { + T internalValue; + + internalValue.x = FromDisplayRelX( aDisplayValue.x ); + internalValue.y = FromDisplayRelY( aDisplayValue.y ); + + return internalValue; + } + + +protected: + const PCB_BASE_FRAME& m_pcbBaseFrame; + const bool& m_invertXAxis; + const bool& m_invertYAxis; + + int GetUserXOrigin() const; + int GetUserYOrigin() const; + +}; + +#endif // PCB_ORIGIN_TRANSFORMS_H_