From 6b6bde1baba117b180fe56ae4379022cdd5eb6ea Mon Sep 17 00:00:00 2001 From: wmayer Date: Wed, 25 Jul 2018 16:49:37 +0200 Subject: [PATCH 1/6] use correct spelling of Windows header --- src/Gui/PreCompiled.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gui/PreCompiled.h b/src/Gui/PreCompiled.h index 9caa7f39a5..33afc7351d 100644 --- a/src/Gui/PreCompiled.h +++ b/src/Gui/PreCompiled.h @@ -49,7 +49,7 @@ #ifdef FC_OS_WIN32 #define WIN32_LEAN_AND_MEAN #define NOMINMAX -#include +#include #include #include #endif From b13f1562a35e12ff7f234b25c3d972c8ef78dc3e Mon Sep 17 00:00:00 2001 From: wmayer Date: Wed, 25 Jul 2018 16:57:38 +0200 Subject: [PATCH 2/6] handling of UTF-8 in zipios++ on Win32 --- src/Base/CMakeLists.txt | 1 + src/zipios++/zipfile.cpp | 4 ++-- src/zipios++/zipinputstream.cpp | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Base/CMakeLists.txt b/src/Base/CMakeLists.txt index d589d4d062..8e14465872 100644 --- a/src/Base/CMakeLists.txt +++ b/src/Base/CMakeLists.txt @@ -2,6 +2,7 @@ if(WIN32) add_definitions(-DFCBase) add_definitions(-DPYCXX_DLL) add_definitions(-DBOOST_DYN_LINK) + add_definitions(-DZIPIOS_UTF8) endif(WIN32) include_directories( diff --git a/src/zipios++/zipfile.cpp b/src/zipios++/zipfile.cpp index 6811eba518..498d81d610 100644 --- a/src/zipios++/zipfile.cpp +++ b/src/zipios++/zipfile.cpp @@ -9,7 +9,7 @@ #include "zipios_defs.h" #include "backbuffer.h" -#if defined(_WIN32) +#if defined(_WIN32) && defined(ZIPIOS_UTF8) #include #endif @@ -36,7 +36,7 @@ ZipFile::ZipFile( const string &name , int s_off, int e_off _filename = name ; -#if defined(_WIN32) +#if defined(_WIN32) && defined(ZIPIOS_UTF8) std::wstring wsname = Base::FileInfo(name).toStdWString(); ifstream _zipfile( wsname.c_str(), ios::in | ios::binary ) ; #else diff --git a/src/zipios++/zipinputstream.cpp b/src/zipios++/zipinputstream.cpp index 606e9e2584..f16f993c19 100644 --- a/src/zipios++/zipinputstream.cpp +++ b/src/zipios++/zipinputstream.cpp @@ -5,7 +5,7 @@ #include "zipinputstreambuf.h" #include "zipinputstream.h" -#if defined(_WIN32) +#if defined(_WIN32) && defined(ZIPIOS_UTF8) #include #endif @@ -27,7 +27,7 @@ ZipInputStream::ZipInputStream( const std::string &filename, std::streampos pos : std::istream( 0 ), ifs( 0 ) { -#if defined(_WIN32) +#if defined(_WIN32) && defined(ZIPIOS_UTF8) std::wstring wsname = Base::FileInfo(filename).toStdWString(); ifs = new std::ifstream( wsname.c_str(), std::ios::in |std:: ios::binary ) ; #else From b298e63bcc3160d5f31046769b7064140b0121f5 Mon Sep 17 00:00:00 2001 From: wmayer Date: Wed, 25 Jul 2018 17:25:32 +0200 Subject: [PATCH 3/6] + implement direct and queued mode in console class --- src/App/Application.cpp | 2 +- src/Base/Console.cpp | 118 +++++++++++++++++++++++++++++++++++----- src/Base/Console.h | 18 ++++-- 3 files changed, 119 insertions(+), 19 deletions(-) diff --git a/src/App/Application.cpp b/src/App/Application.cpp index 9f72b685c8..6327190aca 100644 --- a/src/App/Application.cpp +++ b/src/App/Application.cpp @@ -1426,7 +1426,7 @@ void Application::initConfig(int argc, char ** argv) _pConsoleObserverStd = new ConsoleObserverStd(); Console().AttachObserver(_pConsoleObserverStd); if (mConfig["Verbose"] == "Strict") - Console().SetMode(ConsoleSingleton::Verbose); + Console().UnsetConsoleMode(ConsoleSingleton::Verbose); // file logging Init =========================================================== if (mConfig["LoggingFile"] == "1") { diff --git a/src/Base/Console.cpp b/src/Base/Console.cpp index dc54d1a0c9..b36898f362 100644 --- a/src/Base/Console.cpp +++ b/src/Base/Console.cpp @@ -39,30 +39,100 @@ #include "Console.h" #include "Exception.h" #include "PyObjectBase.h" -#include +#include using namespace Base; +//========================================================================= + +namespace Base { + +class ConsoleEvent : public QEvent { +public: + ConsoleSingleton::FreeCAD_ConsoleMsgType msgtype; + std::string msg; + + ConsoleEvent(ConsoleSingleton::FreeCAD_ConsoleMsgType type, const std::string& msg) + : QEvent(QEvent::User), msgtype(type), msg(msg) + { + } + ~ConsoleEvent() + { + } +}; + +class ConsoleOutput : public QObject +{ +public: + static ConsoleOutput* getInstance() { + if (!instance) + instance = new ConsoleOutput; + return instance; + } + static void destruct() { + delete instance; + instance = 0; + } + + void customEvent(QEvent* ev) { + if (ev->type() == QEvent::User) { + ConsoleEvent* ce = static_cast(ev); + switch (ce->msgtype) { + case ConsoleSingleton::MsgType_Txt: + Console().NotifyMessage(ce->msg.c_str()); + break; + case ConsoleSingleton::MsgType_Log: + Console().NotifyLog(ce->msg.c_str()); + break; + case ConsoleSingleton::MsgType_Wrn: + Console().NotifyWarning(ce->msg.c_str()); + break; + case ConsoleSingleton::MsgType_Err: + Console().NotifyError(ce->msg.c_str()); + break; + } + } + } + +private: + ConsoleOutput() + { + } + ~ConsoleOutput() + { + } + + static ConsoleOutput* instance; +}; + +ConsoleOutput* ConsoleOutput::instance = 0; + +} + //************************************************************************** // Construction destruction ConsoleSingleton::ConsoleSingleton(void) - :_bVerbose(false),_bCanRefresh(true) + : _bVerbose(true) + , _bCanRefresh(true) + , connectionMode(Direct) #ifdef FC_DEBUG ,_defaultLogLevel(FC_LOGLEVEL_LOG) #else ,_defaultLogLevel(FC_LOGLEVEL_MSG) #endif { - + // make sure this object is part of the main thread + ConsoleOutput::getInstance(); } ConsoleSingleton::~ConsoleSingleton() { + ConsoleOutput::destruct(); for(std::set::iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();++Iter) delete (*Iter); } @@ -74,15 +144,16 @@ ConsoleSingleton::~ConsoleSingleton() /** * sets the console in a special mode */ -void ConsoleSingleton::SetMode(ConsoleMode m) +void ConsoleSingleton::SetConsoleMode(ConsoleMode m) { if(m && Verbose) _bVerbose = true; } + /** * unsets the console from a special mode */ -void ConsoleSingleton::UnsetMode(ConsoleMode m) +void ConsoleSingleton::UnsetConsoleMode(ConsoleMode m) { if(m && Verbose) _bVerbose = false; @@ -159,6 +230,11 @@ bool ConsoleSingleton::IsMsgTypeEnabled(const char* sObs, FreeCAD_ConsoleMsgType } } +void ConsoleSingleton::SetConnectionMode(ConnectionMode mode) +{ + connectionMode = mode; +} + /** Prints a Message * This method issues a Message. * Messages are used to show some non vital information. That means when @@ -182,7 +258,11 @@ void ConsoleSingleton::Message( const char *pMsg, ... ) va_start(namelessVars, pMsg); // Get the "..." vars vsnprintf(format, format_len, pMsg, namelessVars); va_end(namelessVars); - NotifyMessage(format); + + if (connectionMode == Direct) + NotifyMessage(format); + else + QCoreApplication::postEvent(ConsoleOutput::getInstance(), new ConsoleEvent(MsgType_Txt, format)); } /** Prints a Message @@ -209,7 +289,11 @@ void ConsoleSingleton::Warning( const char *pMsg, ... ) va_start(namelessVars, pMsg); // Get the "..." vars vsnprintf(format, format_len, pMsg, namelessVars); va_end(namelessVars); - NotifyWarning(format); + + if (connectionMode == Direct) + NotifyWarning(format); + else + QCoreApplication::postEvent(ConsoleOutput::getInstance(), new ConsoleEvent(MsgType_Wrn, format)); } /** Prints a Message @@ -236,7 +320,11 @@ void ConsoleSingleton::Error( const char *pMsg, ... ) va_start(namelessVars, pMsg); // Get the "..." vars vsnprintf(format, format_len, pMsg, namelessVars); va_end(namelessVars); - NotifyError(format); + + if (connectionMode == Direct) + NotifyError(format); + else + QCoreApplication::postEvent(ConsoleOutput::getInstance(), new ConsoleEvent(MsgType_Err, format)); } @@ -261,13 +349,17 @@ void ConsoleSingleton::Log( const char *pMsg, ... ) char format[4024]; const unsigned int format_len = 4024; - if (!_bVerbose) + if (_bVerbose) { va_list namelessVars; va_start(namelessVars, pMsg); // Get the "..." vars vsnprintf(format, format_len, pMsg, namelessVars); va_end(namelessVars); - NotifyLog(format); + + if (connectionMode == Direct) + NotifyLog(format); + else + QCoreApplication::postEvent(ConsoleOutput::getInstance(), new ConsoleEvent(MsgType_Log, format)); } } @@ -416,9 +508,9 @@ PyMethodDef ConsoleSingleton::Methods[] = { {"PrintWarning", (PyCFunction) ConsoleSingleton::sPyWarning, 1, "PrintWarning -- Print a warning to the output"}, {"SetStatus", (PyCFunction) ConsoleSingleton::sPySetStatus, 1, - "Set the status for either Log, Msg, Wrn, or Error for an observer"}, + "Set the status for either Log, Msg, Wrn or Error for an observer"}, {"GetStatus", (PyCFunction) ConsoleSingleton::sPyGetStatus, 1, - "Get the status for either Log, Msg, Wrn, or Error for an observer"}, + "Get the status for either Log, Msg, Wrn or Error for an observer"}, {NULL, NULL, 0, NULL} /* Sentinel */ }; @@ -657,7 +749,7 @@ PyObject *ConsoleSingleton::sPySetStatus(PyObject * /*self*/, PyObject *args, Py else if(strcmp(pstr2,"Err") == 0) pObs->bErr = (Bool==0)?false:true; else - Py_Error(Base::BaseExceptionFreeCADError,"Unknown Message Type (use Log, Err, Msg, or Wrn)"); + Py_Error(Base::BaseExceptionFreeCADError,"Unknown Message Type (use Log, Err, Msg or Wrn)"); Py_INCREF(Py_None); return Py_None; diff --git a/src/Base/Console.h b/src/Base/Console.h index 539830f1e0..a6b5969cd5 100644 --- a/src/Base/Console.h +++ b/src/Base/Console.h @@ -516,22 +516,27 @@ public: enum ConsoleMode{ Verbose = 1, // suppress Log messages }; + enum ConnectionMode { + Direct = 0, + Queued =1 + }; - enum FreeCAD_ConsoleMsgType { + enum FreeCAD_ConsoleMsgType { MsgType_Txt = 1, MsgType_Log = 2, // ConsoleObserverStd sends this and higher to stderr MsgType_Wrn = 4, MsgType_Err = 8 - } ; + }; /// Change mode - void SetMode(ConsoleMode m); + void SetConsoleMode(ConsoleMode m); /// Change mode - void UnsetMode(ConsoleMode m); + void UnsetConsoleMode(ConsoleMode m); /// Enables or disables message types of a certain console observer ConsoleMsgFlags SetEnabledMsgType(const char* sObs, ConsoleMsgFlags type, bool b); /// Enables or disables message types of a certain console observer bool IsMsgTypeEnabled(const char* sObs, FreeCAD_ConsoleMsgType type) const; + void SetConnectionMode(ConnectionMode mode); int *GetLogLevel(const char *tag, bool create=true); @@ -549,7 +554,7 @@ public: // retrieval of an observer by name ConsoleObserver *Get(const char *Name) const; - static PyMethodDef Methods[]; + static PyMethodDef Methods[]; void Refresh(); void EnableRefresh(bool enable); @@ -566,6 +571,7 @@ protected: bool _bVerbose; bool _bCanRefresh; + ConnectionMode connectionMode; // Singleton! ConsoleSingleton(void); @@ -587,6 +593,8 @@ private: std::map _logLevels; int _defaultLogLevel; + + friend class ConsoleOutput; }; /** Access to the Console From 806ad88c5a6a49a761e527e5a0e41c16af424184 Mon Sep 17 00:00:00 2001 From: wmayer Date: Wed, 25 Jul 2018 17:31:11 +0200 Subject: [PATCH 4/6] + implement a faster method to multiply vector with matrix + add convenience method to transform a point array --- src/Base/Matrix.h | 32 ++++++++++++++++++++++++++---- src/Mod/Mesh/App/Core/Elements.cpp | 6 ++++++ src/Mod/Mesh/App/Core/Elements.h | 14 +++++++++++++ 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/Base/Matrix.h b/src/Base/Matrix.h index dc27d349a9..bbc4141b68 100644 --- a/src/Base/Matrix.h +++ b/src/Base/Matrix.h @@ -83,6 +83,8 @@ public: /// Multiplication matrix with vector inline Vector3f operator * (const Vector3f& rclVct) const; inline Vector3d operator * (const Vector3d& rclVct) const; + inline void multVec(const Vector3d & src, Vector3d & dst) const; + inline void multVec(const Vector3f & src, Vector3f & dst) const; /// Comparison inline bool operator != (const Matrix4D& rclMtrx) const; /// Comparison @@ -278,9 +280,9 @@ inline Vector3f Matrix4D::operator* (const Vector3f& rclVct) const { return Vector3f((float)(dMtrx4D[0][0]*rclVct.x + dMtrx4D[0][1]*rclVct.y + dMtrx4D[0][2]*rclVct.z + dMtrx4D[0][3]), - (float)(dMtrx4D[1][0]*rclVct.x + dMtrx4D[1][1]*rclVct.y + + (float)(dMtrx4D[1][0]*rclVct.x + dMtrx4D[1][1]*rclVct.y + dMtrx4D[1][2]*rclVct.z + dMtrx4D[1][3]), - (float)(dMtrx4D[2][0]*rclVct.x + dMtrx4D[2][1]*rclVct.y + + (float)(dMtrx4D[2][0]*rclVct.x + dMtrx4D[2][1]*rclVct.y + dMtrx4D[2][2]*rclVct.z + dMtrx4D[2][3])); } @@ -288,12 +290,34 @@ inline Vector3d Matrix4D::operator* (const Vector3d& rclVct) const { return Vector3d((dMtrx4D[0][0]*rclVct.x + dMtrx4D[0][1]*rclVct.y + dMtrx4D[0][2]*rclVct.z + dMtrx4D[0][3]), - (dMtrx4D[1][0]*rclVct.x + dMtrx4D[1][1]*rclVct.y + + (dMtrx4D[1][0]*rclVct.x + dMtrx4D[1][1]*rclVct.y + dMtrx4D[1][2]*rclVct.z + dMtrx4D[1][3]), - (dMtrx4D[2][0]*rclVct.x + dMtrx4D[2][1]*rclVct.y + + (dMtrx4D[2][0]*rclVct.x + dMtrx4D[2][1]*rclVct.y + dMtrx4D[2][2]*rclVct.z + dMtrx4D[2][3])); } +inline void Matrix4D::multVec(const Vector3d & src, Vector3d & dst) const +{ + double x = (dMtrx4D[0][0]*src.x + dMtrx4D[0][1]*src.y + + dMtrx4D[0][2]*src.z + dMtrx4D[0][3]); + double y = (dMtrx4D[1][0]*src.x + dMtrx4D[1][1]*src.y + + dMtrx4D[1][2]*src.z + dMtrx4D[1][3]); + double z = (dMtrx4D[2][0]*src.x + dMtrx4D[2][1]*src.y + + dMtrx4D[2][2]*src.z + dMtrx4D[2][3]); + dst.Set(x,y,z); +} + +inline void Matrix4D::multVec(const Vector3f & src, Vector3f & dst) const +{ + float x = (dMtrx4D[0][0]*src.x + dMtrx4D[0][1]*src.y + + dMtrx4D[0][2]*src.z + dMtrx4D[0][3]); + float y = (dMtrx4D[1][0]*src.x + dMtrx4D[1][1]*src.y + + dMtrx4D[1][2]*src.z + dMtrx4D[1][3]); + float z = (dMtrx4D[2][0]*src.x + dMtrx4D[2][1]*src.y + + dMtrx4D[2][2]*src.z + dMtrx4D[2][3]); + dst.Set(x,y,z); +} + inline bool Matrix4D::operator== (const Matrix4D& rclMtrx) const { short iz, is; diff --git a/src/Mod/Mesh/App/Core/Elements.cpp b/src/Mod/Mesh/App/Core/Elements.cpp index 5fcbc6381c..016f283be5 100644 --- a/src/Mod/Mesh/App/Core/Elements.cpp +++ b/src/Mod/Mesh/App/Core/Elements.cpp @@ -90,6 +90,12 @@ MeshPointArray& MeshPointArray::operator = (const MeshPointArray &rclPAry) return *this; } +void MeshPointArray::Transform(const Base::Matrix4D& mat) +{ + for (_TIterator pP = begin(); pP != end(); ++pP) + mat.multVec(*pP,*pP); +} + void MeshFacetArray::Erase (_TIterator pIter) { unsigned long i, *pulN; diff --git a/src/Mod/Mesh/App/Core/Elements.h b/src/Mod/Mesh/App/Core/Elements.h index 2d73229a59..f49eea9c10 100644 --- a/src/Mod/Mesh/App/Core/Elements.h +++ b/src/Mod/Mesh/App/Core/Elements.h @@ -33,6 +33,7 @@ #include #include +#include // Cannot use namespace Base in constructors of MeshPoint #ifdef _MSC_VER @@ -99,6 +100,7 @@ public: /** @name Construction */ //@{ MeshPoint (void) : _ucFlag(0), _ulProp(0) { } + inline MeshPoint (float x, float y, float z); inline MeshPoint (const Base::Vector3f &rclPt); inline MeshPoint (const MeshPoint &rclPt); ~MeshPoint (void) { } @@ -523,6 +525,7 @@ public: // Assignment MeshPointArray& operator = (const MeshPointArray &rclPAry); + void Transform(const Base::Matrix4D&); /** * Searches for the first point index Two points are equal if the distance is less * than EPSILON. If no such points is found ULONG_MAX is returned. @@ -643,6 +646,17 @@ private: MeshFacetArray& rFacets; }; +inline MeshPoint::MeshPoint (float x, float y, float z) +#ifdef _MSC_VER +: Vector3f(x, y, z), +#else +: Base::Vector3f(x, y, z), +#endif + _ucFlag(0), + _ulProp(0) +{ +} + inline MeshPoint::MeshPoint (const Base::Vector3f &rclPt) #ifdef _MSC_VER : Vector3f(rclPt), From 3b3e4fd4ce16534359fe3a0f2ae3491eeeb70ec4 Mon Sep 17 00:00:00 2001 From: wmayer Date: Wed, 25 Jul 2018 17:49:28 +0200 Subject: [PATCH 5/6] minor fix --- src/Base/Tools2D.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Base/Tools2D.cpp b/src/Base/Tools2D.cpp index b2703207da..674d14c2aa 100644 --- a/src/Base/Tools2D.cpp +++ b/src/Base/Tools2D.cpp @@ -281,7 +281,7 @@ BoundBox2d Polygon2d::CalcBoundBox (void) const static short _CalcTorsion (double *pfLine, double fX, double fY) { - short sQuad[2], i; + int sQuad[2], i; // Changing this from short to int allows the compiler to inline this function double fResX; // Klassifizierung der beiden Polygonpunkte in Quadranten From 1fcfbcf1aba24259acbc6822a3feb5e38760a930 Mon Sep 17 00:00:00 2001 From: wmayer Date: Wed, 25 Jul 2018 17:50:30 +0200 Subject: [PATCH 6/6] + move implementation of Base::ifstream and Base::ofstream to header and remove export macro. This is needed for VS 2013 to avoid that it exports methods of the base class and thus causing linker errors for modules that link FreeCADBase --- src/Base/Stream.cpp | 30 ------------------------------ src/Base/Stream.h | 31 +++++++++++++++++++++++++------ 2 files changed, 25 insertions(+), 36 deletions(-) diff --git a/src/Base/Stream.cpp b/src/Base/Stream.cpp index 095ca3a029..06a573f0d1 100644 --- a/src/Base/Stream.cpp +++ b/src/Base/Stream.cpp @@ -39,7 +39,6 @@ #include "Stream.h" #include "Swap.h" -#include "FileInfo.h" #include using namespace Base; @@ -785,32 +784,3 @@ Streambuf::seekpos(std::streambuf::pos_type pos, { return seekoff(pos, std::ios_base::beg); } - -// --------------------------------------------------------- - -Base::ofstream::ofstream(const FileInfo& fi, ios_base::openmode mode) -#ifdef _MSC_VER -: std::ofstream(fi.toStdWString().c_str(), mode) -#else -: std::ofstream(fi.filePath().c_str(), mode) -#endif -{ -} - -Base::ofstream::~ofstream() -{ -} - -Base::ifstream::ifstream(const FileInfo& fi, ios_base::openmode mode) -#ifdef _MSC_VER -: std::ifstream(fi.toStdWString().c_str(), mode) -#else -: std::ifstream(fi.filePath().c_str(), mode) -#endif -{ -} - -Base::ifstream::~ifstream() -{ -} - diff --git a/src/Base/Stream.h b/src/Base/Stream.h index 4312f32e16..464805c3de 100644 --- a/src/Base/Stream.h +++ b/src/Base/Stream.h @@ -35,6 +35,7 @@ #include #include #include +#include "FileInfo.h" class QByteArray; class QIODevice; @@ -302,12 +303,21 @@ class FileInfo; * while on Linux platforms the file name is UTF-8 encoded. * @author Werner Mayer */ -class BaseExport ofstream : public std::ofstream +class ofstream : public std::ofstream { public: ofstream(const FileInfo& fi, ios_base::openmode mode = - std::ios::out | std::ios::trunc); - virtual ~ofstream(); + std::ios::out | std::ios::trunc) +#ifdef _MSC_VER + : std::ofstream(fi.toStdWString().c_str(), mode) +#else + : std::ofstream(fi.filePath().c_str(), mode) +#endif + { + } + virtual ~ofstream() + { + } }; /** @@ -316,12 +326,21 @@ public: * while on Linux platforms the file name is UTF-8 encoded. * @author Werner Mayer */ -class BaseExport ifstream : public std::ifstream +class ifstream : public std::ifstream { public: ifstream(const FileInfo& fi, ios_base::openmode mode = - std::ios::in); - virtual ~ifstream(); + std::ios::in) +#ifdef _MSC_VER + : std::ifstream(fi.toStdWString().c_str(), mode) +#else + : std::ifstream(fi.filePath().c_str(), mode) +#endif + { + } + virtual ~ifstream() + { + } }; } // namespace Base