File indexing completed on 2024-12-01 03:37:32

0001 /*
0002     SPDX-FileCopyrightText: 2007 Vladimir Kuznetsov <ks.vladimir@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 /** \file types.h
0008  *  \brief Type to and from string conversion helpers
0009  */
0010 
0011 #ifndef STEPCORE_TYPES_H
0012 #define STEPCORE_TYPES_H
0013 
0014 #include "object.h"
0015 #include "vector.h"
0016 #define EIGEN_USE_NEW_STDVECTOR
0017 #include <Eigen/StdVector>
0018 #include <Eigen/Sparse>
0019 
0020 #include <QByteArray>
0021 
0022 namespace StepCore {
0023 
0024 typedef Eigen::SparseMatrix<double> SparseColMatrix;
0025 typedef Eigen::SparseMatrix<double,Eigen::RowMajor> SparseRowMatrix;
0026 // a sparse matrix with efficient write facilities
0027 typedef Eigen::SparseMatrix<double,Eigen::RowMajor> DynSparseRowMatrix;
0028 typedef Eigen::Map<Eigen::VectorXd> MappedVector;
0029 
0030 ///////////////// Color
0031 struct Color
0032 {
0033     Color() {}
0034     Color(unsigned int v): value(v) {}
0035     operator unsigned int() const { return value; }
0036     unsigned int value;
0037 };
0038 
0039 template<> inline QString typeToString(const Color& v)
0040 {
0041     return QStringLiteral("#%1").arg(v, 8, 16, QLatin1Char('0'));
0042 }
0043 
0044 template<> inline Color stringToType(const QString& s, bool *ok)
0045 {
0046     if(ok) *ok = false;
0047     QString s1 = s.trimmed();
0048     if(!s1.startsWith('#')) return Color(0);
0049     s1 = s1.mid(1);
0050     return Color(s1.toUInt(ok, 16));
0051 }
0052 
0053 ///////////////// QByteArray
0054 template<> inline QString typeToString(const QByteArray& v)
0055 {
0056     return QString::fromLatin1(v.toBase64());
0057 }
0058 
0059 template<> inline QByteArray stringToType(const QString& s, bool *ok)
0060 {
0061     if(ok) *ok = true;
0062     return QByteArray::fromBase64(s.toLatin1());
0063 }
0064 
0065 ///////////////// Vector2d
0066 template<> inline QString typeToString(const Vector2d& v)
0067 {
0068     return QStringLiteral("(%1,%2)").arg(v[0]).arg(v[1]);
0069 }
0070 
0071 template<> inline Vector2d stringToType(const QString& s, bool *ok)
0072 {
0073     // XXX: Write something better
0074     if(ok) *ok = false;
0075     QString s1 = s.trimmed();
0076     if(!s1.startsWith('(') || !s1.endsWith(')')) return Vector2d();
0077     s1 = s1.mid(1, s1.size()-2);    
0078     bool ok1, ok2;
0079     StepCore::Vector2d v(s1.section(',',0,0).toDouble(&ok1), s1.section(',',1,1).toDouble(&ok2));
0080     if(!ok1 || !ok2) return v;
0081     if(ok) *ok = true;
0082     return v;
0083 }
0084 
0085 ///////////////// Vector2i
0086 template<> inline QString typeToString(const Vector2i& v)
0087 {
0088     return QStringLiteral("(%1,%2)").arg(v[0]).arg(v[1]);
0089 }
0090 
0091 template<> inline Vector2i stringToType(const QString& s, bool *ok)
0092 {
0093     // XXX: Write something better
0094     if(ok) *ok = false;
0095     QString s1 = s.trimmed();
0096     if(!s1.startsWith('(') || !s1.endsWith(')')) return Vector2i();
0097     s1 = s1.mid(1, s1.size()-2);    
0098     bool ok1, ok2;
0099     StepCore::Vector2i v(s1.section(',',0,0).toInt(&ok1), s1.section(',',1,1).toInt(&ok2));
0100     if(!ok1 || !ok2) return v;
0101     if(ok) *ok = true;
0102     return v;
0103 }
0104 
0105 ///////////////// Vector2dList
0106 typedef std::vector<Vector2d, Eigen::aligned_allocator<Vector2d> > Vector2dList;
0107 
0108 template<> inline QString typeToString(const Vector2dList& v)
0109 {
0110     QString ret;
0111     for(Vector2dList::const_iterator it = v.begin(); it != v.end(); ++it) {
0112         if(!ret.isEmpty()) ret += QLatin1String(",");
0113         ret += QStringLiteral("(%1,%2)").arg((*it)[0]).arg((*it)[1]);
0114     }
0115     return ret;
0116 }
0117 
0118 template<> inline Vector2dList stringToType(const QString& s, bool *ok)
0119 {
0120     // XXX: Write something better
0121     Vector2dList ret;
0122     if(ok) *ok = false;
0123     QString s1 = s.trimmed();
0124     if (s1.isEmpty()) {
0125         if(ok) *ok = true;
0126         return ret;
0127     }
0128     //if(!s1.startsWith('(') || !s1.endsWith(')')) return ret;
0129     //s1 = s1.mid(1, s1.size()-2).trimmed();
0130     while(s1[0] == '(' && s1.contains(')')) {
0131         bool ok; double d1, d2;
0132         s1 = s1.mid(1);
0133         d1 = s1.section(',',0,0).toDouble(&ok);
0134         if(!ok) return Vector2dList();
0135         s1 = s1.section(',',1);
0136         d2 = s1.section(')',0,0).toDouble(&ok);
0137         if(!ok) return Vector2dList();
0138         s1 = s1.section(')',1).trimmed();
0139         ret.push_back(Vector2d(d1, d2));
0140         if(s1.isEmpty()) break;
0141         if(s1[0] != ',') return Vector2dList();
0142         s1 = s1.mid(1).trimmed();
0143     }
0144     if(!s1.isEmpty()) return Vector2dList();
0145     if(ok) *ok = true;
0146     return ret;
0147 }
0148 
0149 } // namespace StepCore
0150 
0151 #ifdef STEPCORE_WITH_QT
0152 Q_DECLARE_METATYPE(StepCore::Vector2dList)
0153 Q_DECLARE_METATYPE(StepCore::Object*)
0154 Q_DECLARE_METATYPE(StepCore::Color)
0155 #endif
0156 
0157 
0158 #endif
0159