New upstream version 2.3+repack1
authorAnton Gladky <gladk@debian.org>
Sat, 31 Dec 2016 08:50:56 +0000 (09:50 +0100)
committerAnton Gladky <gladk@debian.org>
Sat, 31 Dec 2016 08:50:56 +0000 (09:50 +0100)
44 files changed:
.gitattributes [deleted file]
.gitignore [deleted file]
.gitmodules [deleted file]
.travis.yml
CHANGELOG.md
CMakeLists.txt
README.md
appveyor.yml
extlib/libdxfrw/intern/dwgbuffer.cpp
extlib/libdxfrw/intern/dwgbuffer.h
extlib/libdxfrw/intern/dwgreader.h
extlib/libdxfrw/intern/dwgreader15.h
extlib/libdxfrw/intern/dwgreader18.h
extlib/libdxfrw/intern/dwgreader21.h
extlib/libdxfrw/intern/dwgreader24.h
extlib/libdxfrw/intern/dwgreader27.h
extlib/libdxfrw/intern/dxfreader.h
extlib/libdxfrw/intern/dxfwriter.cpp
extlib/libdxfrw/intern/dxfwriter.h
extlib/libdxfrw/libdwgr.cpp
extlib/libdxfrw/libdwgr.h
extlib/libdxfrw/libdxfrw.cpp
extlib/libdxfrw/libdxfrw.h
src/CMakeLists.txt
src/cocoa/cocoamain.mm
src/constraint.cpp
src/exportvector.cpp
src/generate.cpp
src/groupmesh.cpp
src/gtk/gtkmain.cpp
src/importdxf.cpp
src/mesh.cpp
src/mouse.cpp
src/solvespace.cpp
src/solvespace.h
src/srf/surface.cpp
src/system.cpp
src/textwin.cpp
src/ttf.cpp
src/ttf.h
src/ui.h
src/util.cpp
src/win32/w32main.cpp
src/win32/w32util.cpp

diff --git a/.gitattributes b/.gitattributes
deleted file mode 100644 (file)
index 7c97503..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-# .gitattributes for SolveSpace
-
-# Set default behaviour, in case users don't have core.autocrlf set.
-* text=auto
-
-# Explicitly declare text files we want to always be normalized and converted
-# to native line endings on checkout.
-*.cpp text
-*.h   text
-*.txt text
-
-# Declare files that will always have CRLF line endings on checkout.
-*.sln text eol=crlf
-
-# Denote all files that are truly binary and should not be modified.
-*.gz  binary
-*.ico binary
-*.jpg binary
-*.lib binary
-*.png binary
-
-# end .gitattributes
diff --git a/.gitignore b/.gitignore
deleted file mode 100644 (file)
index 28be69f..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/CMakeCache.txt
-/build*/
-*.trace # OpenGL apitrace files
-/debian/tmp/
-/debian/*.log
-/debian/*.substvars
-/debian/*.debhelper
-/debian/files
-/debian/solvespace/
-/debian/libslvs1/
-/debian/libslvs1-dev/
-/obj-*/
diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644 (file)
index dabc567..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-[submodule "extlib/zlib"]
-       path = extlib/zlib
-       url = https://github.com/madler/zlib
-       ignore = dirty
-[submodule "extlib/libpng"]
-       path = extlib/libpng
-       url = https://github.com/glennrp/libpng
-[submodule "extlib/libfreetype"]
-       path = extlib/libfreetype
-       url = http://git.sv.nongnu.org/r/freetype/freetype2.git
-[submodule "extlib/libdxfrw"]
-       path = extlib/libdxfrw
-       url = https://github.com/solvespace/libdxfrw.git
index 5e831b192f83f6ecabf85ae005d58dfda16e1e2e..b51c80c70ddb3e46f8053effac690f7965ac5dfe 100644 (file)
@@ -11,18 +11,6 @@ script:
   - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./.travis/build-debian.sh; fi
   - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ./.travis/build-macos.sh; fi
 deploy:
-  # Releases to solvespace/solvespace
-  - provider: releases
-    api_key:
-      secure: dDlkIawHcODlW9B/20/cQCtzeoocvs0hKuNngRKXKqzXLWTRq33oq/B7+39tAixWbmv6exTpijiKrRNFiSCW5Z4iwHLwaRD4XJznxw63e/Hus/dxg2Tvqx7XFpkCz8mT1Z+gZQE5YxAngeZPpI/sZbZtF1UO3yH5eLeeokZ15p26ZskQUPoYuzrTgTzYL3XfpG3F+20rNBawH1ycsCTVD/08/n31d2m3CrKAsbW7er92ek6w4fzKr7NW8WeXjrPJETVpw5fQg1Od3pRGW8dPQaJcvKQEogMp8Mm0ETYd0qigg89/giBz7QwOgmAWQ4dH+DfZH4Ojl//127QztBolMvyDMQBykWrtJoGcij05sT6K2IJr2FHeUBO12MAEdjiVvhQj3DtTzjPiZAHHDBSLWxLKWWhlhHE4pq7g1MQhqXkaAHI2BLNzwLmaowbMT0bECf9yfz6xx18h6XPQFX44oOktraobVALFlyHqeKa8zdcUt22LF6uAL1m5dxL0tny3eXCIPE4UH/RZgua/cHV9G3cUvKQa/QnFSLRhvWVSbGB+7YsHouBJcsUOOW1gmd5442XuC7mpppccRldh+GSxUk6TBJRAx7TeQ0ybDUaoco9MUqp2twv3KreR2+8Q12PDaAhfQVNEGdF3wTm1sShImjCN4VN3eSLlBEbve1QRQXM=
-    skip_cleanup: true
-    file_glob: true
-    file:
-      - ../*.deb
-    on:
-      repo: solvespace/solvespace
-      tags: true
-      condition: "$TRAVIS_OS_NAME == linux"
   - provider: releases
     api_key:
       secure: dDlkIawHcODlW9B/20/cQCtzeoocvs0hKuNngRKXKqzXLWTRq33oq/B7+39tAixWbmv6exTpijiKrRNFiSCW5Z4iwHLwaRD4XJznxw63e/Hus/dxg2Tvqx7XFpkCz8mT1Z+gZQE5YxAngeZPpI/sZbZtF1UO3yH5eLeeokZ15p26ZskQUPoYuzrTgTzYL3XfpG3F+20rNBawH1ycsCTVD/08/n31d2m3CrKAsbW7er92ek6w4fzKr7NW8WeXjrPJETVpw5fQg1Od3pRGW8dPQaJcvKQEogMp8Mm0ETYd0qigg89/giBz7QwOgmAWQ4dH+DfZH4Ojl//127QztBolMvyDMQBykWrtJoGcij05sT6K2IJr2FHeUBO12MAEdjiVvhQj3DtTzjPiZAHHDBSLWxLKWWhlhHE4pq7g1MQhqXkaAHI2BLNzwLmaowbMT0bECf9yfz6xx18h6XPQFX44oOktraobVALFlyHqeKa8zdcUt22LF6uAL1m5dxL0tny3eXCIPE4UH/RZgua/cHV9G3cUvKQa/QnFSLRhvWVSbGB+7YsHouBJcsUOOW1gmd5442XuC7mpppccRldh+GSxUk6TBJRAx7TeQ0ybDUaoco9MUqp2twv3KreR2+8Q12PDaAhfQVNEGdF3wTm1sShImjCN4VN3eSLlBEbve1QRQXM=
@@ -32,25 +20,3 @@ deploy:
       repo: solvespace/solvespace
       tags: true
       condition: "$TRAVIS_OS_NAME == osx"
-  # Releases to whitequark/solvespace (to be removed)
-  - provider: releases
-    api_key:
-      secure: DA3tW0My37vbi2t3dZ061281Xm8KSIkeLdFZsQISrut0g1kkbWuBTPxAfvE3B6OE8p47wAclE/wxA1+obMTVkY0oYpd5u+JelYNHxU/oL8Ww0xdUANwKNJ1JD2EZP8nSz7JSvxuGILC6AFPoTjawsG97SXwiTyp7z0PA6nvzraE=
-    skip_cleanup: true
-    file_glob: true
-    file:
-      - ../*.deb
-    on:
-      repo: whitequark/solvespace
-      tags: true
-      condition: "$TRAVIS_OS_NAME == linux"
-  - provider: releases
-    api_key:
-      secure: DA3tW0My37vbi2t3dZ061281Xm8KSIkeLdFZsQISrut0g1kkbWuBTPxAfvE3B6OE8p47wAclE/wxA1+obMTVkY0oYpd5u+JelYNHxU/oL8Ww0xdUANwKNJ1JD2EZP8nSz7JSvxuGILC6AFPoTjawsG97SXwiTyp7z0PA6nvzraE=
-    skip_cleanup: true
-    file: build/solvespace.dmg
-    on:
-      repo: whitequark/solvespace
-      tags: true
-      condition: "$TRAVIS_OS_NAME == osx"
-
index 63dee5bd9b251e31a9a7250130c34d44999b519f..095eee67adf1b0491059e95a219b27c2b35d8015 100644 (file)
@@ -1,11 +1,22 @@
 Changelog
 =========
 
+2.3
+---
+
+Bug fixes:
+  * Do not crash when applying a symmetry constraint to two points.
+  * Fix TTF font metrics again (properly this time).
+  * Fix the "draw back faces in red" option.
+  * Fix export of wireframe as 3D DXF.
+  * Various minor crashes.
+
 2.2
 ---
 
 Other new features:
   * OS X: support 3Dconnexion devices (SpaceMouse, SpaceNavigator, etc).
+  * GTK: files with uppercase extensions can be opened.
 
 Bug fixes:
   * Do not remove autosaves after successfully opening a file, preventing
@@ -20,6 +31,11 @@ Bug fixes:
   * Forcibly show the current group once we start a drawing operation.
   * DXF export: always declare layers before using them.
   * Do not truncate operations on selections to first 32 selected entities.
+  * Translate and rotate groups inherit the "suppress solid model" setting.
+  * DXF: files with paths containing non-ASCII or spaces can be exported
+    or imported.
+  * Significantly improved performance when dragging an entity.
+  * Various crashes and minor glitches.
 
 2.1
 ---
index 90a3eb8bf49c5285fcbf271cdc3e59e15b66758e..ea464e58701a27b2c066c5f7df9184cd184dc947 100644 (file)
@@ -17,11 +17,16 @@ set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX
 
 # project
 
+# NOTE TO PACKAGERS: The embedded git commit hash is critical for rapid bug triage when the builds
+# can come from a variety of sources. If you are mirroring the sources or otherwise build when
+# the .git directory is not present, please comment the following line:
 include(GetGitCommitHash)
+# and instead uncomment the following, adding the complete git hash of the checkout you are using:
+# set(GIT_COMMIT_HASH 0000000000000000000000000000000000000000)
 
 project(solvespace)
 set(solvespace_VERSION_MAJOR 2)
-set(solvespace_VERSION_MINOR 1)
+set(solvespace_VERSION_MINOR 3)
 string(SUBSTRING "${GIT_COMMIT_HASH}" 0 8 solvespace_GIT_HASH)
 
 if(NOT WIN32 AND NOT APPLE)
index a1a49ec26fb52b4c5f3efc2e5e4912d5b08fa3b3..838b92fab6fb36adbcfd9b73a18d2d2d7979481e 100644 (file)
--- a/README.md
+++ b/README.md
@@ -26,12 +26,13 @@ Building on Linux
 ### Building for Linux
 
 You will need CMake, libpng, zlib, json-c, fontconfig, freetype, gtkmm 2.4,
-pangomm 1.4, OpenGL and OpenGL GLU.
+pangomm 1.4, OpenGL, OpenGL GLU and OpenGL GLEW, and optionally, the Space Navigator
+client library.
 On a Debian derivative (e.g. Ubuntu) these can be installed with:
 
     apt-get install libpng12-dev libjson-c-dev libfreetype6-dev \
                     libfontconfig1-dev libgtkmm-2.4-dev libpangomm-1.4-dev \
-                    libgl-dev libglu-dev libglew-dev cmake
+                    libgl-dev libglu-dev libglew-dev libspnav-dev cmake
 
 Before building, check out the necessary submodules:
 
index 8078a565545bcb83c38dddb1b7006ecce87e1755..4f4b3ae17959d3a7493f9cca7b632a8bc0c0e576 100644 (file)
@@ -1,4 +1,4 @@
-version: 2.1.{build}
+version: 2.2.{build}
 clone_depth: 1
 before_build:
   - git submodule update --init
@@ -19,7 +19,6 @@ artifacts:
   - path: build\src\RelWithDebInfo\solvespace.pdb
     name: solvespace.pdb
 deploy:
-  # Releases to solvespace/solvespace
   - provider: GitHub
     auth_token:
       secure: P9/pf2nM+jlWKe7pCjMp41HycBNP/+5AsmE/TETrDUoBOa/9WFHelqdVFrbRn9IC
@@ -27,11 +26,3 @@ deploy:
     artifact: solvespace.exe
     on:
       appveyor_repo_tag: true
-  # Releases to whitequark/solvespace (to be removed)
-  - provider: GitHub
-    auth_token:
-      secure: Flqxu1cz6PyxVT1wzTP4bSrQOY8wFrO7pJxYxvjEkLqIUU4dsDQrs2rac/A9deet
-    description: ""
-    artifact: solvespace.exe
-    on:
-      appveyor_repo_tag: true
index a8d9b683ca5b28a066f85df5ad20473df4355df6..8bf914f215f737d5a0d5ec39952c430325295e94 100644 (file)
@@ -151,7 +151,7 @@ dwgBuffer::dwgBuffer(duint8 *buf, int size, DRW_TextCodec *dc){
     bitPos = 0;
 }
 
-dwgBuffer::dwgBuffer(std::ifstream *stream, DRW_TextCodec *dc){
+dwgBuffer::dwgBuffer(std::istream *stream, DRW_TextCodec *dc){
     filestr = new dwgFileStream(stream);
     decoder = dc;
     maxSize = filestr->size();
index bfc4fa65ff95aa2a8830feb3648d471c619103d0..2dffc23d5712d3b26e20bfaab47b6bff98f1fe4d 100644 (file)
@@ -35,7 +35,7 @@ public:
 
 class dwgFileStream: public dwgBasicStream{
 public:
-    dwgFileStream(std::ifstream *s){
+    dwgFileStream(std::istream *s){
         stream =s;
         stream->seekg (0, std::ios::end);
         sz = stream->tellg();
@@ -49,7 +49,7 @@ public:
     virtual bool good(){return stream->good();}
     virtual dwgBasicStream* clone(){return new dwgFileStream(stream);}
 private:
-    std::ifstream *stream;
+    std::istream *stream;
     duint64 sz;
 };
 
@@ -77,7 +77,7 @@ private:
 
 class dwgBuffer {
 public:
-    dwgBuffer(std::ifstream *stream, DRW_TextCodec *decoder = NULL);
+    dwgBuffer(std::istream *stream, DRW_TextCodec *decoder = NULL);
     dwgBuffer(duint8 *buf, int size, DRW_TextCodec *decoder= NULL);
     dwgBuffer( const dwgBuffer& org );
     dwgBuffer& operator=( const dwgBuffer& org );
index 9f34885319f5949c86e5edd6da623f825203a47c..4e889328638192d87257917e89c76139d8040e5a 100644 (file)
@@ -120,7 +120,7 @@ public:
 class dwgReader {
     friend class dwgR;
 public:
-    dwgReader(std::ifstream *stream, dwgR *p){
+    dwgReader(std::istream *stream, dwgR *p){
         fileBuf = new dwgBuffer(stream);
         parent = p;
         decoder.setVersion(DRW::AC1021, false);//default 2007 in utf8(no convert)
index 8b3dc24e60b2a6407f2554663a54c110a82cb55a..e3a1f97b77014ad435c1e10697d8448959bd7fad 100644 (file)
@@ -21,7 +21,7 @@
 
 class dwgReader15 : public dwgReader {
 public:
-    dwgReader15(std::ifstream *stream, dwgR *p):dwgReader(stream, p){ }
+    dwgReader15(std::istream *stream, dwgR *p):dwgReader(stream, p){ }
     virtual ~dwgReader15() {}
     bool readMetaData();
     bool readFileHeader();
index 4b66313bb286e053dad4f14ecb0dca92f6902bff..f81409669481e37664d19bd5009f1007b83b9418 100644 (file)
@@ -43,7 +43,7 @@ static const int DRW_magicNumEnd18[] = {
 
 class dwgReader18 : public dwgReader {
 public:
-    dwgReader18(std::ifstream *stream, dwgR *p):dwgReader(stream, p){
+    dwgReader18(std::istream *stream, dwgR *p):dwgReader(stream, p){
         objData = NULL;
     }
     virtual ~dwgReader18(){
index 9cecd69fe1d542fef605ae71c3964fecd8153581..f95c77a25b28cc29d0cefce807d12906d02fa79d 100644 (file)
@@ -22,7 +22,7 @@
 //reader for AC1021 aka v2007, chapter 5
 class dwgReader21 : public dwgReader {
 public:
-    dwgReader21(std::ifstream *stream, dwgR *p):dwgReader(stream, p){
+    dwgReader21(std::istream *stream, dwgR *p):dwgReader(stream, p){
         objData = NULL;
         dataSize = 0;
     }
index 36ac7fe022c2e57d3eb9b552b8662ad7f691b66f..e5fc43a72c15e39c107adcdbe5fe1ec044b6af80 100644 (file)
@@ -21,7 +21,7 @@
 
 class dwgReader24 : public dwgReader18 {
 public:
-    dwgReader24(std::ifstream *stream, dwgR *p):dwgReader18(stream, p){ }
+    dwgReader24(std::istream *stream, dwgR *p):dwgReader18(stream, p){ }
     virtual ~dwgReader24(){}
     bool readFileHeader();
     bool readDwgHeader(DRW_Header& hdr);
index 676cdc1976de53a7f325b939f4f423abfaa760a2..32c67f65b537c92b331b4f754b33f2f92c5c0ea4 100644 (file)
@@ -21,7 +21,7 @@
 
 class dwgReader27 : public dwgReader18 {
 public:
-    dwgReader27(std::ifstream *stream, dwgR *p):dwgReader18(stream, p){ }
+    dwgReader27(std::istream *stream, dwgR *p):dwgReader18(stream, p){ }
     virtual ~dwgReader27(){}
     bool readFileHeader();
     bool readDwgHeader(DRW_Header& hdr);
index bcb3c1ae11f3935d796b868c562d29c50c4251be..a0fa327c96070ea13fadc2ee028ac0f6e8553c28 100644 (file)
@@ -27,7 +27,7 @@ public:
     };
     enum TYPE type;
 public:
-    dxfReader(std::ifstream *stream){
+    dxfReader(std::istream *stream){
         filestr = stream;
         type = INVALID;
     }
@@ -58,7 +58,7 @@ protected:
     virtual bool readBool() = 0;
 
 protected:
-    std::ifstream *filestr;
+    std::istream *filestr;
     std::string strData;
     double doubleData;
     signed int intData; //32 bits integer
@@ -70,7 +70,7 @@ private:
 
 class dxfReaderBinary : public dxfReader {
 public:
-    dxfReaderBinary(std::ifstream *stream):dxfReader(stream){skip = false; }
+    dxfReaderBinary(std::istream *stream):dxfReader(stream){skip = false; }
     virtual ~dxfReaderBinary() {}
     virtual bool readCode(int *code);
     virtual bool readString(std::string *text);
@@ -84,7 +84,7 @@ public:
 
 class dxfReaderAscii : public dxfReader {
 public:
-    dxfReaderAscii(std::ifstream *stream):dxfReader(stream){skip = true; }
+    dxfReaderAscii(std::istream *stream):dxfReader(stream){skip = true; }
     virtual ~dxfReaderAscii(){}
     virtual bool readCode(int *code);
     virtual bool readString(std::string *text);
index b31d69ae546d05923836197eee4c6abdf00ba5c7..2276e7cee4068c30f8d5485bf1f398ebcc961385 100644 (file)
@@ -214,7 +214,7 @@ bool dxfWriterBinary::writeBool(int code, bool data) {
     return (filestr->good());
 }
 
-dxfWriterAscii::dxfWriterAscii(std::ofstream *stream):dxfWriter(stream){
+dxfWriterAscii::dxfWriterAscii(std::ostream *stream):dxfWriter(stream){
     filestr->precision(16);
 }
 
index 2af464bea6b76929861660ab7784d836af137b69..adabe022e2b223c7530384bb09aa9846c4ed6403 100644 (file)
@@ -17,7 +17,7 @@
 
 class dxfWriter {
 public:
-    dxfWriter(std::ofstream *stream){filestr = stream; /*count =0;*/}
+    dxfWriter(std::ostream *stream){filestr = stream; /*count =0;*/}
     virtual ~dxfWriter(){}
     virtual bool writeString(int code, std::string text) = 0;
     bool writeUtf8String(int code, std::string text);
@@ -32,14 +32,14 @@ public:
     void setCodePage(std::string *c){encoder.setCodePage(c, true);}
     std::string getCodePage(){return encoder.getCodePage();}
 protected:
-    std::ofstream *filestr;
+    std::ostream *filestr;
 private:
     DRW_TextCodec encoder;
 };
 
 class dxfWriterBinary : public dxfWriter {
 public:
-    dxfWriterBinary(std::ofstream *stream):dxfWriter(stream){}
+    dxfWriterBinary(std::ostream *stream):dxfWriter(stream){}
     virtual ~dxfWriterBinary() {}
     virtual bool writeString(int code, std::string text);
     virtual bool writeInt16(int code, int data);
@@ -51,7 +51,7 @@ public:
 
 class dxfWriterAscii : public dxfWriter {
 public:
-    dxfWriterAscii(std::ofstream *stream);
+    dxfWriterAscii(std::ostream *stream);
     virtual ~dxfWriterAscii(){}
     virtual bool writeString(int code, std::string text);
     virtual bool writeInt16(int code, int data);
index 4ba77ffdc1d2dbfe64c0c8c7c8fcb44a5f474dd0..adca43c25bd9904ebbec32fde52ddd2c3ed3f2ac 100644 (file)
@@ -35,9 +35,8 @@
     secObjects
 };*/
 
-dwgR::dwgR(const char* name){
+dwgR::dwgR(){
     DRW_DBGSL(DRW_dbg::NONE);
-    fileName = name;
     reader = NULL;
 //    writer = NULL;
     applyExt = false;
@@ -62,11 +61,10 @@ void dwgR::setDebug(DRW::DBG_LEVEL lvl){
 }
 
 /*reads metadata and loads image preview*/
-bool dwgR::getPreview(){
+bool dwgR::getPreview(std::istream &stream){
     bool isOk = false;
 
-    std::ifstream filestr;
-    isOk = openFile(&filestr);
+    isOk = open(&stream);
     if (!isOk)
         return false;
 
@@ -76,7 +74,6 @@ bool dwgR::getPreview(){
     } else
         error = DRW::BAD_READ_METADATA;
 
-    filestr.close();
     if (reader != NULL) {
         delete reader;
         reader = NULL;
@@ -84,70 +81,13 @@ bool dwgR::getPreview(){
     return isOk;
 }
 
-bool dwgR::testReader(){
-    bool isOk = false;
-
-    std::ifstream filestr;
-    filestr.open (fileName.c_str(), std::ios_base::in | std::ios::binary);
-    if (!filestr.is_open() || !filestr.good() ){
-        error = DRW::BAD_OPEN;
-        return isOk;
-    }
-
-    dwgBuffer fileBuf(&filestr);
-    duint8 *tmpStrData = new duint8[fileBuf.size()];
-    fileBuf.getBytes(tmpStrData, fileBuf.size());
-    dwgBuffer dataBuf(tmpStrData, fileBuf.size());
-    fileBuf.setPosition(0);
-    DRW_DBG("\ndwgR::testReader filebuf size: ");DRW_DBG(fileBuf.size());
-    DRW_DBG("\ndwgR::testReader dataBuf size: ");DRW_DBG(dataBuf.size());
-    DRW_DBG("\n filebuf pos: ");DRW_DBG(fileBuf.getPosition());
-    DRW_DBG("\n dataBuf pos: ");DRW_DBG(dataBuf.getPosition());
-    DRW_DBG("\n filebuf bitpos: ");DRW_DBG(fileBuf.getBitPos());
-    DRW_DBG("\n dataBuf bitpos: ");DRW_DBG(dataBuf.getBitPos());
-    DRW_DBG("\n filebuf first byte : ");DRW_DBGH(fileBuf.getRawChar8());
-    DRW_DBG("\n dataBuf  first byte : ");DRW_DBGH(dataBuf.getRawChar8());
-    fileBuf.setBitPos(4);
-    dataBuf.setBitPos(4);
-    DRW_DBG("\n filebuf first byte : ");DRW_DBGH(fileBuf.getRawChar8());
-    DRW_DBG("\n dataBuf  first byte : ");DRW_DBGH(dataBuf.getRawChar8());
-    DRW_DBG("\n filebuf pos: ");DRW_DBG(fileBuf.getPosition());
-    DRW_DBG("\n dataBuf pos: ");DRW_DBG(dataBuf.getPosition());
-    DRW_DBG("\n filebuf bitpos: ");DRW_DBG(fileBuf.getBitPos());
-    DRW_DBG("\n dataBuf bitpos: ");DRW_DBG(dataBuf.getBitPos());
-    fileBuf.setBitPos(6);
-    dataBuf.setBitPos(6);
-    DRW_DBG("\n filebuf pos: ");DRW_DBG(fileBuf.getPosition());
-    DRW_DBG("\n dataBuf pos: ");DRW_DBG(dataBuf.getPosition());
-    DRW_DBG("\n filebuf bitpos: ");DRW_DBG(fileBuf.getBitPos());
-    DRW_DBG("\n dataBuf bitpos: ");DRW_DBG(dataBuf.getBitPos());
-    DRW_DBG("\n filebuf first byte : ");DRW_DBGH(fileBuf.getRawChar8());
-    DRW_DBG("\n dataBuf  first byte : ");DRW_DBGH(dataBuf.getRawChar8());
-    fileBuf.setBitPos(0);
-    dataBuf.setBitPos(0);
-    DRW_DBG("\n filebuf first byte : ");DRW_DBGH(fileBuf.getRawChar8());
-    DRW_DBG("\n dataBuf  first byte : ");DRW_DBGH(dataBuf.getRawChar8());
-    DRW_DBG("\n filebuf pos: ");DRW_DBG(fileBuf.getPosition());
-    DRW_DBG("\n dataBuf pos: ");DRW_DBG(dataBuf.getPosition());
-    DRW_DBG("\n filebuf bitpos: ");DRW_DBG(fileBuf.getBitPos());
-    DRW_DBG("\n dataBuf bitpos: ");DRW_DBG(dataBuf.getBitPos());
-
-    delete[]tmpStrData;
-    filestr.close();
-    DRW_DBG("\n\n");
-    return isOk;
-}
-
-/*start reading dwg file header and, if can read it, continue reading all*/
-bool dwgR::read(DRW_Interface *interface_, bool ext){
-    bool isOk = false;
+bool dwgR::read(std::istream &stream, DRW_Interface *interface_, bool ext){
     applyExt = ext;
     iface = interface_;
 
-//testReader();return false;
+    bool isOk = false;
 
-    std::ifstream filestr;
-    isOk = openFile(&filestr);
+    isOk = open(&stream);
     if (!isOk)
         return false;
 
@@ -161,7 +101,6 @@ bool dwgR::read(DRW_Interface *interface_, bool ext){
     } else
         error = DRW::BAD_READ_METADATA;
 
-    filestr.close();
     if (reader != NULL) {
         delete reader;
         reader = NULL;
@@ -170,23 +109,9 @@ bool dwgR::read(DRW_Interface *interface_, bool ext){
     return isOk;
 }
 
-/* Open the file and stores it in filestr, install the correct reader version.
- * If fail opening file, error are set as DRW::BAD_OPEN
- * If not are DWG or are unsupported version, error are set as DRW::BAD_VERSION
- * and closes filestr.
- * Return true on succeed or false on fail
-*/
-bool dwgR::openFile(std::ifstream *filestr){
-    bool isOk = false;
-    DRW_DBG("dwgR::read 1\n");
-    filestr->open (fileName.c_str(), std::ios_base::in | std::ios::binary);
-    if (!filestr->is_open() || !filestr->good() ){
-        error = DRW::BAD_OPEN;
-        return isOk;
-    }
-
+bool dwgR::open(std::istream *stream){
     char line[7];
-    filestr->read (line, 6);
+    stream->read (line, 6);
     line[6]='\0';
     DRW_DBG("dwgR::read 2\n");
     DRW_DBG("dwgR::read line version: ");
@@ -200,35 +125,33 @@ bool dwgR::openFile(std::ifstream *filestr){
 //        reader = new dwgReader09(&filestr, this);
     }else if (strcmp(line, "AC1012") == 0){
         version = DRW::AC1012;
-        reader = new dwgReader15(filestr, this);
+        reader = new dwgReader15(stream, this);
     } else if (strcmp(line, "AC1014") == 0) {
         version = DRW::AC1014;
-        reader = new dwgReader15(filestr, this);
+        reader = new dwgReader15(stream, this);
     } else if (strcmp(line, "AC1015") == 0) {
         version = DRW::AC1015;
-        reader = new dwgReader15(filestr, this);
+        reader = new dwgReader15(stream, this);
     } else if (strcmp(line, "AC1018") == 0){
         version = DRW::AC1018;
-        reader = new dwgReader18(filestr, this);
+        reader = new dwgReader18(stream, this);
     } else if (strcmp(line, "AC1021") == 0) {
         version = DRW::AC1021;
-        reader = new dwgReader21(filestr, this);
+        reader = new dwgReader21(stream, this);
     } else if (strcmp(line, "AC1024") == 0) {
         version = DRW::AC1024;
-        reader = new dwgReader24(filestr, this);
+        reader = new dwgReader24(stream, this);
     } else if (strcmp(line, "AC1027") == 0) {
         version = DRW::AC1027;
-        reader = new dwgReader27(filestr, this);
+        reader = new dwgReader27(stream, this);
     } else
         version = DRW::UNKNOWNV;
 
     if (reader == NULL) {
         error = DRW::BAD_VERSION;
-        filestr->close();
-    } else
-        isOk = true;
-
-    return isOk;
+        return false;
+    }
+    return true;
 }
 
 /********* Reader Process *********/
index 8e035fe50c1ee964e3814897c1184613c5dbaf3c..060100495bf956c185d4b9bb5dc1f10b95e62815 100644 (file)
@@ -24,18 +24,17 @@ class dwgReader;
 
 class dwgR {
 public:
-    dwgR(const char* name);
+    dwgR();
     ~dwgR();
     //read: return true if all ok
-    bool read(DRW_Interface *interface_, bool ext);
-    bool getPreview();
+    bool read(std::istream &stream, DRW_Interface *interface_, bool ext);
+    bool getPreview(std::istream &stream);
     DRW::Version getVersion(){return version;}
     DRW::error getError(){return error;}
-bool testReader();
     void setDebug(DRW::DBG_LEVEL lvl);
 
 private:
-    bool openFile(std::ifstream *filestr);
+    bool open(std::istream *stream);
     bool processDwg();
 private:
     DRW::Version version;
index d1edcfe7a3cfe1df5f46c260fe6a40437ac6bc58..9eecea7a21c60b532aca38d440681f2bf7bd3406 100644 (file)
@@ -32,9 +32,8 @@
     secObjects
 };*/
 
-dxfRW::dxfRW(const char* name){
+dxfRW::dxfRW(){
     DRW_DBGSL(DRW_dbg::NONE);
-    fileName = name;
     reader = NULL;
     writer = NULL;
     applyExt = false;
@@ -61,63 +60,46 @@ void dxfRW::setDebug(DRW::DBG_LEVEL lvl){
     }
 }
 
-bool dxfRW::read(DRW_Interface *interface_, bool ext){
-    drw_assert(fileName.empty() == false);
-    bool isOk = false;
+bool dxfRW::read(std::istream &stream, DRW_Interface *interface_, bool ext){
     applyExt = ext;
-    std::ifstream filestr;
-    if ( interface_ == NULL )
-                return isOk;
-    DRW_DBG("dxfRW::read 1def\n");
-    filestr.open (fileName.c_str(), std::ios_base::in | std::ios::binary);
-    if (!filestr.is_open())
-        return isOk;
-    if (!filestr.good())
-        return isOk;
+
+    if(interface_ == NULL)
+        return false;
 
     char line[22];
     char line2[22] = "AutoCAD Binary DXF\r\n";
     line2[20] = (char)26;
     line2[21] = '\0';
-    filestr.read (line, 22);
-    filestr.close();
+    stream.read (line, 22);
     iface = interface_;
     DRW_DBG("dxfRW::read 2\n");
     if (strcmp(line, line2) == 0) {
-        filestr.open (fileName.c_str(), std::ios_base::in | std::ios::binary);
         binFile = true;
-        //skip sentinel
-        filestr.seekg (22, std::ios::beg);
-        reader = new dxfReaderBinary(&filestr);
+        reader = new dxfReaderBinary(&stream);
         DRW_DBG("dxfRW::read binary file\n");
     } else {
         binFile = false;
-        filestr.open (fileName.c_str(), std::ios_base::in);
-        reader = new dxfReaderAscii(&filestr);
+        stream.seekg(0, std::ios::beg);
+        reader = new dxfReaderAscii(&stream);
     }
 
-    isOk = processDxf();
-    filestr.close();
+    bool isOk = processDxf();
     delete reader;
     reader = NULL;
     return isOk;
 }
 
-bool dxfRW::write(DRW_Interface *interface_, DRW::Version ver, bool bin){
-    bool isOk = false;
-    std::ofstream filestr;
+bool dxfRW::write(std::ostream &stream, DRW_Interface *interface_, DRW::Version ver, bool bin){
     version = ver;
     binFile = bin;
     iface = interface_;
     if (binFile) {
-        filestr.open (fileName.c_str(), std::ios_base::out | std::ios::binary | std::ios::trunc);
         //write sentinel
-        filestr << "AutoCAD Binary DXF\r\n" << (char)26 << '\0';
-        writer = new dxfWriterBinary(&filestr);
+        stream << "AutoCAD Binary DXF\r\n" << (char)26 << '\0';
+        writer = new dxfWriterBinary(&stream);
         DRW_DBG("dxfRW::read binary file\n");
     } else {
-        filestr.open (fileName.c_str(), std::ios_base::out | std::ios::trunc);
-        writer = new dxfWriterAscii(&filestr);
+        writer = new dxfWriterAscii(&stream);
         std::string comm = std::string("dxfrw ") + std::string(DRW_VERSION);
         writer->writeString(999, comm);
     }
@@ -153,12 +135,10 @@ bool dxfRW::write(DRW_Interface *interface_, DRW::Version ver, bool bin){
         writer->writeString(0, "ENDSEC");
     }
     writer->writeString(0, "EOF");
-    filestr.flush();
-    filestr.close();
-    isOk = true;
+    stream.flush();
     delete writer;
     writer = NULL;
-    return isOk;
+    return true;
 }
 
 bool dxfRW::writeEntity(DRW_Entity *ent) {
index 18c26495204beae6ea5048ff6929842a1a3f8c49..b3de272176178c5d17deed48151c24482052b417 100644 (file)
@@ -25,7 +25,7 @@ class dxfWriter;
 
 class dxfRW {
 public:
-    dxfRW(const char* name);
+    dxfRW();
     ~dxfRW();
     void setDebug(DRW::DBG_LEVEL lvl);
     /// reads the file specified in constructor
@@ -36,10 +36,10 @@ public:
      * @param ext should the extrusion be applied to convert in 2D?
      * @return true for success
      */
-    bool read(DRW_Interface *interface_, bool ext);
+    bool read(std::istream &stream, DRW_Interface *interface_, bool ext);
     void setBinary(bool b) {binFile = b;}
 
-    bool write(DRW_Interface *interface_, DRW::Version ver, bool bin);
+    bool write(std::ostream &stream, DRW_Interface *interface_, DRW::Version ver, bool bin);
     bool writeLineType(DRW_LType *ent);
     bool writeLayer(DRW_Layer *ent);
     bool writeDimstyle(DRW_Dimstyle *ent);
index b3e0b17f243f15200afba6ffc48bc89f7754ba06..5c53130336cc8add7e63ef706fa354a51349a049 100644 (file)
@@ -342,8 +342,9 @@ if(APPLE)
     set(fixups)
     foreach(lib ${platform_BUNDLED_LIBS})
         get_filename_component(name ${lib} NAME)
-        execute_process(COMMAND otool -XD ${lib}
+        execute_process(COMMAND otool -D ${lib}
             OUTPUT_VARIABLE canonical_lib OUTPUT_STRIP_TRAILING_WHITESPACE)
+        string(REGEX REPLACE "^.+:\n" "" canonical_lib ${canonical_lib})
         add_custom_command(TARGET solvespace POST_BUILD
             COMMAND install_name_tool -change ${canonical_lib} @executable_path/${name}
                     $<TARGET_FILE:solvespace>
index 8d21e9cce166137764d8d4f86f46eaa140cfac4c..1b6d3e6c3aabf5098847b9632ae2e465ff10f828 100644 (file)
@@ -374,8 +374,6 @@ CONVERT(Rect)
     if(NSString *nsChr = [event charactersIgnoringModifiers])
         chr = [nsChr characterAtIndex:0];
 
-    if(chr == NSDeleteCharacter) /* map delete back to backspace */
-        chr = '\b';
     if(chr >= NSF1FunctionKey && chr <= NSF12FunctionKey)
         chr = SolveSpace::GraphicsWindow::FUNCTION_KEY_BASE + (chr - NSF1FunctionKey);
 
@@ -650,12 +648,15 @@ void InitMainMenu(NSMenu *mainMenu) {
             label = [[NSString stringWithUTF8String:entry->label]
                 stringByReplacingOccurrencesOfString:@"&" withString:@""];
 
-            unichar accel_char = entry->accel &
+            unichar accelChar = entry->accel &
                 ~(GraphicsWindow::SHIFT_MASK | GraphicsWindow::CTRL_MASK);
-            if(accel_char > GraphicsWindow::FUNCTION_KEY_BASE &&
-                    accel_char <= GraphicsWindow::FUNCTION_KEY_BASE + 12)
-                accel_char = NSF1FunctionKey + (accel_char - GraphicsWindow::FUNCTION_KEY_BASE - 1);
-            NSString *accel = [NSString stringWithCharacters:&accel_char length:1];
+            if(accelChar > GraphicsWindow::FUNCTION_KEY_BASE &&
+                    accelChar <= GraphicsWindow::FUNCTION_KEY_BASE + 12) {
+                accelChar = NSF1FunctionKey + (accelChar - GraphicsWindow::FUNCTION_KEY_BASE - 1);
+            } else if(accelChar == GraphicsWindow::DELETE_KEY) {
+                accelChar = NSBackspaceCharacter;
+            }
+            NSString *accel = [NSString stringWithCharacters:&accelChar length:1];
 
             menuItem = [levels[entry->level] addItemWithTitle:label
                 action:NULL keyEquivalent:[accel lowercaseString]];
@@ -809,6 +810,9 @@ bool SolveSpace::GetSaveFile(std::string *file, const std::string &defExtension,
     if(defExtension != "") {
         extensionIndex = [extensions indexOfObject:
             [NSString stringWithUTF8String:defExtension.c_str()]];
+        if(extensionIndex == -1) {
+            extensionIndex = 0;
+        }
     }
 
     [button selectItemAtIndex:extensionIndex];
@@ -1028,17 +1032,12 @@ void InitTextWindow() {
     [TW setFrameAutosaveName:@"TextWindow"];
     [TW setFloatingPanel:YES];
     [TW setBecomesKeyOnlyIfNeeded:YES];
-    [GW addChildWindow:TW ordered:NSWindowAbove];
-
-    // Without this, graphics window is also hidden when the text window is shown
-    // (and is its child window). We replicate the standard behavior manually, in
-    // the application delegate;
-    [TW setHidesOnDeactivate:NO];
 
     NSScrollView *scrollView = [[NSScrollView alloc] init];
     [TW setContentView:scrollView];
     [scrollView setBackgroundColor:[NSColor blackColor]];
     [scrollView setHasVerticalScroller:YES];
+    [scrollView setScrollerKnobStyle:NSScrollerKnobStyleLight];
     [[scrollView contentView] setCopiesOnScroll:YES];
 
     TWView = [[TextWindowView alloc] init];
@@ -1052,9 +1051,9 @@ void InitTextWindow() {
 
 void ShowTextWindow(bool visible) {
     if(visible)
-        [GW addChildWindow:TW ordered:NSWindowAbove];
+        [TW orderFront:nil];
     else
-        [TW orderOut:GW];
+        [TW close];
 }
 
 void GetTextWindowSize(int *w, int *h) {
@@ -1097,7 +1096,7 @@ bool TextEditControlIsVisible(void) {
 void SolveSpace::DoMessageBox(const char *str, int rows, int cols, bool error) {
     NSAlert *alert = [[NSAlert alloc] init];
     [alert setAlertStyle:(error ? NSWarningAlertStyle : NSInformationalAlertStyle)];
-    [[alert addButtonWithTitle:@"OK"] setKeyEquivalent: @"\033"];
+    [alert addButtonWithTitle:@"OK"];
 
     /* do some additional formatting of the message these are
        heuristics, but they are made failsafe and lead to nice results. */
@@ -1145,8 +1144,6 @@ std::vector<std::string> SolveSpace::GetFontFiles() {
 - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication;
 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
 - (void)applicationWillTerminate:(NSNotification *)aNotification;
-- (void)applicationWillBecomeActive:(NSNotification *)aNotification;
-- (void)applicationWillResignActive:(NSNotification *)aNotification;
 - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename;
 - (IBAction)preferences:(id)sender;
 @end
@@ -1167,18 +1164,6 @@ std::vector<std::string> SolveSpace::GetFontFiles() {
     SolveSpace::SS.Exit();
 }
 
-- (void)applicationWillBecomeActive:(NSNotification *)aNotification {
-    if(SolveSpace::SS.GW.showTextWindow) {
-        [GW addChildWindow:TW ordered:NSWindowAbove];
-    }
-}
-
-- (void)applicationWillResignActive:(NSNotification *)aNotification {
-    [TW setAnimationBehavior:NSWindowAnimationBehaviorNone];
-    [TW orderOut:nil];
-    [TW setAnimationBehavior:NSWindowAnimationBehaviorDefault];
-}
-
 - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename {
     return SolveSpace::SS.OpenFile([filename UTF8String]);
 }
index 613702190bf0892020968d23e2f0b285484bd614..e5aae1b0161fbc4c8fa3b4aeff633aee1991d46f 100644 (file)
@@ -370,16 +370,21 @@ void Constraint::MenuConstrain(int id) {
                                 ((gs.workplanes == 1 && gs.n == 3) ||
                                  (gs.n == 2)))
             {
-                c.entityA = gs.entity[0];
+                if(gs.entities > 0)
+                    c.entityA = gs.entity[0];
                 c.ptA = gs.point[0];
                 c.ptB = gs.point[1];
             } else if(gs.lineSegments == 1 &&
                                 ((gs.workplanes == 1 && gs.n == 2) ||
                                  (gs.n == 1)))
             {
-                int i = SK.GetEntity(gs.entity[0])->IsWorkplane() ? 1 : 0;
-                Entity *line = SK.GetEntity(gs.entity[i]);
-                c.entityA = gs.entity[1-i];
+                Entity *line;
+                if(SK.GetEntity(gs.entity[0])->IsWorkplane()) {
+                    line = SK.GetEntity(gs.entity[1]);
+                    c.entityA = gs.entity[0];
+                } else {
+                    line = SK.GetEntity(gs.entity[0]);
+                }
                 c.ptA = line->point[0];
                 c.ptB = line->point[1];
             } else if(SS.GW.LockedInWorkplane()
index 1b76b8eb034335049736120271001346e066055b..ca625ec03faf9f78816e9ec371fa8782c87cd20d 100644 (file)
@@ -259,14 +259,17 @@ public:
                 found = true;
                 e->tag = 1;
 
-                DRW_LWPolyline polyline;
+                DRW_Polyline polyline;
                 assignEntityDefaults(&polyline, e->style);
-                polyline.vertlist.push_back(new DRW_Vertex2D(start->pos.x, start->pos.y, 0.0));
-                polyline.vertlist.push_back(new DRW_Vertex2D(next->pos.x, next->pos.y, 0.0));
+                polyline.vertlist.push_back(
+                    new DRW_Vertex(start->pos.x, start->pos.y, start->pos.z, 0.0));
+                polyline.vertlist.push_back(
+                    new DRW_Vertex(next->pos.x, next->pos.y, next->pos.z, 0.0));
                 while(next->getNext(e->style, &next)) {
-                    polyline.vertlist.push_back(new DRW_Vertex2D(next->pos.x, next->pos.y, 0.0));
+                    polyline.vertlist.push_back(
+                        new DRW_Vertex(next->pos.x, next->pos.y, next->pos.z, 0.0));
                 }
-                dxf->writeLWPolyline(&polyline);
+                dxf->writePolyline(&polyline);
             }
 
             if(!found && !loop) {
@@ -384,7 +387,7 @@ public:
                         Vector dna = norm.Cross(da).WithMagnitude(1.0);
 
                         double thetaf = acos(da.DirectionCosineWith(db));
-                        
+
                         // Calculate median
                         Vector m = da.WithMagnitude(1.0).ScaledBy(cos(thetaf/2)).Plus(
                                    dna.ScaledBy(sin(thetaf/2)));
@@ -479,16 +482,14 @@ public:
         List<Vector> lv = {};
         sb->MakePwlInto(&lv, SS.ExportChordTolMm());
         hStyle hs = { (uint32_t)sb->auxA };
-        DRW_LWPolyline polyline;
+        DRW_Polyline polyline;
         assignEntityDefaults(&polyline, hs);
         for(int i = 0; i < lv.n; i++) {
             Vector *v = &lv.elem[i];
-            DRW_Vertex2D *vertex = new DRW_Vertex2D();
-            vertex->x = v->x;
-            vertex->y = v->y;
+            DRW_Vertex *vertex = new DRW_Vertex(v->x, v->y, v->z, 0.0);
             polyline.vertlist.push_back(vertex);
         }
-        dxf->writeLWPolyline(&polyline);
+        dxf->writePolyline(&polyline);
         lv.Clear();
     }
 
@@ -527,7 +528,8 @@ public:
         spline.ncontrol = sb->deg + 1;
         makeKnotsFor(&spline);
         for(int i = 0; i <= sb->deg; i++) {
-            spline.controllist.push_back(new DRW_Coord(sb->ctrl[i].x, sb->ctrl[i].y, 0.0));
+            spline.controllist.push_back(
+                new DRW_Coord(sb->ctrl[i].x, sb->ctrl[i].y, sb->ctrl[i].z));
             if(isRational) spline.weightlist.push_back(sb->weight[i]);
         }
         dxf->writeSpline(&spline);
@@ -684,12 +686,19 @@ void DxfFileWriter::Bezier(SBezier *sb) {
     paths.back().beziers.push_back(sb);
 }
 
-void DxfFileWriter::FinishAndCloseFile(void) {
-    dxfRW dxf(filename.c_str());
+void DxfFileWriter::FinishAndCloseFile() {
+    dxfRW dxf;
+
     DxfWriteInterface interface(this, &dxf);
-    dxf.write(&interface, DRW::AC1021, false);
+    std::stringstream stream;
+    dxf.write(stream, &interface, DRW::AC1021, /*bin=*/false);
     paths.clear();
     constraint = NULL;
+
+    if(!WriteFile(filename, stream.str())) {
+        Error("Couldn't write to '%s'", filename.c_str());
+        return;
+    }
 }
 
 bool DxfFileWriter::NeedToOutput(Constraint *c) {
index 278409850aec994be9ed1bf626d31640f9c0d806..581add6b5f99aff360a7670d0a6fb8b16affdd3b 100644 (file)
@@ -308,7 +308,7 @@ void SolveSpaceUI::GenerateAll(GenerateType type, bool andFindFree, bool genForB
                 // The group falls inside the range, so really solve it,
                 // and then regenerate the mesh based on the solved stuff.
                 if(genForBBox) {
-                    SolveGroup(g->h, andFindFree);
+                    SolveGroupAndReport(g->h, andFindFree);
                 } else {
                     g->GenerateLoops();
                     g->GenerateShellAndMesh();
@@ -491,6 +491,23 @@ void SolveSpaceUI::MarkDraggedParams(void) {
     }
 }
 
+void SolveSpaceUI::SolveGroupAndReport(hGroup hg, bool andFindFree) {
+    SolveGroup(hg, andFindFree);
+
+    Group *g = SK.GetGroup(hg);
+    if(g->solved.how == System::REDUNDANT_OKAY) {
+        // Solve again, in case we lost a degree of freedom because of a numeric error.
+        SolveGroup(hg, andFindFree);
+    }
+
+    bool isOkay = g->solved.how == System::SOLVED_OKAY ||
+                  (g->allowRedundant && g->solved.how == System::REDUNDANT_OKAY);
+
+    if(!isOkay || (isOkay && !g->IsSolvedOkay())) {
+        TextWindow::ReportHowGroupSolved(g->h);
+    }
+}
+
 void SolveSpaceUI::SolveGroup(hGroup hg, bool andFindFree) {
     int i;
     // Clear out the system to be solved.
@@ -518,12 +535,6 @@ void SolveSpaceUI::SolveGroup(hGroup hg, bool andFindFree) {
     g->solved.remove.Clear();
     int how = sys.Solve(g, &(g->solved.dof),
                            &(g->solved.remove), true, andFindFree);
-    bool isOkay = how == System::SOLVED_OKAY ||
-                  (g->allowRedundant && how == System::REDUNDANT_OKAY);
-    if(!isOkay || (isOkay && !g->IsSolvedOkay()))
-    {
-        TextWindow::ReportHowGroupSolved(g->h);
-    }
     g->solved.how = how;
     FreeAllTemporary();
 }
index 342f0c2449fa995a5473ce7b7b51027471a44d03..77130bc4d6d8b683e30e373b6f526fdcd9e21b8c 100644 (file)
@@ -203,8 +203,10 @@ void Group::GenerateShellAndMesh(void) {
         // not our own previous group.
         srcg = SK.GetGroup(opA);
 
-        GenerateForStepAndRepeat<SShell>(&(srcg->thisShell), &thisShell);
-        GenerateForStepAndRepeat<SMesh> (&(srcg->thisMesh),  &thisMesh);
+        if(!srcg->suppress) {
+            GenerateForStepAndRepeat<SShell>(&(srcg->thisShell), &thisShell);
+            GenerateForStepAndRepeat<SMesh> (&(srcg->thisMesh),  &thisMesh);
+        }
     } else if(type == EXTRUDE && haveSrc) {
         Group *src = SK.GetGroup(opA);
         Vector translate = Vector::From(h.param(0), h.param(1), h.param(2));
index 0f67fb7f49437cd0dd797b4a8eaafe7050c20d61..386e970b75b5d7c2124350b9f84d8b63372a1084 100644 (file)
 #include "../unix/gloffscreen.h"
 
 #ifdef HAVE_SPACEWARE
-#   include <spnav.h>
-#   ifndef SI_APP_FIT_BUTTON
-#       define SI_APP_FIT_BUTTON 31
-#   endif
+#include <spnav.h>
 #endif
 
 namespace SolveSpace {
@@ -1086,6 +1083,7 @@ static std::string ConvertFilters(std::string active, const FileFilter ssFilters
         for(const char *const *ssPattern = ssFilter->patterns; *ssPattern; ssPattern++) {
             std::string pattern = "*." + std::string(*ssPattern);
             filter->add_pattern(pattern);
+            filter->add_pattern(Glib::ustring(pattern).uppercase());
             if(active == "")
                 active = pattern.substr(2);
             if("*." + active == pattern)
@@ -1522,7 +1520,7 @@ static GdkFilterReturn GdkSpnavFilter(GdkXEvent *gxevent, GdkEvent *, gpointer)
             break;
 
         case SPNAV_EVENT_BUTTON:
-            if(!sev.button.press && sev.button.bnum == SI_APP_FIT_BUTTON) {
+            if(!sev.button.press && sev.button.bnum == 0) {
                 SS.GW.SpaceNavigatorButtonUp();
             }
             break;
index 5b7d6bd164c9ca2ebc51809e88844cf4dacf0fe8..dbd4e4779d5fb649abab05878dc19694ca1f21d3 100644 (file)
@@ -902,13 +902,21 @@ public:
 };
 
 void ImportDxf(const std::string &filename) {
-    SS.UndoRemember();
-    dxfRW dxf(filename.c_str());
     DxfReadInterface interface;
     interface.clearBlockTransform();
-    if(!dxf.read(&interface, false)) {
-        Error("Corrupted DXF file!");
+
+    std::string data;
+    if(!ReadFile(filename, &data)) {
+        Error("Couldn't read from '%s'", filename.c_str());
+        return;
+    }
+
+    SS.UndoRemember();
+    std::stringstream stream(data);
+    if(!dxfRW().read(stream, &interface, /*ext=*/false)) {
+        Error("Corrupted DXF file.");
     }
+
     if(interface.unknownEntities > 0) {
         Message(ssprintf("%u DXF entities of unknown type were ignored.",
                          interface.unknownEntities).c_str());
@@ -916,13 +924,21 @@ void ImportDxf(const std::string &filename) {
 }
 
 void ImportDwg(const std::string &filename) {
-    SS.UndoRemember();
-    dwgR dwg(filename.c_str());
     DxfReadInterface interface;
     interface.clearBlockTransform();
-    if(!dwg.read(&interface, false)) {
-        Error("Corrupted DWG file!");
+
+    std::string data;
+    if(!ReadFile(filename, &data)) {
+        Error("Couldn't read from '%s'", filename.c_str());
+        return;
+    }
+
+    SS.UndoRemember();
+    std::stringstream stream(data);
+    if(!dwgR().read(stream, &interface, /*ext=*/false)) {
+        Error("Corrupted DWG file.");
     }
+
     if(interface.unknownEntities > 0) {
         Message(ssprintf("%u DWG entities of unknown type were ignored.",
                          interface.unknownEntities).c_str());
index 4fec2b45bbfa51e4ea71d33b775a725ac9b65705..6458e5d6ff7eaf3a1e8e1394a2d8975702cd3f63 100644 (file)
@@ -34,7 +34,8 @@ void SMesh::AddTriangle(STriMeta meta, Vector a, Vector b, Vector c) {
     AddTriangle(&t);
 }
 void SMesh::AddTriangle(STriangle *st) {
-    if(st->meta.color.alpha != 255) isTransparent = true;
+    RgbaColor color = st->meta.color;
+    if(color.ToARGB32() != 0 && color.alpha != 255) isTransparent = true;
     l.Add(st);
 }
 
index 352c17eec9a068e3213dcd43606507a77caaa96c..700b7659a2970b048f475f248297d6c0de4688a2 100644 (file)
@@ -463,6 +463,15 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
        pending.operation != DRAGGING_MARQUEE)
     {
         SS.GenerateAll();
+
+        // Activate degraded mode, and regenerate display items without edges.
+        if(activeGroup.v != 0) {
+            bool showEdges = SS.GW.showEdges;
+            SS.GW.showEdges = false;
+            SK.GetGroup(activeGroup)->GenerateDisplayItems();
+            SS.GW.showEdges = showEdges;
+            isDegraded = true;
+        }
     }
 }
 
@@ -470,6 +479,12 @@ void GraphicsWindow::ClearPending(void) {
     pending.points.Clear();
     pending = {};
     SS.ScheduleShowTW();
+
+    // If degraded mode was enabled, we need to regenerate again to get edges back.
+    if(isDegraded) {
+        isDegraded = false;
+        SK.GetGroup(activeGroup)->displayDirty = true;
+    }
 }
 
 void GraphicsWindow::MouseMiddleOrRightDown(double x, double y) {
index 398cba0ab3d14c8af890d8730254c60cccc826c4..c923b7bce7ca9f523d64d4a2f194ca0f2e2f5770 100644 (file)
@@ -427,8 +427,11 @@ void SolveSpaceUI::UpdateWindowTitle(void) {
 
 static std::string Extension(const std::string &filename) {
     int dot = filename.rfind('.');
-    if(dot >= 0)
-        return filename.substr(dot + 1, filename.length());
+    if(dot >= 0) {
+        std::string ext = filename.substr(dot + 1, filename.length());
+        std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
+        return ext;
+    }
     return "";
 }
 
@@ -548,7 +551,10 @@ void SolveSpaceUI::MenuFile(int id) {
                 ImportDxf(importFile);
             } else if(Extension(importFile) == "dwg") {
                 ImportDwg(importFile);
-            } else oops();
+            } else {
+                Error("Can't identify file type from file extension of "
+                      "filename '%s'; try .dxf or .dwg.", importFile.c_str());
+            }
 
             SS.GenerateAll(SolveSpaceUI::GENERATE_UNTIL_ACTIVE);
             SS.ScheduleShowTW();
index 46debb9a847fde68805cf1ce23fccf058581f8e7..6cb59c7543084ae7d2095c5d7a9165e05c7f952a 100644 (file)
@@ -24,6 +24,7 @@
 #include <unordered_map>
 #include <map>
 #include <set>
+#include <sstream>
 #ifdef WIN32
 #   include <windows.h> // required by GL headers
 #endif
@@ -135,6 +136,7 @@ class RgbaColor;
 #endif
 
 FILE *ssfopen(const std::string &filename, const char *mode);
+std::fstream ssfstream(const std::string &filename, std::ios_base::openmode mode);
 void ssremove(const std::string &filename);
 
 #define MAX_RECENT 8
@@ -374,6 +376,8 @@ void MakeMatrix(double *mat, double a11, double a12, double a13, double a14,
                              double a41, double a42, double a43, double a44);
 std::string MakeAcceleratorLabel(int accel);
 bool FilenameHasExtension(const std::string &str, const char *ext);
+bool ReadFile(const std::string &filename, std::string *data);
+bool WriteFile(const std::string &filename, const std::string &data);
 void Message(const char *str, ...);
 void Error(const char *str, ...);
 void CnfFreezeBool(bool v, const std::string &name);
@@ -908,6 +912,7 @@ public:
     void GenerateAll(GenerateType type = GENERATE_DIRTY, bool andFindFree = false,
                      bool genForBBox = false);
     void SolveGroup(hGroup hg, bool andFindFree);
+    void SolveGroupAndReport(hGroup hg, bool andFindFree);
     void MarkDraggedParams(void);
     void ForceReferences(void);
 
index 9b36cb90f05409ded32f6566c7b9b6966c853b96..3f3178c79841408d49f73d729f1e2b989df5a315 100644 (file)
@@ -426,6 +426,7 @@ void SSurface::TriangulateInto(SShell *shell, SMesh *sm) {
         for(i = start; i < sm->l.n; i++) {
             STriangle *st = &(sm->l.elem[i]);
             st->meta = meta;
+            if(st->meta.color.alpha != 255) sm->isTransparent = true;
             st->an = NormalAt(st->a.x, st->a.y);
             st->bn = NormalAt(st->b.x, st->b.y);
             st->cn = NormalAt(st->c.x, st->c.y);
index 5ff118ef6f662d6350c25aba8a321b99e1d0d9d1..6b222b9772bd916b53cacbd96a831c7cd8f51ee9 100644 (file)
@@ -463,36 +463,34 @@ int System::Solve(Group *g, int *dof, List<hConstraint> *bad,
     if(!rankOk) {
         if(!g->allowRedundant) {
             if(andFindBad) FindWhichToRemoveToFixJacobian(g, bad);
-            return System::REDUNDANT_OKAY;
         }
-    }
-
-    // This is not the full Jacobian, but any substitutions or single-eq
-    // solves removed one equation and one unknown, therefore no effect
-    // on the number of DOF.
-    if(dof) *dof = mat.n - mat.m;
-
-    // If requested, find all the free (unbound) variables. This might be
-    // more than the number of degrees of freedom. Don't always do this,
-    // because the display would get annoying and it's slow.
-    for(i = 0; i < param.n; i++) {
-        Param *p = &(param.elem[i]);
-        p->free = false;
-
-        if(andFindFree) {
-            if(p->tag == 0) {
-                p->tag = VAR_DOF_TEST;
-                WriteJacobian(0);
-                EvalJacobian();
-                int rank = CalculateRank();
-                if(rank == mat.m) {
-                    p->free = true;
+    } else {
+        // This is not the full Jacobian, but any substitutions or single-eq
+        // solves removed one equation and one unknown, therefore no effect
+        // on the number of DOF.
+        if(dof) *dof = mat.n - mat.m;
+
+        // If requested, find all the free (unbound) variables. This might be
+        // more than the number of degrees of freedom. Don't always do this,
+        // because the display would get annoying and it's slow.
+        for(i = 0; i < param.n; i++) {
+            Param *p = &(param.elem[i]);
+            p->free = false;
+
+            if(andFindFree) {
+                if(p->tag == 0) {
+                    p->tag = VAR_DOF_TEST;
+                    WriteJacobian(0);
+                    EvalJacobian();
+                    int rank = CalculateRank();
+                    if(rank == mat.m) {
+                        p->free = true;
+                    }
+                    p->tag = 0;
                 }
-                p->tag = 0;
             }
         }
     }
-
     // System solved correctly, so write the new values back in to the
     // main parameter table.
     for(i = 0; i < param.n; i++) {
index 78e4308a3d4247e15331c3abd3551d2947efd76e..656ac626749859b1a4698f1edfc531c115b14951 100644 (file)
@@ -988,7 +988,7 @@ void TextWindow::MouseEvent(bool leftClick, bool leftDown, double x, double y) {
             break;
         }
     }
-    if(r >= rows) {
+    if(r < 0 || c < 0 || r >= rows || c >= MAX_COLS) {
         SetMousePointerToHand(false);
         goto done;
     }
index 0d9bfa7ba2b4c024485be9f68bbda28feab4f867..79cbffd0a306657703175bb9750ab2f4a0282951 100644 (file)
@@ -88,7 +88,9 @@ void TtfFontList::PlotString(const std::string &font, const std::string &str,
         [&](const TtfFont &tf) { return tf.FontFileBaseName() == font; });
 
     if(!str.empty() && tf != &l.elem[l.n]) {
-        tf->LoadFromFile(fontLibrary, /*nameOnly=*/false);
+        if(tf->fontFace == NULL) {
+            tf->LoadFromFile(fontLibrary, /*nameOnly=*/false);
+        }
         tf->PlotString(str, sbl, origin, u, v);
     } else {
         // No text or no font; so draw a big X for an error marker.
@@ -135,6 +137,7 @@ bool TtfFont::LoadFromFile(FT_Library fontLibrary, bool nameOnly) {
         dbp("freetype: loading unicode CMap for file '%s' failed: %s",
             fontFile.c_str(), ft_error_string(fterr));
         FT_Done_Face(fontFace);
+        fontFace = NULL;
         return false;
     }
 
@@ -144,6 +147,47 @@ bool TtfFont::LoadFromFile(FT_Library fontLibrary, bool nameOnly) {
     if(nameOnly) {
         FT_Done_Face(fontFace);
         fontFace = NULL;
+        return true;
+    }
+
+    // We always ask Freetype to give us a unit size character.
+    // It uses fixed point; put the unit size somewhere in the middle of the dynamic
+    // range of its 26.6 fixed point type, and adjust the factors so that the unit
+    // matches cap height.
+    FT_Size_RequestRec sizeRequest;
+    sizeRequest.type           = FT_SIZE_REQUEST_TYPE_REAL_DIM;
+    sizeRequest.width          = 1 << 16;
+    sizeRequest.height         = 1 << 16;
+    sizeRequest.horiResolution = 128;
+    sizeRequest.vertResolution = 128;
+    if(int fterr = FT_Request_Size(fontFace, &sizeRequest)) {
+        dbp("freetype: cannot set character size: %s",
+            ft_error_string(fterr));
+        FT_Done_Face(fontFace);
+        fontFace = NULL;
+        return false;
+    }
+
+    char chr = 'A';
+    uint32_t gid = FT_Get_Char_Index(fontFace, 'A');
+    if (gid == 0) {
+        dbp("freetype: CID-to-GID mapping for CID 0x%04x failed: %s; using CID as GID",
+            chr, ft_error_string(gid));
+        gid = chr;
+    }
+
+    if(gid) {
+        if(int fterr = FT_Load_Glyph(fontFace, gid, FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING)) {
+            dbp("freetype: cannot load glyph for GID 0x%04x: %s",
+                gid, ft_error_string(fterr));
+            FT_Done_Face(fontFace);
+            fontFace = NULL;
+            return false;
+        }
+
+        FT_BBox bbox;
+        FT_Outline_Get_CBox(&fontFace->glyph->outline, &bbox);
+        capHeight = (double)bbox.yMax;
     }
 
     return true;
@@ -225,27 +269,12 @@ void TtfFont::PlotString(const std::string &str,
     outlineFuncs.delta    = 0;
 
     FT_Pos dx = 0;
-    for(char32_t chr : ReadUTF8(str)) {
-        uint32_t gid = FT_Get_Char_Index(fontFace, chr);
+    for(char32_t cid : ReadUTF8(str)) {
+        uint32_t gid = FT_Get_Char_Index(fontFace, cid);
         if (gid == 0) {
             dbp("freetype: CID-to-GID mapping for CID 0x%04x failed: %s; using CID as GID",
-                chr, ft_error_string(gid));
-        }
-
-        // We always ask Freetype to give us a unit size character.
-        // It uses fixed point; put the unit size somewhere in the middle of the dynamic
-        // range of its 26.6 fixed point type, and adjust the factors so that the unit
-        // matches cap height.
-        FT_Size_RequestRec sizeRequest;
-        sizeRequest.type           = FT_SIZE_REQUEST_TYPE_REAL_DIM;
-        sizeRequest.width          = 1 << 16;
-        sizeRequest.height         = 1 << 16;
-        sizeRequest.horiResolution = 128;
-        sizeRequest.vertResolution = 128;
-        if(int fterr = FT_Request_Size(fontFace, &sizeRequest)) {
-            dbp("freetype: cannot set character size: %s",
-                ft_error_string(fterr));
-            return;
+                cid, ft_error_string(gid));
+            gid = cid;
         }
 
         /*
@@ -257,7 +286,7 @@ void TtfFont::PlotString(const std::string &str,
          *    ones, antialiasing mitigates this considerably though.
          */
         if(int fterr = FT_Load_Glyph(fontFace, gid, FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING)) {
-            dbp("freetype: cannot load glyph (gid %d): %s",
+            dbp("freetype: cannot load glyph for GID 0x%04x: %s",
                 gid, ft_error_string(fterr));
             return;
         }
@@ -287,7 +316,7 @@ void TtfFont::PlotString(const std::string &str,
         data.u       = u;
         data.v       = v;
         data.beziers = sbl;
-        data.factor  = 1.0f/(float)(1 << 16);
+        data.factor  = 1.0 / capHeight;
         data.bx      = bx;
         if(int fterr = FT_Outline_Decompose(&fontFace->glyph->outline, &outlineFuncs, &data)) {
             dbp("freetype: bezier decomposition failed (gid %d): %s",
index fb26ab95a5116edf82b514b00995d567555dbbeb..ec911272517b21df00d9692cf2ba3c1f3d686ff0 100644 (file)
--- a/src/ttf.h
+++ b/src/ttf.h
@@ -14,6 +14,7 @@ public:
     std::string     fontFile;
     std::string     name;
     FT_FaceRec_    *fontFace;
+    double          capHeight;
 
     std::string FontFileBaseName() const;
     bool LoadFromFile(FT_LibraryRec_ *fontLibrary, bool nameOnly = true);
index ebb60b2702939e4eb4da264a5d8026c7be5b35f3..a041ed36d7a1c010268546caf80110230a8cbf7d 100644 (file)
--- a/src/ui.h
+++ b/src/ui.h
@@ -504,6 +504,9 @@ public:
     // allowing a paint in between. The extra solves are wasted if they're
     // not displayed.
     bool    havePainted;
+    // Similarly, don't draw edges and outlines, since that's too slow
+    // for real-time dragging.
+    bool    isDegraded;
 
     // Some state for the context menu.
     struct {
index f1c50e4bb54d7ac04fde0cb6711a174fc0d9bef9..847f378eb96f90fdb44e221bc037d61d14c98524 100644 (file)
@@ -61,6 +61,33 @@ bool SolveSpace::FilenameHasExtension(const std::string &str, const char *ext)
     return true;
 }
 
+bool SolveSpace::ReadFile(const std::string &filename, std::string *data)
+{
+    FILE *f = ssfopen(filename.c_str(), "rb");
+    if(f == NULL)
+        return false;
+
+    fseek(f, 0, SEEK_END);
+    data->resize(ftell(f));
+    fseek(f, 0, SEEK_SET);
+    fread(&(*data)[0], 1, data->size(), f);
+    fclose(f);
+
+    return true;
+}
+
+bool SolveSpace::WriteFile(const std::string &filename, const std::string &data)
+{
+    FILE *f = ssfopen(filename.c_str(), "wb");
+    if(f == NULL)
+        return false;
+
+    fwrite(&data[0], 1, data.size(), f);
+    fclose(f);
+
+    return true;
+}
+
 void SolveSpace::MakeMatrix(double *mat,
                             double a11, double a12, double a13, double a14,
                             double a21, double a22, double a23, double a24,
index f96ed81e80a9b8d78cb6df33fc1c6e29c0a167d5..562499bdb4f41501ed42e09369d97ee2b422e773 100644 (file)
@@ -56,6 +56,7 @@ SiHdl SpaceNavigator = SI_NO_HANDLE;
 
 HWND MessageWnd, OkButton;
 bool MessageDone;
+int MessageWidth, MessageHeight;
 const char *MessageString;
 
 static LRESULT CALLBACK MessageProc(HWND hwnd, UINT msg, WPARAM wParam,
@@ -76,21 +77,13 @@ static LRESULT CALLBACK MessageProc(HWND hwnd, UINT msg, WPARAM wParam,
         case WM_PAINT: {
             PAINTSTRUCT ps;
             HDC hdc = BeginPaint(hwnd, &ps);
-            int row = 0, col = 0, i;
             SelectObject(hdc, FixedFont);
             SetTextColor(hdc, 0x000000);
             SetBkMode(hdc, TRANSPARENT);
-            for(i = 0; MessageString[i]; i++) {
-                if(MessageString[i] == '\n') {
-                    col = 0;
-                    row++;
-                } else {
-                    TextOutW(hdc, col*SS.TW.CHAR_WIDTH + 10,
-                                  row*SS.TW.LINE_HEIGHT + 10,
-                                  Widen(&(MessageString[i])).c_str(), 1);
-                    col++;
-                }
-            }
+            RECT rc;
+            SetRect(&rc, 10, 10, MessageWidth, MessageHeight);
+            std::wstring text = Widen(MessageString);
+            DrawText(hdc, text.c_str(), text.length(), &rc, DT_LEFT | DT_WORDBREAK);
             EndPaint(hwnd, &ps);
             break;
         }
@@ -147,6 +140,8 @@ void SolveSpace::DoMessageBox(const char *str, int rows, int cols, bool error)
     const char *title = error ? "SolveSpace - Error" : "SolveSpace - Message";
     int width  = cols*SS.TW.CHAR_WIDTH + 20,
         height = rows*SS.TW.LINE_HEIGHT + 60;
+    MessageWidth = width;
+    MessageHeight = height;
     MessageWnd = CreateWindowClient(0, L"MessageWnd", Widen(title).c_str(),
         WS_OVERLAPPED | WS_SYSMENU,
         r.left + 100, r.top + 100, width, height, NULL, NULL, Instance, NULL);
index 20f3ec6c4861ab728fcdb52d8aefd416d8913261..cba9c7868b64bce0c92ab25f912733e3730765c3 100644 (file)
@@ -67,7 +67,7 @@ std::wstring Widen(const std::string &in)
     return out;
 }
 
-FILE *ssfopen(const std::string &filename, const char *mode)
+static std::string MakeUNCFilename(const std::string &filename)
 {
     // Prepend \\?\ UNC prefix unless already an UNC path.
     // We never try to fopen paths that are not absolute or
@@ -76,9 +76,13 @@ FILE *ssfopen(const std::string &filename, const char *mode)
     std::string uncFilename = filename;
     if(uncFilename.substr(0, 2) != "\\\\")
         uncFilename = "\\\\?\\" + uncFilename;
+    return uncFilename;
+}
 
+FILE *ssfopen(const std::string &filename, const char *mode)
+{
     if(filename.length() != strlen(filename.c_str())) oops();
-    return _wfopen(Widen(uncFilename).c_str(), Widen(mode).c_str());
+    return _wfopen(Widen(MakeUNCFilename(filename)).c_str(), Widen(mode).c_str());
 }
 
 void ssremove(const std::string &filename)