Add support for using a SpaceMouse to pan & zoom in the schematic editor.
This commit is contained in:
parent
e8a543f1ea
commit
1a9ef4bd0f
|
@ -44,35 +44,6 @@
|
||||||
*/
|
*/
|
||||||
const wxChar* NL_3D_VIEWER_PLUGIN_IMPL::m_logTrace = wxT( "KI_TRACE_NL_3D_VIEWER_PLUGIN" );
|
const wxChar* NL_3D_VIEWER_PLUGIN_IMPL::m_logTrace = wxT( "KI_TRACE_NL_3D_VIEWER_PLUGIN" );
|
||||||
|
|
||||||
/**
|
|
||||||
* Template to compare two floating point values for equality within a required epsilon.
|
|
||||||
*
|
|
||||||
* @param aFirst value to compare.
|
|
||||||
* @param aSecond value to compare.
|
|
||||||
* @param aEpsilon allowed error.
|
|
||||||
* @return true if the values considered equal within the specified epsilon, otherwise false.
|
|
||||||
*/
|
|
||||||
template <class T>
|
|
||||||
bool equals( T aFirst, T aSecond, T aEpsilon = static_cast<T>( FLT_EPSILON ) )
|
|
||||||
{
|
|
||||||
T diff = fabs( aFirst - aSecond );
|
|
||||||
|
|
||||||
if( diff < aEpsilon )
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
aFirst = fabs( aFirst );
|
|
||||||
aSecond = fabs( aSecond );
|
|
||||||
T largest = aFirst > aSecond ? aFirst : aSecond;
|
|
||||||
|
|
||||||
if( diff <= largest * aEpsilon )
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Template to compare two glm::mat<T> values for equality within a required epsilon.
|
* Template to compare two glm::mat<T> values for equality within a required epsilon.
|
||||||
|
@ -245,13 +216,13 @@ void NL_3D_VIEWER_PLUGIN_IMPL::exportCommandsAndImages()
|
||||||
streamBuffer->GetBufferSize() ),
|
streamBuffer->GetBufferSize() ),
|
||||||
0 );
|
0 );
|
||||||
|
|
||||||
wxLogTrace( m_logTrace, "Adding image for : %s", name );
|
wxLogTrace( m_logTrace, wxT( "Adding image for : %s" ), name );
|
||||||
vImages.push_back( std::move( tdxImage ) );
|
vImages.push_back( std::move( tdxImage ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wxLogTrace( m_logTrace, "Inserting command: %s, description: %s, in category: %s", name,
|
wxLogTrace( m_logTrace, wxT( "Inserting command: %s, description: %s, in category: %s" ),
|
||||||
description, iter->first );
|
name, description, iter->first );
|
||||||
|
|
||||||
iter->second->push_back(
|
iter->second->push_back(
|
||||||
CCommand( std::move( name ), std::move( label ), std::move( description ) ) );
|
CCommand( std::move( name ), std::move( label ), std::move( description ) ) );
|
||||||
|
@ -681,7 +652,7 @@ long NL_3D_VIEWER_PLUGIN_IMPL::GetFrontView( navlib::matrix_t& matrix ) const
|
||||||
long NL_3D_VIEWER_PLUGIN_IMPL::GetCoordinateSystem( navlib::matrix_t& matrix ) const
|
long NL_3D_VIEWER_PLUGIN_IMPL::GetCoordinateSystem( navlib::matrix_t& matrix ) const
|
||||||
{
|
{
|
||||||
// Use the right-handed coordinate system X-right, Z-up, Y-in (row vectors)
|
// Use the right-handed coordinate system X-right, Z-up, Y-in (row vectors)
|
||||||
matrix = { 1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1 };
|
matrix = { 1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1 };
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -255,6 +255,19 @@ void EDA_3D_VIEWER_FRAME::setupUIConditions()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void EDA_3D_VIEWER_FRAME::handleIconizeEvent( wxIconizeEvent& aEvent )
|
||||||
|
{
|
||||||
|
KIWAY_PLAYER::handleIconizeEvent( aEvent );
|
||||||
|
|
||||||
|
#if defined( KICAD_USE_3DCONNEXION )
|
||||||
|
if( m_spaceMouse != nullptr && aEvent.IsIconized() )
|
||||||
|
{
|
||||||
|
m_spaceMouse->SetFocus( false );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void EDA_3D_VIEWER_FRAME::ReloadRequest()
|
void EDA_3D_VIEWER_FRAME::ReloadRequest()
|
||||||
{
|
{
|
||||||
// This will schedule a request to load later
|
// This will schedule a request to load later
|
||||||
|
|
|
@ -120,6 +120,8 @@ public:
|
||||||
protected:
|
protected:
|
||||||
void setupUIConditions() override;
|
void setupUIConditions() override;
|
||||||
|
|
||||||
|
void handleIconizeEvent( wxIconizeEvent& aEvent ) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Called when user press the File->Exit
|
/// Called when user press the File->Exit
|
||||||
void Exit3DFrame( wxCommandEvent& event );
|
void Exit3DFrame( wxCommandEvent& event );
|
||||||
|
|
|
@ -0,0 +1,202 @@
|
||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
|
@ -8,6 +8,8 @@ KiCad EDA suite by the KiCad project or any third party, e.g. Linux distributor.
|
||||||
|
|
||||||
You are free to use the *sources* under the terms of their respective licenses.
|
You are free to use the *sources* under the terms of their respective licenses.
|
||||||
|
|
||||||
|
Licensed under Apache License, Version 2.0
|
||||||
|
- portions of code in libs/kimath/include/math/util.h
|
||||||
Licensed under BOOSTv1:
|
Licensed under BOOSTv1:
|
||||||
- libcontext [https://github.com/boostorg/context] in thirdparty/libcontext
|
- libcontext [https://github.com/boostorg/context] in thirdparty/libcontext
|
||||||
- clipper in thirdparty/clipper
|
- clipper in thirdparty/clipper
|
||||||
|
|
|
@ -107,6 +107,7 @@ BEGIN_EVENT_TABLE( EDA_BASE_FRAME, wxFrame )
|
||||||
EVT_MAXIMIZE( EDA_BASE_FRAME::OnMaximize )
|
EVT_MAXIMIZE( EDA_BASE_FRAME::OnMaximize )
|
||||||
|
|
||||||
EVT_SYS_COLOUR_CHANGED( EDA_BASE_FRAME::onSystemColorChange )
|
EVT_SYS_COLOUR_CHANGED( EDA_BASE_FRAME::onSystemColorChange )
|
||||||
|
EVT_ICONIZE( EDA_BASE_FRAME::onIconize )
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
|
|
||||||
|
@ -1325,6 +1326,16 @@ void EDA_BASE_FRAME::onSystemColorChange( wxSysColourChangedEvent& aEvent )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void EDA_BASE_FRAME::onIconize( wxIconizeEvent& aEvent )
|
||||||
|
{
|
||||||
|
// Call the handler
|
||||||
|
handleIconizeEvent( aEvent );
|
||||||
|
|
||||||
|
// Skip the event.
|
||||||
|
aEvent.Skip();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
WXLRESULT EDA_BASE_FRAME::MSWWindowProc( WXUINT message, WXWPARAM wParam, WXLPARAM lParam )
|
WXLRESULT EDA_BASE_FRAME::MSWWindowProc( WXUINT message, WXWPARAM wParam, WXLPARAM lParam )
|
||||||
{
|
{
|
||||||
|
|
|
@ -435,6 +435,13 @@ if( KICAD_SPICE )
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if( KICAD_USE_3DCONNEXION )
|
||||||
|
message( STATUS "Including 3Dconnexion SpaceMouse navigation support in eeschema" )
|
||||||
|
add_subdirectory( ./navlib )
|
||||||
|
target_link_libraries( eeschema_kiface PRIVATE eeschema_navlib)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
set_target_properties( eeschema_kiface PROPERTIES
|
set_target_properties( eeschema_kiface PROPERTIES
|
||||||
# Decorate OUTPUT_NAME with PREFIX and SUFFIX, creating something like
|
# Decorate OUTPUT_NAME with PREFIX and SUFFIX, creating something like
|
||||||
# _eeschema.so, _eeschema.dll, or _eeschema.kiface
|
# _eeschema.so, _eeschema.dll, or _eeschema.kiface
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
if( KICAD_USE_3DCONNEXION )
|
||||||
|
add_library(eeschema_navlib STATIC
|
||||||
|
"nl_schematic_plugin.cpp"
|
||||||
|
"nl_schematic_plugin_impl.cpp"
|
||||||
|
)
|
||||||
|
|
||||||
|
# eeschema_navlib depends on make_lexer outputs in common
|
||||||
|
add_dependencies( eeschema_navlib common )
|
||||||
|
|
||||||
|
# Find the 3DxWare SDK component 3DxWare::NlClient
|
||||||
|
# find_package(TDxWare_SDK 4.0 REQUIRED COMPONENTS 3DxWare::Navlib)
|
||||||
|
target_compile_definitions(eeschema_navlib PRIVATE
|
||||||
|
$<TARGET_PROPERTY:3DxWare::Navlib,INTERFACE_COMPILE_DEFINITIONS>
|
||||||
|
)
|
||||||
|
target_compile_options(eeschema_navlib PRIVATE
|
||||||
|
$<TARGET_PROPERTY:3DxWare::Navlib,INTERFACE_COMPILE_OPTIONS>
|
||||||
|
)
|
||||||
|
target_include_directories(eeschema_navlib PRIVATE
|
||||||
|
$<TARGET_PROPERTY:3DxWare::Navlib,INTERFACE_INCLUDE_DIRECTORIES>
|
||||||
|
$<TARGET_PROPERTY:eeschema_kiface_objects,INCLUDE_DIRECTORIES>
|
||||||
|
)
|
||||||
|
target_link_libraries(eeschema_navlib
|
||||||
|
$<TARGET_PROPERTY:3DxWare::Navlib,INTERFACE_LINK_LIBRARIES>
|
||||||
|
3DxWare::Navlib
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
add_library(eeschema_navlib STATIC
|
||||||
|
"nl_schematic_plugin.cpp"
|
||||||
|
)
|
||||||
|
endif(KICAD_USE_3DCONNEXION)
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 3Dconnexion
|
||||||
|
* Copyright (C) 2022 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nl_schematic_plugin.h"
|
||||||
|
#if defined( KICAD_USE_3DCONNEXION )
|
||||||
|
|
||||||
|
#include "nl_schematic_plugin_impl.h"
|
||||||
|
|
||||||
|
|
||||||
|
NL_SCHEMATIC_PLUGIN::NL_SCHEMATIC_PLUGIN() : m_impl( new NL_SCHEMATIC_PLUGIN_IMPL() )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NL_SCHEMATIC_PLUGIN::~NL_SCHEMATIC_PLUGIN()
|
||||||
|
{
|
||||||
|
delete m_impl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void NL_SCHEMATIC_PLUGIN::SetFocus( bool focus )
|
||||||
|
{
|
||||||
|
m_impl->SetFocus( focus );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void NL_SCHEMATIC_PLUGIN::SetCanvas( EDA_DRAW_PANEL_GAL* aViewport )
|
||||||
|
{
|
||||||
|
m_impl->SetCanvas( aViewport );
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
|
||||||
|
NL_SCHEMATIC_PLUGIN::NL_SCHEMATIC_PLUGIN( EDA_DRAW_PANEL_GAL* aViewport )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void NL_SCHEMATIC_PLUGIN::SetFocus( bool focus )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void NL_SCHEMATIC_PLUGIN::SetCanvas( EDA_DRAW_PANEL_GAL* aViewport )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NL_SCHEMATIC_PLUGIN::~NL_SCHEMATIC_PLUGIN()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 3Dconnexion
|
||||||
|
* Copyright (C) 2022 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file nl_schematic_plugin.h
|
||||||
|
* @brief Declaration of the NL_SCHEMATIC_PLUGIN class
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NL_SCHEMATIC_PLUGIN_H_
|
||||||
|
#define NL_SCHEMATIC_PLUGIN_H_
|
||||||
|
|
||||||
|
// Forward declarations.
|
||||||
|
class EDA_DRAW_PANEL_GAL;
|
||||||
|
class NL_SCHEMATIC_PLUGIN_IMPL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The class that implements the public interface to the SpaceMouse plug-in.
|
||||||
|
*/
|
||||||
|
class NL_SCHEMATIC_PLUGIN
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Initializes a new instance of the NL_SCHEMATIC_PLUGIN.
|
||||||
|
*/
|
||||||
|
NL_SCHEMATIC_PLUGIN();
|
||||||
|
|
||||||
|
virtual ~NL_SCHEMATIC_PLUGIN();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the viewport controlled by the SpaceMouse.
|
||||||
|
*
|
||||||
|
* @param aViewport is the viewport to be navigated.
|
||||||
|
*/
|
||||||
|
void SetCanvas( EDA_DRAW_PANEL_GAL* aViewport );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the connection to the 3Dconnexion driver to the focus state so that
|
||||||
|
* 3DMouse data is routed to this connexion.
|
||||||
|
*
|
||||||
|
* @param aFocus is true to set the connexion active.
|
||||||
|
*/
|
||||||
|
void SetFocus( bool aFocus );
|
||||||
|
|
||||||
|
private:
|
||||||
|
NL_SCHEMATIC_PLUGIN_IMPL* m_impl;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NL_SCHEMATIC_PLUGIN_H_
|
|
@ -0,0 +1,608 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 3Dconnexion
|
||||||
|
* Copyright (C) 2022 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nl_schematic_plugin_impl.h"
|
||||||
|
|
||||||
|
// KiCAD includes
|
||||||
|
#include <sch_base_frame.h>
|
||||||
|
#include <bitmaps.h>
|
||||||
|
#include <class_draw_panel_gal.h>
|
||||||
|
#include <view/view.h>
|
||||||
|
#include <view/wx_view_controls.h>
|
||||||
|
#include <tool/action_manager.h>
|
||||||
|
#include <tool/tool_action.h>
|
||||||
|
#include <tool/tool_manager.h>
|
||||||
|
|
||||||
|
// stdlib
|
||||||
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
#include <cfloat>
|
||||||
|
|
||||||
|
#include <wx/log.h>
|
||||||
|
#include <wx/mstream.h>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flag to enable the NL_SCHEMATIC_PLUGIN debug tracing.
|
||||||
|
*
|
||||||
|
* Use "KI_TRACE_NL_SCHEMATIC_PLUGIN" to enable.
|
||||||
|
*
|
||||||
|
* @ingroup trace_env_vars
|
||||||
|
*/
|
||||||
|
const wxChar* NL_SCHEMATIC_PLUGIN_IMPL::m_logTrace = wxT( "KI_TRACE_NL_SCHEMATIC_PLUGIN" );
|
||||||
|
|
||||||
|
|
||||||
|
NL_SCHEMATIC_PLUGIN_IMPL::NL_SCHEMATIC_PLUGIN_IMPL() :
|
||||||
|
CNavigation3D( false, false ), m_viewport2D( nullptr ), m_isMoving( false )
|
||||||
|
{
|
||||||
|
PutProfileHint( "KiCAD Eeschema" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NL_SCHEMATIC_PLUGIN_IMPL::~NL_SCHEMATIC_PLUGIN_IMPL()
|
||||||
|
{
|
||||||
|
EnableNavigation( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void NL_SCHEMATIC_PLUGIN_IMPL::SetCanvas( EDA_DRAW_PANEL_GAL* aViewport )
|
||||||
|
{
|
||||||
|
bool init = m_viewport2D == nullptr;
|
||||||
|
|
||||||
|
m_viewport2D = aViewport;
|
||||||
|
|
||||||
|
if( m_viewport2D != nullptr )
|
||||||
|
{
|
||||||
|
m_view = static_cast<KIGFX::SCH_VIEW*>( m_viewport2D->GetView() );
|
||||||
|
m_viewportWidth = m_view->GetBoundary().GetWidth();
|
||||||
|
|
||||||
|
if( init )
|
||||||
|
{
|
||||||
|
// Use the default settings for the connexion to the 3DMouse navigation
|
||||||
|
// They are use a single-threaded threading model and row vectors.
|
||||||
|
EnableNavigation( true );
|
||||||
|
|
||||||
|
// Use the SpaceMouse internal timing source for the frame rate.
|
||||||
|
PutFrameTimingSource( TimingSource::SpaceMouse );
|
||||||
|
|
||||||
|
exportCommandsAndImages();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void NL_SCHEMATIC_PLUGIN_IMPL::SetFocus( bool aFocus )
|
||||||
|
{
|
||||||
|
wxLogTrace( m_logTrace, wxT( "NL_SCHEMATIC_PLUGIN_IMPL::SetFocus %d" ), aFocus );
|
||||||
|
NAV_3D::Write( navlib::focus_k, aFocus );
|
||||||
|
}
|
||||||
|
|
||||||
|
// temporary store for the command categories
|
||||||
|
typedef std::map<std::string, TDx::CCommandTreeNode*> CATEGORY_STORE;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a category to the store.
|
||||||
|
*
|
||||||
|
* The function adds category paths of the format "A.B" where B is a sub-category of A.
|
||||||
|
*
|
||||||
|
* @param aCategoryPath is the std::string representation of the category.
|
||||||
|
* @param aCategoryStore is the CATEGORY_STORE instance to add to.
|
||||||
|
* @return a CATEGORY_STORE::iterator where the category was added.
|
||||||
|
*/
|
||||||
|
static CATEGORY_STORE::iterator add_category( std::string aCategoryPath,
|
||||||
|
CATEGORY_STORE& aCategoryStore )
|
||||||
|
{
|
||||||
|
using TDx::SpaceMouse::CCategory;
|
||||||
|
|
||||||
|
CATEGORY_STORE::iterator parent_iter = aCategoryStore.begin();
|
||||||
|
std::string::size_type pos = aCategoryPath.find_last_of( '.' );
|
||||||
|
|
||||||
|
if( pos != std::string::npos )
|
||||||
|
{
|
||||||
|
std::string parentPath = aCategoryPath.substr( 0, pos );
|
||||||
|
parent_iter = aCategoryStore.find( parentPath );
|
||||||
|
|
||||||
|
if( parent_iter == aCategoryStore.end() )
|
||||||
|
{
|
||||||
|
parent_iter = add_category( parentPath, aCategoryStore );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string name = aCategoryPath.substr( pos + 1 );
|
||||||
|
std::unique_ptr<CCategory> categoryNode =
|
||||||
|
std::make_unique<CCategory>( aCategoryPath.c_str(), name.c_str() );
|
||||||
|
|
||||||
|
CATEGORY_STORE::iterator iter = aCategoryStore.insert(
|
||||||
|
aCategoryStore.end(), CATEGORY_STORE::value_type( aCategoryPath, categoryNode.get() ) );
|
||||||
|
|
||||||
|
parent_iter->second->push_back( std::move( categoryNode ) );
|
||||||
|
return iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void NL_SCHEMATIC_PLUGIN_IMPL::exportCommandsAndImages()
|
||||||
|
{
|
||||||
|
wxLogTrace( m_logTrace, wxT( "NL_SCHEMATIC_PLUGIN_IMPL::exportCommandsAndImages" ) );
|
||||||
|
|
||||||
|
std::list<TOOL_ACTION*> actions = ACTION_MANAGER::GetActionList();
|
||||||
|
|
||||||
|
if( actions.size() == 0 )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
using TDx::SpaceMouse::CCommand;
|
||||||
|
using TDx::SpaceMouse::CCommandSet;
|
||||||
|
|
||||||
|
// The root action set node
|
||||||
|
CCommandSet commandSet( "SCHEMATIC_EDITOR", "Schematic Editor" );
|
||||||
|
|
||||||
|
// Activate the command set
|
||||||
|
NAV_3D::PutActiveCommands( commandSet.GetId() );
|
||||||
|
|
||||||
|
// temporary store for the categories
|
||||||
|
CATEGORY_STORE categoryStore;
|
||||||
|
|
||||||
|
std::vector<TDx::CImage> vImages;
|
||||||
|
|
||||||
|
// add the action set to the category_store
|
||||||
|
categoryStore.insert( categoryStore.end(), CATEGORY_STORE::value_type( ".", &commandSet ) );
|
||||||
|
|
||||||
|
std::list<TOOL_ACTION*>::const_iterator it;
|
||||||
|
|
||||||
|
for( it = actions.begin(); it != actions.end(); ++it )
|
||||||
|
{
|
||||||
|
const TOOL_ACTION* action = *it;
|
||||||
|
std::string label = action->GetLabel().ToStdString();
|
||||||
|
|
||||||
|
if( label.empty() )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string name = action->GetName();
|
||||||
|
|
||||||
|
// Do no export commands for the 3DViewer app.
|
||||||
|
|
||||||
|
if( name.rfind( "3DViewer.", 0 ) == 0 )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string strCategory = action->GetToolName();
|
||||||
|
CATEGORY_STORE::iterator iter = categoryStore.find( strCategory );
|
||||||
|
|
||||||
|
if( iter == categoryStore.end() )
|
||||||
|
{
|
||||||
|
iter = add_category( std::move( strCategory ), categoryStore );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string description = action->GetDescription().ToStdString();
|
||||||
|
|
||||||
|
// Arbitrary 8-bit data stream
|
||||||
|
wxMemoryOutputStream imageStream;
|
||||||
|
|
||||||
|
if( action->GetIcon() != BITMAPS::INVALID_BITMAP )
|
||||||
|
{
|
||||||
|
wxImage image = KiBitmap( action->GetIcon() ).ConvertToImage();
|
||||||
|
image.SaveFile( imageStream, wxBitmapType::wxBITMAP_TYPE_PNG );
|
||||||
|
image.Destroy();
|
||||||
|
|
||||||
|
if( imageStream.GetSize() )
|
||||||
|
{
|
||||||
|
wxStreamBuffer* streamBuffer = imageStream.GetOutputStreamBuffer();
|
||||||
|
TDx::CImage tdxImage = TDx::CImage::FromData( "", 0, name.c_str() );
|
||||||
|
tdxImage.AssignImage( std::string( reinterpret_cast<const char*>(
|
||||||
|
streamBuffer->GetBufferStart() ),
|
||||||
|
streamBuffer->GetBufferSize() ),
|
||||||
|
0 );
|
||||||
|
|
||||||
|
wxLogTrace( m_logTrace, wxT( "Adding image for : %s" ), name );
|
||||||
|
vImages.push_back( std::move( tdxImage ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wxLogTrace( m_logTrace, wxT( "Inserting command: %s, description: %s, in category: %s" ),
|
||||||
|
name, description, iter->first );
|
||||||
|
|
||||||
|
iter->second->push_back(
|
||||||
|
CCommand( std::move( name ), std::move( label ), std::move( description ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
NAV_3D::AddCommandSet( commandSet );
|
||||||
|
NAV_3D::AddImages( vImages );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long NL_SCHEMATIC_PLUGIN_IMPL::GetCameraMatrix( navlib::matrix_t& matrix ) const
|
||||||
|
{
|
||||||
|
if( m_view == nullptr )
|
||||||
|
{
|
||||||
|
return navlib::make_result_code( navlib::navlib_errc::no_data_available );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_viewPosition = m_view->GetCenter();
|
||||||
|
|
||||||
|
double x = m_view->IsMirroredX() ? -1 : 1;
|
||||||
|
double y = m_view->IsMirroredY() ? 1 : -1;
|
||||||
|
|
||||||
|
// x * y * z = 1 for a right-handed coordinate system.
|
||||||
|
double z = x * y;
|
||||||
|
|
||||||
|
// Note: the connexion has been configured as row vectors, the coordinate system is defined in
|
||||||
|
// NL_SCHEMATIC_PLUGIN_IMPL::GetCoordinateSystem and the front view in NL_SCHEMATIC_PLUGIN_IMPL::GetFrontView.
|
||||||
|
matrix = { x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, m_viewPosition.x, m_viewPosition.y, 0, 1 };
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long NL_SCHEMATIC_PLUGIN_IMPL::GetPointerPosition( navlib::point_t& position ) const
|
||||||
|
{
|
||||||
|
if( m_view == nullptr )
|
||||||
|
{
|
||||||
|
return navlib::make_result_code( navlib::navlib_errc::no_data_available );
|
||||||
|
}
|
||||||
|
|
||||||
|
VECTOR2D mouse_pointer = m_viewport2D->GetViewControls()->GetMousePosition();
|
||||||
|
|
||||||
|
position.x = mouse_pointer.x;
|
||||||
|
position.y = mouse_pointer.y;
|
||||||
|
position.z = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long NL_SCHEMATIC_PLUGIN_IMPL::GetViewExtents( navlib::box_t& extents ) const
|
||||||
|
{
|
||||||
|
if( m_view == nullptr )
|
||||||
|
{
|
||||||
|
return navlib::make_result_code( navlib::navlib_errc::no_data_available );
|
||||||
|
}
|
||||||
|
|
||||||
|
double scale = m_viewport2D->GetGAL()->GetWorldScale();
|
||||||
|
BOX2D box = m_view->GetViewport();
|
||||||
|
|
||||||
|
m_viewportWidth = box.GetWidth();
|
||||||
|
|
||||||
|
extents = navlib::box_t{ -box.GetWidth() / 2.0,
|
||||||
|
-box.GetHeight() / 2.0,
|
||||||
|
m_viewport2D->GetGAL()->GetMinDepth() / scale,
|
||||||
|
box.GetWidth() / 2.0,
|
||||||
|
box.GetHeight() / 2.0,
|
||||||
|
m_viewport2D->GetGAL()->GetMaxDepth() / scale };
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long NL_SCHEMATIC_PLUGIN_IMPL::GetIsViewPerspective( navlib::bool_t& perspective ) const
|
||||||
|
{
|
||||||
|
perspective = false;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long NL_SCHEMATIC_PLUGIN_IMPL::SetCameraMatrix( const navlib::matrix_t& matrix )
|
||||||
|
{
|
||||||
|
if( m_view == nullptr )
|
||||||
|
{
|
||||||
|
return navlib::make_result_code( navlib::navlib_errc::invalid_operation );
|
||||||
|
}
|
||||||
|
|
||||||
|
long result = 0;
|
||||||
|
VECTOR2D viewPos( matrix.m4x4[3][0], matrix.m4x4[3][1] );
|
||||||
|
|
||||||
|
if( !equals( m_view->GetCenter(), m_viewPosition,
|
||||||
|
static_cast<VECTOR2D::coord_type>( FLT_EPSILON ) ) )
|
||||||
|
{
|
||||||
|
m_view->SetCenter( viewPos + m_view->GetCenter() - m_viewPosition );
|
||||||
|
result = navlib::make_result_code( navlib::navlib_errc::error );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_view->SetCenter( viewPos );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_viewPosition = viewPos;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long NL_SCHEMATIC_PLUGIN_IMPL::SetViewExtents( const navlib::box_t& extents )
|
||||||
|
{
|
||||||
|
if( m_view == nullptr )
|
||||||
|
{
|
||||||
|
return navlib::make_result_code( navlib::navlib_errc::invalid_operation );
|
||||||
|
}
|
||||||
|
|
||||||
|
long result = 0;
|
||||||
|
|
||||||
|
if( m_viewportWidth != m_view->GetViewport().GetWidth() )
|
||||||
|
{
|
||||||
|
result = navlib::make_result_code( navlib::navlib_errc::error );
|
||||||
|
}
|
||||||
|
|
||||||
|
double width = m_viewportWidth;
|
||||||
|
m_viewportWidth = extents.max_x - extents.min_x;
|
||||||
|
|
||||||
|
double scale = width / m_viewportWidth * m_view->GetScale();
|
||||||
|
m_view->SetScale( scale, m_view->GetCenter() );
|
||||||
|
|
||||||
|
if( !equals( m_view->GetScale(), scale, static_cast<double>( FLT_EPSILON ) ) )
|
||||||
|
{
|
||||||
|
result = navlib::make_result_code( navlib::navlib_errc::error );
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long NL_SCHEMATIC_PLUGIN_IMPL::SetViewFOV( double fov )
|
||||||
|
{
|
||||||
|
return navlib::make_result_code( navlib::navlib_errc::invalid_operation );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long NL_SCHEMATIC_PLUGIN_IMPL::SetViewFrustum( const navlib::frustum_t& frustum )
|
||||||
|
{
|
||||||
|
return navlib::make_result_code( navlib::navlib_errc::invalid_operation );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long NL_SCHEMATIC_PLUGIN_IMPL::GetModelExtents( navlib::box_t& extents ) const
|
||||||
|
{
|
||||||
|
if( m_view == nullptr )
|
||||||
|
{
|
||||||
|
return navlib::make_result_code( navlib::navlib_errc::no_data_available );
|
||||||
|
}
|
||||||
|
|
||||||
|
BOX2I box = static_cast<SCH_BASE_FRAME*>( m_viewport2D->GetParent() )->GetDocumentExtents();
|
||||||
|
box.Normalize();
|
||||||
|
|
||||||
|
double half_depth = 0.1 / m_viewport2D->GetGAL()->GetWorldScale();
|
||||||
|
|
||||||
|
if( box.GetWidth() == 0 && box.GetHeight() == 0 )
|
||||||
|
{
|
||||||
|
half_depth = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
extents = { static_cast<double>( box.GetOrigin().x ),
|
||||||
|
static_cast<double>( box.GetOrigin().y ),
|
||||||
|
-half_depth,
|
||||||
|
static_cast<double>( box.GetEnd().x ),
|
||||||
|
static_cast<double>( box.GetEnd().y ),
|
||||||
|
half_depth };
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long NL_SCHEMATIC_PLUGIN_IMPL::GetCoordinateSystem( navlib::matrix_t& matrix ) const
|
||||||
|
{
|
||||||
|
// The coordinate system is defined as x to the right, y down and z into the screen.
|
||||||
|
matrix = { 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1 };
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long NL_SCHEMATIC_PLUGIN_IMPL::GetFrontView( navlib::matrix_t& matrix ) const
|
||||||
|
{
|
||||||
|
matrix = { 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1 };
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long NL_SCHEMATIC_PLUGIN_IMPL::GetIsSelectionEmpty( navlib::bool_t& empty ) const
|
||||||
|
{
|
||||||
|
empty = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long NL_SCHEMATIC_PLUGIN_IMPL::GetIsViewRotatable( navlib::bool_t& isRotatable ) const
|
||||||
|
{
|
||||||
|
isRotatable = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long NL_SCHEMATIC_PLUGIN_IMPL::SetActiveCommand( std::string commandId )
|
||||||
|
{
|
||||||
|
if( commandId.empty() )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::list<TOOL_ACTION*> actions = ACTION_MANAGER::GetActionList();
|
||||||
|
TOOL_ACTION* context = nullptr;
|
||||||
|
|
||||||
|
for( std::list<TOOL_ACTION*>::const_iterator it = actions.begin(); it != actions.end(); it++ )
|
||||||
|
{
|
||||||
|
TOOL_ACTION* action = *it;
|
||||||
|
std::string nm = action->GetName();
|
||||||
|
|
||||||
|
if( commandId == nm )
|
||||||
|
{
|
||||||
|
context = action;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( context != nullptr )
|
||||||
|
{
|
||||||
|
wxWindow* parent = m_viewport2D->GetParent();
|
||||||
|
|
||||||
|
// Only allow command execution if the window is enabled. i.e. there is not a modal dialog
|
||||||
|
// currently active.
|
||||||
|
|
||||||
|
if( parent->IsEnabled() )
|
||||||
|
{
|
||||||
|
TOOL_MANAGER* tool_manager = static_cast<SCH_BASE_FRAME*>( parent )->GetToolManager();
|
||||||
|
|
||||||
|
// Get the selection to use to test if the action is enabled
|
||||||
|
SELECTION& sel = tool_manager->GetToolHolder()->GetCurrentSelection();
|
||||||
|
|
||||||
|
bool runAction = true;
|
||||||
|
|
||||||
|
if( const ACTION_CONDITIONS* aCond =
|
||||||
|
tool_manager->GetActionManager()->GetCondition( *context ) )
|
||||||
|
{
|
||||||
|
runAction = aCond->enableCondition( sel );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( runAction )
|
||||||
|
{
|
||||||
|
tool_manager->RunAction( *context, true );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return navlib::make_result_code( navlib::navlib_errc::invalid_operation );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long NL_SCHEMATIC_PLUGIN_IMPL::SetSettingsChanged( long change )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long NL_SCHEMATIC_PLUGIN_IMPL::SetMotionFlag( bool value )
|
||||||
|
{
|
||||||
|
m_isMoving = value;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long NL_SCHEMATIC_PLUGIN_IMPL::SetTransaction( long value )
|
||||||
|
{
|
||||||
|
if( value == 0L )
|
||||||
|
{
|
||||||
|
m_viewport2D->ForceRefresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long NL_SCHEMATIC_PLUGIN_IMPL::GetViewFOV( double& fov ) const
|
||||||
|
{
|
||||||
|
return navlib::make_result_code( navlib::navlib_errc::invalid_operation );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long NL_SCHEMATIC_PLUGIN_IMPL::GetViewFrustum( navlib::frustum_t& frustum ) const
|
||||||
|
{
|
||||||
|
return navlib::make_result_code( navlib::navlib_errc::invalid_operation );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long NL_SCHEMATIC_PLUGIN_IMPL::GetSelectionExtents( navlib::box_t& extents ) const
|
||||||
|
{
|
||||||
|
return navlib::make_result_code( navlib::navlib_errc::no_data_available );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long NL_SCHEMATIC_PLUGIN_IMPL::GetSelectionTransform( navlib::matrix_t& transform ) const
|
||||||
|
{
|
||||||
|
return navlib::make_result_code( navlib::navlib_errc::no_data_available );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long NL_SCHEMATIC_PLUGIN_IMPL::SetSelectionTransform( const navlib::matrix_t& matrix )
|
||||||
|
{
|
||||||
|
return navlib::make_result_code( navlib::navlib_errc::invalid_operation );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long NL_SCHEMATIC_PLUGIN_IMPL::GetPivotPosition( navlib::point_t& position ) const
|
||||||
|
{
|
||||||
|
return navlib::make_result_code( navlib::navlib_errc::invalid_operation );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long NL_SCHEMATIC_PLUGIN_IMPL::IsUserPivot( navlib::bool_t& userPivot ) const
|
||||||
|
{
|
||||||
|
return navlib::make_result_code( navlib::navlib_errc::invalid_operation );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long NL_SCHEMATIC_PLUGIN_IMPL::SetPivotPosition( const navlib::point_t& position )
|
||||||
|
{
|
||||||
|
return navlib::make_result_code( navlib::navlib_errc::invalid_operation );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long NL_SCHEMATIC_PLUGIN_IMPL::GetPivotVisible( navlib::bool_t& visible ) const
|
||||||
|
{
|
||||||
|
return navlib::make_result_code( navlib::navlib_errc::invalid_operation );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long NL_SCHEMATIC_PLUGIN_IMPL::SetPivotVisible( bool visible )
|
||||||
|
{
|
||||||
|
return navlib::make_result_code( navlib::navlib_errc::invalid_operation );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long NL_SCHEMATIC_PLUGIN_IMPL::GetHitLookAt( navlib::point_t& position ) const
|
||||||
|
{
|
||||||
|
return navlib::make_result_code( navlib::navlib_errc::no_data_available );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long NL_SCHEMATIC_PLUGIN_IMPL::SetHitAperture( double aperture )
|
||||||
|
{
|
||||||
|
return navlib::make_result_code( navlib::navlib_errc::invalid_operation );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long NL_SCHEMATIC_PLUGIN_IMPL::SetHitDirection( const navlib::vector_t& direction )
|
||||||
|
{
|
||||||
|
return navlib::make_result_code( navlib::navlib_errc::invalid_operation );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long NL_SCHEMATIC_PLUGIN_IMPL::SetHitLookFrom( const navlib::point_t& eye )
|
||||||
|
{
|
||||||
|
return navlib::make_result_code( navlib::navlib_errc::invalid_operation );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long NL_SCHEMATIC_PLUGIN_IMPL::SetHitSelectionOnly( bool onlySelection )
|
||||||
|
{
|
||||||
|
return navlib::make_result_code( navlib::navlib_errc::invalid_operation );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long NL_SCHEMATIC_PLUGIN_IMPL::SetCameraTarget( const navlib::point_t& position )
|
||||||
|
{
|
||||||
|
return navlib::make_result_code( navlib::navlib_errc::invalid_operation );
|
||||||
|
}
|
|
@ -0,0 +1,147 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 3Dconnexion
|
||||||
|
* Copyright (C) 2022 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file nl_schematic_plugin_impl.h
|
||||||
|
* @brief Declaration of the NL_SCHEMATIC_PLUGIN_IMPL class
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NL_SCHEMATIC_PLUGIN_IMPL_H_
|
||||||
|
#define NL_SCHEMATIC_PLUGIN_IMPL_H_
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
#ifndef _WIN32_WINNT
|
||||||
|
#define _WIN32_WINNT 0x0603
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// TDxWare SDK.
|
||||||
|
#include <SpaceMouse/CNavigation3D.hpp>
|
||||||
|
|
||||||
|
// wx
|
||||||
|
#include <wx/chartype.h>
|
||||||
|
|
||||||
|
// KiCAD
|
||||||
|
#include <math/vector2d.h>
|
||||||
|
|
||||||
|
// stdlib
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// Forward declarations.
|
||||||
|
class EDA_DRAW_PANEL_GAL;
|
||||||
|
namespace KIGFX
|
||||||
|
{
|
||||||
|
class SCH_VIEW;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convenience typedef.
|
||||||
|
typedef TDx::SpaceMouse::Navigation3D::CNavigation3D NAV_3D;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The class that implements the accessors and mutators required for
|
||||||
|
* 3D navigation in an PCB_DRAW_PANEL_GAL using a SpaceMouse.
|
||||||
|
*/
|
||||||
|
class NL_SCHEMATIC_PLUGIN_IMPL : public NAV_3D
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Initializes a new instance of the NL_SCHEMATIC_PLUGIN_IMPL.
|
||||||
|
*/
|
||||||
|
NL_SCHEMATIC_PLUGIN_IMPL();
|
||||||
|
|
||||||
|
|
||||||
|
virtual ~NL_SCHEMATIC_PLUGIN_IMPL();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the viewport controlled by the SpaceMouse.
|
||||||
|
*
|
||||||
|
* @param aViewport is the viewport to be navigated.
|
||||||
|
*/
|
||||||
|
void SetCanvas( EDA_DRAW_PANEL_GAL* aViewport );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the connection to the 3Dconnexion driver to the focus state so that
|
||||||
|
* 3DMouse data is routed here.
|
||||||
|
*
|
||||||
|
* @param aFocus is true to set the connection active.
|
||||||
|
*/
|
||||||
|
void SetFocus( bool aFocus );
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Export the invocable actions and images to the 3Dconnexion UI.
|
||||||
|
*/
|
||||||
|
void exportCommandsAndImages();
|
||||||
|
|
||||||
|
long GetCameraMatrix( navlib::matrix_t& aMatrix ) const override;
|
||||||
|
long GetPointerPosition( navlib::point_t& aPosition ) const override;
|
||||||
|
long GetViewExtents( navlib::box_t& aExtents ) const override;
|
||||||
|
long GetViewFOV( double& aFov ) const override;
|
||||||
|
long GetViewFrustum( navlib::frustum_t& aFrustum ) const override;
|
||||||
|
long GetIsViewPerspective( navlib::bool_t& aPerspective ) const override;
|
||||||
|
long SetCameraMatrix( const navlib::matrix_t& aMatrix ) override;
|
||||||
|
long SetViewExtents( const navlib::box_t& aExtents ) override;
|
||||||
|
long SetViewFOV( double aFov ) override;
|
||||||
|
long SetViewFrustum( const navlib::frustum_t& aFrustum ) override;
|
||||||
|
long GetModelExtents( navlib::box_t& aExtents ) const override;
|
||||||
|
long GetSelectionExtents( navlib::box_t& aExtents ) const override;
|
||||||
|
long GetSelectionTransform( navlib::matrix_t& aTransform ) const override;
|
||||||
|
long GetIsSelectionEmpty( navlib::bool_t& aEmpty ) const override;
|
||||||
|
long SetSelectionTransform( const navlib::matrix_t& aMatrix ) override;
|
||||||
|
long GetPivotPosition( navlib::point_t& aPosition ) const override;
|
||||||
|
long IsUserPivot( navlib::bool_t& aUserPivot ) const override;
|
||||||
|
long SetPivotPosition( const navlib::point_t& aPosition ) override;
|
||||||
|
long GetPivotVisible( navlib::bool_t& aVisible ) const override;
|
||||||
|
long SetPivotVisible( bool aVisible ) override;
|
||||||
|
long GetHitLookAt( navlib::point_t& aPosition ) const override;
|
||||||
|
long SetHitAperture( double aAperture ) override;
|
||||||
|
long SetHitDirection( const navlib::vector_t& aDirection ) override;
|
||||||
|
long SetHitLookFrom( const navlib::point_t& aPosition ) override;
|
||||||
|
long SetHitSelectionOnly( bool aSelectionOnly ) override;
|
||||||
|
long SetActiveCommand( std::string aCommandId ) override;
|
||||||
|
|
||||||
|
long SetSettingsChanged( long aChangeNumber ) override;
|
||||||
|
long SetMotionFlag( bool aValue ) override;
|
||||||
|
long SetTransaction( long aValue ) override;
|
||||||
|
long SetCameraTarget( const navlib::point_t& aPosition ) override;
|
||||||
|
|
||||||
|
long GetFrontView( navlib::matrix_t& aMatrix ) const override;
|
||||||
|
long GetCoordinateSystem( navlib::matrix_t& aMatrix ) const override;
|
||||||
|
long GetIsViewRotatable( navlib::bool_t& isRotatable ) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
EDA_DRAW_PANEL_GAL* m_viewport2D;
|
||||||
|
KIGFX::SCH_VIEW* m_view;
|
||||||
|
bool m_isMoving;
|
||||||
|
mutable double m_viewportWidth;
|
||||||
|
mutable VECTOR2D m_viewPosition;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trace mask used to enable or disable the trace output of this class.
|
||||||
|
* The debug output can be turned on by setting the WXTRACE environment variable to
|
||||||
|
* "KI_TRACE_NL_SCHEMATIC_PLUGIN". See the wxWidgets documentation on wxLogTrace for
|
||||||
|
* more information.
|
||||||
|
*/
|
||||||
|
static const wxChar* m_logTrace;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NL_SCHEMATIC_PLUGIN_IMPL
|
|
@ -42,6 +42,9 @@
|
||||||
#include <tools/ee_actions.h>
|
#include <tools/ee_actions.h>
|
||||||
#include <tools/ee_selection_tool.h>
|
#include <tools/ee_selection_tool.h>
|
||||||
|
|
||||||
|
#if defined( KICAD_USE_3DCONNEXION )
|
||||||
|
#include <navlib/nl_schematic_plugin.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
LIB_SYMBOL* SchGetLibSymbol( const LIB_ID& aLibId, SYMBOL_LIB_TABLE* aLibTable,
|
LIB_SYMBOL* SchGetLibSymbol( const LIB_ID& aLibId, SYMBOL_LIB_TABLE* aLibTable,
|
||||||
SYMBOL_LIB* aCacheLib, wxWindow* aParent, bool aShowErrorMsg )
|
SYMBOL_LIB* aCacheLib, wxWindow* aParent, bool aShowErrorMsg )
|
||||||
|
@ -81,7 +84,8 @@ LIB_SYMBOL* SchGetLibSymbol( const LIB_ID& aLibId, SYMBOL_LIB_TABLE* aLibTable,
|
||||||
SCH_BASE_FRAME::SCH_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aWindowType,
|
SCH_BASE_FRAME::SCH_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aWindowType,
|
||||||
const wxString& aTitle, const wxPoint& aPosition,
|
const wxString& aTitle, const wxPoint& aPosition,
|
||||||
const wxSize& aSize, long aStyle, const wxString& aFrameName ) :
|
const wxSize& aSize, long aStyle, const wxString& aFrameName ) :
|
||||||
EDA_DRAW_FRAME( aKiway, aParent, aWindowType, aTitle, aPosition, aSize, aStyle, aFrameName ),
|
EDA_DRAW_FRAME( aKiway, aParent, aWindowType, aTitle, aPosition, aSize, aStyle,
|
||||||
|
aFrameName ),
|
||||||
m_base_frame_defaults( nullptr, "base_Frame_defaults" )
|
m_base_frame_defaults( nullptr, "base_Frame_defaults" )
|
||||||
{
|
{
|
||||||
createCanvas();
|
createCanvas();
|
||||||
|
@ -300,6 +304,28 @@ void SCH_BASE_FRAME::createCanvas()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SCH_BASE_FRAME::ActivateGalCanvas()
|
||||||
|
{
|
||||||
|
EDA_DRAW_FRAME::ActivateGalCanvas();
|
||||||
|
|
||||||
|
#if defined( KICAD_USE_3DCONNEXION )
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if( !m_spaceMouse )
|
||||||
|
{
|
||||||
|
m_spaceMouse = std::make_unique<NL_SCHEMATIC_PLUGIN>();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_spaceMouse->SetCanvas( GetCanvas() );
|
||||||
|
}
|
||||||
|
catch( const std::system_error& e )
|
||||||
|
{
|
||||||
|
wxLogTrace( wxT( "KI_TRACE_NAVLIB" ), e.what() );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_BASE_FRAME::UpdateItem( EDA_ITEM* aItem, bool isAddOrDelete, bool aUpdateRtree )
|
void SCH_BASE_FRAME::UpdateItem( EDA_ITEM* aItem, bool isAddOrDelete, bool aUpdateRtree )
|
||||||
{
|
{
|
||||||
EDA_ITEM* parent = aItem->GetParent();
|
EDA_ITEM* parent = aItem->GetParent();
|
||||||
|
@ -471,3 +497,28 @@ COLOR4D SCH_BASE_FRAME::GetDrawBgColor() const
|
||||||
return GetColorSettings()->GetColor( LAYER_SCHEMATIC_BACKGROUND );
|
return GetColorSettings()->GetColor( LAYER_SCHEMATIC_BACKGROUND );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SCH_BASE_FRAME::handleActivateEvent( wxActivateEvent& aEvent )
|
||||||
|
{
|
||||||
|
EDA_DRAW_FRAME::handleActivateEvent( aEvent );
|
||||||
|
|
||||||
|
#if defined( KICAD_USE_3DCONNEXION )
|
||||||
|
if( m_spaceMouse )
|
||||||
|
{
|
||||||
|
m_spaceMouse->SetFocus( aEvent.GetActive() );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SCH_BASE_FRAME::handleIconizeEvent( wxIconizeEvent& aEvent )
|
||||||
|
{
|
||||||
|
EDA_DRAW_FRAME::handleIconizeEvent( aEvent );
|
||||||
|
|
||||||
|
#if defined( KICAD_USE_3DCONNEXION )
|
||||||
|
if( m_spaceMouse && aEvent.IsIconized() )
|
||||||
|
{
|
||||||
|
m_spaceMouse->SetFocus( false );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
|
@ -58,6 +58,10 @@ class SYMBOL_LIB_TABLE;
|
||||||
class EESCHEMA_SETTINGS;
|
class EESCHEMA_SETTINGS;
|
||||||
class SYMBOL_EDITOR_SETTINGS;
|
class SYMBOL_EDITOR_SETTINGS;
|
||||||
|
|
||||||
|
#if defined( KICAD_USE_3DCONNEXION )
|
||||||
|
class NL_SCHEMATIC_PLUGIN;
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load symbol from symbol library table.
|
* Load symbol from symbol library table.
|
||||||
*
|
*
|
||||||
|
@ -241,7 +245,13 @@ public:
|
||||||
|
|
||||||
COLOR_SETTINGS* GetColorSettings( bool aForceRefresh = false ) const override;
|
COLOR_SETTINGS* GetColorSettings( bool aForceRefresh = false ) const override;
|
||||||
|
|
||||||
|
void ActivateGalCanvas() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void handleActivateEvent( wxActivateEvent& aEvent ) override;
|
||||||
|
|
||||||
|
void handleIconizeEvent( wxIconizeEvent& aEvent ) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save Symbol Library Tables to disk.
|
* Save Symbol Library Tables to disk.
|
||||||
*
|
*
|
||||||
|
@ -254,6 +264,11 @@ protected:
|
||||||
/// These are only used by symbol_editor. Eeschema should be using the one inside
|
/// These are only used by symbol_editor. Eeschema should be using the one inside
|
||||||
/// the SCHEMATIC.
|
/// the SCHEMATIC.
|
||||||
SCHEMATIC_SETTINGS m_base_frame_defaults;
|
SCHEMATIC_SETTINGS m_base_frame_defaults;
|
||||||
|
|
||||||
|
private:
|
||||||
|
#if defined( KICAD_USE_3DCONNEXION )
|
||||||
|
std::unique_ptr<NL_SCHEMATIC_PLUGIN> m_spaceMouse;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SCH_BASE_FRAME_H_
|
#endif // SCH_BASE_FRAME_H_
|
||||||
|
|
|
@ -606,6 +606,15 @@ protected:
|
||||||
*/
|
*/
|
||||||
void onAutoSaveTimer( wxTimerEvent& aEvent );
|
void onAutoSaveTimer( wxTimerEvent& aEvent );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle a window iconize event.
|
||||||
|
*
|
||||||
|
* @param aEvent is the data for the event.
|
||||||
|
*/
|
||||||
|
virtual void handleIconizeEvent( wxIconizeEvent& aEvent ) {}
|
||||||
|
void onIconize( wxIconizeEvent& aEvent );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the auto save status of the application.
|
* Return the auto save status of the application.
|
||||||
*
|
*
|
||||||
|
|
|
@ -392,6 +392,8 @@ protected:
|
||||||
|
|
||||||
void handleActivateEvent( wxActivateEvent& aEvent ) override;
|
void handleActivateEvent( wxActivateEvent& aEvent ) override;
|
||||||
|
|
||||||
|
void handleIconizeEvent( wxIconizeEvent& aEvent ) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to load \a aFootprintId from the footprint library table.
|
* Attempts to load \a aFootprintId from the footprint library table.
|
||||||
*
|
*
|
||||||
|
|
|
@ -7,6 +7,11 @@
|
||||||
*
|
*
|
||||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
*
|
*
|
||||||
|
* The equals() method to compare two floating point values adapted from
|
||||||
|
* AlmostEqualRelativeAndAbs() on
|
||||||
|
* https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
|
||||||
|
* (C) Bruce Dawson subject to the Apache 2.0 license.
|
||||||
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation; either version 2
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
@ -32,6 +37,7 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to avoid directly including wx/log.h for the templated functions in kimath
|
* Helper to avoid directly including wx/log.h for the templated functions in kimath
|
||||||
|
@ -113,4 +119,37 @@ int rescale( int aNumerator, int aValue, int aDenominator );
|
||||||
template <>
|
template <>
|
||||||
int64_t rescale( int64_t aNumerator, int64_t aValue, int64_t aDenominator );
|
int64_t rescale( int64_t aNumerator, int64_t aValue, int64_t aDenominator );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Template to compare two floating point values for equality within a required epsilon.
|
||||||
|
*
|
||||||
|
* @param aFirst value to compare.
|
||||||
|
* @param aSecond value to compare.
|
||||||
|
* @param aEpsilon allowed error.
|
||||||
|
* @return true if the values considered equal within the specified epsilon, otherwise false.
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
typename std::enable_if<!std::numeric_limits<T>::is_integer, bool>::type
|
||||||
|
equals( T aFirst, T aSecond, T aEpsilon = std::numeric_limits<T>::epsilon() )
|
||||||
|
{
|
||||||
|
T diff = fabs( aFirst - aSecond );
|
||||||
|
|
||||||
|
if( diff < aEpsilon )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
aFirst = fabs( aFirst );
|
||||||
|
aSecond = fabs( aSecond );
|
||||||
|
T largest = aFirst > aSecond ? aFirst : aSecond;
|
||||||
|
|
||||||
|
if( diff <= largest * aEpsilon )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // UTIL_H
|
#endif // UTIL_H
|
||||||
|
|
|
@ -573,6 +573,28 @@ const int LexicographicalCompare( const VECTOR2<T>& aA, const VECTOR2<T>& aB )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Template to compare two VECTOR2<T> values for equality within a required epsilon.
|
||||||
|
*
|
||||||
|
* @param aFirst value to compare.
|
||||||
|
* @param aSecond value to compare.
|
||||||
|
* @param aEpsilon allowed error.
|
||||||
|
* @return true if the values considered equal within the specified epsilon, otherwise false.
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
typename std::enable_if<!std::numeric_limits<T>::is_integer, bool>::type
|
||||||
|
equals( VECTOR2<T> const& aFirst, VECTOR2<T> const& aSecond,
|
||||||
|
T aEpsilon = std::numeric_limits<T>::epsilon() )
|
||||||
|
{
|
||||||
|
if( !equals( aFirst.x, aSecond.x, aEpsilon ) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return equals( aFirst.y, aSecond.y, aEpsilon );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
std::ostream& operator<<( std::ostream& aStream, const VECTOR2<T>& aVector )
|
std::ostream& operator<<( std::ostream& aStream, const VECTOR2<T>& aVector )
|
||||||
{
|
{
|
||||||
|
|
|
@ -42,55 +42,6 @@
|
||||||
#include <wx/log.h>
|
#include <wx/log.h>
|
||||||
#include <wx/mstream.h>
|
#include <wx/mstream.h>
|
||||||
|
|
||||||
/**
|
|
||||||
* Template to compare two floating point values for equality within a required epsilon.
|
|
||||||
*
|
|
||||||
* @param aFirst value to compare.
|
|
||||||
* @param aSecond value to compare.
|
|
||||||
* @param aEpsilon allowed error.
|
|
||||||
* @return true if the values considered equal within the specified epsilon, otherwise false.
|
|
||||||
*/
|
|
||||||
template <class T>
|
|
||||||
bool equals( T aFirst, T aSecond, T aEpsilon = static_cast<T>( FLT_EPSILON ) )
|
|
||||||
{
|
|
||||||
T diff = fabs( aFirst - aSecond );
|
|
||||||
|
|
||||||
if( diff < aEpsilon )
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
aFirst = fabs( aFirst );
|
|
||||||
aSecond = fabs( aSecond );
|
|
||||||
T largest = aFirst > aSecond ? aFirst : aSecond;
|
|
||||||
|
|
||||||
if( diff <= largest * aEpsilon )
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Template to compare two VECTOR2<T> values for equality within a required epsilon.
|
|
||||||
*
|
|
||||||
* @param aFirst value to compare.
|
|
||||||
* @param aSecond value to compare.
|
|
||||||
* @param aEpsilon allowed error.
|
|
||||||
* @return true if the values considered equal within the specified epsilon, otherwise false.
|
|
||||||
*/
|
|
||||||
template <class T>
|
|
||||||
bool equals( VECTOR2<T> const& aFirst, VECTOR2<T> const& aSecond,
|
|
||||||
T aEpsilon = static_cast<T>( FLT_EPSILON ) )
|
|
||||||
{
|
|
||||||
if( !equals( aFirst.x, aSecond.x, aEpsilon ) )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return equals( aFirst.y, aSecond.y, aEpsilon );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag to enable the NL_PCBNEW_PLUGIN debug tracing.
|
* Flag to enable the NL_PCBNEW_PLUGIN debug tracing.
|
||||||
|
@ -129,7 +80,7 @@ NL_PCBNEW_PLUGIN_IMPL::~NL_PCBNEW_PLUGIN_IMPL()
|
||||||
|
|
||||||
void NL_PCBNEW_PLUGIN_IMPL::SetFocus( bool aFocus )
|
void NL_PCBNEW_PLUGIN_IMPL::SetFocus( bool aFocus )
|
||||||
{
|
{
|
||||||
wxLogTrace( m_logTrace, "NL_PCBNEW_PLUGIN_IMPL::SetFocus %d", aFocus );
|
wxLogTrace( m_logTrace, wxT( "NL_PCBNEW_PLUGIN_IMPL::SetFocus %d" ), aFocus );
|
||||||
NAV_3D::Write( navlib::focus_k, aFocus );
|
NAV_3D::Write( navlib::focus_k, aFocus );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +129,7 @@ static CATEGORY_STORE::iterator add_category( std::string aCategoryPath,
|
||||||
|
|
||||||
void NL_PCBNEW_PLUGIN_IMPL::exportCommandsAndImages()
|
void NL_PCBNEW_PLUGIN_IMPL::exportCommandsAndImages()
|
||||||
{
|
{
|
||||||
wxLogTrace( m_logTrace, "NL_PCBNEW_PLUGIN_IMPL::exportCommandsAndImages" );
|
wxLogTrace( m_logTrace, wxT( "NL_PCBNEW_PLUGIN_IMPL::exportCommandsAndImages" ) );
|
||||||
|
|
||||||
std::list<TOOL_ACTION*> actions = ACTION_MANAGER::GetActionList();
|
std::list<TOOL_ACTION*> actions = ACTION_MANAGER::GetActionList();
|
||||||
|
|
||||||
|
@ -253,13 +204,13 @@ void NL_PCBNEW_PLUGIN_IMPL::exportCommandsAndImages()
|
||||||
streamBuffer->GetBufferSize() ),
|
streamBuffer->GetBufferSize() ),
|
||||||
0 );
|
0 );
|
||||||
|
|
||||||
wxLogTrace( m_logTrace, "Adding image for : %s", name );
|
wxLogTrace( m_logTrace, wxT( "Adding image for : %s" ), name );
|
||||||
vImages.push_back( std::move( tdxImage ) );
|
vImages.push_back( std::move( tdxImage ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wxLogTrace( m_logTrace, "Inserting command: %s, description: %s, in category: %s", name,
|
wxLogTrace( m_logTrace, wxT( "Inserting command: %s, description: %s, in category: %s" ),
|
||||||
description, iter->first );
|
name, description, iter->first );
|
||||||
|
|
||||||
iter->second->push_back(
|
iter->second->push_back(
|
||||||
CCommand( std::move( name ), std::move( label ), std::move( description ) ) );
|
CCommand( std::move( name ), std::move( label ), std::move( description ) ) );
|
||||||
|
@ -349,7 +300,8 @@ long NL_PCBNEW_PLUGIN_IMPL::SetCameraMatrix( const navlib::matrix_t& matrix )
|
||||||
long result = 0;
|
long result = 0;
|
||||||
VECTOR2D viewPos( matrix.m4x4[3][0], matrix.m4x4[3][1] );
|
VECTOR2D viewPos( matrix.m4x4[3][0], matrix.m4x4[3][1] );
|
||||||
|
|
||||||
if( !equals( m_view->GetCenter(), m_viewPosition ) )
|
if( !equals( m_view->GetCenter(), m_viewPosition,
|
||||||
|
static_cast<VECTOR2D::coord_type>( FLT_EPSILON ) ) )
|
||||||
{
|
{
|
||||||
m_view->SetCenter( viewPos + m_view->GetCenter() - m_viewPosition );
|
m_view->SetCenter( viewPos + m_view->GetCenter() - m_viewPosition );
|
||||||
result = navlib::make_result_code( navlib::navlib_errc::error );
|
result = navlib::make_result_code( navlib::navlib_errc::error );
|
||||||
|
@ -385,7 +337,7 @@ long NL_PCBNEW_PLUGIN_IMPL::SetViewExtents( const navlib::box_t& extents )
|
||||||
double scale = width / m_viewportWidth * m_view->GetScale();
|
double scale = width / m_viewportWidth * m_view->GetScale();
|
||||||
m_view->SetScale( scale, m_view->GetCenter() );
|
m_view->SetScale( scale, m_view->GetCenter() );
|
||||||
|
|
||||||
if( !equals( m_view->GetScale(), scale ) )
|
if( !equals( m_view->GetScale(), scale, static_cast<double>( FLT_EPSILON ) ) )
|
||||||
{
|
{
|
||||||
result = navlib::make_result_code( navlib::navlib_errc::error );
|
result = navlib::make_result_code( navlib::navlib_errc::error );
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,6 +119,19 @@ void PCB_BASE_FRAME::handleActivateEvent( wxActivateEvent& aEvent )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PCB_BASE_FRAME::handleIconizeEvent( wxIconizeEvent& aEvent )
|
||||||
|
{
|
||||||
|
EDA_DRAW_FRAME::handleIconizeEvent( aEvent );
|
||||||
|
|
||||||
|
#if defined( KICAD_USE_3DCONNEXION )
|
||||||
|
if( m_spaceMouse != nullptr && aEvent.IsIconized() )
|
||||||
|
{
|
||||||
|
m_spaceMouse->SetFocus( false );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
EDA_3D_VIEWER_FRAME* PCB_BASE_FRAME::Get3DViewerFrame()
|
EDA_3D_VIEWER_FRAME* PCB_BASE_FRAME::Get3DViewerFrame()
|
||||||
{
|
{
|
||||||
wxWindow* frame = FindWindowByName( QUALIFIED_VIEWER3D_FRAMENAME( this ) );
|
wxWindow* frame = FindWindowByName( QUALIFIED_VIEWER3D_FRAMENAME( this ) );
|
||||||
|
|
Loading…
Reference in New Issue