Include the required third party code for the SpaceMouse implementation

The commit only adds the headers and code required by the SpaceMouse
implementation to compile and link. This extract from the 3Dconnexion
SDK is added to the third party directory to allow developers to build without
needing to acquire a cmake enabled version.
This commit is contained in:
markus-bonk 2021-06-14 14:14:17 +02:00 committed by Wayne Stambaugh
parent cd82a927c2
commit c99a4f4d85
38 changed files with 7620 additions and 0 deletions

48
thirdparty/3dxware_sdk/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,48 @@
cmake_policy(PUSH)
cmake_policy(VERSION 2.6)
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Compute the installation prefix relative to this file.
get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
if(_IMPORT_PREFIX STREQUAL "/")
set(_IMPORT_PREFIX "")
endif()
set(TDxWare_INCLUDE_DIR "${_IMPORT_PREFIX}/inc")
set(TDxWare_INCLUDE_DIRS ${TDxWare_INCLUDE_DIR})
# ------------------------------------------------------------------------
# Add imported targets
# ------------------------------------------------------------------------
if(NOT TARGET 3DxWare::headers)
add_library(3DxWare::headers INTERFACE IMPORTED)
if(TDxWare_INCLUDE_DIRS)
set_target_properties(3DxWare::headers PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${TDxWare_INCLUDE_DIRS}")
endif()
endif()
if(NOT TARGET TDxNavlib)
set(NAVLIB_LIB_SRCS
src/navlib_stub.c
src/navlib_load.cpp
)
add_library(TDxNavlib STATIC ${NAVLIB_LIB_SRCS})
target_include_directories( TDxNavlib PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc" )
set_target_properties(TDxNavlib PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${TDxWare_INCLUDE_DIRS}")
set_target_properties(TDxNavlib PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "CXX")
endif()
if(NOT TARGET 3DxWare::Navlib)
add_library(3DxWare::Navlib ALIAS TDxNavlib)
endif()
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)

3
thirdparty/3dxware_sdk/README.txt vendored Normal file
View File

@ -0,0 +1,3 @@
This directory contains part of the the 3Dconnexion 3DxWare_SDK v4
The full sdk can be obtained from https://3dconnexion.com/software-developer-program/

View File

@ -0,0 +1,108 @@
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Right
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: false
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 100
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
- Regex: '.*'
Priority: 1
IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: false
IndentWidth: 2
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 8
UseTab: Never
...

View File

@ -0,0 +1,364 @@
#ifndef CActionNode_HPP_INCLUDED
#define CActionNode_HPP_INCLUDED
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (c) 2018-2021 3Dconnexion.
*
* 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 CActionNode.hpp
* @brief SiActionNodeEx_t wrapper.
*/
// 3dxware
#include <siappcmd_types.h>
// stdlib
#include <memory>
#include <string>
#include <vector>
#ifndef NOEXCEPT
#if defined(_MSC_VER) && _MSC_VER < 1800
#ifdef _NOEXCEPT
#define NOEXCEPT _NOEXCEPT
#else
#define NOEXCEPT
#endif
#else
#define NOEXCEPT noexcept
#endif
#endif
#if !_MSC_VER
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#endif
/// <summary>
/// The TDx namespace provides support for the types used in the 3DxWare interface.
/// </summary>
namespace TDx {
/// <summary>
/// Wrapper class for the <see cref="SiActionNodeEx_t"/> structure.
/// </summary>
class CActionNode : private SiActionNodeEx_t {
typedef SiActionNodeEx_t base_type;
public:
/// <summary>
/// Initializes a new instance of the <see cref="CActionNode"/> class.
/// </summary>
#if defined(_MSC_VER) && _MSC_VER < 1800
CActionNode() : base_type() {
base_type::size = sizeof(base_type);
}
#else
CActionNode() : base_type{sizeof(base_type)} {
}
#endif
/// <summary>
/// Constructor a <see cref="CActionNode"/> with a label.
/// </summary>
/// <param name="id">The unique node identifier.</param>
/// <param name="label">Text to display to the user in the user interface.</param>
/// <param name="type">The <see cref="SiActionNodeType_t"/> of the node.</param>
explicit CActionNode(std::string id, std::string label, SiActionNodeType_t type)
#if defined(_MSC_VER) && _MSC_VER < 1800
: base_type(), m_id(std::move(id)), m_label(std::move(label)) {
base_type::size = sizeof(base_type);
base_type::type = type;
#else
: base_type({sizeof(base_type), type}), m_id(std::move(id)), m_label(std::move(label)) {
#endif
if (!m_id.empty()) {
base_type::id = m_id.c_str();
}
if (!m_label.empty()) {
base_type::label = m_label.c_str();
}
}
/// <summary>
/// Constructor a <see cref="CActionNode"/> with a label and a description for a tooltip.
/// </summary>
/// <param name="id">The unique node identifier</param>
/// <param name="label">Text to display to the user in the user interface.</param>
/// <param name="description">Text to display in a tooltip.</param>
/// <param name="type">The <see cref="SiActionNodeType_t"/> of the node.</param>
explicit CActionNode(std::string id, std::string label, std::string description,
SiActionNodeType_t type)
#if defined(_MSC_VER) && _MSC_VER < 1800
: base_type(), m_id(std::move(id)), m_label(std::move(label)),
m_description(std::move(description)) {
base_type::size = sizeof(base_type);
base_type::type = type;
#else
: base_type({sizeof(base_type), type}), m_id(std::move(id)), m_label(std::move(label)),
m_description(std::move(description)) {
#endif
if (!m_id.empty()) {
base_type::id = m_id.c_str();
}
if (!m_label.empty()) {
base_type::label = m_label.c_str();
}
if (!m_description.empty()) {
base_type::description = m_description.c_str();
}
}
virtual ~CActionNode() {
Tidy();
}
/// <summary>
/// Move constructor
/// </summary>
/// <param name="other">The <see cref="CActionNode"/> to use for construction.</param>
CActionNode(CActionNode &&other) NOEXCEPT : base_type(other),
m_id(std::move(other.m_id)),
m_label(std::move(other.m_label)),
m_description(std::move(other.m_description)) {
base_type zero = {sizeof(base_type)};
static_cast<base_type &>(other) = zero;
base_type::id = !m_id.empty() ? m_id.c_str() : nullptr;
base_type::label = !m_label.empty() ? m_label.c_str() : nullptr;
base_type::description = !m_description.empty() ? m_description.c_str() : nullptr;
}
/// <summary>
/// Move assignment
/// </summary>
/// <param name="other">The <see cref="CActionNode"/> to use for construction.</param>
CActionNode &operator=(CActionNode &&other) NOEXCEPT {
static_cast<base_type &>(*this) = static_cast<base_type>(other);
m_id = std::move(other.m_id);
m_label = std::move(other.m_label);
m_description = std::move(other.m_description);
base_type zero = {sizeof(base_type)};
static_cast<base_type &>(other) = zero;
base_type::id = !m_id.empty() ? m_id.c_str() : nullptr;
base_type::label = !m_label.empty() ? m_label.c_str() : nullptr;
base_type::description = !m_description.empty() ? m_description.c_str() : nullptr;
return *this;
}
#if !defined(_MSC_VER) || _MSC_VER > 1700
CActionNode(const CActionNode &) = delete;
CActionNode &operator=(const CActionNode &) = delete;
#else
private:
CActionNode(const CActionNode &);
CActionNode &operator=(const CActionNode &);
#endif
public:
/// <summary>
/// Set the <see cref="SiActionNodeEx_t"/> child node.
/// </summary>
/// <param name="child">The child node.</param>
template <typename _Ty> void PutChild(_Ty &&child) {
if (base_type::children) {
delete static_cast<CActionNode *>(base_type::children);
}
base_type::children = child.release();
}
/// <summary>
/// Set the next <see cref="SiActionNodeEx_t"/> node.
/// </summary>
/// <param name="next">The next node.</param>
template <typename _Ty> void PutNext(_Ty &&next) {
if (base_type::next) {
delete static_cast<CActionNode *>(base_type::next);
}
base_type::next = next.release();
}
#if !defined(__GNUC__) || defined(__clang__)
/// <summary>
/// The <see cref="SiActionNodeEx_t"/> properties.
/// </summary>
__declspec(property(get = GetId, put = PutId)) std::string Id;
__declspec(property(get = GetDescription, put = PutDescription)) std::string Description;
__declspec(property(get = GetLabel, put = PutLabel)) std::string Label;
__declspec(property(get = GetType, put = PutType)) SiActionNodeType_t Type;
#endif
void PutType(const SiActionNodeType_t value) {
base_type::type = value;
}
void PutId(std::string value) {
m_id = std::move(value);
base_type::id = m_id.c_str();
}
void PutLabel(std::string value) {
m_label = std::move(value);
base_type::label = m_label.c_str();
}
void PutDescription(std::string value) {
m_description = std::move(value);
base_type::description = m_description.c_str();
}
CActionNode *DetachChild() {
CActionNode *p = static_cast<CActionNode *>(base_type::children);
base_type::children = nullptr;
return p;
}
CActionNode *DetachNext() {
CActionNode *p = static_cast<CActionNode *>(base_type::next);
base_type::next = nullptr;
return p;
}
CActionNode *GetChild() {
return static_cast<CActionNode *>(base_type::children);
}
const CActionNode *GetChild() const {
return static_cast<const CActionNode *>(base_type::children);
}
CActionNode *GetNext() {
return static_cast<CActionNode *>(base_type::next);
}
const CActionNode *GetNext() const {
return static_cast<const CActionNode *>(base_type::next);
}
std::string GetId() const {
return m_id;
}
std::string GetLabel() const {
return m_label;
}
std::string GetDescription() const {
return m_description;
}
const SiActionNodeType_t GetType() const {
return base_type::type;
}
const SiActionNodeEx_t &GetSiActionNode() const {
return *this;
}
/// <summary>
/// Clears this and the linked nodes.
/// </summary>
void clear() {
base_type::id = base_type::label = base_type::description = nullptr;
m_id.clear();
m_label.clear();
m_description.clear();
Tidy();
}
/// <summary>
/// Returns true if the node is empty and has no linked nodes
/// </summary>
/// <returns></returns>
bool empty() const {
return m_id.empty() && base_type::next == nullptr && base_type::children == nullptr &&
m_label.empty() && m_description.empty();
}
private:
void AssignBaseDataValues() {
base_type::id = !m_id.empty() ? m_id.c_str() : nullptr;
base_type::label = !m_label.empty() ? m_label.c_str() : nullptr;
base_type::description = !m_description.empty() ? m_description.c_str() : nullptr;
}
void Tidy() {
if (base_type::next == 0 && base_type::children == 0) {
return;
}
CActionNode *nextNode = static_cast<CActionNode *>(base_type::next);
CActionNode *childrenNodes = static_cast<CActionNode *>(base_type::children);
base_type::next = 0;
base_type::children = 0;
// Fix to avoid a stack overflow when destructing large lists
// This traverses to the end of the list and deletes from there
std::vector<CActionNode *> vnodes;
if (nextNode) {
vnodes.push_back(nextNode);
}
if (childrenNodes) {
vnodes.push_back(childrenNodes);
}
size_t i;
for (i = 0; i < vnodes.size(); ++i) {
nextNode = static_cast<CActionNode *>(vnodes[i]->next);
childrenNodes = static_cast<CActionNode *>(vnodes[i]->children);
if (nextNode) {
vnodes[i]->next = 0;
vnodes.push_back(nextNode);
}
if (childrenNodes) {
vnodes[i]->children = 0;
vnodes.push_back(childrenNodes);
}
}
std::vector<CActionNode *>::reverse_iterator riter;
for (riter = vnodes.rbegin(); riter != vnodes.rend(); ++riter) {
delete (*riter);
}
}
private:
std::string m_id;
std::string m_label;
std::string m_description;
};
} // namespace TDx
#if !_MSC_VER
#pragma GCC diagnostic pop
#endif
#endif // CActionNode_HPP_INCLUDED

View File

@ -0,0 +1,71 @@
#ifndef CCategory_HPP_INCLUDED
#define CCategory_HPP_INCLUDED
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (c) 2018-2021 3Dconnexion.
*
* 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 CCategory.hpp
* @brief SiActionNodeEx_t wrapper.
*/
#include <SpaceMouse/CCommandTreeNode.hpp>
#if !_MSC_VER
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow"
#endif
namespace TDx {
/// <summary>
/// Contains types used for programming the SpaceMouse.
/// </summary>
namespace SpaceMouse {
/// <summary>
/// The helper class implements the <see cref="SiActionNodeType_t::SI_CATEGORY_NODE"/> node type.
/// </summary>
class CCategory : public CCommandTreeNode {
typedef CCommandTreeNode base_type;
public:
CCategory() {
}
explicit CCategory(std::string id, std::string name)
: base_type(std::move(id), std::move(name), SiActionNodeType_t::SI_CATEGORY_NODE) {
}
#if defined(_MSC_VER) && _MSC_VER < 1900
CCategory(CCategory &&other) NOEXCEPT : base_type(std::forward<base_type>(other)) {
}
CCategory &operator=(CCategory &&other) NOEXCEPT {
base_type::operator=(std::forward<base_type>(other));
return *this;
}
#else
CCategory(CCategory &&) = default;
CCategory &operator=(CCategory &&) = default;
#endif
};
} // namespace SpaceMouse
} // namespace TDx
#if !_MSC_VER
#pragma GCC diagnostic pop
#endif
#endif // CCategory_HPP_INCLUDED

View File

@ -0,0 +1,71 @@
#ifndef CCommand_HPP_INCLUDED
#define CCommand_HPP_INCLUDED
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (c) 2018-2021 3Dconnexion.
*
* 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 CCommand.hpp
* @brief SiActionNodeEx_t wrapper.
*/
#include <SpaceMouse/CCommandTreeNode.hpp>
#if !_MSC_VER
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow"
#endif
namespace TDx {
namespace SpaceMouse {
/// <summary>
/// The <see cref="CCommand"/> class implements the application command node.
/// </summary>
class CCommand : public CCommandTreeNode {
typedef CCommandTreeNode base_type;
public:
CCommand() {
}
explicit CCommand(std::string id, std::string name, std::string description)
: base_type(std::move(id), std::move(name), std::move(description),
SiActionNodeType_t::SI_ACTION_NODE) {
}
explicit CCommand(std::string id, std::string name)
: base_type(std::move(id), std::move(name), SiActionNodeType_t::SI_ACTION_NODE) {
}
#if defined(_MSC_VER) && _MSC_VER < 1900
CCommand(CCommand &&other) NOEXCEPT : base_type(std::forward<base_type>(other)) {
}
CCommand &operator=(CCommand &&other) NOEXCEPT {
base_type::operator=(std::forward<base_type>(other));
return *this;
}
#else
CCommand(CCommand &&) = default;
CCommand &operator=(CCommand &&) = default;
#endif
};
} // namespace SpaceMouse
} // namespace TDx
#if !_MSC_VER
#pragma GCC diagnostic pop
#endif
#endif // CCommand_HPP_INCLUDED

View File

@ -0,0 +1,67 @@
#ifndef CCommandSet_HPP_INCLUDED
#define CCommandSet_HPP_INCLUDED
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (c) 2018-2021 3Dconnexion.
*
* 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 CCommandSet.hpp
* @brief SiActionNodeEx_t wrapper.
*/
#include <SpaceMouse/CCommandTreeNode.hpp>
#if !_MSC_VER
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow"
#endif
namespace TDx {
namespace SpaceMouse {
/// <summary>
/// The helper class implements the <see cref="SiActionNodeType_t::SI_ACTIONSET_NODE"/> node type.
/// </summary>
class CCommandSet : public CCommandTreeNode {
typedef CCommandTreeNode base_type;
public:
CCommandSet() {
}
explicit CCommandSet(std::string id, std::string name)
: base_type(std::move(id), std::move(name), SiActionNodeType_t::SI_ACTIONSET_NODE) {
}
#if defined(_MSC_VER) && _MSC_VER < 1900
CCommandSet(CCommandSet &&other) NOEXCEPT : base_type(std::forward<base_type>(other)) {
}
CCommandSet &operator=(CCommandSet &&other) NOEXCEPT {
base_type::operator=(std::forward<base_type>(other));
return *this;
}
#else
CCommandSet(CCommandSet &&) = default;
CCommandSet &operator=(CCommandSet &&) = default;
#endif
};
} // namespace SpaceMouse
} // namespace TDx
#if !_MSC_VER
#pragma GCC diagnostic pop
#endif
#endif // CCommandSet_HPP_INCLUDED

View File

@ -0,0 +1,295 @@
#ifndef CCommandTreeNode_HPP_INCLUDED
#define CCommandTreeNode_HPP_INCLUDED
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (c) 2018-2021 3Dconnexion.
*
* 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 CCommandTreeNode.hpp
* @brief Tree container for CActionNode.
*/
#include <SpaceMouse/CActionNode.hpp>
// stdlib
#include <exception>
#include <iterator>
#include <memory>
#if !_MSC_VER
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow"
#endif
namespace TDx {
template <typename _Ty, bool doubled_linked = false> class raw_linkedlist_iterator {
public:
typedef std::input_iterator_tag iterator_category;
typedef _Ty value_type;
typedef ptrdiff_t difference_type;
typedef _Ty *pointer;
typedef _Ty &reference;
public:
raw_linkedlist_iterator(_Ty *_ptr = nullptr) : _MyPtr(_ptr) {
}
raw_linkedlist_iterator(const raw_linkedlist_iterator<_Ty> &_other) : _MyPtr(_other._MyPtr) {
}
raw_linkedlist_iterator<_Ty> &operator=(const raw_linkedlist_iterator<_Ty> &_other) {
_MyPtr = _other._MyPtr;
return *this;
}
raw_linkedlist_iterator<_Ty> &operator=(_Ty *_ptr) {
_MyPtr = _ptr;
return *this;
}
// accessors
_Ty &operator*() {
return *_MyPtr;
}
_Ty const &operator*() const {
return *_MyPtr;
}
_Ty *operator->() {
return _MyPtr;
}
_Ty const *operator->() const {
return _MyPtr;
}
raw_linkedlist_iterator<_Ty> &operator++() {
if (_MyPtr)
_MyPtr = _MyPtr->GetNext();
return *this;
}
raw_linkedlist_iterator<_Ty> &operator--() {
if (doubled_linked) {
if (_MyPtr)
_MyPtr = _MyPtr->GetPrevious();
} else {
throw std::logic_error("Not Supported");
}
return *this;
}
bool operator<(raw_linkedlist_iterator<_Ty> const &rhs) const {
if (!_MyPtr)
return false;
else if (!rhs._MyPtr)
return true;
return (_MyPtr < rhs._MyPtr);
}
bool operator<=(raw_linkedlist_iterator<_Ty> const &rhs) const {
if (_MyPtr == rhs._MyPtr)
return true;
return operator<(rhs);
}
bool operator>(raw_linkedlist_iterator<_Ty> const &rhs) const {
return !operator<=(rhs);
}
bool operator>=(raw_linkedlist_iterator<_Ty> const &rhs) const {
return !operator<(rhs);
}
operator bool() const {
return _MyPtr != nullptr;
}
protected:
_Ty *_MyPtr;
};
/// <summary>
/// Tree container for CActionNode.
/// </summary>
/// <remarks>The tree is implemented as a singularly linked list.</remarks>
class CCommandTree : public CActionNode {
public:
typedef CActionNode base_type;
typedef CActionNode const const_base_type;
typedef CActionNode const &const_base_ref_type;
typedef CActionNode const *const_base_ptr_type;
typedef CCommandTree self_type;
public:
typedef CCommandTree &reference;
typedef CCommandTree const &const_reference;
typedef raw_linkedlist_iterator<base_type> iterator;
typedef raw_linkedlist_iterator<const base_type> const_iterator;
CCommandTree() {
}
explicit CCommandTree(std::string id, std::string label, std::string description,
SiActionNodeType_t type)
: base_type(std::move(id), std::move(label), std::move(description), type) {
}
explicit CCommandTree(std::string id, std::string label, SiActionNodeType_t type)
: base_type(std::move(id), std::move(label), type) {
}
#if defined(_MSC_VER) && _MSC_VER < 1900
CCommandTree(CCommandTree &&other) NOEXCEPT : base_type(std::forward<base_type>(other)) {
}
CCommandTree &operator=(CCommandTree &&other) NOEXCEPT {
base_type::operator=(std::forward<base_type>(other));
return *this;
}
private:
CCommandTree(const CCommandTree &) {
}
const CCommandTree &operator=(const CCommandTree &){};
#else
CCommandTree(CCommandTree &&) = default;
CCommandTree &operator=(CCommandTree &&) = default;
// No copying
CCommandTree(const CCommandTree &) = delete;
const CCommandTree &operator=(const CCommandTree &) = delete;
#endif // defined(_MSC_VER) && _MSC_VER<1900
public:
void push_back(base_type &&value) {
#if (defined(_MSC_VER) && _MSC_VER < 1900)
std::unique_ptr<base_type> node(new base_type(std::forward<base_type>(value)));
#else
std::unique_ptr<base_type> node = std::make_unique<base_type>(std::forward<base_type>(value));
#endif
push_back(std::move(node));
}
template <class T>
void
push_back(std::unique_ptr<T> &&value,
typename std::enable_if<std::is_base_of<CActionNode, T>::value>::type * = nullptr) {
base_type *last = this->GetChild();
if (!last) {
PutChild(std::unique_ptr<base_type>(static_cast<base_type *>(value.release())));
} else {
while (last->GetNext() != nullptr) {
last = last->GetNext();
}
last->PutNext(std::unique_ptr<base_type>(static_cast<base_type *>(value.release())));
}
}
void push_front(base_type &&value) {
#if (defined(_MSC_VER) && _MSC_VER < 1900)
std::unique_ptr<base_type> node(new base_type(std::forward<base_type>(value)));
#else
std::unique_ptr<base_type> node = std::make_unique<base_type>(std::forward<base_type>(value));
#endif
push_front(std::move(node));
}
void push_front(std::unique_ptr<base_type> &&value) {
value->PutNext(std::unique_ptr<base_type>(DetachChild()));
PutChild(std::forward<std::unique_ptr<base_type>>(value));
}
const_reference back() const {
const base_type *last = this->GetChild();
if (!last) {
return *this;
}
while (last->GetNext() != nullptr) {
last = last->GetNext();
}
return *static_cast<const self_type *>(last);
}
reference back() {
base_type *last = this->GetChild();
if (!last) {
return *this;
}
while (last->GetNext() != nullptr) {
last = last->GetNext();
}
return *static_cast<self_type *>(last);
}
void clear() {
base_type *head = this->DetachChild();
if (head) {
head->clear();
}
}
const_reference front() const {
const base_type *head = this->GetChild();
if (!head) {
return *this;
}
return *static_cast<const self_type *>(head);
}
reference front() {
base_type *head = this->GetChild();
if (!head) {
return *this;
}
return *static_cast<self_type *>(head);
}
const_iterator begin() const {
if (empty()) {
return end();
}
return const_iterator(this->GetChild());
}
iterator begin() {
if (empty()) {
return end();
}
return iterator(this->GetChild());
}
bool empty() const {
return (this->GetChild() == nullptr);
}
const_iterator end() const {
return nullptr;
}
iterator end() {
return nullptr;
}
};
typedef CCommandTree CCommandTreeNode;
} // namespace TDx
#if !_MSC_VER
#pragma GCC diagnostic pop
#endif
#endif // CCommandTreeNode_HPP_INCLUDED

View File

@ -0,0 +1,108 @@
#ifndef CCookieCollection_HPP_INCLUDED
#define CCookieCollection_HPP_INCLUDED
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (c) 2018-2021 3Dconnexion.
*
* 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 CCookieCollection.hpp
* @brief Cookie collection.
*/
#include <navlib/navlib_types.h>
// stdlib
#include <map>
#include <memory>
#include <stdexcept>
#if (!defined(_MSC_VER) || (_MSC_VER > 1600))
#include <mutex>
#else
#pragma warning(disable : 4482) // non-standard
#include <boost/thread/lock_guard.hpp>
#include <boost/thread/mutex.hpp>
namespace std {
using boost::lock_guard;
using boost::mutex;
using boost::unique_lock;
} // namespace std
#endif
namespace TDx {
namespace SpaceMouse {
/// <summary>
/// The class maps a cookie to a weak_ptr<typeparam name="T"></typeparam>.
/// </summary>
template <class T> class CCookieCollection : protected std::map<navlib::param_t, std::weak_ptr<T>> {
typedef std::map<navlib::param_t, std::weak_ptr<T>> map_t;
public:
typedef typename map_t::size_type size_type;
/// <summary>
/// Gets the shared pointer to class T corresponding to the passed in cookie.
/// </summary>
/// <param name="cookie">The <see cref="navlib::param_t"/> to search for.</param>
/// <returns>The shared pointer to the instance of T</returns>
/// <exception cref="std::out_of_range">If the cookie does not exist.</exception>
std::shared_ptr<T> at(const navlib::param_t &cookie) {
std::lock_guard<std::mutex> guard(m_mutex);
typename map_t::iterator iter = map_t::find(cookie);
if (iter != map_t::end()) {
return iter->second.lock();
}
throw std::out_of_range("Cookie does not exist in the Collection");
}
/// <summary>
/// Removes the elements that match the cookie.
/// </summary>
/// <param name="cookie">The cookie entry to remove.</param>
/// <returns>The number of elements that have been removed.</returns>
size_type erase(const navlib::param_t &cookie) {
std::lock_guard<std::mutex> guard(m_mutex);
return map_t::erase(cookie);
}
/// <summary>
/// Inserts a weak pointer (to class T) and returns a cookie that is needed to retrieve it later.
/// </summary>
/// <param name="sp">Shared pointer to class T.</param>
/// <returns>A cookie that is needed to find the shared pointer.</returns>
navlib::param_t insert(const std::shared_ptr<T> &sp) {
navlib::param_t param = 0;
if (sp) {
std::lock_guard<std::mutex> guard(m_mutex);
do {
using namespace std::chrono;
param =
duration_cast<microseconds>(high_resolution_clock::now().time_since_epoch()).count();
} while (map_t::find(param) != map_t::end());
(*this)[param] = sp;
}
return param;
}
protected:
/// <summary>
/// When changing the contents of the collection always use the mutex as a guard
/// </summary>
std::mutex m_mutex;
};
} // namespace SpaceMouse
} // namespace TDx
#endif // CCookieCollection_HPP_INCLUDED

View File

@ -0,0 +1,138 @@
#ifndef CHitTest_HPP_INCLUDED
#define CHitTest_HPP_INCLUDED
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (c) 2018-2021 3Dconnexion.
*
* 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 CHitTest.hpp
* @brief Hit-test properties.
*/
// 3dxware
#include <navlib/navlib_types.h>
namespace TDx {
namespace SpaceMouse {
/// <summary>
/// Class can be used to hold the hit-test properties.
/// </summary>
template <class point_ = navlib::point_t, class vector_ = navlib::vector_t> class CHitTest {
public:
typedef point_ point_type;
typedef vector_ vector_type;
public:
/// <summary>
/// Creates a new instance of the <see cref="CHitTest"/> class.
/// </summary>
CHitTest() : m_aperture(1), m_dirty(false), m_selectionOnly(false) {
}
#if !defined(__GNUC__) || defined(__clang__)
/// <summary>
/// Property accessors
/// </summary>
__declspec(property(get = GetDirection, put = PutDirection)) vector_type Direction;
__declspec(property(get = GetLookFrom, put = PutLookFrom)) point_type LookFrom;
__declspec(property(get = GetLookingAt, put = PutLookingAt)) point_type LookingAt;
__declspec(property(get = GetIsDirty, put = PutIsDirty)) bool IsDirty;
__declspec(property(get = GetAperture, put = PutAperture)) double Aperture;
__declspec(property(get = GetSelectionOnly, put = PutSelectionOnly)) bool SelectionOnly;
#endif
/// <summary>
/// Gets or sets the ray direction.
/// </summary>
void PutDirection(vector_type value) {
if (!m_dirty) {
m_dirty = static_cast<bool>(m_direction != value);
}
m_direction = std::move(value);
}
vector_type GetDirection() const {
return m_direction;
}
/// <summary>
/// Gets or sets the ray origin.
/// </summary>
void PutLookFrom(point_type value) {
if (!m_dirty) {
m_dirty = static_cast<bool>(m_lookFrom != value);
}
m_lookFrom = std::move(value);
}
const point_type GetLookFrom() const {
return m_lookFrom;
}
/// <summary>
/// Gets or sets the ray hit test result location.
/// </summary>
void PutLookingAt(point_type value) {
m_lookingAt = std::move(value);
m_dirty = false;
}
const point_type GetLookingAt() const {
return m_lookingAt;
}
/// <summary>
/// Gets or sets a value indicating if a the parameters have changed since the last hit calculation.
/// </summary>
void PutIsDirty(bool value) {
m_dirty = value;
}
bool GetIsDirty() const {
return m_dirty;
}
/// <summary>
/// Gets or sets the ray diameter / aperture on the near clipping plane.
/// </summary>
void PutAperture(double value) {
m_dirty = (m_aperture != value);
m_aperture = value;
}
double GetAperture() const {
return m_aperture;
}
/// <summary>
/// Gets or sets a value indicating whether the hit-testing is limited to the selection set.
/// </summary>
void PutSelectionOnly(bool value) {
m_selectionOnly = value;
}
bool GetSelectionOnly() const {
return m_selectionOnly;
}
private:
double m_aperture;
mutable bool m_dirty;
vector_type m_direction;
point_type m_lookFrom;
mutable point_type m_lookingAt;
bool m_selectionOnly;
};
} // namespace SpaceMouse
} // namespace TDx
#endif // CHitTest_HPP_INCLUDED

View File

@ -0,0 +1,298 @@
#ifndef CImage_HPP_INCLUDED
#define CImage_HPP_INCLUDED
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (c) 2018-2021 3Dconnexion.
*
* 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 CImage.hpp
* @brief SiImage_t wrapper.
*/
// stdlib
#include <string>
#include <sstream>
// 3dxware
#include <siappcmd_types.h>
#if defined(_MSC_VER) && _MSC_VER<1800
// #pragma warning(1 : 4519) // convert error C4519 'default template arguments are only allowed on a class template' to warning
#pragma warning(disable : 4519) // disable error C4519
#if _MSC_VER < 1700
#pragma warning(disable : 4482) // warning C4482: nonstandard extension used
#endif
#endif
#ifdef __APPLE__
#define IS_INTRESOURCE(x) false
#endif
namespace TDx {
/// <summary>
/// A class that represents the SiImage_t structure.
/// </summary>
class CImage {
public:
/// <summary>
/// Initializes a new instance of the <see cref="CImage"/> class.
/// </summary>
CImage() : m_type(SiImageType_t::e_none), m_index(0) {
}
/// <summary>
/// Initializes a new instance of the <see cref="CImage"/> class from a <see cref="SiImage_t"/>.
/// </summary>
/// <param name="image"></param>
explicit CImage(const SiImage_t &siImage) : m_id(siImage.id), m_type(siImage.type) {
if (siImage.size != sizeof(SiImage_t)) {
throw std::invalid_argument("Invalid SiImage_t structure.");
}
switch (m_type) {
case SiImageType_t::e_image_file:
m_source = siImage.file.file_name;
m_index = siImage.file.index;
break;
case SiImageType_t::e_resource_file:
m_source = siImage.resource.file_name;
m_resourceId = siImage.resource.id;
m_resourceType = siImage.resource.type;
m_index = siImage.resource.index;
break;
case SiImageType_t::e_image:
m_source.assign(reinterpret_cast<const char *>(siImage.image.data), siImage.image.size);
m_index = siImage.image.index;
break;
case SiImageType_t::e_none:
default:
break;
}
}
#if !defined(__GNUC__) || defined(__clang__)
/// <summary>
/// Gets or sets the image id.
/// </summary>
__declspec(property(get = GetId, put = PutId)) std::string Id;
/// <summary>
/// Gets or sets the resource id.
/// </summary>
__declspec(property(get = GetResourceId, put = PutResourceId)) std::string ResourceId;
/// <summary>
/// Gets the image type.
/// </summary>
__declspec(property(get = GetType)) SiImageType_t Type;
#endif
/// <summary>
/// Sets the id of the image.
/// </summary>
/// <param name="id">A <see cref="std::string"/> representing the name or id of the image.</param>
void PutId(std::string id) {
m_id = std::move(id);
}
/// <summary>
/// Gets the image id.
/// </summary>
/// <returns>A <see cref="std::string"/> representing the name or id of the image.</returns>
std::string GetId() const {
return m_id;
}
/// <summary>
/// Sets the id of the resource in the resource file.
/// </summary>
/// <param name="id">A <see cref="std::string"/> representing the name or id of the image in the
/// resource file.</param>
/// <remarks>For example for Microsoft resource libraries MAKEINTRESOURCE(216) = "#216".</remarks>
void PutResourceId(std::string id) {
m_resourceId = std::move(id);
}
/// <summary>
/// Gets the resource id.
/// </summary>
/// <returns>A <see cref="std::string"/> representing the name or id of the image.</returns>
/// <remarks>For example for Microsoft resource libraries MAKEINTRESOURCE(216) = "#216".</remarks>
std::string GetResourceId() const {
return m_resourceId;
}
/// <summary>
/// Gets the image type.
/// </summary>
/// <returns>One of <see cref="SiImageType_t"/>.</returns>
SiImageType_t GetType() const {
return m_type;
}
/// <summary>
/// Assigns image data to the <see cref="CImage"/> instance.
/// </summary>
/// <param name="buffer">The image data. The image may be in any format that can be loaded by
/// Gdiplus::Bitmap::FromStream() or is in a recognizable svg format.</param>
/// <returns>true if successful, otherwise false.</returns>
/// <remarks>The <see cref="CImage"/> type is set to <see
/// cref="SiImageType_t::e_image"/>.</remarks>
bool AssignImage(std::string buffer, uint32_t index = 0) {
m_source = std::move(buffer);
m_type = e_image;
m_index = index;
m_resourceId.clear();
m_resourceType.clear();
return true;
}
/// <summary>
/// Initializes a new instance of the <see cref="CImage"/> class that contains the data for an
/// image held in a resource file.
/// </summary>
/// <param name="resourceFile">The name of the resource file.</param>
/// <param name="resourceId">The name or id of the image in the resource file. i.e.
/// MAKEINTRESOURCE(216) = "#216".</param>
/// <param name="resourceType">The type of the resource in the resource file. i.e. RT_BITMAP =
/// "#2".</param>
/// <param name="index">The index in a multi-image resource.</param>
/// <param name="id">The id of the command to associate with this image.</param>
/// <returns>A <see cref="CImage"/> instance.</returns>
template <class T = CImage>
static T FromResource(const std::string &resourceFile, const char *resourceId,
const char *resourceType, uint32_t index = 0, const char *id = nullptr) {
std::string r_id;
if (resourceId != nullptr) {
if (IS_INTRESOURCE(resourceId)) {
std::ostringstream stream;
stream << "#" << reinterpret_cast<uintptr_t>(resourceId);
r_id = stream.str();
} else {
r_id = resourceId;
}
}
std::string r_type;
if (resourceType != nullptr) {
if (IS_INTRESOURCE(resourceType)) {
std::ostringstream stream;
stream << "#" << reinterpret_cast<uintptr_t>(resourceType);
r_type = stream.str();
} else {
r_type = resourceType;
}
}
T image(resourceFile, r_id, r_type, id != nullptr ? id : "", e_resource_file,
index);
return image;
}
/// <summary>
/// Initializes a new instance of the <see cref="CImage"/> class that contains the data for an
/// image in a file.
/// </summary>
/// <param name="filename">The name of the image file.</param>
/// <param name="index">The index in a multi-image file.</param>
/// <param name="id">The id of the command to associate with this image.</param>
/// <returns>A <see cref="CImage"/> instance.</returns>
template <class T = CImage>
static T FromFile(const std::string &filename, uint32_t index = 0, const char *id = nullptr) {
T image(filename, id != nullptr ? id : "", e_image_file, index);
return image;
}
/// <summary>
/// Initializes a new instance of the CImage class that contains the data for an image in a file.
/// </summary>
/// <param name="buffer">The image data. The image may be in any format that can be loaded by
/// Gdiplus::Bitmap::FromStream() or is in a recognizable svg format.</param>
/// <param name="index">The index in a multi-image file.</param>
/// <param name="id">The id of the command to associate with this image.</param>
/// <returns>A <see cref="CImage"/> instance.</returns>
template <class T = CImage>
static T FromData(const std::string &buffer, uint32_t index = 0, const char *id = nullptr) {
T image(buffer, id != nullptr ? id : "", e_image, index);
return image;
}
/// <summary>
/// Returns an <see cref="SiImage_t"/> view of the <see cref="CImage"/> instance.
/// </summary>
/// <returns>A <see cref="SiImage_t"/>.</returns>
operator SiImage_t() const {
SiImage_t siImage = {sizeof(SiImage_t), m_type, m_id.c_str(), {nullptr, nullptr, nullptr, 0}};
switch (m_type) {
case SiImageType_t::e_image_file:
siImage.file.file_name = m_source.c_str();
siImage.file.index = m_index;
break;
case SiImageType_t::e_resource_file:
siImage.resource.file_name = m_source.c_str();
siImage.resource.id = m_resourceId.c_str();
siImage.resource.type = m_resourceType.c_str();
siImage.resource.index = m_index;
break;
case SiImageType_t::e_image:
siImage.image.data = reinterpret_cast<const uint8_t *>(m_source.data());
siImage.image.size = m_source.size();
siImage.image.index = m_index;
break;
case SiImageType_t::e_none:
break;
default:
siImage.type = SiImageType_t::e_none;
break;
}
return siImage;
}
/// <summary>
/// checks whether the image is empty.
/// </summary>
/// <returns>true if the image contains data, otherwise false.</returns>
bool empty() const {
return m_type == SiImageType_t::e_none || (m_type == SiImageType_t::e_image && m_source.empty());
}
protected:
CImage(std::string source, std::string id, SiImageType_t type, uint32_t index = 0)
: m_source(std::move(source)), m_id(std::move(id)), m_type(type), m_index(index) {
}
CImage(std::string source, std::string resourceName, std::string resourceType, std::string id,
SiImageType_t type, uint32_t index = 0)
: m_source(std::move(source)), m_resourceId(std::move(resourceName)),
m_resourceType(std::move(resourceType)), m_id(std::move(id)), m_type(type), m_index(index) {
}
protected:
std::string m_source;
std::string m_resourceId;
std::string m_resourceType;
std::string m_id;
SiImageType_t m_type;
uint32_t m_index;
};
} // namespace TDx
#endif // CImage_HPP_INCLUDED

View File

@ -0,0 +1,511 @@
#ifndef CNavigation3D_HPP_INCLUDED
#define CNavigation3D_HPP_INCLUDED
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (c) 2018-2021 3Dconnexion.
*
* 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 CNavigation3D.hpp
* @brief base class for 3D navigation.
*/
// SpaceMouse
#include <SpaceMouse/CCategory.hpp>
#include <SpaceMouse/CCommand.hpp>
#include <SpaceMouse/CCommandSet.hpp>
#include <SpaceMouse/CHitTest.hpp>
#include <SpaceMouse/CImage.hpp>
#include <SpaceMouse/CNavlibImpl.hpp>
#include <SpaceMouse/IAccessors.hpp>
#include <SpaceMouse/INavlib.hpp>
// stdlib
#include <memory>
#include <string>
#include <vector>
#if (!defined(_MSC_VER) || (_MSC_VER > 1600))
#include <chrono>
#else
#include <boost/chrono.hpp>
namespace std {
namespace chrono = boost::chrono;
using boost::milli;
} // namespace std
#endif
// navlib
#include <navlib/navlib.h>
#include <navlib/navlib_error.h>
namespace TDx {
namespace SpaceMouse {
/// <summary>
/// Contains types that support 3DMouse navigation.
/// </summary>
namespace Navigation3D {
/// <summary>
/// The base class for 3D navigation implements defaults for the <see cref="IAccessors"/> interface.
/// </summary>
/// <remarks>This class can be used as the base class for the application specific implementation of
/// the accessors.</remarks>
class CNavigation3D : public INavlibProperty, protected IAccessors {
public:
/// <summary>
/// The timing source for the frame time.
/// </summary>
enum TimingSource {
/// <summary>
/// The space mouse is the source of the frame timing.
/// </summary>
SpaceMouse = 0,
/// <summary>
/// The application is the source of the frame timing.
/// </summary>
Application = 1,
};
public:
/// <summary>
/// Initializes a new instance of the CNavigation3D class.
/// </summary>
/// <param name="multiThreaded">true to use multi-threading, false for single-threaded.</param>
/// <param name="rowMajor">true for row-major ordered matrices, false for column-major.</param>
/// <remarks>The default is single-threaded, column major matrices</remarks>
explicit CNavigation3D(bool multiThreaded = false, bool rowMajor = false)
: m_enabled(false), m_pImpl(CNavlibImpl::CreateInstance(this, multiThreaded, rowMajor)) {
}
/// <summary>
/// Initializes a new instance of the CNavigation3D class.
/// </summary>
/// <param name="multiThreaded">true to use multi-threading, false for single-threaded.</param>
/// <param name="options">A combination of the <see cref="navlib::nlOptions_t"/> values.</param>
explicit CNavigation3D(bool multiThreaded, navlib::nlOptions_t options)
: m_enabled(false), m_pImpl(CNavlibImpl::CreateInstance(this, multiThreaded, options)) {
}
/// <summary>
/// Clean up the resources
/// </summary>
virtual ~CNavigation3D() {
}
#if !defined(__GNUC__) || defined(__clang__)
/// <summary>
/// Gets or sets a value indicating whether the 3DMouse navigation is enabled.
/// </summary>
__declspec(property(get = IsEnabled, put = EnableNavigation)) bool Enable;
/// <summary>
/// Gets or sets the animation frame time.
/// </summary>
__declspec(property(get = GetFrameTime,
put = PutFrameTime)) std::chrono::high_resolution_clock::time_point FrameTime;
/// <summary>
/// Gets or sets the frame timing source.
/// </summary>
__declspec(property(get = GetFrameTimingSource,
put = PutFrameTimingSource)) TimingSource FrameTiming;
/// <summary>
/// Gets or sets the text to pass to the 3Dconnexion driver to use in Properties Utility.
/// </summary>
/// <remarks>If the connection to the navlib is already open, the connection is closed and
/// reopened.</remarks>
__declspec(property(get = GetProfileHint, put = PutProfileHint)) std::string Profile;
/// <summary>
/// Gets or sets a value representing the active command set.
/// </summary>
/// <exception cref="std::system_error"></exception>
__declspec(property(get = GetActiveCommands, put = PutActiveCommands)) std::string ActiveCommands;
#endif
/// <summary>
/// Gets a value indicating whether 3DMouse navigation is enabled.
/// </summary>
/// <returns>true if enabled, otherwise false.</returns>
bool IsEnabled() const {
return m_enabled;
}
/// <summary>
/// Sets a value indicating whether 3DMouse navigation is enabled.
/// </summary>
/// <param name="value">true to enable, false to disable.</param>
/// <exception cref="std::invalid_argument">The text for the '3Dconnexion Properties' is
/// empty.</exception>
/// <exception cref="std::system_error">Cannot create a connection to the library.</exception>
void EnableNavigation(bool value) {
if (m_enabled == value) {
return;
}
if (value) {
m_pImpl->Open(m_profileHint);
m_enabled = true;
} else {
m_pImpl->Close();
m_enabled = false;
}
}
/// <summary>
/// Sets a value indicating whether 3DMouse navigation is enabled.
/// </summary>
/// <param name="value">true to enable, false to disable.</param>
/// <param name="ec">The <see cref="std::error_code"/> contains the error if something goes
/// wrong.</param>
/// <exception cref="std::invalid_argument">The text for the '3Dconnexion Properties' is
/// empty.</exception>
/// <exception cref="std::system_error">Cannot create a connection to the library.</exception>
void EnableNavigation(bool value, std::error_code &ec) NOEXCEPT {
try {
EnableNavigation(value);
}
#if _DEBUG && TRACE_NAVLIB
catch (const std::system_error &e) {
ec = e.code();
std::cout << "system_error exception thrown in EnableNavigation(" << value << ") 0x" << std::hex
<< ec.value() << std::dec << ", " << ec.message() << ", " << e.what() << "\n";
} catch (const std::invalid_argument &e) {
ec = std::make_error_code(std::errc::invalid_argument);
std::cout << "invalid_argument exception thrown in EnableNavigation(" << value << ") 0x"
<< std::hex << ec.value() << std::dec << ", " << ec.message() << ", " << e.what()
<< "\n";
} catch (const std::exception &e) {
ec = std::make_error_code(std::errc::io_error);
std::cout << "exception thrown in EnableNavigation(" << value << ") 0x" << std::hex << ec.value()
<< std::dec << ", " << ec.message() << ", " << e.what() << "\n";
}
#else
catch (const std::system_error &e) {
ec = e.code();
} catch (const std::invalid_argument &) {
ec = std::make_error_code(std::errc::invalid_argument);
} catch (const std::exception &) {
ec = std::make_error_code(std::errc::io_error);
}
#endif
}
/// <summary>
/// Gets or sets the animation frame time.
/// </summary>
std::chrono::high_resolution_clock::time_point GetFrameTime() {
return m_frameTime;
}
void PutFrameTime(std::chrono::high_resolution_clock::time_point value) {
if (m_frameTime != value) {
m_frameTime = std::move(value);
auto elapsed = std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(
m_frameTime.time_since_epoch());
m_pImpl->Write(navlib::frame_time_k, elapsed.count());
}
}
/// <summary>
/// Gets or sets the frame timing source.
/// </summary>
TimingSource GetFrameTimingSource() {
return m_frameTimingSource;
}
void PutFrameTimingSource(TimingSource value) {
if (m_frameTimingSource != value) {
m_frameTimingSource = value;
m_pImpl->Write(navlib::frame_timing_source_k, static_cast<long>(value));
}
}
/// <summary>
/// Gets or sets the text to pass to the 3Dconnexion driver to use in Properties Utility.
/// </summary>
/// <remarks>If the connection to the navlib is already open, the connection is closed and
/// reopened.</remarks>
std::string GetProfileHint() const {
return m_profileHint;
}
void PutProfileHint(std::string value) {
if (m_profileHint != value) {
m_profileHint = std::move(value);
if (IsEnabled()) {
EnableNavigation(false);
EnableNavigation(true);
}
}
}
/// <summary>
/// Gets or sets a value representing the active command set.
/// </summary>
/// <exception cref="std::system_error"></exception>
std::string GetActiveCommands() const {
std::string result;
long error = m_pImpl->Read(navlib::commands_activeSet_k, result);
if (error != 0) {
throw std::system_error(make_error_code(error));
}
return result;
}
void PutActiveCommands(const std::string &id) {
long error = m_pImpl->Write(navlib::commands_activeSet_k, id);
if (error != 0) {
throw std::system_error(make_error_code(error));
}
}
/// <summary>
/// Add commands to the sets of commands.
/// </summary>
/// <param name="commands">The <see cref="CCommandTree"/> to add.</param>
/// <exception cref="std::system_error"></exception>
void AddCommands(const CCommandTree &commands) {
const SiActionNodeEx_t *pnode = &commands.GetSiActionNode();
long error = m_pImpl->Write(navlib::commands_tree_k, pnode);
if (error != 0) {
throw std::system_error(make_error_code(error));
}
}
/// <summary>
/// Add a set of commands to the sets of commands.
/// </summary>
/// <param name="commands">The <see cref="CCommandSet"/> to add.</param>
/// <exception cref="std::system_error"></exception>
void AddCommandSet(const CCommandSet &commands) {
AddCommands(commands);
}
/// <summary>
/// Add to the images available to the 3Dconnexion properties utility.
/// </summary>
/// <param name="images">The <see cref="std::vector"/> container containing the images to
/// add.</param>
/// <exception cref="std::system_error"></exception>
template <class T>
void AddImages(const std::vector<T> &images,
typename std::enable_if<std::is_base_of<SiImage_t, T>::value &&
sizeof(T) == sizeof(SiImage_t)>::type * = nullptr) {
long error;
navlib::imagearray_t imagearray = {images.data(), images.size()};
error = m_pImpl->Write(navlib::images_k, imagearray);
if (error != 0) {
throw std::system_error(make_error_code(error));
}
}
/// <summary>
/// Add to the images available to the 3Dconnexion properties utility.
/// </summary>
/// <param name="images">The <see cref="std::vector{T}"/> container containing the images to
/// add.</param>
/// <exception cref="std::system_error"></exception>
template <class T>
void
AddImages(const std::vector<T> &images,
typename std::enable_if<std::is_base_of<TDx::CImage, T>::value>::type * = nullptr) {
std::vector<SiImage_t> siImages;
for (auto iter = images.begin(); iter != images.end(); ++iter) {
siImages.push_back(static_cast<SiImage_t>(*iter));
}
navlib::imagearray_t imagearray = {siImages.data(), siImages.size()};
long error = m_pImpl->Write(navlib::images_k, imagearray);
if (error != 0) {
throw std::system_error(make_error_code(error));
}
}
/// <summary>
/// Writes the value of a property to the navlib.
/// </summary>
/// <param name="propertyName">The <see cref="navlib::property_t"/> name of the navlib property to
/// write.</param>
/// <param name="value">The <see cref="navlib::value"/> to write.</param>
/// <returns>0 =no error, otherwise a value from <see cref="navlib::make_result_code"/>.</returns>
/// <exception cref="std::system_error">No connection to the navlib / 3D Mouse.</exception>
long Write(const std::string &propertyName, const navlib::value &value) override {
return m_pImpl->Write(propertyName, value);
}
/// <summary>
/// Reads the value of a navlib property.
/// </summary>
/// <param name="propertyName">The <see cref="navlib::property_t"/> name of the navlib property to
/// read.</param>
/// <param name="value">The <see cref="navlib::value"/> to read.</param>
/// <returns>0 =no error, otherwise a value from <see cref="navlib::make_result_code"/>.</returns>
/// <exception cref="std::system_error">No connection to the navlib / 3D Mouse.</exception>
long Read(const std::string &propertyName, navlib::value &value) const override {
return m_pImpl->Read(propertyName, value);
}
/// <summary>
/// Reads the value of a navlib string property.
/// </summary>
/// <param name="propertyName">The <see cref="navlib::property_t"/> name of the navlib property to
/// read.</param>
/// <param name="string">The <see cref="std::string"/> value of the property.</param>
/// <returns>0 =no error, otherwise a value from <see cref="navlib::make_result_code"/>.</returns>
/// <exception cref="std::system_error">No connection to the navlib.</exception>
long Read(const std::string &propertyName, std::string &string) const override {
return m_pImpl->Read(propertyName, string);
}
protected:
// IEvents overrides
/// <summary>
/// Default for SetSettingsChanged.
/// </summary>
/// <param name="count">The change count.</param>
/// <returns>navlib::navlib_errc::function_not_supported error.</returns>
long SetSettingsChanged(long count) override {
return navlib::make_result_code(navlib::navlib_errc::function_not_supported);
}
/// <summary>
/// Default for SetKeyPress.
/// </summary>
/// <param name="vkey">The virtual key code of the key pressed.</param>
/// <returns>navlib::navlib_errc::function_not_supported error.</returns>
long SetKeyPress(long vkey) override {
return navlib::make_result_code(navlib::navlib_errc::function_not_supported);
}
/// <summary>
/// Default for SetKeyRelease.
/// </summary>
/// <param name="vkey">The virtual key code of the key pressed.</param>
/// <returns>navlib::navlib_errc::function_not_supported error.</returns>
long SetKeyRelease(long vkey) override {
return navlib::make_result_code(navlib::navlib_errc::function_not_supported);
}
/// ISpace3D overrides
/// <summary>
/// Gets the coordinate system used by the client.
/// </summary>
/// <param name="matrix">The coordinate system <see cref="navlib::matrix_t"/>.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
/// <remarks>The matrix describes the applications coordinate frame in the navlib coordinate
/// system. i.e. the application to navlib transform. The default is a right-handed coordinate
/// system X-right, Z-up, Y-in (column-major)</remarks>
long GetCoordinateSystem(navlib::matrix_t &matrix) const override {
// Use the right-handed coordinate system X-right, Y-up, Z-out (same as navlib)
navlib::matrix_t cs = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
// Use the right-handed coordinate system X-right, Z-up, Y-in (column-major)
// navlib::matrix_t cs = {1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1};
matrix = cs;
return 0;
}
/// <summary>
/// Gets the orientation of the front view.
/// </summary>
/// <param name="matrix">The front view transform <see cref="navlib::matrix_t"/>.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
/// <remarks>The default is the same as the coordinate system tripod, i.e. the identity
/// matrix.</remarks>
long GetFrontView(navlib::matrix_t &matrix) const override {
navlib::matrix_t front = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
matrix = front;
return 0;
}
// IState overrides
long SetTransaction(long transaction) override {
return navlib::make_result_code(navlib::navlib_errc::function_not_supported);
}
long SetMotionFlag(bool motion) override {
return navlib::make_result_code(navlib::navlib_errc::function_not_supported);
}
/// <summary>
/// Gets the camera's target
/// </summary>
/// <param name="target">The position of the camera target in world coordinates.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
/// <remarks>Free cameras do not have a target.</remarks>
long GetCameraTarget(navlib::point_t &target) const override {
return navlib::make_result_code(navlib::navlib_errc::no_data_available);
}
/// <summary>
/// Gets the view's construction plane.
/// </summary>
/// <param name="plane">The plane equation of the construction plane.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
/// <remarks>Required to disable rotations when constructing.</remarks>
long GetViewConstructionPlane(navlib::plane_t &plane) const override {
return navlib::make_result_code(navlib::navlib_errc::no_data_available);
}
/// <summary>
/// Gets a value indicating whether the view can be rotated.
/// </summary>
/// <param name="isRotatable">true if the view can be rotated, false otherwise.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
/// <remarks>For paper space return false.</remarks>
long GetIsViewRotatable(navlib::bool_t &isRotatable) const override {
isRotatable = true;
return 0;
}
/// <summary>
/// Sets the camera's target position.
/// </summary>
/// <param name="target">The position of the camera target in world coordinates.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
/// <remarks>Free cameras do not have a target.</remarks>
long SetCameraTarget(const navlib::point_t &target) override {
return navlib::make_result_code(navlib::navlib_errc::function_not_supported);
}
/// <summary>
/// Sets the position of the pointer on the projection plane.
/// </summary>
/// <param name="position">The <see cref="navlib::point_t"/> in world coordinates of the
/// pointer.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
long SetPointerPosition(const navlib::point_t &position) override {
return navlib::make_result_code(navlib::navlib_errc::function_not_supported);
}
protected:
std::error_code make_error_code(long result_code) const {
int errc = result_code & 0xffff;
int facility = result_code >> 16 & 0x7fff;
if (facility == FACILITY_NAVLIB) {
return std::error_code(errc, navlib_category);
}
return std::error_code(errc, std::generic_category());
}
protected:
bool m_enabled;
std::string m_profileHint;
std::chrono::high_resolution_clock::time_point m_frameTime;
TimingSource m_frameTimingSource;
std::shared_ptr<CNavlibImpl> m_pImpl;
};
} // namespace Navigation3D
} // namespace SpaceMouse
} // namespace TDx
#endif // CNavigationModelImpl_HPP_INCLUDED

View File

@ -0,0 +1,310 @@
#ifndef CNavlibImpl_HPP_INCLUDED
#define CNavlibImpl_HPP_INCLUDED
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (c) 2018-2021 3Dconnexion.
*
* 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 CNavlibImpl.hpp
* @brief INavlib implementation.
*/
#include <SpaceMouse/CNavlibInterface.hpp>
#include <SpaceMouse/IAccessors.hpp>
#include <SpaceMouse/INavlib.hpp>
// stdlib
#include <map>
#include <memory>
#include <string>
#include <vector>
// navlib
#include <navlib/navlib.h>
#include <navlib/navlib_error.h>
namespace TDx {
namespace SpaceMouse {
namespace Navigation3D {
/// <summary>
/// Implementation for creating a shared pointer.
/// </summary>
class CNavlibImpl : public INavlib,
#if defined(_MSC_VER) && _MSC_VER < 1800
public IAccessors,
#else
private IAccessors,
#endif
public std::enable_shared_from_this<CNavlibImpl> {
typedef CNavlibImpl this_type;
friend std::shared_ptr<IAccessors>
std::static_pointer_cast<IAccessors, CNavlibImpl>(const std::shared_ptr<CNavlibImpl> &) NOEXCEPT;
/// <summary>
/// Make the constructors private to force creation of a shared pointer.
/// </summary>
CNavlibImpl(){};
CNavlibImpl(IAccessors *iclient) : m_iclient(iclient) {
}
public:
/// <summary>
/// Creates a new instance of the CNavlibImpl class.
/// </summary>
/// <param name="iclient">pointer to the instance implementing the IAccessors interface.</param>
/// <param name="multiThreaded">true to use multi-threading, false for single-threaded.</param>
/// <param name="rowMajor">true for row-major ordered matrices, false for column-major.</param>
/// <returns>
/// A <see cref="std::shared_ptr{CNavlibImpl}"/> to the new CNavlibImpl instance.
/// </returns>
static std::shared_ptr<CNavlibImpl>
CreateInstance(IAccessors *iclient, bool multiThreaded = false, bool rowMajor = false) {
return CreateInstance(iclient, multiThreaded,
rowMajor ? navlib::row_major_order : navlib::none);
}
/// <summary>
/// Creates a new instance of the CNavlibImpl class.
/// </summary>
/// <param name="iclient">pointer to the instance implementing the IAccessors interface.</param>
/// <param name="multiThreaded">true to use multi-threading, false for single-threaded.</param>
/// <param name="options">A combination of the <see cref="navlib::nlOptions_t"/> values.</param>
/// <returns>
/// A <see cref="std::shared_ptr{CNavlibImpl}"/> to the new CNavlibImpl instance.
/// </returns>
static std::shared_ptr<CNavlibImpl> CreateInstance(IAccessors *iclient, bool multiThreaded,
navlib::nlOptions_t options) {
if (iclient == nullptr) {
throw std::logic_error("The accessor interface is null");
}
// So that std::make_shared<> can be used with the private constructor.
struct make_shared_enabler : public this_type {
make_shared_enabler(IAccessors *iclient) : this_type(iclient) {
}
};
std::shared_ptr<CNavlibImpl> result = std::make_shared<make_shared_enabler>(iclient);
#if 1
result->m_pNavlib = std::unique_ptr<CNavlibInterface>(
new CNavlibInterface(std::static_pointer_cast<IAccessors>(result), multiThreaded, options));
#endif
return result;
}
/// <summary>
/// Clean up the resources
/// </summary>
virtual ~CNavlibImpl() {
}
// INavlib implementation
/// <summary>
/// Close the connection to the 3D navigation library.
/// </summary>
void Close() override {
m_pNavlib->Close();
}
/// <summary>
/// Opens a connection to the 3D navigation library.
/// </summary>
void Open() override {
m_pNavlib->Open();
}
/// <summary>
/// Opens a connection to the 3D navigation library
/// </summary>
/// <param name="profileName">The name of the 3Dconnexion profile to use.</param>
/// <exception cref="std::system_error">The connection to the library is already open.</exception>
/// <exception cref="std::system_error">Cannot create a connection to the library.</exception>
/// <exception cref="std::invalid_argument">The name of the profile is empty.</exception>
void Open(std::string profileName) override {
m_pNavlib->Open(std::move(profileName));
}
/// <summary>
/// Writes the value of a property to the navlib.
/// </summary>
/// <param name="propertyName">The <see cref="navlib::property_t"/> name of the navlib property to
/// write.</param>
/// <param name="value">The <see cref="navlib::value"/> to write.</param>
/// <returns>0 =no error, otherwise a value from <see cref="navlib::make_result_code"/>.</returns>
/// <exception cref="std::system_error">No connection to the navlib / 3D Mouse.</exception>
long Write(const std::string &propertyName, const navlib::value &value) override {
return m_pNavlib->Write(propertyName, value);
}
/// <summary>
/// Reads the value of a navlib property.
/// </summary>
/// <param name="propertyName">The <see cref="navlib::property_t"/> name of the navlib property to
/// read.</param>
/// <param name="value">The <see cref="navlib::value"/> to read.</param>
/// <returns>0 =no error, otherwise a value from <see cref="navlib::make_result_code"/>.</returns>
/// <exception cref="std::system_error">No connection to the navlib / 3D Mouse.</exception>
long Read(const std::string &propertyName, navlib::value &value) const override {
return m_pNavlib->Read(propertyName, value);
}
/// <summary>
/// Reads the value of a navlib string property.
/// </summary>
/// <param name="propertyName">The <see cref="navlib::property_t"/> name of the navlib property to
/// read.</param>
/// <param name="string">The <see cref="std::string"/> value of the property.</param>
/// <returns>0 =no error, otherwise a value from <see cref="navlib::make_result_code"/>.</returns>
/// <exception cref="std::system_error">No connection to the navlib.</exception>
long Read(const std::string &propertyName, std::string &string) const override {
return m_pNavlib->Read(propertyName, string);
}
private:
// IEvents overrides
long SetActiveCommand(std::string commandId) override {
return m_iclient->SetActiveCommand(commandId);
}
long SetSettingsChanged(long change) override {
return m_iclient->SetSettingsChanged(change);
}
long SetKeyPress(long vkey) override {
return m_iclient->SetKeyPress(vkey);
}
long SetKeyRelease(long vkey) override {
return m_iclient->SetKeyRelease(vkey);
}
// IHit overrides
long GetHitLookAt(navlib::point_t &position) const override {
return m_iclient->GetHitLookAt(position);
}
long SetHitAperture(double aperture) override {
return m_iclient->SetHitAperture(aperture);
}
long SetHitDirection(const navlib::vector_t &direction) override {
return m_iclient->SetHitDirection(direction);
}
long SetHitLookFrom(const navlib::point_t &eye) override {
return m_iclient->SetHitLookFrom(eye);
}
long SetHitSelectionOnly(bool onlySelection) override {
return m_iclient->SetHitSelectionOnly(onlySelection);
}
// IModel overrides
long GetModelExtents(navlib::box_t &extents) const override {
return m_iclient->GetModelExtents(extents);
}
long GetSelectionExtents(navlib::box_t &extents) const override {
return m_iclient->GetSelectionExtents(extents);
}
long GetSelectionTransform(navlib::matrix_t &transform) const override {
return m_iclient->GetSelectionTransform(transform);
}
long GetIsSelectionEmpty(navlib::bool_t &empty) const override {
return m_iclient->GetIsSelectionEmpty(empty);
}
long SetSelectionTransform(const navlib::matrix_t &matrix) override {
return m_iclient->SetSelectionTransform(matrix);
}
// IPivot overrides
long GetPivotPosition(navlib::point_t &position) const override {
return m_iclient->GetPivotPosition(position);
}
long IsUserPivot(navlib::bool_t &userPivot) const override {
return m_iclient->IsUserPivot(userPivot);
}
long SetPivotPosition(const navlib::point_t &position) override {
return m_iclient->SetPivotPosition(position);
}
long GetPivotVisible(navlib::bool_t &visible) const override {
return m_iclient->GetPivotVisible(visible);
}
long SetPivotVisible(bool visible) override {
return m_iclient->SetPivotVisible(visible);
}
// ISpace3D overrides
long GetCoordinateSystem(navlib::matrix_t &matrix) const override {
return m_iclient->GetCoordinateSystem(matrix);
}
long GetFrontView(navlib::matrix_t &matrix) const override {
return m_iclient->GetFrontView(matrix);
}
// IState overrides
long SetTransaction(long transaction) override {
return m_iclient->SetTransaction(transaction);
}
long SetMotionFlag(bool motion) override {
return m_iclient->SetMotionFlag(motion);
}
// IView overrides
long GetCameraMatrix(navlib::matrix_t &matrix) const override {
return m_iclient->GetCameraMatrix(matrix);
}
long GetCameraTarget(navlib::point_t &point) const override {
return m_iclient->GetCameraTarget(point);
}
long GetPointerPosition(navlib::point_t &position) const override {
return m_iclient->GetPointerPosition(position);
}
long GetViewConstructionPlane(navlib::plane_t &plane) const override {
return m_iclient->GetViewConstructionPlane(plane);
}
long GetViewExtents(navlib::box_t &extents) const override {
return m_iclient->GetViewExtents(extents);
}
long GetViewFOV(double &fov) const override {
return m_iclient->GetViewFOV(fov);
}
long GetViewFrustum(navlib::frustum_t &frustum) const override {
return m_iclient->GetViewFrustum(frustum);
}
long GetIsViewPerspective(navlib::bool_t &perspective) const override {
return m_iclient->GetIsViewPerspective(perspective);
}
long GetIsViewRotatable(navlib::bool_t &isRotatable) const override {
return m_iclient->GetIsViewRotatable(isRotatable);
}
long SetCameraMatrix(const navlib::matrix_t &matrix) override {
return m_iclient->SetCameraMatrix(matrix);
}
long SetCameraTarget(const navlib::point_t &target) override {
return m_iclient->SetCameraTarget(target);
}
long SetPointerPosition(const navlib::point_t &position) override {
return m_iclient->SetPointerPosition(position);
}
long SetViewExtents(const navlib::box_t &extents) override {
return m_iclient->SetViewExtents(extents);
}
long SetViewFOV(double fov) override {
return m_iclient->SetViewFOV(fov);
}
long SetViewFrustum(const navlib::frustum_t &frustum) override {
return m_iclient->SetViewFrustum(frustum);
}
private:
IAccessors *m_iclient;
std::unique_ptr<CNavlibInterface> m_pNavlib;
};
} // namespace Navigation3D
} // namespace SpaceMouse
} // namespace TDx
#endif // CNavlibImpl_HPP_INCLUDED

View File

@ -0,0 +1,643 @@
#ifndef CNavlibInterface_HPP_INCLUDED
#define CNavlibInterface_HPP_INCLUDED
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (c) 2018-2021 3Dconnexion.
*
* 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 CNavlibInterface.hpp
* @brief The interface to the navlib.
*/
#include <SpaceMouse/CCookieCollection.hpp>
#include <SpaceMouse/IAccessors.hpp>
#include <SpaceMouse/INavlib.hpp>
// stdlib
#include <map>
#include <memory>
#include <string>
#include <vector>
#include <iostream>
// navlib
#include <navlib/navlib.h>
#include <navlib/navlib_error.h>
#include <navlib/navlib_ostream.h>
namespace TDx {
namespace SpaceMouse {
/// <summary>
/// Template to allow defining the static members in the header file
/// </summary>
template <typename Ty_, typename I_> struct StaticSinkCollection {
protected:
static CCookieCollection<I_> s_sinkCollection;
static std::mutex s_mutex;
};
template <class Ty_, class I_>
CCookieCollection<I_> StaticSinkCollection<Ty_, I_>::s_sinkCollection;
/// <summary>
/// Mutex used to synchronize the trace output.
/// </summary>
template <class Ty_, class I_> std::mutex StaticSinkCollection<Ty_, I_>::s_mutex;
namespace Navigation3D {
/// <summary>
/// Class implements the interface to the navlib.
/// </summary>
class CNavlibInterface : public INavlib,
private StaticSinkCollection<CNavlibInterface, IAccessors> {
public:
/// <summary>
/// Initializes a new instance of the CNavlibInterface class.
/// </summary>
/// <param name="sink">Shared pointer to the instance implementing the IAccessors interface
/// accessors and mutators.</param>
/// <param name="multiThreaded">true to use multi-threading, false for single-threaded.</param>
/// <param name="rowMajor">true for row-major ordered matrices, false for column-major.</param>
explicit CNavlibInterface(std::shared_ptr<IAccessors> sink, bool multiThreaded = false,
bool rowMajor = false)
: m_hdl(INVALID_NAVLIB_HANDLE), m_cookie(s_sinkCollection.insert(sink))
#if defined(_MSC_VER) && (_MSC_VER < 1800)
{
navlib::nlCreateOptions_t options = {sizeof(navlib::nlCreateOptions_t), multiThreaded,
rowMajor ? navlib::row_major_order : navlib::none};
m_createOptions = options;
}
#else
,
m_createOptions{sizeof(navlib::nlCreateOptions_t), multiThreaded,
rowMajor ? navlib::row_major_order : navlib::none} {
}
#endif
/// <summary>
/// Initializes a new instance of the CNavlibInterface class.
/// </summary>
/// <param name="sink">Shared pointer to the instance implementing the IAccessors interface
/// accessors and mutators.</param>
/// <param name="multiThreaded">true to use multi-threading, false for single-threaded.</param>
/// <param name="options">A combination of the <see cref="navlib::nlOptions_t"/> values.</param>
explicit CNavlibInterface(std::shared_ptr<IAccessors> sink, bool multiThreaded,
navlib::nlOptions_t options)
: m_hdl(INVALID_NAVLIB_HANDLE), m_cookie(s_sinkCollection.insert(sink))
#if defined(_MSC_VER) && (_MSC_VER < 1800)
{
navlib::nlCreateOptions_t createOptions = {sizeof(navlib::nlCreateOptions_t), multiThreaded,
options};
m_createOptions = createOptions;
}
#else
,
m_createOptions{sizeof(navlib::nlCreateOptions_t), multiThreaded, options} {
}
#endif
/// <summary>
/// Clean up the resources
/// </summary>
virtual ~CNavlibInterface() {
using namespace ::navlib;
if (m_cookie) {
s_sinkCollection.erase(m_cookie);
}
if (m_hdl != INVALID_NAVLIB_HANDLE) {
NlClose(m_hdl);
}
}
public:
/// <summary>
/// Close the connection to the 3D navigation library.
/// </summary>
void Close() override {
using namespace ::navlib;
if (m_hdl != INVALID_NAVLIB_HANDLE) {
std::unique_lock<std::mutex> lock(m_mutex);
if (m_hdl != INVALID_NAVLIB_HANDLE) {
NlClose(m_hdl);
m_hdl = INVALID_NAVLIB_HANDLE;
}
}
}
/// <summary>
/// Opens a connection to the 3D navigation library.
/// </summary>
void Open() override {
Open(m_name);
}
/// <summary>
/// Opens a connection to the 3D navigation library
/// </summary>
/// <param name="profileText">The text to display in the 3Dconnexion profile.</param>
/// <exception cref="std::system_error">The connection to the library is already open.</exception>
/// <exception cref="std::system_error">Cannot create a connection to the library.</exception>
/// <exception cref="std::invalid_argument">The text for the profile is empty.</exception>
void Open(std::string profileText) override {
using namespace ::navlib;
if (profileText.empty()) {
throw std::invalid_argument("The text for the profile is empty.");
}
std::unique_lock<std::mutex> lock(m_mutex);
if (m_hdl != INVALID_NAVLIB_HANDLE) {
throw std::system_error(navlib::make_error_code(navlib_errc::already_connected),
"Connection to the library is already open.");
}
accessor_t accessors[] = {
{motion_k, nullptr, &CNavlibInterface::SetMotionFlag, m_cookie},
{transaction_k, nullptr, &CNavlibInterface::SetTransaction, m_cookie},
{coordinate_system_k, &CNavlibInterface::GetCoordinateSystem, nullptr, m_cookie},
{views_front_k, &CNavlibInterface::GetFrontView, nullptr, m_cookie},
// view access
{view_affine_k, &CNavlibInterface::GetCameraMatrix, &CNavlibInterface::SetCameraMatrix,
m_cookie},
{view_constructionPlane_k, &CNavlibInterface::GetViewConstructionPlane, nullptr, m_cookie},
{view_extents_k, &CNavlibInterface::GetViewExtents, &CNavlibInterface::SetViewExtents,
m_cookie},
{view_fov_k, &CNavlibInterface::GetViewFOV, &CNavlibInterface::SetViewFOV, m_cookie},
{view_frustum_k, &CNavlibInterface::GetViewFrustum, &CNavlibInterface::SetViewFrustum,
m_cookie},
{view_perspective_k, &CNavlibInterface::GetIsViewPerspective, nullptr, m_cookie},
{view_target_k, &CNavlibInterface::GetCameraTarget, &CNavlibInterface::SetCameraTarget,
m_cookie},
{view_rotatable_k, &CNavlibInterface::GetIsViewRotatable, nullptr, m_cookie},
{pointer_position_k, &CNavlibInterface::GetPointerPosition,
&CNavlibInterface::SetPointerPosition, m_cookie},
// pivot accessors
{pivot_position_k, &CNavlibInterface::GetPivotPosition, &CNavlibInterface::SetPivotPosition,
m_cookie},
{pivot_user_k, &CNavlibInterface::IsUserPivot, nullptr, m_cookie},
{pivot_visible_k, &CNavlibInterface::GetPivotVisible, &CNavlibInterface::SetPivotVisible,
m_cookie},
// hit testing for auto pivot algorithm etc.
{hit_lookfrom_k, nullptr, &CNavlibInterface::SetHitLookFrom, m_cookie},
{hit_direction_k, nullptr, &CNavlibInterface::SetHitDirection, m_cookie},
{hit_aperture_k, nullptr, &CNavlibInterface::SetHitAperture, m_cookie},
{hit_lookat_k, &CNavlibInterface::GetHitLookAt, nullptr, m_cookie},
{hit_selectionOnly_k, nullptr, &CNavlibInterface::SetHitSelectionOnly, m_cookie},
// model access
{model_extents_k, &CNavlibInterface::GetModelExtents, nullptr, m_cookie},
{selection_empty_k, &CNavlibInterface::GetIsSelectionEmpty, nullptr, m_cookie},
{selection_extents_k, &CNavlibInterface::GetSelectionExtents, nullptr, m_cookie},
{selection_affine_k, &CNavlibInterface::GetSelectionTransform,
&CNavlibInterface::SetSelectionTransform, m_cookie},
// events
{commands_activeCommand_k, nullptr, &CNavlibInterface::SetActiveCommand, m_cookie},
{events_keyPress_k, nullptr, &CNavlibInterface::SetKeyPress, m_cookie},
{events_keyRelease_k, nullptr, &CNavlibInterface::SetKeyRelease, m_cookie},
{settings_changed_k, nullptr, &CNavlibInterface::SetSettingsChanged, m_cookie}};
// Create the navlib instance
long error = NlCreate(&m_hdl, profileText.c_str(), static_cast<const accessor_t *>(accessors),
sizeof(accessors) / sizeof(accessors[0]), &m_createOptions);
if (error != 0) {
throw std::system_error(
navlib::make_error_code(static_cast<navlib_errc::navlib_errc_t>(error & 0xffff)),
"Cannot create a connection to the 3DMouse.");
}
m_name = std::move(profileText);
}
/// <summary>
/// Writes the value of a property to the navlib.
/// </summary>
/// <param name="propertyName">The <see cref="navlib::property_t"/> name of the navlib property to
/// write.</param>
/// <param name="value">The <see cref="navlib::value"/> to write.</param>
/// <returns>0 =no error, otherwise a value from <see cref="navlib::make_result_code"/>.</returns>
/// <exception cref="std::system_error">No connection to the navlib.</exception>
long Write(const std::string &propertyName, const navlib::value &value) override {
if (m_hdl == INVALID_NAVLIB_HANDLE) {
return navlib::make_result_code(navlib::navlib_errc::invalid_operation);
}
long resultCode = WriteValue(m_hdl, propertyName.c_str(), &value);
return resultCode;
}
/// <summary>
/// Reads the value of a navlib property.
/// </summary>
/// <param name="propertyName">The <see cref="navlib::property_t"/> name of the navlib property to
/// read.</param>
/// <param name="value">The <see cref="navlib::value"/> to read.</param>
/// <returns>0 =no error, otherwise a value from <see cref="navlib::make_result_code"/>.</returns>
/// <exception cref="std::system_error">No connection to the navlib.</exception>
long Read(const std::string &propertyName, navlib::value &value) const override {
if (m_hdl == INVALID_NAVLIB_HANDLE) {
return navlib::make_result_code(navlib::navlib_errc::invalid_operation);
}
long resultCode = ReadValue(m_hdl, propertyName.c_str(), &value);
return resultCode;
}
/// <summary>
/// Reads the value of a navlib string property.
/// </summary>
/// <param name="propertyName">The <see cref="navlib::property_t"/> name of the navlib property to
/// read.</param>
/// <param name="string">The <see cref="std::string"/> value of the property.</param>
/// <returns>0 =no error, otherwise a value from <see cref="navlib::make_result_code"/>.</returns>
/// <exception cref="std::system_error">No connection to the navlib.</exception>
long Read(const std::string &propertyName, std::string &string) const override {
if (m_hdl == INVALID_NAVLIB_HANDLE) {
return navlib::make_result_code(navlib::navlib_errc::invalid_operation);
}
navlib::value value(&string[0], string.length());
long resultCode = ReadValue(m_hdl, propertyName.c_str(), &value);
if ((resultCode & 0xffff) == static_cast<int>(navlib::navlib_errc::insufficient_buffer)) {
string.resize(value.string.length);
value = navlib::value(&string[0], string.length());
resultCode = ReadValue(m_hdl, propertyName.c_str(), &value);
}
return resultCode;
}
private:
typedef std::shared_ptr<IAccessors> isink_t;
template <typename F>
static long GetValue(navlib::param_t cookie, navlib::property_t property, navlib::value_t *value,
F fn) {
isink_t isink;
try {
isink = s_sinkCollection.at(cookie);
long result = fn(isink);
#if _DEBUG && TRACE_NAVLIB
std::unique_lock<std::mutex> lock(s_mutex);
std::clog << "GetValue(0x" << std::hex << cookie << std::dec << ", " << property << ", "
<< *value << ") result =0x" << std::hex << result << std::endl;
#endif
return result;
}
catch (const std::out_of_range &e) {
std::unique_lock<std::mutex> lock(s_mutex);
std::cerr << "std::out_of_range exception thrown in GetValue(0x" << std::hex << cookie
<< std::dec << ", " << property << ", value)\n"
<< *value << e.what() << std::endl;
return navlib::make_result_code(navlib::navlib_errc::invalid_argument);
} catch (const std::exception &e) {
std::cerr << "Uncaught exception thrown in GetValue(0x" << std::hex << cookie << std::dec
<< ", " << property << ", value)\n"
<< *value << e.what() << std::endl;
}
return navlib::make_result_code(navlib::navlib_errc::error);
}
template <typename F>
static long SetValue(navlib::param_t cookie, navlib::property_t property,
const navlib::value_t *value, F fn) {
isink_t isink;
try {
isink = s_sinkCollection.at(cookie);
long result = fn(isink);
#if _DEBUG && TRACE_NAVLIB
std::clog << "SetValue(0x" << std::hex << cookie << std::dec << ", " << property << ", "
<< *value << ") result =0x" << std::hex << result << std::endl;
#endif
return result;
}
catch (const std::out_of_range &e) {
std::unique_lock<std::mutex> lock(s_mutex);
std::cerr << "std::out_of_range exception thrown in SetValue(0x" << std::hex << cookie
<< std::dec << ", " << property << ", value)\n"
<< *value << e.what() << std::endl;
return navlib::make_result_code(navlib::navlib_errc::invalid_argument);
} catch (const std::exception &e) {
std::unique_lock<std::mutex> lock(s_mutex);
std::cerr << "Uncaught exception thrown in SetValue(0x" << std::hex << cookie << std::dec
<< ", " << property << "," << *value << ")\n"
<< e.what() << std::endl;
}
return navlib::make_result_code(navlib::navlib_errc::error);
}
/// <summary>
/// IEvents accessors and mutators
/// </summary>
static long SetActiveCommand(navlib::param_t cookie, navlib::property_t property,
const navlib::value_t *value) {
return SetValue(cookie, property, value, [&](isink_t isink) {
return isink->SetActiveCommand(static_cast<const char *>(*value));
});
}
static long SetSettingsChanged(navlib::param_t cookie, navlib::property_t property,
const navlib::value_t *value) {
return SetValue(cookie, property, value,
[&](isink_t isink) { return isink->SetSettingsChanged(*value); });
}
static long SetKeyPress(navlib::param_t cookie, navlib::property_t property,
const navlib::value_t *value) {
return SetValue(cookie, property, value,
[&](isink_t isink) { return isink->SetKeyPress(*value); });
}
static long SetKeyRelease(navlib::param_t cookie, navlib::property_t property,
const navlib::value_t *value) {
return SetValue(cookie, property, value,
[&](isink_t isink) { return isink->SetKeyRelease(*value); });
}
/// <summary>
/// IHit accessors and mutators
/// </summary>
static long GetHitLookAt(navlib::param_t cookie, navlib::property_t property,
navlib::value_t *value) {
return GetValue(cookie, property, value,
[&](isink_t isink) { return isink->GetHitLookAt(*value); });
}
static long SetHitAperture(navlib::param_t cookie, navlib::property_t property,
const navlib::value_t *value) {
return SetValue(cookie, property, value,
[&](isink_t isink) { return isink->SetHitAperture(*value); });
}
static long SetHitDirection(navlib::param_t cookie, navlib::property_t property,
const navlib::value_t *value) {
return SetValue(cookie, property, value,
[&](isink_t isink) { return isink->SetHitDirection(*value); });
}
static long SetHitLookFrom(navlib::param_t cookie, navlib::property_t property,
const navlib::value_t *value) {
return SetValue(cookie, property, value,
[&](isink_t isink) { return isink->SetHitLookFrom(*value); });
}
static long SetHitSelectionOnly(navlib::param_t cookie, navlib::property_t property,
const navlib::value_t *value) {
return SetValue(cookie, property, value,
[&](isink_t isink) { return isink->SetHitSelectionOnly(*value); });
}
/// <summary>
/// IModel accessors and mutators
/// </summary>
static long GetModelExtents(navlib::param_t cookie, navlib::property_t property,
navlib::value_t *value) {
return GetValue(cookie, property, value,
[&](isink_t isink) { return isink->GetModelExtents(*value); });
}
static long GetSelectionExtents(navlib::param_t cookie, navlib::property_t property,
navlib::value_t *value) {
return GetValue(cookie, property, value,
[&](isink_t isink) { return isink->GetSelectionExtents(*value); });
}
static long GetSelectionTransform(navlib::param_t cookie, navlib::property_t property,
navlib::value_t *value) {
return GetValue(cookie, property, value,
[&](isink_t isink) { return isink->GetSelectionTransform(*value); });
}
static long GetIsSelectionEmpty(navlib::param_t cookie, navlib::property_t property,
navlib::value_t *value) {
return GetValue(cookie, property, value,
[&](isink_t isink) { return isink->GetIsSelectionEmpty(*value); });
}
static long SetSelectionTransform(navlib::param_t cookie, navlib::property_t property,
const navlib::value_t *value) {
return SetValue(cookie, property, value,
[&](isink_t isink) { return isink->SetSelectionTransform(*value); });
}
/// <summary>
/// IPivot accessors and mutators
/// </summary>
static long GetPivotPosition(navlib::param_t cookie, navlib::property_t property,
navlib::value_t *value) {
return GetValue(cookie, property, value,
[&](isink_t isink) { return isink->GetPivotPosition(*value); });
}
static long IsUserPivot(navlib::param_t cookie, navlib::property_t property,
navlib::value_t *value) {
return GetValue(cookie, property, value,
[&](isink_t isink) { return isink->IsUserPivot(*value); });
}
static long SetPivotPosition(navlib::param_t cookie, navlib::property_t property,
const navlib::value_t *value) {
return SetValue(cookie, property, value,
[&](isink_t isink) { return isink->SetPivotPosition(*value); });
}
static long GetPivotVisible(navlib::param_t cookie, navlib::property_t property,
navlib::value_t *value) {
return GetValue(cookie, property, value,
[&](isink_t isink) { return isink->GetPivotVisible(*value); });
}
static long SetPivotVisible(navlib::param_t cookie, navlib::property_t property,
const navlib::value_t *value) {
return SetValue(cookie, property, value,
[&](isink_t isink) { return isink->SetPivotVisible(*value); });
}
/// <summary>
/// ISpace3D accessors and mutators
/// </summary>
static long GetCoordinateSystem(navlib::param_t cookie, navlib::property_t property,
navlib::value_t *value) {
return GetValue(cookie, property, value,
[&](isink_t isink) { return isink->GetCoordinateSystem(*value); });
}
static long GetFrontView(navlib::param_t cookie, navlib::property_t property,
navlib::value_t *value) {
return GetValue(cookie, property, value,
[&](isink_t isink) { return isink->GetFrontView(*value); });
}
/// <summary>
/// IState accessors and mutators
/// </summary>
static long SetTransaction(navlib::param_t cookie, navlib::property_t property,
const navlib::value_t *value) {
return SetValue(cookie, property, value,
[&](isink_t isink) { return isink->SetTransaction(*value); });
}
static long SetMotionFlag(navlib::param_t cookie, navlib::property_t property,
const navlib::value_t *value) {
return SetValue(cookie, property, value,
[&](isink_t isink) { return isink->SetMotionFlag(*value); });
}
/// <summary>
/// IView accessors and mutators
/// </summary>
static long GetCameraMatrix(navlib::param_t cookie, navlib::property_t property,
navlib::value_t *value) {
return GetValue(cookie, property, value,
[&](isink_t isink) { return isink->GetCameraMatrix(*value); });
}
static long GetCameraTarget(navlib::param_t cookie, navlib::property_t property,
navlib::value_t *value) {
return GetValue(cookie, property, value,
[&](isink_t isink) { return isink->GetCameraTarget(*value); });
}
static long GetPointerPosition(navlib::param_t cookie, navlib::property_t property,
navlib::value_t *value) {
return GetValue(cookie, property, value,
[&](isink_t isink) { return isink->GetPointerPosition(*value); });
}
static long GetViewConstructionPlane(navlib::param_t cookie, navlib::property_t property,
navlib::value_t *value) {
return GetValue(cookie, property, value,
[&](isink_t isink) { return isink->GetViewConstructionPlane(*value); });
}
static long GetViewExtents(navlib::param_t cookie, navlib::property_t property,
navlib::value_t *value) {
return GetValue(cookie, property, value,
[&](isink_t isink) { return isink->GetViewExtents(*value); });
}
static long GetViewFOV(navlib::param_t cookie, navlib::property_t property,
navlib::value_t *value) {
return GetValue(cookie, property, value,
[&](isink_t isink) { return isink->GetViewFOV(*value); });
}
static long GetViewFrustum(navlib::param_t cookie, navlib::property_t property,
navlib::value_t *value) {
return GetValue(cookie, property, value,
[&](isink_t isink) { return isink->GetViewFrustum(*value); });
}
static long GetIsViewPerspective(navlib::param_t cookie, navlib::property_t property,
navlib::value_t *value) {
return GetValue(cookie, property, value,
[&](isink_t isink) { return isink->GetIsViewPerspective(*value); });
}
static long GetIsViewRotatable(navlib::param_t cookie, navlib::property_t property,
navlib::value_t *value) {
return GetValue(cookie, property, value,
[&](isink_t isink) { return isink->GetIsViewRotatable(*value); });
}
static long SetCameraMatrix(navlib::param_t cookie, navlib::property_t property,
const navlib::value_t *value) {
return SetValue(cookie, property, value,
[&](isink_t isink) { return isink->SetCameraMatrix(*value); });
}
static long SetCameraTarget(navlib::param_t cookie, navlib::property_t property,
const navlib::value_t *value) {
return SetValue(cookie, property, value,
[&](isink_t isink) { return isink->SetCameraTarget(*value); });
}
static long SetPointerPosition(navlib::param_t cookie, navlib::property_t property,
const navlib::value_t *value) {
return SetValue(cookie, property, value,
[&](isink_t isink) { return isink->SetPointerPosition(*value); });
}
static long SetViewExtents(navlib::param_t cookie, navlib::property_t property,
const navlib::value_t *value) {
return SetValue(cookie, property, value,
[&](isink_t isink) { return isink->SetViewExtents(*value); });
}
static long SetViewFOV(navlib::param_t cookie, navlib::property_t property,
const navlib::value_t *value) {
return SetValue(cookie, property, value,
[&](isink_t isink) { return isink->SetViewFOV(*value); });
}
static long SetViewFrustum(navlib::param_t cookie, navlib::property_t property,
const navlib::value_t *value) {
return SetValue(cookie, property, value,
[&](isink_t isink) { return isink->SetViewFrustum(*value); });
}
private:
/// <summary>
/// Read a <see cref="navlib::property_t"/> value from the navlib.
/// </summary>
/// <param name="nh">The <see cref="navlib::nlHandle_t"/> to the navigation library returned by
/// a previous call to <see cref="navlib::NlCreate"/>.</param>
/// <param name="name">The name of the navlib property to read.</param>
/// <param name="value">Pointer to a <see cref="navlib::value_t"/> to receive the value.</param>
/// <returns>0 =no error, otherwise a value from <see cref="navlib::make_result_code"/>.</returns>
/// <exception cref="std::system_error">No connection to the navlib / 3D Mouse.</exception>
long ReadValue(navlib::nlHandle_t nh, navlib::property_t name, navlib::value_t *value) const {
using namespace ::navlib;
try {
long resultCode = NlReadValue(nh, name, value);
#if _DEBUG && TRACE_NAVLIB
std::unique_lock<std::mutex> lock(s_mutex);
std::clog << "NlReadValue(0x" << std::hex << nh << std::dec << ", " << name << ", " << *value
<< ") result =0x" << std::hex << resultCode << std::endl;
#endif
return resultCode;
}
catch (const std::exception &e) {
std::unique_lock<std::mutex> lock(s_mutex);
std::cerr << "exception thrown in NlReadValue(0x" << std::hex << nh << std::dec
<< ", " << name << ", value)\n"
<< *value << " " << e.what() << std::endl;
}
return navlib::make_result_code(navlib::navlib_errc::error);
}
/// <summary>
/// Write a <see cref="navlib::property_t"/> value to the navlib.
/// </summary>
/// <param name="nh">The <see cref="navlib::nlHandle_t"/> to the navigation library returned by
/// a previous call to <see cref="navlib::NlCreate"/>.</param>
/// <param name="name">The name of the navlib property to read.</param>
/// <param name="value">Pointer to a <see cref="navlib::value_t"/> to receive the value.</param>
/// <returns>0 =no error, otherwise a value from <see cref="navlib::make_result_code"/>.</returns>
/// <exception cref="std::system_error">No connection to the navlib / 3D Mouse.</exception>
long WriteValue(navlib::nlHandle_t nh, navlib::property_t name,
const navlib::value_t *value) {
using namespace ::navlib;
try {
long resultCode = NlWriteValue(nh, name, value);
#if _DEBUG && TRACE_NAVLIB
std::unique_lock<std::mutex> lock(s_mutex);
std::clog << "NlWriteValue(0x" << std::hex << nh << std::dec << ", " << name << ", " << *value
<< ") result =0x" << std::hex << resultCode << std::endl;
#endif
return resultCode;
}
catch (const std::exception &e) {
std::unique_lock<std::mutex> lock(s_mutex);
std::cerr << "exception thrown in NlWriteValue(0x" << std::hex << nh << std::dec
<< ", " << name << ", value)\n"
<< *value << " " << e.what() << std::endl;
}
return navlib::make_result_code(navlib::navlib_errc::error);
}
private:
navlib::nlHandle_t m_hdl;
std::mutex m_mutex;
navlib::param_t m_cookie;
std::string m_name;
navlib::nlCreateOptions_t m_createOptions;
};
} // namespace Navigation3D
} // namespace SpaceMouse
} // namespace TDx
#endif // CNavigationModelImpl_HPP_INCLUDED

View File

@ -0,0 +1,50 @@
#ifndef IAccessors_HPP_INCLUDED
#define IAccessors_HPP_INCLUDED
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (c) 2018-2021 3Dconnexion.
*
* 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 IAccessors.hpp
* @brief The accessor interface to the client 3D properties.
*/
#include <SpaceMouse/IEvents.hpp>
#include <SpaceMouse/IHit.hpp>
#include <SpaceMouse/IModel.hpp>
#include <SpaceMouse/IPivot.hpp>
#include <SpaceMouse/ISpace3D.hpp>
#include <SpaceMouse/IState.hpp>
#include <SpaceMouse/IView.hpp>
namespace TDx {
namespace SpaceMouse {
namespace Navigation3D {
/// <summary>
/// The accessor interface to the client 3D properties.
/// </summary>
class IAccessors : public ISpace3D,
public IView,
public IModel,
public IPivot,
public IHit,
public IEvents,
public IState {};
} // namespace Navigation3D
} // namespace SpaceMouse
} // namespace TDx
#endif // IAccessors_HPP_INCLUDED

View File

@ -0,0 +1,72 @@
#ifndef IEvents_HPP_INCLUDED
#define IEvents_HPP_INCLUDED
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (c) 2018-2021 3Dconnexion.
*
* 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 IEvents.hpp
* @brief The events interface.
*/
#include <navlib/navlib_types.h>
//stdlib
#include <string>
namespace TDx {
namespace SpaceMouse {
namespace Navigation3D {
/// <summary>
/// The Events interface
/// </summary>
class IEvents {
public:
/// <summary>
/// Is called when the user invokes an application command from the SpaceMouse.
/// </summary>
/// <param name="commandId">The id of the command to invoke.</param>
/// <returns>The result of the function: 0 = no error, otherwise &lt;0.</returns>
virtual long SetActiveCommand(std::string commandId) = 0;
/// <summary>
/// Is called when the navigation settings change.
/// </summary>
/// <param name="count">The change count.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
virtual long SetSettingsChanged(long count) = 0;
/// <summary>
/// Is invoked when the user releases a key on the 3D Mouse, which has been programmed to send a
/// virtual key code.
/// </summary>
/// <param name="vkey">The virtual key code of the key pressed.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
virtual long SetKeyPress(long vkey) = 0;
/// <summary>
/// Is invoked when the user releases a key on the 3D Mouse, which has been programmed to send a
/// virtual key code.
/// </summary>
/// <param name="vkey">The virtual key code of the key released.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
virtual long SetKeyRelease(long vkey) = 0;
};
} // namespace Navigation3D
} // namespace SpaceMouse
} // namespace TDx
#endif // IEvents_HPP_INCLUDED

View File

@ -0,0 +1,74 @@
#ifndef IHit_HPP_INCLUDED
#define IHit_HPP_INCLUDED
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (c) 2018-2021 3Dconnexion.
*
* 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 IHit.hpp
* @brief The hit-testing interface.
*/
#include <navlib/navlib_types.h>
namespace TDx {
namespace SpaceMouse {
namespace Navigation3D {
/// <summary>
/// The hit-testing interface.
/// </summary>
class IHit {
public:
/// <summary>
/// Is called when the navigation library queries the result of the hit-testing.
/// </summary>
/// <param name="position">The hit <see cref="navlib::point_t"/> in world coordinates.</param>
/// <returns>0 =no error, otherwise &lt;0 <see cref="navlib::make_result_code"/>.</returns>
virtual long GetHitLookAt(navlib::point_t &position) const = 0;
/// <summary>
/// Is called when the navigation library sets the aperture of the hit-testing ray/cone.
/// </summary>
/// <param name="aperture">The aperture of the ray/cone on the near plane.</param>
/// <returns>0 =no error, otherwise &lt;0 <see cref="navlib::make_result_code"/>.</returns>
virtual long SetHitAperture(double aperture) = 0;
/// <summary>
/// Is called when the navigation library sets the direction of the hit-testing ray/cone.
/// </summary>
/// <param name="direction">The <see cref="navlib::vector_t"/> direction of the ray/cone.</param>
/// <returns>0 =no error, otherwise &lt;0 <see cref="navlib::make_result_code"/>.</returns>
virtual long SetHitDirection(const navlib::vector_t& direction) = 0;
/// <summary>
/// Is called when the navigation library sets the source of the hit-testing ray/cone.
/// </summary>
/// <param name="eye">The source <see cref="navlib::point_t"/> of the hit cone.</param>
/// <returns>0 =no error, otherwise &lt;0 <see cref="navlib::make_result_code"/>.</returns>
virtual long SetHitLookFrom(const navlib::point_t& eye) = 0;
/// <summary>
/// Is called when the navigation library sets the selection filter for hit-testing.
/// </summary>
/// <param name="onlySelection">true = ignore non-selected items.</param>
/// <returns>0 =no error, otherwise &lt;0 <see cref="navlib::make_result_code"/>.</returns>
virtual long SetHitSelectionOnly(bool onlySelection) = 0;
};
} // namespace Navigation3D
} // namespace SpaceMouse
} // namespace TDx
#endif // IHit_HPP_INCLUDED

View File

@ -0,0 +1,77 @@
#ifndef IModel_HPP_INCLUDED
#define IModel_HPP_INCLUDED
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (c) 2018-2021 3Dconnexion.
*
* 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 IModel.hpp
* @brief The 3D model interface.
*/
#include <navlib/navlib_types.h>
namespace TDx {
namespace SpaceMouse {
namespace Navigation3D {
/// <summary>
/// The Model interface
/// </summary>
class IModel {
public:
/// <summary>
/// Is called when the navigation library needs to get the extents of the model.
/// </summary>
/// <param name="extents">A <see cref="navlib::box_t"/> representing the extents of the
/// model.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
virtual long GetModelExtents(navlib::box_t &extents) const = 0;
/// <summary>
/// Is called when the navigation library needs to get the extents of the selection.
/// </summary>
/// <param name="extents">A <see cref="navlib::box_t"/> representing the extents of the
/// selection.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
virtual long GetSelectionExtents(navlib::box_t &extents) const = 0;
/// <summary>
/// Is called to get the selections's transform <see cref="navlib::matrix_t"/>.
/// </summary>
/// <param name="transform">The world affine <see cref="navlib::matrix_t"/> of the
/// selection.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
virtual long GetSelectionTransform(navlib::matrix_t &transform) const = 0;
/// <summary>
/// Is called to query if the selection is empty.
/// </summary>
/// <param name="empty">true if nothing is selected.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
virtual long GetIsSelectionEmpty(navlib::bool_t &empty) const = 0;
/// <summary>
/// Is called to set the selections's transform <see cref="navlib::matrix_t"/>.
/// </summary>
/// <param name="matrix">The world affine <see cref="navlib::matrix_t"/> of the selection.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
virtual long SetSelectionTransform(const navlib::matrix_t& matrix) = 0;
};
} // namespace Navigation3D
} // namespace SpaceMouse
} // namespace TDx
#endif // IModel_HPP_INCLUDED

View File

@ -0,0 +1,94 @@
#ifndef INavlib_HPP_INCLUDED
#define INavlib_HPP_INCLUDED
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (c) 2018-2021 3Dconnexion.
*
* 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 INavlib.hpp
* @brief Interface to access the navigation library.
*/
#include <navlib/navlib_types.h>
namespace TDx {
namespace SpaceMouse {
namespace Navigation3D {
/// <summary>
/// The interface to access the navigation library properties.
/// </summary>
class INavlibProperty {
public:
/// <summary>
/// Writes the value of a property to the navlib.
/// </summary>
/// <param name="propertyName">The <see cref="navlib::property_t"/> name of the navlib property to
/// write.</param>
/// <param name="value">The <see cref="navlib::value"/> to write.</param>
/// <returns>0 =no error, otherwise a value from <see cref="navlib::make_result_code"/>.</returns>
/// <exception cref="std::system_error">No connection to the navlib / 3D Mouse.</exception>
virtual long Write(const std::string &propertyName, const navlib::value &value) = 0;
/// <summary>
/// Reads the value of a navlib property.
/// </summary>
/// <param name="propertyName">The <see cref="navlib::property_t"/> name of the navlib property to
/// read.</param>
/// <param name="value">The <see cref="navlib::value"/> to read.</param>
/// <returns>0 =no error, otherwise a value from <see cref="navlib::make_result_code"/>.</returns>
/// <exception cref="std::system_error">No connection to the navlib / 3D Mouse.</exception>
virtual long Read(const std::string &propertyName, navlib::value &value) const = 0;
/// <summary>
/// Reads the value of a navlib string property.
/// </summary>
/// <param name="propertyName">The <see cref="navlib::property_t"/> name of the navlib property to
/// read.</param>
/// <param name="string">The <see cref="std::string"/> value of the property.</param>
/// <returns>0 =no error, otherwise a value from <see cref="navlib::make_result_code"/>.</returns>
/// <exception cref="std::system_error">No connection to the navlib.</exception>
virtual long Read(const std::string &propertyName, std::string &string) const = 0;
};
/// <summary>
/// The interface to access the navigation library.
/// </summary>
class INavlib : public INavlibProperty {
public:
/// <summary>
/// Close the connection to the 3D navigation library.
/// </summary>
virtual void Close() = 0;
/// <summary>
/// Opens a connection to the 3D navigation library.
/// </summary>
virtual void Open() = 0;
/// <summary>
/// Opens a connection to the 3D navigation library
/// </summary>
/// <param name="profileName">The name of the 3Dconnexion profile to use.</param>
/// <exception cref="std::system_error">The connection to the library is already open.</exception>
/// <exception cref="std::system_error">Cannot create a connection to the library.</exception>
/// <exception cref="std::invalid_argument">The name of the profile is empty.</exception>
virtual void Open(std::string profileName) = 0;
};
} // namespace Navigation3D
} // namespace SpaceMouse
} // namespace TDx
#endif // INavlib_HPP_INCLUDED

View File

@ -0,0 +1,74 @@
#ifndef IPivot_HPP_INCLUDED
#define IPivot_HPP_INCLUDED
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (c) 2018-2021 3Dconnexion.
*
* 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 IPivot.hpp
* @brief Interface to access the pivot.
*/
#include <navlib/navlib_types.h>
namespace TDx {
namespace SpaceMouse {
namespace Navigation3D {
/// <summary>
/// The interface to access the pivot.
/// </summary>
class IPivot {
public:
/// <summary>
/// Gets the position of the rotation pivot.
/// </summary>
/// <param name="position">The pivot <see cref="navlib::point_t"/> in world coordinates.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
virtual long GetPivotPosition(navlib::point_t &position) const = 0;
/// <summary>
/// Queries if the user has manually set a pivot point.
/// </summary>
/// <param name="userPivot">true if the user has set a pivot otherwise false.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
virtual long IsUserPivot(navlib::bool_t &userPivot) const = 0;
/// <summary>
/// Sets the position of the rotation pivot.
/// </summary>
/// <param name="position">The pivot <see cref="navlib::point_t"/> in world coordinates.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
virtual long SetPivotPosition(const navlib::point_t& position) = 0;
/// <summary>
/// Queries the visibility of the pivot image.
/// </summary>
/// <param name="visible">true if the pivot is visible otherwise false.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
virtual long GetPivotVisible(navlib::bool_t &visible) const = 0;
/// <summary>
/// Sets the visibility of the pivot image.
/// </summary>
/// <param name="visible">true if the pivot is visible otherwise false.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
virtual long SetPivotVisible(bool visible) = 0;
};
} // namespace Navigation3D
} // namespace SpaceMouse
} // namespace TDx
#endif // IPivot_HPP_INCLUDED

View File

@ -0,0 +1,55 @@
#ifndef ISpace3D_HPP_INCLUDED
#define ISpace3D_HPP_INCLUDED
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (c) 2018-2021 3Dconnexion.
*
* 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 ISpace3D.hpp
* @brief Interface to the client coordinate system.
*/
#include <navlib/navlib_types.h>
namespace TDx {
namespace SpaceMouse {
namespace Navigation3D {
/// <summary>
/// The interface to access the client coordinate system.
/// </summary>
class ISpace3D {
public:
/// <summary>
/// Gets the coordinate system used by the client.
/// </summary>
/// <param name="matrix">The coordinate system <see cref="navlib::matrix_t"/>.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
/// <remarks>The matrix describes the applications coordinate frame in the navlib coordinate
/// system. i.e. the application to navlib transform.</remarks>
virtual long GetCoordinateSystem(navlib::matrix_t &matrix) const = 0;
/// <summary>
/// Gets the orientation of the front view.
/// </summary>
/// <param name="matrix">The front view transform <see cref="navlib::matrix_t"/>.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
virtual long GetFrontView(navlib::matrix_t &matrix) const = 0;
};
} // namespace Navigation3D
} // namespace SpaceMouse
} // namespace TDx
#endif // ISpace3D_HPP_INCLUDED

View File

@ -0,0 +1,54 @@
#ifndef IState_HPP_INCLUDED
#define IState_HPP_INCLUDED
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (c) 2018-2021 3Dconnexion.
*
* 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 IState.hpp
* @brief Interface to access the navigation state.
*/
#include <navlib/navlib_types.h>
namespace TDx {
namespace SpaceMouse {
namespace Navigation3D {
/// <summary>
/// Interface to access the navigation state.
/// </summary>
class IState {
public:
/// <summary>
/// Is called when the navigation library starts or stops a navigation transaction.
/// </summary>
/// <param name="transaction">The transaction number: >0 begin, ==0 end.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
virtual long SetTransaction(long transaction) = 0;
/// <summary>
/// Is called when the navigation instance starts or stops a sequence of motion frames.
/// </summary>
/// <param name="motion">The motion flag: true = start, false = end.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
/// <remarks>This can be used to start an animation loop.</remarks>
virtual long SetMotionFlag(bool motion) = 0;
};
} // namespace Navigation3D
} // namespace SpaceMouse
} // namespace TDx
#endif // IState_HPP_INCLUDED

View File

@ -0,0 +1,149 @@
#ifndef IView_HPP_INCLUDED
#define IView_HPP_INCLUDED
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (c) 2018-2021 3Dconnexion.
*
* 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 IView.hpp
* @brief View callback interface.
*/
#include <navlib/navlib_types.h>
namespace TDx {
namespace SpaceMouse {
namespace Navigation3D {
/// <summary>
/// View callback interface.
/// </summary>
class IView {
public:
/// <summary>
/// Gets the camera matrix of the view.
/// </summary>
/// <param name="matrix">The camera/view <see cref="navlib::matrix_t"/>.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
virtual long GetCameraMatrix(navlib::matrix_t &matrix) const = 0;
/// <summary>
/// Gets the camera's target point.
/// </summary>
/// <param name="target">The position of the camera target in world coordinates.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
/// <remarks>Free cameras do not have a target.</remarks>
virtual long GetCameraTarget(navlib::point_t &target) const = 0;
/// <summary>
/// Gets the position of the pointer on the near clipping plane.
/// </summary>
/// <param name="position">The <see cref="navlib::point_t"/> in world coordinates of the
/// pointer.</param> <returns>0 = no error, otherwise &lt;0.</returns>
virtual long GetPointerPosition(navlib::point_t &position) const = 0;
/// <summary>
/// Gets the view's construction plane.
/// </summary>
/// <param name="plane">The plane equation of the construction plane.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
virtual long GetViewConstructionPlane(navlib::plane_t &plane) const = 0;
/// <summary>
/// Gets the extents of the view.
/// </summary>
/// <param name="extents">A <see cref="navlib::box_t"/> representing the extents of the
/// view.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
virtual long GetViewExtents(navlib::box_t &extents) const = 0;
/// <summary>
/// Gets the camera's/view's field of view.
/// </summary>
/// <param name="fov">The field of view in radians.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
virtual long GetViewFOV(double &fov) const = 0;
/// <summary>
/// Gets the camera/view frustum.
/// </summary>
/// <param name="frustum">The camera/view <see cref="navlib::frustum_t"/>.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
virtual long GetViewFrustum(navlib::frustum_t &frustum) const = 0;
/// <summary>
/// Get's the view's projection type
/// </summary>
/// <param name="perspective">true for a perspective view, false for an orthographic view.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
virtual long GetIsViewPerspective(navlib::bool_t &perspective) const = 0;
/// <summary>
/// Gets a value indicating whether the view can be rotated.
/// </summary>
/// <param name="isRotatable">true if the view can be rotated, false otherwise.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
virtual long GetIsViewRotatable(navlib::bool_t &isRotatable) const = 0;
/// <summary>
/// Sets the camera affine matrix.
/// </summary>
/// <param name="matrix">The camera/view <see cref="navlib::matrix_t"/>.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
virtual long SetCameraMatrix(const navlib::matrix_t& matrix) = 0;
/// <summary>
/// Sets the camera's target position.
/// </summary>
/// <param name="target">The position of the camera target in world coordinates.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
/// <remarks>Free cameras do not have a target.</remarks>
virtual long SetCameraTarget(const navlib::point_t &target) = 0;
/// <summary>
/// Sets the position of the pointer on the near clipping plane.
/// </summary>
/// <param name="position">The <see cref="navlib::point_t"/> in world coordinates of the
/// pointer.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
virtual long SetPointerPosition(const navlib::point_t& position) = 0;
/// <summary>
/// Sets the extents of the view.
/// </summary>
/// <param name="extents">A <see cref="navlib::box_t"/> representing the extents of the
/// view.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
virtual long SetViewExtents(const navlib::box_t& extents) = 0;
/// <summary>
/// Sets the camera's/view's field of view.
/// </summary>
/// <param name="fov">The field of view in radians.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
virtual long SetViewFOV(double fov) = 0;
/// <summary>
/// Sets the camera/view frustum.
/// </summary>
/// <param name="frustum">The camera/view <see cref="navlib::frustum_t"/>.</param>
/// <returns>0 = no error, otherwise &lt;0.</returns>
virtual long SetViewFrustum(const navlib::frustum_t& frustum) = 0;
};
} // namespace Navigation3D
} // namespace SpaceMouse
} // namespace TDx
#endif // IView_HPP_INCLUDED

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
<HasSharedItems>true</HasSharedItems>
<ItemsProjectGuid>{5df960db-b916-4732-a13d-228f20a806fe}</ItemsProjectGuid>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory)</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ProjectCapability Include="SourceItemsFromImports" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(MSBuildThisFileDirectory)CActionNode.hpp" />
<ClInclude Include="$(MSBuildThisFileDirectory)CCategory.hpp" />
<ClInclude Include="$(MSBuildThisFileDirectory)CCommand.hpp" />
<ClInclude Include="$(MSBuildThisFileDirectory)CCommandSet.hpp" />
<ClInclude Include="$(MSBuildThisFileDirectory)CCommandTreeNode.hpp" />
<ClInclude Include="$(MSBuildThisFileDirectory)CCookieCollection.hpp" />
<ClInclude Include="$(MSBuildThisFileDirectory)CHitTest.hpp" />
<ClInclude Include="$(MSBuildThisFileDirectory)CImage.hpp" />
<ClInclude Include="$(MSBuildThisFileDirectory)CNavigation3D.hpp" />
<ClInclude Include="$(MSBuildThisFileDirectory)CNavlibImpl.hpp" />
<ClInclude Include="$(MSBuildThisFileDirectory)CNavlibInterface.hpp" />
<ClInclude Include="$(MSBuildThisFileDirectory)IAccessors.hpp" />
<ClInclude Include="$(MSBuildThisFileDirectory)IEvents.hpp" />
<ClInclude Include="$(MSBuildThisFileDirectory)IHit.hpp" />
<ClInclude Include="$(MSBuildThisFileDirectory)IModel.hpp" />
<ClInclude Include="$(MSBuildThisFileDirectory)INavlib.hpp" />
<ClInclude Include="$(MSBuildThisFileDirectory)IPivot.hpp" />
<ClInclude Include="$(MSBuildThisFileDirectory)ISpace3D.hpp" />
<ClInclude Include="$(MSBuildThisFileDirectory)IState.hpp" />
<ClInclude Include="$(MSBuildThisFileDirectory)IView.hpp" />
</ItemGroup>
<ItemGroup>
<None Include="$(MSBuildThisFileDirectory).editorconfig" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,15 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27703.2042
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Navigation3D", "Navigation3D.vcxitems", "{5DF960DB-B916-4732-A13D-228F20A806FE}"
EndProject
Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {7CEA499A-2163-4040-AFCB-8897C44712C3}
EndGlobalSection
EndGlobal

227
thirdparty/3dxware_sdk/inc/V3DCMD.h vendored Normal file
View File

@ -0,0 +1,227 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (c) 2013-2021 3Dconnexion.
*
* 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 V3DCMD.hpp
* @brief Virtual 3D Commands.
*/
/*----------------------------------------------------------------------
* V3DCMD.h -- Virtual 3D Commands
*
* enums for all current V3DCMDs
* These are functions that all applications should respond to if they are
* at all applicable. These cmds are generated from any number of places
* including hard and soft buttons. They don't necessarily represent a
* hardware button
*
* Written: January 2013
* Original author: Jim Wick
*
*/
#ifndef _V3DCMD_H_
#define _V3DCMD_H_
/*
* Constants
*/
/*
* Virtual 3D Commands
*
* These function numbers will never change, but the list will be amended as more
* V3DCMDs are created.
* For use with SI_CMD_EVENT.
* Most of these don't have a separate press and release of these events.
* Some keys do have press and release (Esc, Shift, Ctrl) as expected of keyboard keys.
*/
typedef enum
{
V3DCMD_NOOP = 0,
V3DCMD_MENU_OPTIONS = 1,
V3DCMD_VIEW_FIT = 2,
V3DCMD_VIEW_TOP = 3,
V3DCMD_VIEW_LEFT = 4,
V3DCMD_VIEW_RIGHT = 5,
V3DCMD_VIEW_FRONT = 6,
V3DCMD_VIEW_BOTTOM = 7,
V3DCMD_VIEW_BACK = 8,
V3DCMD_VIEW_ROLLCW = 9,
V3DCMD_VIEW_ROLLCCW = 10,
V3DCMD_VIEW_ISO1 = 11,
V3DCMD_VIEW_ISO2 = 12,
V3DCMD_KEY_F1 = 13,
V3DCMD_KEY_F2 = 14,
V3DCMD_KEY_F3 = 15,
V3DCMD_KEY_F4 = 16,
V3DCMD_KEY_F5 = 17,
V3DCMD_KEY_F6 = 18,
V3DCMD_KEY_F7 = 19,
V3DCMD_KEY_F8 = 20,
V3DCMD_KEY_F9 = 21,
V3DCMD_KEY_F10 = 22,
V3DCMD_KEY_F11 = 23,
V3DCMD_KEY_F12 = 24,
V3DCMD_KEY_ESC = 25,
V3DCMD_KEY_ALT = 26,
V3DCMD_KEY_SHIFT = 27,
V3DCMD_KEY_CTRL = 28,
V3DCMD_FILTER_ROTATE = 29,
V3DCMD_FILTER_PANZOOM = 30,
V3DCMD_FILTER_DOMINANT = 31,
V3DCMD_SCALE_PLUS = 32,
V3DCMD_SCALE_MINUS = 33,
V3DCMD_VIEW_SPINCW = 34,
V3DCMD_VIEW_SPINCCW = 35,
V3DCMD_VIEW_TILTCW = 36,
V3DCMD_VIEW_TILTCCW = 37,
V3DCMD_MENU_POPUP = 38,
V3DCMD_MENU_BUTTONMAPPINGEDITOR = 39,
V3DCMD_MENU_ADVANCEDSETTINGSEDITOR = 40,
V3DCMD_MOTIONMACRO_ZOOM = 41,
V3DCMD_MOTIONMACRO_ZOOMOUT_CURSORTOCENTER = 42,
V3DCMD_MOTIONMACRO_ZOOMIN_CURSORTOCENTER = 43,
V3DCMD_MOTIONMACRO_ZOOMOUT_CENTERTOCENTER = 44,
V3DCMD_MOTIONMACRO_ZOOMIN_CENTERTOCENTER = 45,
V3DCMD_MOTIONMACRO_ZOOMOUT_CURSORTOCURSOR = 46,
V3DCMD_MOTIONMACRO_ZOOMIN_CURSORTOCURSOR = 47,
V3DCMD_VIEW_QZ_IN = 48,
V3DCMD_VIEW_QZ_OUT = 49,
V3DCMD_KEY_ENTER = 50,
V3DCMD_KEY_DELETE = 51,
V3DCMD_KEY_F13 = 52,
V3DCMD_KEY_F14 = 53,
V3DCMD_KEY_F15 = 54,
V3DCMD_KEY_F16 = 55,
V3DCMD_KEY_F17 = 56,
V3DCMD_KEY_F18 = 57,
V3DCMD_KEY_F19 = 58,
V3DCMD_KEY_F20 = 59,
V3DCMD_KEY_F21 = 60,
V3DCMD_KEY_F22 = 61,
V3DCMD_KEY_F23 = 62,
V3DCMD_KEY_F24 = 63,
V3DCMD_KEY_F25 = 64,
V3DCMD_KEY_F26 = 65,
V3DCMD_KEY_F27 = 66,
V3DCMD_KEY_F28 = 67,
V3DCMD_KEY_F29 = 68,
V3DCMD_KEY_F30 = 69,
V3DCMD_KEY_F31 = 70,
V3DCMD_KEY_F32 = 71,
V3DCMD_KEY_F33 = 72,
V3DCMD_KEY_F34 = 73,
V3DCMD_KEY_F35 = 74,
V3DCMD_KEY_F36 = 75,
V3DCMD_VIEW_1 = 76,
V3DCMD_VIEW_2 = 77,
V3DCMD_VIEW_3 = 78,
V3DCMD_VIEW_4 = 79,
V3DCMD_VIEW_5 = 80,
V3DCMD_VIEW_6 = 81,
V3DCMD_VIEW_7 = 82,
V3DCMD_VIEW_8 = 83,
V3DCMD_VIEW_9 = 84,
V3DCMD_VIEW_10 = 85,
V3DCMD_VIEW_11 = 86,
V3DCMD_VIEW_12 = 87,
V3DCMD_VIEW_13 = 88,
V3DCMD_VIEW_14 = 89,
V3DCMD_VIEW_15 = 90,
V3DCMD_VIEW_16 = 91,
V3DCMD_VIEW_17 = 92,
V3DCMD_VIEW_18 = 93,
V3DCMD_VIEW_19 = 94,
V3DCMD_VIEW_20 = 95,
V3DCMD_VIEW_21 = 96,
V3DCMD_VIEW_22 = 97,
V3DCMD_VIEW_23 = 98,
V3DCMD_VIEW_24 = 99,
V3DCMD_VIEW_25 = 100,
V3DCMD_VIEW_26 = 101,
V3DCMD_VIEW_27 = 102,
V3DCMD_VIEW_28 = 103,
V3DCMD_VIEW_29 = 104,
V3DCMD_VIEW_30 = 105,
V3DCMD_VIEW_31 = 106,
V3DCMD_VIEW_32 = 107,
V3DCMD_VIEW_33 = 108,
V3DCMD_VIEW_34 = 109,
V3DCMD_VIEW_35 = 110,
V3DCMD_VIEW_36 = 111,
V3DCMD_SAVE_VIEW_1 = 112,
V3DCMD_SAVE_VIEW_2 = 113,
V3DCMD_SAVE_VIEW_3 = 114,
V3DCMD_SAVE_VIEW_4 = 115,
V3DCMD_SAVE_VIEW_5 = 116,
V3DCMD_SAVE_VIEW_6 = 117,
V3DCMD_SAVE_VIEW_7 = 118,
V3DCMD_SAVE_VIEW_8 = 119,
V3DCMD_SAVE_VIEW_9 = 120,
V3DCMD_SAVE_VIEW_10 = 121,
V3DCMD_SAVE_VIEW_11 = 122,
V3DCMD_SAVE_VIEW_12 = 123,
V3DCMD_SAVE_VIEW_13 = 124,
V3DCMD_SAVE_VIEW_14 = 125,
V3DCMD_SAVE_VIEW_15 = 126,
V3DCMD_SAVE_VIEW_16 = 127,
V3DCMD_SAVE_VIEW_17 = 128,
V3DCMD_SAVE_VIEW_18 = 129,
V3DCMD_SAVE_VIEW_19 = 130,
V3DCMD_SAVE_VIEW_20 = 131,
V3DCMD_SAVE_VIEW_21 = 132,
V3DCMD_SAVE_VIEW_22 = 133,
V3DCMD_SAVE_VIEW_23 = 134,
V3DCMD_SAVE_VIEW_24 = 135,
V3DCMD_SAVE_VIEW_25 = 136,
V3DCMD_SAVE_VIEW_26 = 137,
V3DCMD_SAVE_VIEW_27 = 138,
V3DCMD_SAVE_VIEW_28 = 139,
V3DCMD_SAVE_VIEW_29 = 140,
V3DCMD_SAVE_VIEW_30 = 141,
V3DCMD_SAVE_VIEW_31 = 142,
V3DCMD_SAVE_VIEW_32 = 143,
V3DCMD_SAVE_VIEW_33 = 144,
V3DCMD_SAVE_VIEW_34 = 145,
V3DCMD_SAVE_VIEW_35 = 146,
V3DCMD_SAVE_VIEW_36 = 147,
V3DCMD_KEY_TAB = 148,
V3DCMD_KEY_SPACE = 149,
V3DCMD_MENU_1 = 150,
V3DCMD_MENU_2 = 151,
V3DCMD_MENU_3 = 152,
V3DCMD_MENU_4 = 153,
V3DCMD_MENU_5 = 154,
V3DCMD_MENU_6 = 155,
V3DCMD_MENU_7 = 156,
V3DCMD_MENU_8 = 157,
V3DCMD_MENU_9 = 158,
V3DCMD_MENU_10 = 159,
V3DCMD_MENU_11 = 160,
V3DCMD_MENU_12 = 161,
V3DCMD_MENU_13 = 162,
V3DCMD_MENU_14 = 163,
V3DCMD_MENU_15 = 164,
V3DCMD_MENU_16 = 165,
/* Add here as needed. Don't change any values that may be in use */
} V3DCMD;
#endif /* _V3DCMD_H_ */

View File

@ -0,0 +1,108 @@
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Right
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: false
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 100
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
- Regex: '.*'
Priority: 1
IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: false
IndentWidth: 2
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 8
UseTab: Never
...

View File

@ -0,0 +1,635 @@
#ifndef NAVLIB_H_INCLUDED_
#define NAVLIB_H_INCLUDED_
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (c) 2014-2021 3Dconnexion.
*
* 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 navlib.h
* @brief describes the interface for navigating in a 2D or 3D view.
*/
#include <navlib/navlib_types.h>
/// <summary>
/// Contains the navigation library API types and functions
/// </summary>
/// <remarks>
/// The functions and types describe an interface for navigating in a 2D or 3D view.
/// <para>
/// In this scheme, a 3dconnexion library is responsible for calculating the position of the camera
/// viewing the scene or object as well as displaying the settings and for supporting user
/// customization.
/// </para>
/// <para>
/// The application is responsible for passing the description of an interface of the 2D/3D view to
/// the 3dconnexion library, and for reacting to the changes to the properties identified by the
/// 3dconnexion library.
/// </para>
/// </remarks>
_NAVLIB_BEGIN
// ************************************************************************************************
// Properties
/// <summary>
/// Property set by the client to indicate that the connection is currently active.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="bool_t"/> and <see cref="propertyType_t"/> is
/// <see cref="bool_type"/>.</para>
/// <para>Clients that have multiple navigation instances open need to inform the navlib which of
/// them is the target for 3D Mouse input. They do this by setting the active_k property of a
/// navigation instance to true.</para>
/// </remarks>
static const property_t active_k = "active";
/// <summary>
/// Property that a client sets to indicate it has keyboard focus.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="bool_t"/> and <see cref="propertyType_t"/> is
/// <see cref="bool_type"/>.</para>
/// <para>Clients that run in container applications via the NLServer proxy set this property to
/// indicate keyboard focus. This will set 3DMouse focus to the navlib connection.</para>
/// </remarks>
static const property_t focus_k = "focus";
/// <summary>
/// Client property that the navlib sets when a motion model is active.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="bool_t"/> and <see cref="propertyType_t"/> is
/// <see cref="bool_type"/>.</para>
/// <para>The motion_k property is set to true by the navlib to notify
/// the client that it is executing a motion model and will update the camera matrix regularly. This
/// is useful for clients that need to run an animation loop. When the navlib has finished
/// navigating the camera position it will set the property to false. By setting motion_k to false,
/// a client may temporarily interrupt a navigation communication and force the Navlib to
/// reinitialize the navigation.</para>
/// </remarks>
static const property_t motion_k = "motion";
/// <summary>
/// Specifies the transform from the client's coordinate system to the navlib coordinate system.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="matrix_t"/> and <see cref="propertyType_t"/> is
/// <see cref="matrix_type"/>.</para>
/// <para>The Navigation Library coordinate system is Y up, X to the right and Z out of the screen.
/// This property is queried directly after new navigation instance is created. This allows the
/// client to specify the other properties using the coordinate system used in the client. For the
/// keep Y up ('Lock Horizon') algorithm to work correctly a non-identity matrix needs to be
/// specified whenever the ground plane is not the X-Z plane.</para>
/// </remarks>
static const property_t coordinate_system_k = "coordinateSystem";
/* Frame properties*/
/// <summary>
/// Specifies the begin and end of a navigation transaction.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="long"/> and <see cref="propertyType_t"/> is
/// <see cref="long_type"/>.</para>
/// <para>The Navigation Library can set more than one client property for a single navigation
/// frame. For example when navigating in an orthographic projection possibly both the view affine
/// and extents will be modified depending on the 3DMouse input. The Navigation Library sets the
/// transaction_k property to a value >0 at the beginning of a navigation frame and to 0 at the end.
/// Clients that need to actively refresh the view can trigger the refresh when the value is set to
/// 0.</para>
/// </remarks>
static const property_t transaction_k = "transaction";
/// <summary>
/// Specifies the time stamp of an animation frame in milliseconds.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="double"/> and <see cref="propertyType_t"/> is
/// <see cref="double_type"/>.</para>
/// <para>When the frame_timing_source_k property is set to 1, the client initiates a frame
/// transaction by informing the Navigation Library of the frame time. When the value is 0, the
/// Navigation Library attempts to synchronize the frames to the monitor vertical blanking
/// rate.</para>
/// </remarks>
static const property_t frame_time_k = "frame.time";
/// <summary>
/// Specifies the source of the frame timing.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="long"/> and <see cref="propertyType_t"/> is
/// <see cref="long_type"/>.</para>
/// <para>By setting the frame_timing_source_k property to 1, the client application informs the
/// Navigation Library that the client has an animation loop and will be the source of the frame
/// timing.</para>
/// </remarks>
static const property_t frame_timing_source_k = "frame.timingSource";
/// <summary>
/// Specifies whether a device is present
/// </summary>
/// <remarks>
/// <para>The type is <see cref="bool_t"/> and <see cref="propertyType_t"/> is
/// <see cref="bool_type"/>.</para>
/// <para>Currently this always returns true.</para>
/// </remarks>
static const property_t device_present_k = "device.present";
/// <summary>
/// Defines a set of commands.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="SiActionNode_t"/>* and <see cref="propertyType_t"/> is
/// <see cref="actionnodeexptr_type"/>.</para>
/// <para>Command sets can be considered to be button banks. The set can be either the complete list
/// of commands that are available in the application or a single set of commands for a specific
/// application context. The navlib will not query the application for this property. It is the
/// responsibility of the application to update this property when commands are to be made available
/// to the user.</para>
/// </remarks>
static const property_t commands_tree_k = "commands.tree";
/// <summary>
/// The active command.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="string_t"/> and <see cref="propertyType_t"/> is
/// <see cref="string_type"/>.</para>
/// <para>When the user presses a 3DMouse button that has been assign an application command
/// exposed by the commands_tree_k property, the navlib will write this property. The string value
/// will be the corresponding id passed in the commands_tree_k property. Generally the navlib will
/// set this property to an empty string when the corresponding button has been released.</para>
/// </remarks>
static const property_t commands_activeCommand_k = "commands.activeCommand";
/// <summary>
/// Specifies the active set of commands.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="string_t"/> and <see cref="propertyType_t"/> is
/// <see cref="string_type"/>.</para>
/// <para>In applications that have exposed multiple command sets this property needs to be set to
/// define the command set that is active. The navlib will not query the application for this
/// property. It is the responsibility of the application to update this property when the set of
/// commands need to be changed. Normally this will be due to change in application state and may
/// correspond to a menu/toolbar change. If only a single set of commands has been defined, this
/// property defaults to that set.</para>
/// </remarks>
static const property_t commands_activeSet_k = "commands.activeSet";
/// <summary>
/// Specifies an array of images for the 3Dconnexion UI.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="imagearray_t"/> and <see cref="propertyType_t"/> is
/// <see cref="imagearray_type"/>.</para>
/// <para>An image with the same <see cref="SiImage_t.id"/> as a command
/// <see cref="SiActionNodeEx_t.id"/> will be associated with that command in the 3Dconnexion
/// UI.</para>
/// </remarks>
static const property_t images_k = "images";
/* view properties */
/// <summary>
/// Specifies the transformation matrix of the view camera.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="matrix_t"/> and <see cref="propertyType_t"/> is
/// <see cref="matrix_type"/>.</para>
/// <para>This matrix specifies the camera to world transformation of the view. That is,
/// transforming the position (0, 0, 0) by this matrix yields the position of the camera in world
/// coordinates. The navlib will, generally, query this matrix at the beginning of a navigation
/// action and then set the property once per frame.</para>
/// </remarks>
static const property_t view_affine_k = "view.affine";
/// <summary>
/// Specifies the plane equation of the construction plane.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="plane_t"/> and <see cref="propertyType_t"/> is
/// <see cref="plane_type"/>.</para>
/// <para>The plane equation is used by the Navigation Library to distinguish views used for
/// construction in orthographic projections: typically the top, right left etc. views. The
/// Navigation Library assumes that when the camera's look-at axis is parallel to the plane normal,
/// the view should not be rotated.</para>
/// </remarks>
static const property_t view_constructionPlane_k = "view.constructionPlane";
/// <summary>
/// Specifies the orthographic extents of the view in camera coordinates.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="box_t"/> and <see cref="propertyType_t"/> is
/// <see cref="box_type"/>.</para>
/// <para>The orthographic extents of the view are returned as a bounding box in world units
/// relative to the camera/view frame. The view frame is a right-handed coordinate system centered
/// on the view with x to the right and y up. The Navigation Library will only access this property
/// if the view is orthographic.</para>
/// </remarks>
static const property_t view_extents_k = "view.extents";
/// <summary>
/// Specifies the vertical field-of-view of a perspective camera/view in radians.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="double"/> and <see cref="propertyType_t"/> is
/// <see cref="double_type"/>.</para>
/// </remarks>
static const property_t view_fov_k = "view.fov";
/// <summary>
/// Specifies the frustum of a perspective camera/view in camera coordinates.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="frustum_t"/> and <see cref="propertyType_t"/> is
/// <see cref="frustum_type"/>.</para>
/// <para>The navlib uses this property to calculate the field-of-view of the perspective camera.
/// The frustum is also used in algorithms that need to determine if the model is currently visible.
/// The navlib will not write to this property. Instead, if necessary, the navlib will write to the
/// <see cref="view_fov_k"/> property and leave the client to change the frustum as it
/// wishes.</para>
/// </remarks>
static const property_t view_frustum_k = "view.frustum";
/// <summary>
/// Specifies whether the projection type of the view/camera is perspective.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="bool_t"/> and <see cref="propertyType_t"/> is
/// <see cref="bool_type"/>.</para>
/// <para>This property defaults to true. If the client does not supply a function for the navlib to
/// query the view's projection (which it will generally do at the onset of motion), then it must
/// set the property in the navlib if the projection is orthographic or when it changes.</para>
/// </remarks>
static const property_t view_perspective_k = "view.perspective";
/// <summary>
/// Specifies the position of the target of the view/camera.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="point_t"/> and <see cref="propertyType_t"/> is
/// <see cref="point_type"/>.</para>
/// <para>The view interest.</para>
/// </remarks>
static const property_t view_target_k = "view.target";
/// <summary>
/// Specifies whether the view can be rotated.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="bool_t"/> and <see cref="propertyType_t"/> is
/// <see cref="bool_type"/>.</para>
/// <para>This property is generally used to differentiate between orthographic 3D views and views
/// that can only be panned and zoomed such as plan views.</para>
/// </remarks>
static const property_t view_rotatable_k = "view.rotatable";
/// <summary>
/// Specifies the orientation of the view designated as the front view.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="matrix_t"/> and <see cref="propertyType_t"/> is
/// <see cref="matrix_type"/>.</para>
/// <para>The Navigation Library will only query the value of this property when the connection is
/// created. It is used to orientate the model to one of the 'Front', 'Back', 'Right', 'Left' etc.
/// views in response to the respective pre-defined view commands. If the orientation of the front
/// view is redefined after the connection is opened by the user, the client application is required
/// to update the property to the new value.</para>
/// </remarks>
static const property_t views_front_k = "views.front";
/// <summary>
/// Specifies the position of the rotation pivot.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="point_t"/> and <see cref="propertyType_t"/> is
/// <see cref="point_type"/>.</para>
/// <para>The Navigation Library will generally set <see cref="pivot_position_k"/> property when
/// navigation ends. The position will depend on which pivot model is being used. The application
/// can set the pivot to a fix position by setting this property. A side effect of the application
/// setting the property is that the <see cref="pivot_user_k"/> property is set to true.</para>
/// </remarks>
static const property_t pivot_position_k = "pivot.position";
/// <summary>
/// Specifies whether the position of the rotation pivot is set by the user.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="bool_t"/> and <see cref="propertyType_t"/> is
/// <see cref="point_type"/>.</para>
/// <para>With the property set to true, the Navigation Library will disable the internal pivot
/// position algorithms.</para>
/// </remarks>
static const property_t pivot_user_k = "pivot.user";
/// <summary>
/// Specifies whether the rotation pivot widget is visible.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="bool_t"/> and <see cref="propertyType_t"/> is
/// <see cref="bool_type"/>.</para>
/// <para>Set by the Navigation Library when it wants to set the visibility of the pivot used for
/// the 3D navigation. This will be dependent on the user setting for the pivot visibility in the
/// 3Dconnexion Properties configuration and whether the Navigation Library is actively navigating
/// the scene.</para>
/// </remarks>
static const property_t pivot_visible_k = "pivot.visible";
/// <summary>
/// Specifies the origin of the ray used for hit-testing.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="point_t"/> and <see cref="propertyType_t"/> is
/// <see cref="point_type"/>.</para>
/// <para>Set by the Navigation Library. The location is relative to the world coordinate
/// system.</para>
/// </remarks>
static const property_t hit_lookfrom_k = "hit.lookfrom";
/// <summary>
/// Specifies the direction of the ray used for hit-testing.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="vector_t"/> and <see cref="propertyType_t"/> is
/// <see cref="vector_type"/>.</para>
/// <para>Set by the Navigation Library. The direction is relative to the world coordinate
/// system frame.</para>
/// </remarks>
static const property_t hit_direction_k = "hit.direction";
/// <summary>
/// Specifies the diameter of the ray used for hit-testing.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="double"/> and <see cref="propertyType_t"/> is
/// <see cref="double_type"/>.</para>
/// <para>Set by the Navigation Library. This is the diameter of the aperture on the frustum near
/// plane. In a perspective project the ray is a cone.</para>
/// </remarks>
static const property_t hit_aperture_k = "hit.aperture";
/// <summary>
/// Specifies the point of the model that is hit by the ray originating from
/// <see cref="hit_lookfrom_k"/>.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="point_t"/> and <see cref="propertyType_t"/> is
/// <see cref="point_type"/>.</para>
/// <para>This property is queried by the navlib. The navlib will generally calculate if it is
/// possible to hit a part of the model from the <see cref="model_extents_k"/> and
/// <see cref="selection_extents_k"/> properties before setting up the hit-test properties and
/// querying the property. The position is relative to the world coordinate system frame.</para>
/// </remarks>
static const property_t hit_lookat_k = "hit.lookat";
/// <summary>
/// Specifies whether the hit-testing is limited solely to the current selection set.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="bool_t"/> and <see cref="propertyType_t"/> is
/// <see cref="bool_type"/>.</para>
/// </remarks>
static const property_t hit_selectionOnly_k = "hit.selectionOnly";
/// <summary>
/// Specifies the transformation matrix of the selection set.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="matrix_t"/> and <see cref="propertyType_t"/> is
/// <see cref="matrix_type"/>.</para>
/// <para>This matrix specifies the object to world transformation of the selection set. That is,
/// transforming the position (0, 0, 0) by this matrix yields the position of the set in world
/// coordinates. The navlib will, generally, query this matrix at the beginning of a navigation
/// action that involves moving the selection and then set the property once per frame.</para>
/// </remarks>
static const property_t selection_affine_k = "selection.affine";
/// <summary>
/// Specifies whether the selection set is empty.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="bool_t"/> and <see cref="propertyType_t"/> is
/// <see cref="bool_type"/>.</para>
/// <para>When true, nothing is selected.</para>
/// </remarks>
static const property_t selection_empty_k = "selection.empty";
/// <summary>
/// Specifies the bounding box of the selection set.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="box_t"/> and <see cref="propertyType_t"/> is
/// <see cref="box_type"/>.</para>
/// <para>The extents of the selection are returned as a bounding box in world coordinates. The
/// Navigation Library will only access this property if the <see cref="selection_empty_k"/>
/// property is false.</para>
/// </remarks>
static const property_t selection_extents_k = "selection.extents";
/// <summary>
/// Specifies the bounding box of the model.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="box_t"/> and <see cref="propertyType_t"/> is
/// <see cref="box_type"/>.</para>
/// </remarks>
static const property_t model_extents_k = "model.extents";
/// <summary>
/// Specifies the position of the mouse cursor. on the projection plane in world coordinates.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="point_t"/> and <see cref="propertyType_t"/> is
/// <see cref="point_type"/>.</para>
/// <para>The position of the mouse cursor is in world coordinates on the projection plane. For a
/// perspective projection the Navigation Library uses the near clipping as the projection plane.
/// In OpenGL the position would typically be retrieved using gluUnProject with winZ set to
/// 0.0.</para>
/// </remarks>
static const property_t pointer_position_k = "pointer.position";
/// <summary>
/// V3DK press event.
/// </summary>
static const property_t events_keyPress_k = "events.keyPress";
/// <summary>
/// V3DK release event.
/// </summary>
static const property_t events_keyRelease_k = "events.keyRelease";
/// <summary>
/// Used to query and apply settings in the 3Dconnexion Properties UI.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="string_t"/> and <see cref="propertyType_t"/> is
/// <see cref="string_type"/>.</para>
/// <para>The property settings_k does not actually exist in the Navigation Library. To read or
/// write a property to the application profile, the settings_k needs to be appended with "." and
/// the name of the profile property.<example>"settings.MoveObjects" is used to read or write the
/// value of the "MoveObjects" property in the profile settings.</example></para>
/// </remarks>
static const property_t settings_k = "settings";
/// <summary>
/// Specifies the change revision of the profile settings.
/// </summary>
/// <remarks>
/// <para>The type is <see cref="long"/> and <see cref="propertyType_t"/> is
/// <see cref="long_type"/>.</para>
/// <para>This property is incremented when the settings changed. The value is only valid for the
/// current connection to the Navigation Library and is not persistent over multiple sessions. If
/// the client needs to know the value of a 3Dconnexion profile setting it should re-read the value
/// when settings_changed_k is changed.</para>
/// </remarks>
static const property_t settings_changed_k = "settings.changed";
// Workaround for error C2099: initializer is not a constant when compiling .c
#if __cplusplus
/// <summary>
/// Defines the type of a property and the access required of the client application.
/// </summary>
static const propertyDescription_t propertyDescription[] = {
/* property, type, required client access */
{active_k, bool_type, eno_access},
{focus_k, bool_type, eno_access},
{motion_k, bool_type, ewrite_access},
{coordinate_system_k, matrix_type, eread_access},
{device_present_k, bool_type, eno_access},
{events_keyPress_k, long_type, ewrite_access},
{events_keyRelease_k, long_type, ewrite_access},
/* frame properties*/
{transaction_k, long_type, ewrite_access},
{frame_time_k, double_type, eread_access},
{frame_timing_source_k, long_type, eread_access},
/* view properties */
{view_affine_k, matrix_type, eread_write_access},
{view_constructionPlane_k, plane_type, eread_access},
{view_extents_k, box_type, eread_write_access},
{view_fov_k, float_type, eread_write_access},
{view_frustum_k, frustum_type, eread_access},
{view_perspective_k, bool_type, eread_access},
{view_rotatable_k, bool_type, eread_access},
{view_target_k, point_type, eread_access},
/* views properties*/
{views_front_k, matrix_type, eread_access},
/* pivot properties */
{pivot_position_k, point_type, eread_write_access},
{pivot_user_k, bool_type, eno_access},
{pivot_visible_k, bool_type, ewrite_access},
/* hit-test properties */
{hit_lookfrom_k, point_type, ewrite_access},
{hit_direction_k, vector_type, ewrite_access},
{hit_aperture_k, float_type, ewrite_access},
{hit_lookat_k, point_type, eread_access},
{hit_selectionOnly_k, bool_type, ewrite_access},
/* selection properties */
{selection_affine_k, matrix_type, eread_write_access},
{selection_empty_k, bool_type, eread_access},
{selection_extents_k, box_type, eread_access},
/* model properties */
{model_extents_k, box_type, eread_access},
/* pointer (cursor) properties */
{pointer_position_k, point_type, eread_access},
/* commands properties */
{commands_tree_k, actionnodeexptr_type, eno_access},
{commands_activeSet_k, string_type, eno_access},
{commands_activeCommand_k, string_type, ewrite_access},
/* images properties*/
{images_k, imagearray_type, eno_access},
/* settings property*/
{settings_k, string_type, eno_access},
{settings_changed_k, long_type, ewrite_access}};
#endif
/**********************************************************************************************
Functions exported from the library
**********************************************************************************************/
/// <summary>
/// Creates a new navigation instance.
/// </summary>
/// <remarks>The client specifies the name of the instance and the properties that are available
/// for querying and updating by the navigation framework.</remarks>
/// <param name="pnh">A pointer to a <see cref="nlHandle_t"/> for the new navigation
/// instance.</param>
/// <param name="appname">The name of the application.</param>
/// <param name="property_accessors">An array of <see cref="accessor_t"/> structures containing the
/// property name, accessor and mutator functions that the client exposes to the navigation
/// instance.</param>
/// <param name="accessor_count">The number of <see cref="accessor_t"/> entries passed in the
/// property_accessors parameter.</param>
/// <param name="options">Pointer to a <see cref="nlCreateOptions_t"/>. This parameter is optional
/// and may be null.</param>
/// <returns>0 on success or a navlib error, see <see cref="navlib_errc::navlib_errc_t"/> and
/// <see cref="make_result_code"/>.</returns>
_NAVLIB_DLLAPI long __cdecl NlCreate(nlHandle_t *pnh, const char *appname,
const accessor_t property_accessors[], size_t accessor_count,
const nlCreateOptions_t *options);
/// <summary>
/// Closes an open navigation instance handle and destroys the navigation instance.
/// </summary>
/// <param name="nh">A valid <see cref="nlHandle_t"/> of an open navigation instance.</param>
/// <returns>0 if the function succeeds, otherwise a navlib error, see
/// <see cref="navlib_errc::navlib_errc_t"/> and <see cref="make_result_code"/>.</returns>
_NAVLIB_DLLAPI long __cdecl NlClose(nlHandle_t nh);
/// <summary>
/// Read the value of a property cached in the navlib.
/// </summary>
/// <param name="nh">The <see cref="nlHandle_t"/> of the open navigation instance.</param>
/// <param name="name">The name of the property whose value is being queried.</param>
/// <param name="value">A pointer to a <see cref="value_t"/> that contains the property value when
/// the function returns.</param>
/// <returns>0 if the function succeeds, otherwise a navlib error, see
/// <see cref="navlib_errc::navlib_errc_t"/> and <see cref="make_result_code"/>.</returns>
_NAVLIB_DLLAPI long __cdecl NlReadValue(nlHandle_t nh, property_t name, value_t *value);
/// <summary>
/// Write the value for a property to the navlib.
/// </summary>
/// <param name="nh">The <see cref="nlHandle_t"/> of the open navigation instance.</param>
/// <param name="name">The name of the property whose value is to be written.</param>
/// <param name="value">A pointer to a <see cref="value_t"/> that contains the new property
/// value.</param>
/// <returns>0 if the function succeeds, otherwise a navlib error, see
/// <see cref="navlib_errc::navlib_errc_t"/> and <see cref="make_result_code"/>.</returns>
_NAVLIB_DLLAPI long __cdecl NlWriteValue(nlHandle_t nh, property_t name, const value_t *value);
/// <summary>
/// Query the type of a navlib property.
/// </summary>
/// <param name="name">The name of the property whose type is to be queried.</param>
/// <returns>One of the <see cref="propertyTypes"/> values.</returns>
_NAVLIB_DLLAPI propertyType_t __cdecl NlGetType(property_t name);
_NAVLIB_END
#endif // NAVLIB_H_INCLUDED_

View File

@ -0,0 +1,61 @@
#ifndef NAVLIB_DEFINES_H_INCLUDED_
#define NAVLIB_DEFINES_H_INCLUDED_
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (c) 2014-2021 3Dconnexion.
*
* 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 navlib_defines.h
* @brief the macros used in the 3dconnexion interface and header files.
*/
// Invalid handle
#define INVALID_NAVLIB_HANDLE 0
// Navlib facility used to generate error codes
// Note this is identical to FACILITY_ITF on windows
#if _WIN32
#define FACILITY_NAVLIB 4
#else
#define FACILITY_NAVLIB 4
#endif
// resources
#define NAVLIB_IDB_ManualPivot 0x6004
#define NAVLIB_IDB_AutoPivot 0x6005
#if __cplusplus
#define _NAVLIB_BEGIN namespace navlib {
#define _NAVLIB_END }
#define _NAVLIB ::navlib::
#define _USING_NAVLIB using namespace navlib;
#else
#define _NAVLIB_BEGIN
#define _NAVLIB_END
#define _NAVLIB
#define _USING_NAVLIB
#endif
#if defined(_MSC_VER) && defined(NAVLIB_EXPORTS)
#define _NAVLIB_DLLAPI extern "C" __declspec(dllexport)
#elif __cplusplus
#define _NAVLIB_DLLAPI extern "C"
#else
#define _NAVLIB_DLLAPI
#endif
#endif // NAVLIB_DEFINES_H_INCLUDED_

View File

@ -0,0 +1,97 @@
#ifndef NAVLIB_ERROR_H_INCLUDED_
#define NAVLIB_ERROR_H_INCLUDED_
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (c) 2014-2021 3Dconnexion.
*
* 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 navlib_error.h
* @brief defines the classes used for error reporting.
*/
#include <system_error>
#include <navlib/navlib_types.h>
#ifndef NOEXCEPT
#if defined(_MSC_VER) && _MSC_VER < 1800
#ifdef _NOEXCEPT
#define NOEXCEPT _NOEXCEPT
#else
#define NOEXCEPT
#endif
#else
#define NOEXCEPT noexcept
#endif
#endif
namespace std {
template <> struct is_error_code_enum<::navlib::navlib_errc::navlib_errc_t> : true_type {};
} // namespace std
namespace { // Anonymous namespace
/// <summary>
/// Navigation library error category.
/// </summary>
struct navlib_error_category : public std::error_category {
typedef std::error_category base_type;
public:
navlib_error_category() NOEXCEPT {
}
const char *name() const NOEXCEPT override {
return "navlib";
}
std::string message(int errorValue) const override {
namespace navlib_errc = navlib::navlib_errc;
switch (static_cast<navlib_errc::navlib_errc_t>(errorValue)) {
case navlib_errc::property_not_found:
return "Cannot locate the requested navlib property.";
case navlib_errc::invalid_function:
return "The requested function is not valid.";
case navlib_errc::insufficient_buffer:
return "Insufficient buffer space.";
default:
return std::generic_category().message(errorValue);
}
}
};
/// <summary>
/// Navigation library error category.
/// </summary>
static const navlib_error_category navlib_category;
} // namespace
namespace navlib {
/// <summary>
/// Makes a <see cref="std::error_code"/>.
/// </summary>
/// <param name="errc">The Navigation library error.</param>
/// <returns>A <see cref="std::error_code"/> with the Navigation library category.</returns>
inline std::error_code make_error_code(navlib_errc::navlib_errc_t errc) {
std::error_code ec(static_cast<int>(errc), navlib_category);
return ec;
}
} // namespace navlib
#endif /* NAVLIB_ERROR_H_INCLUDED_ */

View File

@ -0,0 +1,104 @@
#ifndef NAVLIB_OPERATORS_H_INCLUDED_
#define NAVLIB_OPERATORS_H_INCLUDED_
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (c) 2014-2021 3Dconnexion.
*
* 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 navlib_operators.h
* @brief the operator overloads for variable types used in the 3dconnexion
* interface.
*/
#include <navlib/navlib_types.h>
// stdlib
#include <float.h>
#include <math.h>
_NAVLIB_BEGIN
/// <summary>
/// Compare floating point numbers.
/// </summary>
/// <param name="a">First value to compare.</param>
/// <param name="b">Second value to compare.</param>
/// <param name="epsilon">Maximum relative error.</param>
/// <returns></returns>
/// <remarks>
/// From https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition.
/// Copyright Bruce Dawson.
/// </remarks>
template <class T> bool equals(T a, T b, T epsilon = static_cast<T>(FLT_EPSILON)) {
T diff = fabs(a - b);
if (diff < epsilon) {
return true;
}
a = fabs(a);
b = fabs(b);
T largest = (a > b) ? a : b;
if (diff <= largest * epsilon) {
return true;
}
return false;
}
inline bool operator==(const vector_t &lhs, const vector_t &rhs) {
return (equals(lhs.x, rhs.x) && equals(lhs.y, rhs.y) && equals(lhs.z, rhs.z));
}
inline bool operator!=(const vector_t &lhs, const vector_t &rhs) {
return !(lhs == rhs);
}
inline bool operator==(const point_t &lhs, const point_t &rhs) {
return (equals(lhs.x, rhs.x) && equals(lhs.y, rhs.y) && equals(lhs.z, rhs.z));
}
inline bool operator!=(const point_t &lhs, const point_t &rhs) {
return !(lhs == rhs);
}
inline bool operator==(const box_t &lhs, const box_t &rhs) {
return lhs.min == rhs.min && lhs.max == rhs.max;
}
inline bool operator!=(const box_t &lhs, const box_t &rhs) {
return !(lhs == rhs);
}
inline bool operator==(const matrix_t &lhs, const matrix_t &rhs) {
for (size_t i = 0; i < sizeof(rhs.m) / sizeof(rhs.m[0]); ++i) {
if (!equals(lhs.m[i], rhs.m[i])) {
return false;
}
}
return true;
}
inline bool operator!=(const matrix_t &lhs, const matrix_t &rhs) {
return !(lhs == rhs);
}
inline nlOptions_t operator|(nlOptions_t lhs, nlOptions_t rhs) {
return static_cast<nlOptions_t>(static_cast<int>(lhs) | static_cast<int>(rhs));
}
_NAVLIB_END
#endif /* NAVLIB_OPERATORS_H_INCLUDED_ */

View File

@ -0,0 +1,235 @@
#ifndef NAVLIB_OSTREAM_INCLUDED_
#define NAVLIB_OSTREAM_INCLUDED_
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (c) 2014-2021 3Dconnexion.
*
* 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 navlib_ostream.h
* @brief stream operators for the navlib types.
*/
#include <navlib/navlib_types.h>
// C++ convenience functions
#include <iomanip>
#include <limits>
#include <ostream>
#include <string>
_NAVLIB_BEGIN
template <class _Elem, class _Traits>
std::basic_ostream<_Elem, _Traits> &operator<<(std::basic_ostream<_Elem, _Traits> &stream,
const vector_t &vector) {
stream << std::setprecision(std::numeric_limits<float>::digits10 + 1);
stream << "[" << vector.x << ", " << vector.y << ", " << vector.z << "]";
return stream;
}
template <class _Elem, class _Traits>
std::basic_ostream<_Elem, _Traits> &operator<<(std::basic_ostream<_Elem, _Traits> &stream,
const point_t &position) {
stream << std::setprecision(std::numeric_limits<float>::digits10 + 1);
stream << "[" << position.x << ", " << position.y << ", " << position.z << "]";
return stream;
}
template <class _Elem, class _Traits>
std::basic_ostream<_Elem, _Traits> &operator<<(std::basic_ostream<_Elem, _Traits> &stream,
const plane_t &plane) {
stream << std::setprecision(std::numeric_limits<float>::digits10 + 1);
stream << "[" << plane.x << ", " << plane.y << ", " << plane.z << ", " << plane.d << "]";
return stream;
}
template <class _Elem, class _Traits>
std::basic_ostream<_Elem, _Traits> &operator<<(std::basic_ostream<_Elem, _Traits> &stream,
const box_t &box) {
stream << std::setprecision(std::numeric_limits<float>::digits10 + 1);
stream << box.min << ", " << box.max;
return stream;
}
template <class _Elem, class _Traits>
std::basic_ostream<_Elem, _Traits> &operator<<(std::basic_ostream<_Elem, _Traits> &stream,
const frustum_t &frustum) {
stream << std::setprecision(std::numeric_limits<float>::digits10 + 1);
stream << "[" << frustum.left << ", " << frustum.right << ", " << frustum.bottom << ", "
<< frustum.top << ", " << frustum.nearVal << ", " << frustum.farVal << "]";
return stream;
}
template <class _Elem, class _Traits>
std::basic_ostream<_Elem, _Traits> &operator<<(std::basic_ostream<_Elem, _Traits> &stream,
const matrix_t &matrix) {
stream << std::endl;
stream << std::setprecision(std::numeric_limits<float>::digits10 + 1);
stream << "\t[" << matrix.m00 << ", " << matrix.m01 << ", " << matrix.m02 << ", " << matrix.m03
<< "]" << std::endl;
stream << "\t[" << matrix.m10 << ", " << matrix.m11 << ", " << matrix.m12 << ", " << matrix.m13
<< "]" << std::endl;
stream << "\t[" << matrix.m20 << ", " << matrix.m21 << ", " << matrix.m22 << ", " << matrix.m23
<< "]" << std::endl;
stream << "\t[" << matrix.m30 << ", " << matrix.m31 << ", " << matrix.m32 << ", " << matrix.m33
<< "]";
return stream;
}
template <class _Elem, class _Traits>
std::basic_ostream<_Elem, _Traits> &operator<<(std::basic_ostream<_Elem, _Traits> &stream,
const struct siResource_s &resource) {
stream << "{file_name: " << (resource.file_name ? resource.file_name : "nullptr")
<< ", id: " << (resource.id ? resource.id : "nullptr")
<< ", type: " << (resource.type ? resource.type : "nullptr")
<< ", index: " << resource.index << "}";
return stream;
}
template <class _Elem, class _Traits>
std::basic_ostream<_Elem, _Traits> &operator<<(std::basic_ostream<_Elem, _Traits> &stream,
const struct siImageFile_s &file) {
stream << "{file_name: " << (file.file_name ? file.file_name : "nullptr")
<< ", index: " << file.index << "}";
return stream;
}
template <class _Elem, class _Traits>
std::basic_ostream<_Elem, _Traits> &operator<<(std::basic_ostream<_Elem, _Traits> &stream,
const struct siImageData_s &image) {
stream << "{data: 0x" << std::hex << reinterpret_cast<uintptr_t>(image.data) << std::dec
<< ", size: " << image.size << ", index: " << image.index << "}";
return stream;
}
template <class _Elem, class _Traits>
std::basic_ostream<_Elem, _Traits> &operator<<(std::basic_ostream<_Elem, _Traits> &stream,
const imagearray_t &images) {
stream << "count: " << images.count;
std::string indent("\n");
indent.resize(5, ' ');
for (size_t i = 0; i < images.count; ++i) {
SiImage_t const &image = images.p[i];
stream << indent << "{size: " << image.size << ", id: " << (image.id ? image.id : "nullptr");
if (image.type == e_image_file)
stream << ", type: e_image_file, " << image.file;
else if (image.type == e_resource_file)
stream << ", type: e_resource_file, " << image.resource;
if (image.type == e_image)
stream << ", type: e_image, " << image.image;
else
stream << ", type: e_none";
stream << "}";
}
return stream;
}
template <class _Elem, class _Traits>
void StreamActionNodeHeader(std::basic_ostream<_Elem, _Traits> &stream,
const SiActionNodeEx_t &node, size_t level) {
std::string indent("\n");
indent.resize(4 * level + 1, ' ');
stream << indent << "{size: " << node.size << ", type: " << node.type
<< ", id: " << (node.id ? node.id : "nullptr")
<< ", label: " << (node.label ? node.label : "nullptr")
<< ", description: " << (node.description ? node.description : "nullptr") << "}";
if (node.children != NULL)
StreamActionNodeHeader(stream, *node.children, level + 1);
if (node.next != NULL)
StreamActionNodeHeader(stream, *node.next, level);
}
template <class _Elem, class _Traits>
std::basic_ostream<_Elem, _Traits> &operator<<(std::basic_ostream<_Elem, _Traits> &stream,
const SiActionNodeEx_t &node) {
StreamActionNodeHeader(stream, node, 1);
return stream;
}
template <class _Elem, class _Traits>
std::basic_ostream<_Elem, _Traits> &operator<<(std::basic_ostream<_Elem, _Traits> &stream,
const value_t &value) {
try {
switch (value.type) {
case voidptr_type:
stream << value.p;
break;
case bool_type:
stream << (value.b ? "true" : "false");
break;
case long_type:
stream << value.l;
break;
case float_type:
stream << std::setprecision(std::numeric_limits<float>::digits10 + 1) << value.f;
break;
case double_type:
stream << std::setprecision(std::numeric_limits<double>::digits10 + 2) << value.d;
break;
case point_type:
stream << value.point;
break;
case vector_type:
stream << value.vector;
break;
case matrix_type:
stream << value.matrix;
break;
case string_type:
if (value.string.p)
stream << value.string.p;
else
stream << "empty";
break;
case actionnodeexptr_type:
stream << *value.pnode;
break;
case imagearray_type:
stream << value.imagearray;
break;
case plane_type:
stream << value.plane;
break;
case box_type:
stream << value.box;
break;
case frustum_type:
stream << value.frustum;
break;
case cstr_type:
if (value.cstr_.p)
stream << value.cstr_.p;
else
stream << "empty";
break;
default:
stream << "null";
break;
}
} catch (std::runtime_error &e) {
stream << "std::runtime_error " << e.what();
}
return stream;
}
_NAVLIB_END
#endif // NAVLIB_OSTREAM_INCLUDED_

View File

@ -0,0 +1,524 @@
#ifndef NAVLIB_TEMPLATES_H_INCLUDED_
#define NAVLIB_TEMPLATES_H_INCLUDED_
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (c) 2014-2021 3Dconnexion.
*
* 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 navlib_templates.h
* @brief templates used in the 3dconnexion interface.
*/
#if (defined _MSC_VER && _MSC_VER < 1900)
#define CONSTEXPR const
#else
#define CONSTEXPR constexpr
#define has_constexpr
#endif
_NAVLIB_BEGIN
template <class T> struct property_type_v {
static CONSTEXPR propertyType_t type = unknown_type;
#ifdef has_constexpr
static constexpr char const *name = "unknown_type";
#else
static const char *name;
#endif
};
#ifndef has_constexpr
template <class T> const char *property_type_v<T>::name = "unknown_type";
#endif
template <> struct property_type_v<void *> {
static CONSTEXPR propertyType_t type = voidptr_type;
#ifdef has_constexpr
static constexpr char const *name = "voidptr_type";
#else
static const char *name;
#endif
};
#ifndef has_constexpr
__declspec(selectany) const char *property_type_v<void *>::name = "voidptr_type";
#endif
template <> struct property_type_v<bool_t> {
static CONSTEXPR propertyType_t type = bool_type;
#ifdef has_constexpr
static constexpr char const *name = "bool_type";
#else
static const char *name;
#endif
};
#ifndef has_constexpr
__declspec(selectany) const char *property_type_v<bool_t>::name = "bool_type";
#endif
template <> struct property_type_v<long> {
static CONSTEXPR propertyType_t type = long_type;
#ifdef has_constexpr
static constexpr char const *name = "long_type";
#else
static const char *name;
#endif
};
#ifndef has_constexpr
__declspec(selectany) const char *property_type_v<long>::name = "long_type";
#endif
template <> struct property_type_v<float> {
static CONSTEXPR propertyType_t type = float_type;
#ifdef has_constexpr
static constexpr char const *name = "float_type";
#else
static const char *name;
#endif
};
#ifndef has_constexpr
__declspec(selectany) const char *property_type_v<float>::name = "float_type";
#endif
template <> struct property_type_v<double> {
static CONSTEXPR propertyType_t type = double_type;
#ifdef has_constexpr
static constexpr char const *name = "double_type";
#else
static const char *name;
#endif
};
#ifndef has_constexpr
__declspec(selectany) const char *property_type_v<double>::name = "double_type";
#endif
template <> struct property_type_v<point_t> {
static CONSTEXPR propertyType_t type = point_type;
#ifdef has_constexpr
static constexpr char const *name = "point_type";
#else
static const char *name;
#endif
};
#ifndef has_constexpr
__declspec(selectany) const char *property_type_v<point_t>::name = "point_type";
#endif
template <> struct property_type_v<vector_t> {
static CONSTEXPR propertyType_t type = vector_type;
#ifdef has_constexpr
static constexpr char const *name = "vector_type";
#else
static const char *name;
#endif
};
#ifndef has_constexpr
__declspec(selectany) const char *property_type_v<vector_t>::name = "vector_type";
#endif
template <> struct property_type_v<plane_t> {
static CONSTEXPR propertyType_t type = plane_type;
#ifdef has_constexpr
static constexpr char const *name = "plane_type";
#else
static const char *name;
#endif
};
#ifndef has_constexpr
__declspec(selectany) const char *property_type_v<plane_t>::name = "plane_type";
#endif
template <> struct property_type_v<box_t> {
static CONSTEXPR propertyType_t type = box_type;
#ifdef has_constexpr
static constexpr char const *name = "box_type";
#else
static const char *name;
#endif
};
#ifndef has_constexpr
__declspec(selectany) const char *property_type_v<box_t>::name = "box_type";
#endif
template <> struct property_type_v<frustum_t> {
static CONSTEXPR propertyType_t type = frustum_type;
#ifdef has_constexpr
static constexpr char const *name = "frustum_type";
#else
static const char *name;
#endif
};
#ifndef has_constexpr
__declspec(selectany) const char *property_type_v<frustum_t>::name = "frustum_type";
#endif
template <> struct property_type_v<matrix_t> {
static CONSTEXPR propertyType_t type = matrix_type;
#ifdef has_constexpr
static constexpr char const *name = "matrix_type";
#else
static const char *name;
#endif
};
#ifndef has_constexpr
__declspec(selectany) const char *property_type_v<matrix_t>::name = "matrix_type";
#endif
template <> struct property_type_v<SiActionNodeEx_t *> {
static CONSTEXPR propertyType_t type = actionnodeexptr_type;
#ifdef has_constexpr
static constexpr char const *name = "actionnodeexptr_type";
#else
static const char *name;
#endif
};
#ifndef has_constexpr
__declspec(selectany) const
char *property_type_v<SiActionNodeEx_t *>::name = "actionnodeexptr_type";
#endif
template <> struct property_type_v<string_t> {
static CONSTEXPR propertyType_t type = string_type;
#ifdef has_constexpr
static constexpr char const *name = "string_type";
#else
static const char *name;
#endif
};
#ifndef has_constexpr
__declspec(selectany) const char *property_type_v<string_t>::name = "string_type";
#endif
template <> struct property_type_v<cstr_t> {
static CONSTEXPR propertyType_t type = cstr_type;
#ifdef has_constexpr
static constexpr char const *name = "cstr_type";
#else
static const char *name;
#endif
};
#ifndef has_constexpr
__declspec(selectany) const char *property_type_v<cstr_t>::name = "cstr_type";
#endif
template <> struct property_type_v<imagearray_t> {
static CONSTEXPR propertyType_t type = imagearray_type;
#ifdef has_constexpr
static constexpr char const *name = "imagearray_type";
#else
static const char *name;
#endif
};
#ifndef has_constexpr
__declspec(selectany) const char *property_type_v<imagearray_t>::name = "imagearray_type";
#endif
template <class T> struct remove_cvref {
typedef typename std::remove_cv<typename std::remove_reference<T>::type>::type type;
};
// navlib property type from variable type
template <class T> struct property_type : property_type_v<typename remove_cvref<T>::type> {
typedef property_type_v<typename remove_cvref<T>::type> base_type;
typedef propertyType_t value_type;
CONSTEXPR value_type operator()() const {
return base_type::value;
}
#ifdef has_constexpr
constexpr operator value_type() const {
return base_type::value;
}
constexpr operator char *() const {
return base_type::name;
}
#else
operator const value_type() const {
return base_type::value;
}
operator const char *() const {
return base_type::name;
}
#endif
};
template <typename T, typename V, typename TargetType> struct value_member {}; // primary template
// specialization for void*
template <typename T, typename V> struct value_member<T, V, void *> {
T operator()(V &v) {
return v.p;
}
};
// specialization for void**
template <typename T, typename V> struct value_member<T, V, void **> {
T operator()(V &v) {
return &v.p;
}
};
// specialization for bool
template <typename T, typename V> struct value_member<T, V, bool> {
T operator()(V &v) {
return v.b != 0;
}
};
// specialization for bool_t
template <typename T, typename V> struct value_member<T, V, bool_t> {
T operator()(V &v) {
return v.b;
}
};
// specialization for bool_t*
template <typename T, typename V> struct value_member<T, V, bool_t *> {
T operator()(V &v) {
return &v.b;
}
};
// specialization for int
template <typename T, typename V> struct value_member<T, V, int> {
T operator()(V &v) {
return v.l;
}
};
// specialization for long
template <typename T, typename V> struct value_member<T, V, long> {
T operator()(V &v) {
return v.l;
}
};
// specialization for long*
template <typename T, typename V> struct value_member<T, V, long *> {
T operator()(V &v) {
return &v.l;
}
};
// specialization for float
template <typename T, typename V> struct value_member<T, V, float> {
T operator()(V &v) {
return v.f;
}
};
// specialization for float*
template <typename T, typename V> struct value_member<T, V, float *> {
T operator()(V &v) {
return &v.f;
}
};
// specialization for double
template <typename T, typename V> struct value_member<T, V, double> {
T operator()(V &v) {
return v.d;
}
};
// specialization for double*
template <typename T, typename V> struct value_member<T, V, double *> {
T operator()(V &v) {
return &v.d;
}
};
// specialization for point_t
template <typename T, typename V> struct value_member<T, V, point_t> {
T operator()(V &v) {
return v.point;
}
};
// specialization for point_t*
template <typename T, typename V> struct value_member<T, V, point_t *> {
T operator()(V &v) {
return &v.point;
}
};
// specialization for vector_t
template <typename T, typename V> struct value_member<T, V, vector_t> {
T operator()(V &v) {
return v.vector;
}
};
// specialization for vector_t*
template <typename T, typename V> struct value_member<T, V, vector_t *> {
T operator()(V &v) {
return &v.vector;
}
};
// specialization for plane_t
template <typename T, typename V> struct value_member<T, V, plane_t> {
T operator()(V &v) {
return v.plane;
}
};
// specialization for plane_t*
template <typename T, typename V> struct value_member<T, V, plane_t *> {
T operator()(V &v) {
return &v.plane;
}
};
// specialization for box_t
template <typename T, typename V> struct value_member<T, V, box_t> {
T operator()(V &v) {
return v.box;
}
};
// specialization for box_t*
template <typename T, typename V> struct value_member<T, V, box_t *> {
T operator()(V &v) {
return &v.box;
}
};
// specialization for frustum_t
template <typename T, typename V> struct value_member<T, V, frustum_t> {
T operator()(V &v) {
return v.frustum;
}
};
// specialization for frustum_t*
template <typename T, typename V> struct value_member<T, V, frustum_t *> {
T operator()(V &v) {
return &v.frustum;
}
};
// specialization for matrix_t
template <typename T, typename V> struct value_member<T, V, matrix_t> {
T operator()(V &v) {
return v.matrix;
}
};
// specialization for matrix_t*
template <typename T, typename V> struct value_member<T, V, matrix_t *> {
T operator()(V &v) {
return &v.matrix;
}
};
// specialization for SiActionNodeEx_t*
template <typename T, typename V> struct value_member<T, V, const SiActionNodeEx_t *> {
T operator()(V &v) {
return v.pnode;
}
};
// specialization for SiActionNodeEx_t**
template <typename T, typename V> struct value_member<T, V, SiActionNodeEx_t **> {
T operator()(V &v) {
return &v.pnode;
}
};
// specialization for string_t
template <typename T, typename V> struct value_member<T, V, string_t> {
T operator()(V &v) {
return v.string;
}
};
// specialization for string_t*
template <typename T, typename V> struct value_member<T, V, string_t *> {
T operator()(V &v) {
return &v.string;
}
};
// specialization for cstr_t
template <typename T, typename V> struct value_member<T, V, cstr_t> {
T operator()(V &v) {
return v.cstr_;
}
};
// specialization for cstr_t*
template <typename T, typename V> struct value_member<T, V, cstr_t *> {
T operator()(V &v) {
return &v.cstr_;
}
};
// specialization for imagearray_t
template <typename T, typename V> struct value_member<T, V, imagearray_t> {
T operator()(V &v) {
return v.imagearray;
}
};
// specialization for imagearray_t*
template <typename T, typename V> struct value_member<T, V, imagearray_t *> {
T operator()(V &v) {
return &v.imagearray;
}
};
template <typename T, class V> struct cast_value {
T operator()(V &value) {
switch (value.type) {
case bool_type:
return static_cast<T>(value.b);
case long_type:
return static_cast<T>(value.l);
case float_type:
return static_cast<T>(value.f);
case double_type:
return static_cast<T>(value.d);
default:
return static_cast<T>(0);
}
}
};
// Specialization for bool
template <class V> struct cast_value<bool, V> {
bool operator()(V &value) {
switch (value.type) {
case bool_type:
return value.b != 0;
case long_type:
return value.l != 0;
case float_type:
return value.f != 0.0f;
case double_type:
return value.d != 0.0;
default:
return false;
}
}
};
_NAVLIB_END // namespace navlib
#endif /* NAVLIB_TEMPLATES_H_INCLUDED_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,200 @@
#ifndef siappcmd_types_H_INCLUDED_
#define siappcmd_types_H_INCLUDED_
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (c) 2014-2021 3Dconnexion.
*
* 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 siappcmd_types.h
* @brief 3DxWare interface structures.
*/
// *************************************************************************************************
// File Description
//
// This header file describes the variable types used in the 3dconnexion interface that allows a
// user to assign an arbitrary action to a 3dconnexion device button.
//
// Data structures are described in detail below.
//
// *************************************************************************************************
// </description>
#ifdef __cplusplus
extern "C"
{
#endif
#if defined( _MSC_VER ) && ( _MSC_VER < 1600 )
typedef unsigned __int32 uint32_t;
typedef unsigned __int8 uint8_t;
#if _WIN64
typedef unsigned __int64 uintptr_t;
#else
typedef unsigned int uintptr_t;
#endif
#else
#include <stdint.h>
#endif
typedef enum siActionNodeType_e
{
SI_ACTIONSET_NODE = 0,
SI_CATEGORY_NODE,
SI_ACTION_NODE
} SiActionNodeType_t;
/*------------------------------------+---------------------------------------
SiActionNodeEx_t
The application passes a pointer to a structure of type SiActionNodeEx_t to
the function SiAppCmdWriteActionSet
A set of actions is composed of a linked list of SiActionNodeEx_t structures.
Sibling nodes are linked by the next field of the structure and child nodes
by the children field. The root node of the tree represents the name of the
action set while the leaf nodes of the tree represent the actions that can be
assigned to buttons and invoked by the user. The intermediate nodes represent
categories and sub-categories for the actions. An example of this would be the
menu item structure in a menu bar. The menus in the menu bar would be
represented by the SiActionNodeEx_t structures with type SI_CATEGORY_NODE pointed
to by each successively linked next field and the first menu item of each menu
represented by the structure pointed to by their child fields (the rest of the
menu items in each menu would again be linked by the next fields).
size
The size field must always be the byte size of siActionNodeEx_s
type
The type field specifies one of the following values.
SI_ACTIONSET_NODE
SI_CATEGORY_NODE
SI_ACTION_NODE
The root node (and only the root node) of the tree always has type
SI_ACTIONSET_NODE. Only the leaf nodes of the tree have type SI_ACTION_NODE.
All intermediate nodes have type SI_CATEGORY_NODE.
id
The id field specifies a UTF8 string identifier for the action set,
category, or action represented by the node. The field is always non-NULL.
This string needs to remain constant across application sessions and more
or less constant across application releases. The id is used by the
application to identify an action.
label
The label field specifies a UTF8 localized/internationalized name
for the action set, category, or action represented by the node. The label
field can be NULL for the root and intermediate category nodes that are not
explicitly presented to users. All leaf (action) and intermediate nodes
containing leaf nodes have non-NULL labels. If the application only has a
single action tree set, then the label of the root (context) node can also
be NULL.
description
The description field specifies a UTF8 localized/internationalized tooltip
for the action set, category, or action represented by the node. The description
field can be NULL for the root and intermediate category nodes that are not
explicitly presented to users. Leaf (action) nodes should have non-NULL descriptions.
--------------------------------------+-------------------------------------*/
typedef struct siActionNodeEx_s
{
uint32_t size;
SiActionNodeType_t type;
struct siActionNodeEx_s* next;
struct siActionNodeEx_s* children;
const char* id;
const char* label;
const char* description;
} SiActionNodeEx_t;
/*------------------------------------+---------------------------------------
SiImage_t
The application passes a pointer to an array of type SiImage_t to
the function SiAppCmdWriteActionImages
size
The size field specifies the size of the SiImage_t type in bytes.
id
The id field specifies a UTF8 string identifier for the image. The field
is always non-NULL. This string needs to remain constant across application
sessions and more or less constant across application releases.
The id is used by the application to identify the image. To associate an
image with a command the id needs to be identical to the value of the
SiActionNodeEx_t::id of the action.
siImageData_s::size
The siImageData_s::size field specifies the size of the data pointed to
by the siImageData_s::data field in bytes.
siImageData_s::data
The image field contains a pointer to the image. The image may be in coded
in any recognizable format.
--------------------------------------+-------------------------------------*/
typedef enum eSiImageType
{
e_none = 0,
e_image_file,
e_resource_file,
e_image
} SiImageType_t;
struct siResource_s
{
const char* file_name;
const char* id;
const char* type;
uint32_t index;
};
struct siImageFile_s
{
const char* file_name;
uint32_t index;
};
struct siImageData_s
{
const uint8_t* data;
uintptr_t size;
uint32_t index;
};
typedef struct siImage_s
{
uint32_t size;
SiImageType_t type;
const char* id;
union
{
struct siResource_s resource;
struct siImageFile_s file;
struct siImageData_s image;
};
} SiImage_t;
#ifdef __cplusplus
} // extern "C"
#endif
#endif /* siappcmd_types_H_INCLUDED_ */

View File

@ -0,0 +1,27 @@
/*-----------------------------------------------------------------------------
*
* navlib_load.cpp -- navlib library interface.
*
*
* The module loads the navlib dynamic link library at startup.
*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* 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/.
*/
extern "C"
{
extern long NlLoadLibrary();
long NlErrorCode = NlLoadLibrary();
}

203
thirdparty/3dxware_sdk/src/navlib_stub.c vendored Normal file
View File

@ -0,0 +1,203 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (c) 2014-2021 3Dconnexion.
*
* 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 navlib_stub.c
* @brief interface routines to the navlib library routines.
*/
/*-----------------------------------------------------------------------------
* The module contains interface routines to the navlib library routines contained
* in the associated Dynamic Link Library. The DLL is loaded explicitly when
* NlLoadLibrary is invoked. When the DLL is loaded, the initialization routine
* finds the addresses of the routines that it exposes and allows them to be used
* in this code.
*/
#if _WIN32
/* windows */
#include <Windows.h>
#include <errno.h>
#elif __APPLE__
#include <dlfcn.h>
#include <errno.h>
#include <stdio.h>
#endif
#ifndef EISCONN
#define EISCONN 113
#define ENOBUFS 119
#define ENODATA 120
#define EOPNOTSUPP 130
#endif
/* navlib */
#include <navlib/navlib.h>
/* library name */
#ifdef _WIN32
static const wchar_t* TheLibrary = L"TDxNavLib";
#elif __APPLE__
static const char* TheLibrary = "/Library/Frameworks/3DconnexionNavlib.framework/3DconnexionNavlib";
#endif
/* Names of functions contained in the framework used to find their addresses at load time */
static const char* cNlCreate = "NlCreate";
static const char* cNlClose = "NlClose";
static const char* cNlReadValue = "NlReadValue";
static const char* cNlWriteValue = "NlWriteValue";
static const char* cNlGetType = "NlGetType";
typedef long( __cdecl* PFN_NLCREATE )( nlHandle_t* pnh, const char* appname,
const accessor_t accessors[], size_t accessor_count,
nlCreateOptions_t const* options );
typedef long( __cdecl* PFN_NLCLOSE )( nlHandle_t nh );
typedef long( __cdecl* PFN_NLREADVALUE )( nlHandle_t nh, property_t name, value_t* value );
typedef long( __cdecl* PFN_NLWRITEVALUE )( nlHandle_t nh, property_t name, const value_t* value );
typedef propertyType_t( __cdecl* PFN_NLGETTYPE )( property_t name );
/* Function pointers to functions in DLL */
static PFN_NLCREATE pfnNlCreate = NULL;
static PFN_NLCLOSE pfnNlClose = NULL;
static PFN_NLREADVALUE pfnNlReadValue = NULL;
static PFN_NLWRITEVALUE pfnNlWriteValue = NULL;
static PFN_NLGETTYPE pfnNlGetType = NULL;
extern long NlErrorCode;
#if _WIN32
long NlLoadLibrary()
{
long error = 0;
HMODULE h = LoadLibrary( TheLibrary );
if( !h )
{
error = HRESULT_FROM_WIN32( GetLastError() );
}
else
{
/* load up the function pointer table */
if( ( ( pfnNlCreate = (PFN_NLCREATE) GetProcAddress( h, cNlCreate ) ) == NULL )
|| ( ( pfnNlClose = (PFN_NLCLOSE) GetProcAddress( h, cNlClose ) ) == NULL )
|| ( ( pfnNlReadValue = (PFN_NLREADVALUE) GetProcAddress( h, cNlReadValue ) ) == NULL )
|| ( ( pfnNlWriteValue = (PFN_NLWRITEVALUE) GetProcAddress( h, cNlWriteValue ) )
== NULL )
|| ( ( pfnNlGetType = (PFN_NLGETTYPE) GetProcAddress( h, cNlGetType ) ) == NULL ) )
{
error = HRESULT_FROM_WIN32( GetLastError() );
FreeLibrary( h );
h = NULL;
}
}
return error;
}
#elif __APPLE__
long NlLoadLibrary()
{
long error = 0;
void* libHandle = dlopen( TheLibrary, RTLD_LAZY | RTLD_LOCAL );
if( NULL == libHandle )
{
error = -1; // whatever error it's an error dlopen() does not set errno
fprintf( stderr, "Error: Failed to open library \"%s\"! Error: %s!\n", TheLibrary,
dlerror() );
}
else
{
/* load up the function pointer table */
if( ( ( pfnNlCreate = (PFN_NLCREATE) dlsym( libHandle, cNlCreate ) ) == NULL )
|| ( ( pfnNlClose = (PFN_NLCLOSE) dlsym( libHandle, cNlClose ) ) == NULL )
|| ( ( pfnNlReadValue = (PFN_NLREADVALUE) dlsym( libHandle, cNlReadValue ) ) == NULL )
|| ( ( pfnNlWriteValue = (PFN_NLWRITEVALUE) dlsym( libHandle, cNlWriteValue ) )
== NULL )
|| ( ( pfnNlGetType = (PFN_NLGETTYPE) dlsym( libHandle, cNlGetType ) ) == NULL ) )
{
error = -2; // whatever error it is - it's an error dlsym() does not set errno
fprintf( stderr, "Error: Failed to fetch symbols from \"%s\"! Error: %s!\n", TheLibrary,
dlerror() );
dlclose( libHandle );
libHandle = NULL;
}
}
return error;
}
#else
long NlLoadLibrary()
{
return EOPNOTSUPP;
}
#endif
long __cdecl NlCreate( nlHandle_t* pnh, const char* appname, const accessor_t accessors[],
size_t accessor_count, const nlCreateOptions_t* options )
{
if( pfnNlCreate )
{
return pfnNlCreate( pnh, appname, accessors, accessor_count, options );
}
return NlErrorCode;
}
long __cdecl NlClose( nlHandle_t nh )
{
if( pfnNlClose )
{
return pfnNlClose( nh );
}
return NlErrorCode;
}
long __cdecl NlReadValue( nlHandle_t nh, property_t name, value_t* value )
{
if( pfnNlReadValue )
{
return pfnNlReadValue( nh, name, value );
}
return NlErrorCode;
}
long __cdecl NlWriteValue( nlHandle_t nh, property_t name, const value_t* value )
{
if( pfnNlWriteValue )
{
return pfnNlWriteValue( nh, name, value );
}
return NlErrorCode;
}
propertyType_t __cdecl NlGetType( property_t name )
{
if( pfnNlGetType )
{
return pfnNlGetType( name );
}
return unknown_type;
}

View File

@ -40,3 +40,4 @@ add_subdirectory( nlohmann_json )
add_subdirectory( picosha2 )
add_subdirectory( json_schema_validator )
add_subdirectory( pegtl )
add_subdirectory( 3dxware_sdk )