├── debian ├── compat ├── source │ ├── format │ └── options ├── docs ├── libslvs1-dev.install ├── libslvs1.install ├── solvespace.install ├── changelog ├── solvespace.sharedmimeinfo ├── menu ├── rules ├── copyright └── control ├── src ├── cocoa │ ├── AppIcon.iconset │ │ ├── icon_16x16.png │ │ └── icon_32x32.png │ ├── SaveFormatAccessory.xib │ └── MainMenu.xib ├── icons │ ├── angle.png │ ├── arc.png │ ├── edges.png │ ├── equal.png │ ├── faces.png │ ├── horiz.png │ ├── in3d.png │ ├── line.png │ ├── mesh.png │ ├── point.png │ ├── ref.png │ ├── text.png │ ├── trim.png │ ├── vert.png │ ├── bezier.png │ ├── circle.png │ ├── extrude.png │ ├── length.png │ ├── normal.png │ ├── shaded.png │ ├── assemble.png │ ├── constraint.png │ ├── other-supp.png │ ├── parallel.png │ ├── pointonx.png │ ├── rectangle.png │ ├── symmetric.png │ ├── workplane.png │ ├── construction.png │ ├── hidden-lines.png │ ├── sketch-in-3d.png │ ├── step-rotate.png │ ├── tangent-arc.png │ ├── ontoworkplane.png │ ├── perpendicular.png │ ├── sketch-in-plane.png │ ├── step-translate.png │ ├── char-1-check-true.png │ ├── char-3-radio-true.png │ ├── same-orientation.png │ ├── char-0-check-false.png │ └── char-2-radio-false.png ├── win32 │ ├── icon.ico │ ├── resource.rc │ ├── manifest.xml │ ├── freeze.h │ ├── w32util.cpp │ └── freeze.cpp ├── unix │ ├── solvespace-16x16.png │ ├── solvespace-24x24.png │ ├── solvespace-32x32.png │ ├── solvespace-48x48.png │ ├── solvespace.desktop │ ├── gloffscreen.h │ ├── gloffscreen.cpp │ └── unixutil.cpp ├── config.h.in ├── pngchar2c.pl ├── png2c.pl ├── built │ ├── icons-proto.h │ └── bitmapextra.table.h ├── view.cpp ├── undoredo.cpp ├── srf │ └── merge.cpp ├── expr.h ├── request.cpp ├── polygon.h ├── lib.cpp ├── toolbar.cpp ├── CMakeLists.txt └── exportstep.cpp ├── extlib └── si │ ├── siapp.lib │ ├── spwmacro.h │ ├── spwdata.h │ ├── spwerror.h │ ├── siapp.h │ ├── siSyncPriv.h │ ├── siSync.h │ └── si.h ├── tools ├── CMakeLists.txt └── ttf2c.cpp ├── exposed ├── CMakeLists.txt └── CDemo.c ├── .gitmodules ├── .gitignore ├── appveyor.yml ├── cmake ├── c_flag_overrides.cmake ├── cxx_flag_overrides.cmake ├── Toolchain-mingw32.cmake ├── Toolchain-mingw64.cmake ├── FindSpaceWare.cmake ├── MacOSXBundleInfo.plist.in └── FindPerlModules.cmake ├── wishlist.txt ├── .travis.yml ├── .gitattributes ├── README.md └── CMakeLists.txt /debian/compat: -------------------------------------------------------------------------------- 1 | 9 2 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (native) 2 | -------------------------------------------------------------------------------- /debian/docs: -------------------------------------------------------------------------------- 1 | COPYING.txt 2 | README.md 3 | -------------------------------------------------------------------------------- /debian/libslvs1-dev.install: -------------------------------------------------------------------------------- 1 | usr/include/slvs.h 2 | -------------------------------------------------------------------------------- /debian/libslvs1.install: -------------------------------------------------------------------------------- 1 | usr/lib/**/libslvs.so* 2 | -------------------------------------------------------------------------------- /src/cocoa/AppIcon.iconset/icon_16x16.png: -------------------------------------------------------------------------------- 1 | ../../unix/solvespace-16x16.png -------------------------------------------------------------------------------- /src/cocoa/AppIcon.iconset/icon_32x32.png: -------------------------------------------------------------------------------- 1 | ../../unix/solvespace-32x32.png -------------------------------------------------------------------------------- /extlib/si/siapp.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/extlib/si/siapp.lib -------------------------------------------------------------------------------- /src/icons/angle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/angle.png -------------------------------------------------------------------------------- /src/icons/arc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/arc.png -------------------------------------------------------------------------------- /src/icons/edges.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/edges.png -------------------------------------------------------------------------------- /src/icons/equal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/equal.png -------------------------------------------------------------------------------- /src/icons/faces.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/faces.png -------------------------------------------------------------------------------- /src/icons/horiz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/horiz.png -------------------------------------------------------------------------------- /src/icons/in3d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/in3d.png -------------------------------------------------------------------------------- /src/icons/line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/line.png -------------------------------------------------------------------------------- /src/icons/mesh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/mesh.png -------------------------------------------------------------------------------- /src/icons/point.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/point.png -------------------------------------------------------------------------------- /src/icons/ref.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/ref.png -------------------------------------------------------------------------------- /src/icons/text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/text.png -------------------------------------------------------------------------------- /src/icons/trim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/trim.png -------------------------------------------------------------------------------- /src/icons/vert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/vert.png -------------------------------------------------------------------------------- /src/win32/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/win32/icon.ico -------------------------------------------------------------------------------- /debian/solvespace.install: -------------------------------------------------------------------------------- 1 | usr/bin/solvespace 2 | usr/share/icons 3 | usr/share/applications 4 | -------------------------------------------------------------------------------- /src/icons/bezier.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/bezier.png -------------------------------------------------------------------------------- /src/icons/circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/circle.png -------------------------------------------------------------------------------- /src/icons/extrude.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/extrude.png -------------------------------------------------------------------------------- /src/icons/length.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/length.png -------------------------------------------------------------------------------- /src/icons/normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/normal.png -------------------------------------------------------------------------------- /src/icons/shaded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/shaded.png -------------------------------------------------------------------------------- /debian/source/options: -------------------------------------------------------------------------------- 1 | tar-ignore = "*.sublime-*" 2 | tar-ignore = "cbuild" 3 | tar-ignore = ".git" 4 | -------------------------------------------------------------------------------- /src/icons/assemble.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/assemble.png -------------------------------------------------------------------------------- /src/icons/constraint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/constraint.png -------------------------------------------------------------------------------- /src/icons/other-supp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/other-supp.png -------------------------------------------------------------------------------- /src/icons/parallel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/parallel.png -------------------------------------------------------------------------------- /src/icons/pointonx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/pointonx.png -------------------------------------------------------------------------------- /src/icons/rectangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/rectangle.png -------------------------------------------------------------------------------- /src/icons/symmetric.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/symmetric.png -------------------------------------------------------------------------------- /src/icons/workplane.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/workplane.png -------------------------------------------------------------------------------- /src/icons/construction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/construction.png -------------------------------------------------------------------------------- /src/icons/hidden-lines.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/hidden-lines.png -------------------------------------------------------------------------------- /src/icons/sketch-in-3d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/sketch-in-3d.png -------------------------------------------------------------------------------- /src/icons/step-rotate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/step-rotate.png -------------------------------------------------------------------------------- /src/icons/tangent-arc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/tangent-arc.png -------------------------------------------------------------------------------- /src/icons/ontoworkplane.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/ontoworkplane.png -------------------------------------------------------------------------------- /src/icons/perpendicular.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/perpendicular.png -------------------------------------------------------------------------------- /src/icons/sketch-in-plane.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/sketch-in-plane.png -------------------------------------------------------------------------------- /src/icons/step-translate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/step-translate.png -------------------------------------------------------------------------------- /src/unix/solvespace-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/unix/solvespace-16x16.png -------------------------------------------------------------------------------- /src/unix/solvespace-24x24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/unix/solvespace-24x24.png -------------------------------------------------------------------------------- /src/unix/solvespace-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/unix/solvespace-32x32.png -------------------------------------------------------------------------------- /src/unix/solvespace-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/unix/solvespace-48x48.png -------------------------------------------------------------------------------- /src/icons/char-1-check-true.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/char-1-check-true.png -------------------------------------------------------------------------------- /src/icons/char-3-radio-true.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/char-3-radio-true.png -------------------------------------------------------------------------------- /src/icons/same-orientation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/same-orientation.png -------------------------------------------------------------------------------- /tools/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(ttf2c 2 | ttf2c.cpp) 3 | target_link_libraries(ttf2c 4 | comctl32) 5 | -------------------------------------------------------------------------------- /src/icons/char-0-check-false.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/char-0-check-false.png -------------------------------------------------------------------------------- /src/icons/char-2-radio-false.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hean01/solvespace/master/src/icons/char-2-radio-false.png -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | solvespace (2.1) unstable; urgency=low 2 | 3 | * Initial Release. 4 | 5 | -- whitequark Fri, 20 Mar 2015 12:39:28 +0300 6 | -------------------------------------------------------------------------------- /exposed/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories( 2 | ${CMAKE_SOURCE_DIR}/include) 3 | 4 | add_executable(CDemo 5 | CDemo.c) 6 | 7 | target_link_libraries(CDemo 8 | slvs) 9 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "extlib/zlib"] 2 | path = extlib/zlib 3 | url = https://github.com/madler/zlib 4 | [submodule "extlib/libpng"] 5 | path = extlib/libpng 6 | url = git://git.code.sf.net/p/libpng/code 7 | -------------------------------------------------------------------------------- /src/win32/resource.rc: -------------------------------------------------------------------------------- 1 | 2 | // we need a manifest if we want visual styles; put in numbers since somethings a bit screwy 3 | // with my SDK install (I don't think I've got *.rh right) 4 | 1 24 "manifest.xml" 5 | 6 | 4000 ICON "icon.ico" 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /CMakeCache.txt 2 | /cbuild/ 3 | *.trace # OpenGL apitrace files 4 | /debian/tmp/ 5 | /debian/*.log 6 | /debian/*.substvars 7 | /debian/files 8 | /debian/solvespace/ 9 | /debian/libslvs1/ 10 | /debian/libslvs1-dev/ 11 | /obj-*/ 12 | -------------------------------------------------------------------------------- /src/unix/solvespace.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Version=1.0 3 | Name=SolveSpace 4 | Comment=A parametric 2d/3d CAD 5 | Exec=/usr/bin/solvespace 6 | Icon=solvespace 7 | Type=Application 8 | Categories=Graphics 9 | Keywords=parametric;cad;2d;3d; 10 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 1.0.{build} 2 | before_build: 3 | - git submodule update --init 4 | - mkdir cbuild 5 | - cd cbuild 6 | - cmake -DDISABLE_TTF2C=ON -G"Visual Studio 12" .. 7 | build: 8 | project: C:\projects\solvespace\cbuild\src\solvespace.vcxproj 9 | verbosity: minimal 10 | -------------------------------------------------------------------------------- /cmake/c_flag_overrides.cmake: -------------------------------------------------------------------------------- 1 | if(MSVC) 2 | set(CMAKE_C_FLAGS_DEBUG_INIT "/D_DEBUG /MTd /Zi /Ob0 /Od /RTC1") 3 | set(CMAKE_C_FLAGS_MINSIZEREL_INIT "/MT /O1 /Ob1 /D NDEBUG") 4 | set(CMAKE_C_FLAGS_RELEASE_INIT "/MT /O2 /Ob2 /D NDEBUG") 5 | set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /O2 /Ob1 /D NDEBUG") 6 | endif() -------------------------------------------------------------------------------- /debian/solvespace.sharedmimeinfo: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SolveSpace sketch 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /cmake/cxx_flag_overrides.cmake: -------------------------------------------------------------------------------- 1 | if(MSVC) 2 | set(CMAKE_CXX_FLAGS_DEBUG_INIT "/D_DEBUG /MTd /Zi /Ob0 /Od /RTC1") 3 | set(CMAKE_CXX_FLAGS_MINSIZEREL_INIT "/MT /O1 /Ob1 /D NDEBUG") 4 | set(CMAKE_CXX_FLAGS_RELEASE_INIT "/MT /O2 /Ob2 /D NDEBUG") 5 | set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /O2 /Ob1 /D NDEBUG") 6 | endif() 7 | -------------------------------------------------------------------------------- /debian/menu: -------------------------------------------------------------------------------- 1 | ?package(solvespace):needs="X11" section="Applications/Graphics" \ 2 | title="SolveSpace" command="/usr/bin/solvespace" \ 3 | hints="CAD" \ 4 | icon16x16="/usr/share/pixmaps/solvespace-16x16.xpm" \ 5 | icon24x24="/usr/share/pixmaps/solvespace-24x24.xpm" \ 6 | icon32x32="/usr/share/pixmaps/solvespace-32x32.xpm" \ 7 | icon48x48="/usr/share/pixmaps/solvespace-48x48.xpm" 8 | -------------------------------------------------------------------------------- /cmake/Toolchain-mingw32.cmake: -------------------------------------------------------------------------------- 1 | SET(CMAKE_SYSTEM_NAME Windows) 2 | 3 | SET(TRIPLE i686-w64-mingw32) 4 | 5 | SET(CMAKE_C_COMPILER ${TRIPLE}-gcc) 6 | SET(CMAKE_CXX_COMPILER ${TRIPLE}-g++) 7 | SET(CMAKE_RC_COMPILER ${TRIPLE}-windres) 8 | 9 | SET(CMAKE_FIND_ROOT_PATH /usr/${TRIPLE}) 10 | 11 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 12 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 13 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 14 | -------------------------------------------------------------------------------- /cmake/Toolchain-mingw64.cmake: -------------------------------------------------------------------------------- 1 | SET(CMAKE_SYSTEM_NAME Windows) 2 | 3 | SET(TRIPLE x86_64-w64-mingw32) 4 | 5 | SET(CMAKE_C_COMPILER ${TRIPLE}-gcc) 6 | SET(CMAKE_CXX_COMPILER ${TRIPLE}-g++) 7 | SET(CMAKE_RC_COMPILER ${TRIPLE}-windres) 8 | 9 | SET(CMAKE_FIND_ROOT_PATH /usr/${TRIPLE}) 10 | 11 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 12 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 13 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 14 | -------------------------------------------------------------------------------- /src/config.h.in: -------------------------------------------------------------------------------- 1 | #ifndef __CONFIG_H 2 | #define __CONFIG_H 3 | 4 | #define PACKAGE_VERSION "@solvespace_VERSION_MAJOR@.@solvespace_VERSION_MINOR@" 5 | 6 | /* MSVC includes a proper stdint.h, but only since VS2008. */ 7 | #cmakedefine HAVE_STDINT_H 8 | 9 | /* Do we have the si library on win32, or libspnav on *nix? */ 10 | #cmakedefine HAVE_SPACEWARE 11 | 12 | #cmakedefine HAVE_GTK 13 | #cmakedefine HAVE_GTK2 14 | #cmakedefine HAVE_GTK3 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /wishlist.txt: -------------------------------------------------------------------------------- 1 | O(n*log(n)) assembly of edges into contours 2 | fix anti-aliased edge bug with filled contours 3 | crude DXF, HPGL import 4 | a request to import a plane thing 5 | make export assemble only contours in same group 6 | rotation of model view works about z of first point under cursor 7 | a way to kill a slow operation 8 | 9 | ----- 10 | rounding, as a special group 11 | associative entities from solid model, as a special group 12 | better level of detail 13 | some kind of import 14 | faster triangulation 15 | loop detection 16 | IGES export 17 | incremental regen of entities 18 | 19 | 20 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | os: 3 | - linux 4 | - osx 5 | install: 6 | - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo add-apt-repository -y ppa:smspillaz/cmake-2.8.12; sudo add-apt-repository -y ppa:ondrej/php5; sudo apt-get update -qq; sudo apt-get install -q -y cmake cmake-data libpng12-dev zlib1g-dev libjson0-dev libfontconfig1-dev libgtkmm-2.4-dev libpangomm-1.4-dev libgl1-mesa-dev libglu-dev libglew-dev; fi 7 | - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install cmake libpng; fi 8 | script: 9 | - mkdir cbuild 10 | - cd cbuild 11 | - cmake -DCMAKE_BUILD_TYPE=Debug .. 12 | - make 13 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # See debhelper(7) (uncomment to enable) 3 | # output every command that modifies files on the build system. 4 | #DH_VERBOSE = 1 5 | 6 | # see EXAMPLES in dpkg-buildflags(1) and read /usr/share/dpkg/* 7 | DPKG_EXPORT_BUILDFLAGS = 1 8 | include /usr/share/dpkg/default.mk 9 | 10 | # main packaging script based on dh7 syntax 11 | %: 12 | dh $@ 13 | 14 | # debmake generated override targets 15 | # This is example for Cmake (See http://bugs.debian.org/641051 ) 16 | override_dh_auto_configure: 17 | dh_auto_configure -- \ 18 | -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH) 19 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # .gitattributes for SolveSpace 2 | 3 | # Set default behaviour, in case users don't have core.autocrlf set. 4 | * text=auto 5 | 6 | # Explicitly declare text files we want to always be normalized and converted 7 | # to native line endings on checkout. 8 | *.cpp text 9 | *.h text 10 | *.txt text 11 | 12 | # Declare files that will always have CRLF line endings on checkout. 13 | *.sln text eol=crlf 14 | 15 | # Denote all files that are truly binary and should not be modified. 16 | *.gz binary 17 | *.ico binary 18 | *.jpg binary 19 | *.lib binary 20 | *.png binary 21 | 22 | # end .gitattributes 23 | -------------------------------------------------------------------------------- /src/win32/manifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | Parametric 3d CAD tool. 10 | 11 | 12 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /cmake/FindSpaceWare.cmake: -------------------------------------------------------------------------------- 1 | # Find the libspnav library and header. 2 | # 3 | # Sets the usual variables expected for find_package scripts: 4 | # 5 | # SPACEWARE_INCLUDE_DIR - header location 6 | # SPACEWARE_LIBRARIES - library to link against 7 | # SPACEWARE_FOUND - true if pugixml was found. 8 | 9 | if(UNIX) 10 | 11 | find_path(SPACEWARE_INCLUDE_DIR 12 | spnav.h) 13 | 14 | find_library(SPACEWARE_LIBRARY 15 | NAMES spnav libspnav) 16 | 17 | # Support the REQUIRED and QUIET arguments, and set SPACEWARE_FOUND if found. 18 | include(FindPackageHandleStandardArgs) 19 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(SPACEWARE DEFAULT_MSG 20 | SPACEWARE_LIBRARY SPACEWARE_INCLUDE_DIR) 21 | 22 | if(SPACEWARE_FOUND) 23 | set(SPACEWARE_LIBRARIES ${SPACEWARE_LIBRARY}) 24 | endif() 25 | 26 | mark_as_advanced(SPACEWARE_LIBRARY SPACEWARE_INCLUDE_DIR) 27 | 28 | endif() 29 | -------------------------------------------------------------------------------- /src/pngchar2c.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use GD; 7 | 8 | my ($out, $srcdir) = @ARGV; 9 | defined($srcdir) or $srcdir = '.'; 10 | -d "$srcdir/icons" || die "$srcdir/icons/: directory not found"; 11 | 12 | open(OUT, ">$out") or die "$out: $!"; 13 | 14 | print OUT "/**** This is a generated file - do not edit ****/\n\n"; 15 | 16 | for my $file (sort <$srcdir/icons/char-*.png>) { 17 | open(PNG, $file) or die "$file: $!\n"; 18 | my $img = newFromPng GD::Image(\*PNG) or die; 19 | $img->trueColor(1); 20 | close PNG; 21 | 22 | my ($width, $height) = $img->getBounds(); 23 | die "$file: $width, $height" if ($width != 16) or ($height != 16); 24 | 25 | for(my $x = 0; $x < 16; $x++) { 26 | for(my $y = 0; $y < 16; $y++) { 27 | my $index = $img->getPixel($x, $y); 28 | my ($r, $g, $b) = $img->rgb($index); 29 | if($r + $g + $b < 11) { 30 | print OUT " 0, "; 31 | } else { 32 | print OUT "255, "; 33 | } 34 | } 35 | print OUT "\n"; 36 | } 37 | print OUT "\n"; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /src/win32/freeze.h: -------------------------------------------------------------------------------- 1 | /* 2 | * A library for storing parameters in the registry. 3 | * 4 | * Jonathan Westhues, 2002 5 | */ 6 | 7 | #ifndef __FREEZE_H 8 | #define __FREEZE_H 9 | 10 | #ifndef FREEZE_SUBKEY 11 | #error must define FREEZE_SUBKEY to a string uniquely identifying the app 12 | #endif 13 | 14 | #define FreezeWindowPos(hwnd) FreezeWindowPosF(hwnd, FREEZE_SUBKEY, #hwnd) 15 | void FreezeWindowPosF(HWND hWnd, const char *subKey, const char *name); 16 | 17 | #define ThawWindowPos(hwnd) ThawWindowPosF(hwnd, FREEZE_SUBKEY, #hwnd) 18 | void ThawWindowPosF(HWND hWnd, const char *subKey, const char *name); 19 | 20 | #define FreezeDWORD(val) FreezeDWORDF(val, FREEZE_SUBKEY, #val) 21 | void FreezeDWORDF(DWORD val, const char *subKey, const char *name); 22 | 23 | #define ThawDWORD(val) val = ThawDWORDF(val, FREEZE_SUBKEY, #val) 24 | DWORD ThawDWORDF(DWORD val, const char *subKey, const char *name); 25 | 26 | #define FreezeString(val) FreezeStringF(val, FREEZE_SUBKEY, #val) 27 | void FreezeStringF(const char *val, const char *subKey, const char *name); 28 | 29 | #define ThawString(val, max) ThawStringF(val, max, FREEZE_SUBKEY, #val) 30 | void ThawStringF(char *val, int max, const char *subKey, const char *name); 31 | 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/unix/gloffscreen.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Offscreen rendering in OpenGL using framebuffer objects. 3 | // 4 | // Copyright 2015 5 | //----------------------------------------------------------------------------- 6 | #ifndef __GLOFFSCREEN_H 7 | #define __GLOFFSCREEN_H 8 | 9 | #include 10 | 11 | class GLOffscreen { 12 | public: 13 | /* these allocate and deallocate OpenGL resources. 14 | an OpenGL context /must/ be current. */ 15 | GLOffscreen(); 16 | ~GLOffscreen(); 17 | 18 | /* prepare for drawing a frame of specified size. 19 | returns true if OpenGL likes our configuration, false 20 | otherwise. if it returns false, the OpenGL state is restored. */ 21 | bool begin(int width, int height); 22 | 23 | /* get pixels out of the frame and restore OpenGL state. 24 | the pixel format is ARGB32 with top row at index 0 if 25 | flip is true and bottom row at index 0 if flip is false. 26 | the returned array is valid until the next call to begin() */ 27 | uint8_t *end(bool flip = true); 28 | 29 | private: 30 | unsigned int _framebuffer; 31 | unsigned int _color_renderbuffer, _depth_renderbuffer; 32 | uint32_t *_pixels, *_pixels_inv; 33 | int _width, _height; 34 | }; 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /extlib/si/spwmacro.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------- 2 | * spwmacro.h -- cpp macros we ALWAYS use. 3 | * 4 | <<<<<<< spwmacro.h 5 | * $Id: spwmacro.h,v 1.3 2001/01/16 01:18:40 HJin Exp $ 6 | ======= 7 | * $Id: spwmacro.h,v 1.3 2001/01/16 01:18:40 HJin Exp $ 8 | >>>>>>> 1.1.1.1.4.1 9 | * 10 | * We always seem to use the same macros. 11 | * This is the place we define them. 12 | * 13 | *---------------------------------------------------------------------- 14 | */ 15 | 16 | #ifndef SPWMACRO_H 17 | #define SPWMACRO_H 18 | 19 | 20 | #define SPW_FALSE (0) 21 | #define SPW_TRUE (!SPW_FALSE) 22 | 23 | #define SPW_MAX(a,b) (((a)>(b))?(a):(b)) 24 | #define SPW_MIN(a,b) (((a)<(b))?(a):(b)) 25 | 26 | #define SPW_ABS(a) (((a)<0)?(-(a)):(a)) 27 | 28 | #define SPW_SIGN(a) ((a)>=0?1:-1) 29 | 30 | #define SPW_BIND(min,n,max) (SPW_MIN((max),SPW_MAX((min),(n)))) 31 | 32 | #define SPW_NUM_ELEMENTS_IN(a) (sizeof(a)/sizeof((a)[0])) 33 | 34 | #define SPW_PI 3.14159265358979324f 35 | 36 | #define SPW_DEG_TO_RAD(d) ((d)*SPW_PI/180.0f) 37 | #define SPW_RAD_TO_DEG(r) ((r)*180.0f/SPW_PI) 38 | 39 | #define SPW_LENGTH_OF(a) (sizeof(a)/sizeof((a)[0])) 40 | 41 | #define SPW_END_OF(a) (&(a)[SPW_LENGTH_OF(a)-1]) 42 | 43 | #define SPW_SQ(a) ((a)*(a)) 44 | 45 | #define SPW_ABSDIFF(a, b) (fabs((double) (a) - (b))) 46 | 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: solvespace 3 | Source: https://github.com/whitequark/solvespace 4 | 5 | Files: * 6 | Copyright: 2008-2013 Jonathan Westhues. 7 | License: GPL-3.0+ 8 | 9 | Files: debian/* 10 | Copyright: 2015 Peter Zotov 11 | License: GPL-3.0+ 12 | 13 | License: GPL-3.0+ 14 | This program is free software: you can redistribute it and/or modify 15 | it under the terms of the GNU General Public License as published by 16 | the Free Software Foundation, either version 3 of the License, or 17 | (at your option) any later version. 18 | . 19 | This package is distributed in the hope that it will be useful, 20 | but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | GNU General Public License for more details. 23 | . 24 | You should have received a copy of the GNU General Public License 25 | along with this program. If not, see . 26 | . 27 | On Debian systems, the complete text of the GNU General 28 | Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". 29 | 30 | # Please also look if there are files or directories which have a 31 | # different copyright/license attached and list them here. 32 | # Please avoid to pick license terms that are more restrictive than the 33 | # packaged work, as it may make Debian's contributions unacceptable upstream. 34 | -------------------------------------------------------------------------------- /src/png2c.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use GD; 7 | 8 | my ($out, $proto, $srcdir) = @ARGV; 9 | defined($srcdir) or $srcdir = '.'; 10 | -d "$srcdir/icons" || die "$srcdir/icons/: directory not found"; 11 | 12 | open(OUT, ">$out") or die "$out: $!"; 13 | open(PROTO, ">$proto") or die "$proto: $!"; 14 | 15 | print OUT "/**** This is a generated file - do not edit ****/\n\n"; 16 | print PROTO "/**** This is a generated file - do not edit ****/\n\n"; 17 | 18 | for my $file (<$srcdir/icons/*.png>) { 19 | next if $file =~ m#/char-[^/]+$#; 20 | 21 | $file =~ m#/([^/]+)\.png$#; 22 | my $base = "Icon_$1"; 23 | $base =~ y/-/_/; 24 | 25 | open(PNG, $file) or die "$file: $!\n"; 26 | my $img = newFromPng GD::Image(\*PNG) or die; 27 | $img->trueColor(1); 28 | 29 | close PNG; 30 | 31 | my ($width, $height) = $img->getBounds(); 32 | die "$file: $width, $height" if ($width != 24) or ($height != 24); 33 | 34 | print PROTO "extern unsigned char $base\[24*24*3\];\n"; 35 | print OUT "unsigned char $base\[24*24*3] = {\n"; 36 | 37 | for(my $y = 0; $y < 24; $y++) { 38 | for(my $x = 0; $x < 24; $x++) { 39 | my $index = $img->getPixel($x, 23-$y); 40 | my ($r, $g, $b) = $img->rgb($index); 41 | if($r + $g + $b < 11) { 42 | ($r, $g, $b) = (30, 30, 30); 43 | } 44 | printf OUT " 0x%02x, 0x%02x, 0x%02x,\n", $r, $g, $b; 45 | } 46 | } 47 | 48 | print OUT "};\n\n"; 49 | } 50 | 51 | close PROTO; 52 | close OUT; 53 | -------------------------------------------------------------------------------- /src/built/icons-proto.h: -------------------------------------------------------------------------------- 1 | /**** This is a generated file - do not edit ****/ 2 | 3 | extern unsigned char Icon_angle[24*24*3]; 4 | extern unsigned char Icon_arc[24*24*3]; 5 | extern unsigned char Icon_assemble[24*24*3]; 6 | extern unsigned char Icon_bezier[24*24*3]; 7 | extern unsigned char Icon_circle[24*24*3]; 8 | extern unsigned char Icon_constraint[24*24*3]; 9 | extern unsigned char Icon_construction[24*24*3]; 10 | extern unsigned char Icon_edges[24*24*3]; 11 | extern unsigned char Icon_equal[24*24*3]; 12 | extern unsigned char Icon_extrude[24*24*3]; 13 | extern unsigned char Icon_faces[24*24*3]; 14 | extern unsigned char Icon_hidden_lines[24*24*3]; 15 | extern unsigned char Icon_horiz[24*24*3]; 16 | extern unsigned char Icon_in3d[24*24*3]; 17 | extern unsigned char Icon_length[24*24*3]; 18 | extern unsigned char Icon_line[24*24*3]; 19 | extern unsigned char Icon_mesh[24*24*3]; 20 | extern unsigned char Icon_normal[24*24*3]; 21 | extern unsigned char Icon_ontoworkplane[24*24*3]; 22 | extern unsigned char Icon_other_supp[24*24*3]; 23 | extern unsigned char Icon_parallel[24*24*3]; 24 | extern unsigned char Icon_perpendicular[24*24*3]; 25 | extern unsigned char Icon_point[24*24*3]; 26 | extern unsigned char Icon_pointonx[24*24*3]; 27 | extern unsigned char Icon_rectangle[24*24*3]; 28 | extern unsigned char Icon_ref[24*24*3]; 29 | extern unsigned char Icon_same_orientation[24*24*3]; 30 | extern unsigned char Icon_shaded[24*24*3]; 31 | extern unsigned char Icon_sketch_in_3d[24*24*3]; 32 | extern unsigned char Icon_sketch_in_plane[24*24*3]; 33 | extern unsigned char Icon_step_rotate[24*24*3]; 34 | extern unsigned char Icon_step_translate[24*24*3]; 35 | extern unsigned char Icon_symmetric[24*24*3]; 36 | extern unsigned char Icon_tangent_arc[24*24*3]; 37 | extern unsigned char Icon_text[24*24*3]; 38 | extern unsigned char Icon_trim[24*24*3]; 39 | extern unsigned char Icon_vert[24*24*3]; 40 | extern unsigned char Icon_workplane[24*24*3]; 41 | -------------------------------------------------------------------------------- /tools/ttf2c.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | //----------------------------------------------------------------------------- 6 | // Entry point into the program. 7 | //----------------------------------------------------------------------------- 8 | int main(int argc, char** argv) 9 | { 10 | if(argc != 2) { 11 | fprintf(stderr, "usage: ttf2c [output]"); 12 | return 1; 13 | } 14 | 15 | InitCommonControls(); 16 | 17 | // A monospaced font 18 | HFONT font = CreateFont(16, 9, 0, 0, FW_REGULAR, false, 19 | false, false, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, 20 | DEFAULT_QUALITY, FF_DONTCARE, "Lucida Console"); 21 | 22 | HDC hdc = CreateDC("DISPLAY", NULL, NULL, NULL); 23 | HBITMAP bitmap = CreateCompatibleBitmap(hdc, 30, 30); 24 | 25 | SelectObject(hdc, bitmap); 26 | SelectObject(hdc, font); 27 | 28 | FILE* out = fopen(argv[1], "w"); 29 | if(!out) { 30 | fprintf(stderr, "cannot open output file %s", argv[1]); 31 | return 1; 32 | } 33 | 34 | fprintf(out, "static const uint8_t FontTexture[256*16*16] = {\n"); 35 | 36 | int c; 37 | for(c = 0; c < 128; c++) { 38 | 39 | RECT r; 40 | r.left = 0; r.top = 0; 41 | r.right = 30; r.bottom = 30; 42 | FillRect(hdc, &r, (HBRUSH)GetStockObject(BLACK_BRUSH)); 43 | 44 | SetBkColor(hdc, RGB(0, 0, 0)); 45 | SetTextColor(hdc, RGB(255, 255, 255)); 46 | char str[2] = { c, 0 }; 47 | TextOut(hdc, 0, 0, str, 1); 48 | 49 | int i, j; 50 | for(i = 0; i < 16; i++) { 51 | for(j = 0; j < 16; j++) { 52 | COLORREF c = GetPixel(hdc, i, j); 53 | fprintf(out, "%3d, ", c ? 255 : 0); 54 | } 55 | fprintf(out, "\n"); 56 | } 57 | fprintf(out, "\n"); 58 | } 59 | fprintf(out, "#include \"bitmapextra.table.h\"\n"); 60 | fprintf(out, "};\n"); 61 | 62 | fclose(out); 63 | 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /cmake/MacOSXBundleInfo.plist.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | solvespace 9 | CFBundleInfoDictionaryVersion 10 | 6.0 11 | CFBundleName 12 | SolveSpace 13 | CFBundlePackageType 14 | APPL 15 | CFBundleVersion 16 | ${solvespace_VERSION_MAJOR}.${solvespace_VERSION_MINOR} 17 | CFBundleShortVersionString 18 | ${solvespace_VERSION_MAJOR}.${solvespace_VERSION_MINOR} 19 | NSHumanReadableCopyright 20 | © 2008-2015 Jonathan Westhues and other authors 21 | NSPrincipalClass 22 | NSApplication 23 | NSMainNibFile 24 | MainMenu 25 | CFBundleIconFile 26 | AppIcon 27 | CFBundleDocumentTypes 28 | 29 | 30 | CFBundleTypeExtensions 31 | 32 | slvs 33 | 34 | CFBundleTypeIconFile 35 | AppIcon.icns 36 | CFBundleTypeName 37 | SolveSpace sketch 38 | CFBundleTypeOSTypes 39 | 40 | slvs 41 | 42 | CFBundleTypeRole 43 | Editor 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: solvespace 2 | Section: graphics 3 | Priority: optional 4 | Maintainer: whitequark 5 | Build-Depends: debhelper (>= 9), cmake, libpng12-dev, zlib1g-dev, libjson-c-dev, 6 | libfontconfig1-dev, libgtkmm-2.4-dev, libpangomm-1.4-dev, 7 | libgl-dev, libglu-dev, libglew-dev, 8 | libgd-perl 9 | Standards-Version: 3.9.5 10 | Homepage: http://solvespace.com 11 | Vcs-Git: git://github.com/whitequark/solvespace 12 | Vcs-Browser: https://github.com/whitequark/solvespace 13 | 14 | Package: solvespace 15 | Architecture: any 16 | Multi-Arch: foreign 17 | Depends: ${shlibs:Depends}, ${misc:Depends} 18 | Description: SolveSpace is a parametric 2d/3d CAD 19 | SolveSpace is a parametric 2d/3d CAD program. Applications include: 20 | . 21 | * modeling 3d parts — draw with extrudes, revolves, and Boolean 22 | (union / difference) operations; 23 | * modeling 2d parts — draw the part as a single section, and export DXF, 24 | PDF, SVG; use 3d assembly to verify fit; 25 | * 3d-printed parts — export the STL or other triangle mesh expected by 26 | most 3d printers; 27 | * preparing CAM data — export 2d vector art for a waterjet machine or 28 | laser cutter; or generate STEP or STL, for import into third-party 29 | CAM software for machining; 30 | * mechanism design — use the constraint solver to simulate planar or 31 | spatial linkages, with pin, ball, or slide joints; 32 | * plane and solid geometry — replace hand-solved trigonometry and 33 | spreadsheets with a live dimensioned drawing. 34 | 35 | Package: libslvs1 36 | Section: libs 37 | Architecture: any 38 | Multi-Arch: same 39 | Depends: ${shlibs:Depends}, ${misc:Depends} 40 | Description: SolveSpace geometric kernel 41 | SolveSpace is a parametric 2d/3d CAD. libslvs contains the geometric 42 | kernel of SolveSpace, built as a library. 43 | 44 | Package: libslvs1-dev 45 | Section: libs 46 | Architecture: any 47 | Multi-Arch: same 48 | Depends: libslvs1, ${misc:Depends} 49 | Description: SolveSpace geometric kernel (development files) 50 | SolveSpace is a parametric 2d/3d CAD. libslvs contains the geometric 51 | kernel of SolveSpace, built as a library. 52 | . 53 | This package includes development files for libslvs. 54 | -------------------------------------------------------------------------------- /extlib/si/spwdata.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------- 2 | * spwdata.h -- datatypes 3 | * 4 | * 5 | * $Id: spwdata.h,v 1.4 1996/10/08 23:01:39 chris Exp $ 6 | * 7 | * This contains the only acceptable type definitions for 3Dconnexion 8 | * products. Needs more work. 9 | * 10 | *---------------------------------------------------------------------- 11 | * 12 | * (c) 1996-2005 3Dconnexion. All rights reserved. 13 | * 14 | * The computer codes included in this file, including source code and 15 | * object code, constitutes the proprietary and confidential information of 16 | * 3Dconnexion, and are provided pursuant to a license 17 | * agreement. These computer codes are protected by international, federal 18 | * and state law, including United States Copyright Law and international 19 | * treaty provisions. Except as expressly authorized by the license 20 | * agreement, or as expressly permitted under applicable laws of member 21 | * states of the European Union and then only to the extent so permitted, 22 | * no part of these computer codes may be reproduced or transmitted in any 23 | * form or by any means, electronic or mechanical, modified, decompiled, 24 | * disassembled, reverse engineered, sold, transferred, rented or utilized 25 | * for any unauthorized purpose without the express written permission of 26 | * 3Dconnexion. 27 | * 28 | *---------------------------------------------------------------------- 29 | * 30 | */ 31 | 32 | #ifndef SPWDATA_H 33 | #define SPWDATA_H 34 | 35 | static char spwdataCvsId[]="(C) 1996-2005 3Dconnexion: $Id: spwdata.h,v 1.4 1996/10/08 23:01:39 chris Exp $"; 36 | 37 | #include 38 | 39 | #define tchar_t _TCHAR 40 | #define char_t char 41 | #define uint32_t unsigned long 42 | #define sint32_t long 43 | #define boolean_t unsigned char 44 | #define void_t void 45 | #define window_handle_t HWND 46 | 47 | 48 | typedef long SPWint32; 49 | typedef short SPWint16; 50 | typedef char SPWint8; 51 | typedef int SPWbool; 52 | typedef unsigned long SPWuint32; 53 | typedef unsigned short SPWuint16; 54 | typedef unsigned char SPWuint8; 55 | typedef _TCHAR SPWchar; 56 | typedef _TCHAR* SPWstring; 57 | typedef float SPWfloat32; 58 | typedef double SPWfloat64; 59 | 60 | 61 | 62 | #endif /* SPWDATA_H */ 63 | 64 | -------------------------------------------------------------------------------- /cmake/FindPerlModules.cmake: -------------------------------------------------------------------------------- 1 | # - try to find perl modules, passed as COMPONENTS 2 | # 3 | # Non-cache variable you might use in your CMakeLists.txt: 4 | # PERLMODULES_FOUND 5 | # 6 | # Requires these CMake modules: 7 | # FindPackageHandleStandardArgs (known included with CMake >=2.6.2) 8 | # 9 | # Original Author: 10 | # 2012 Ryan Pavlik 11 | # http://academic.cleardefinition.com 12 | # Iowa State University HCI Graduate Program/VRAC 13 | # 14 | # Copyright Iowa State University 2012. 15 | # Distributed under the Boost Software License, Version 1.0. 16 | # (See accompanying file LICENSE_1_0.txt or copy at 17 | # http://www.boost.org/LICENSE_1_0.txt) 18 | 19 | if(NOT PERL_FOUND) 20 | find_package(Perl QUIET) 21 | endif() 22 | 23 | set(_deps_check) 24 | if(PERL_FOUND) 25 | foreach(module ${PerlModules_FIND_COMPONENTS}) 26 | string(REPLACE "::" "/" modfilename "${module}.pm") 27 | string(REPLACE "::" "_" modvarname "PERLMODULES_${module}_MODULE") 28 | string(TOUPPER "${modvarname}" modvarname) 29 | list(APPEND _deps_check ${modvarname}) 30 | if(NOT ${modvarname}) 31 | if(NOT PerlModules_FIND_QUIETLY) 32 | message(STATUS "Checking for perl module ${module}") 33 | endif() 34 | execute_process(COMMAND 35 | "${PERL_EXECUTABLE}" 36 | "-e" 37 | "use ${module}; print \$INC{\"${modfilename}\"}" 38 | RESULT_VARIABLE result_code 39 | OUTPUT_VARIABLE filename 40 | ERROR_VARIABLE error_info 41 | OUTPUT_STRIP_TRAILING_WHITESPACE) 42 | if(result_code EQUAL 0) 43 | if(NOT PerlModules_FIND_QUIETLY) 44 | message(STATUS 45 | "Checking for perl module ${module} - found at ${filename}") 46 | endif() 47 | set(${modvarname} 48 | "${filename}" 49 | CACHE 50 | FILEPATH 51 | "Location found for module ${module}" 52 | FORCE) 53 | mark_as_advanced(${modvarname}) 54 | else() 55 | if(NOT PerlModules_FIND_QUIETLY) 56 | message(STATUS "Checking for perl module ${module} - failed") 57 | endif() 58 | set(${modvarname} 59 | "NOTFOUND" 60 | CACHE 61 | FILEPATH 62 | "No location found for module ${module}" 63 | FORCE) 64 | file(APPEND 65 | ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log 66 | "Determining if the Perl module ${module} exists failed with the following error output:\n" 67 | "${error_info}\n\n") 68 | endif() 69 | endif() 70 | endforeach() 71 | endif() 72 | 73 | include(FindPackageHandleStandardArgs) 74 | find_package_handle_standard_args(PerlModules 75 | DEFAULT_MSG 76 | PERL_FOUND 77 | ${_deps_check}) 78 | -------------------------------------------------------------------------------- /src/win32/w32util.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Utility functions that depend on Win32. Notably, our memory allocation; 3 | // we use two separate allocators, one for long-lived stuff and one for 4 | // stuff that gets freed after every regeneration of the model, to save us 5 | // the trouble of freeing the latter explicitly. 6 | // 7 | // Copyright 2008-2013 Jonathan Westhues. 8 | //----------------------------------------------------------------------------- 9 | #include "solvespace.h" 10 | 11 | namespace SolveSpace { 12 | static HANDLE PermHeap, TempHeap; 13 | 14 | void dbp(const char *str, ...) 15 | { 16 | va_list f; 17 | static char buf[1024*50]; 18 | va_start(f, str); 19 | _vsnprintf(buf, sizeof(buf), str, f); 20 | va_end(f); 21 | 22 | OutputDebugString(buf); 23 | } 24 | 25 | void GetAbsoluteFilename(char *file) 26 | { 27 | char absoluteFile[MAX_PATH]; 28 | GetFullPathName(file, sizeof(absoluteFile), absoluteFile, NULL); 29 | strcpy(file, absoluteFile); 30 | } 31 | 32 | //----------------------------------------------------------------------------- 33 | // A separate heap, on which we allocate expressions. Maybe a bit faster, 34 | // since no fragmentation issues whatsoever, and it also makes it possible 35 | // to be sloppy with our memory management, and just free everything at once 36 | // at the end. 37 | //----------------------------------------------------------------------------- 38 | void *AllocTemporary(size_t n) 39 | { 40 | void *v = HeapAlloc(TempHeap, HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY, n); 41 | if(!v) oops(); 42 | return v; 43 | } 44 | void FreeTemporary(void *p) { 45 | HeapFree(TempHeap, HEAP_NO_SERIALIZE, p); 46 | } 47 | void FreeAllTemporary(void) 48 | { 49 | if(TempHeap) HeapDestroy(TempHeap); 50 | TempHeap = HeapCreate(HEAP_NO_SERIALIZE, 1024*1024*20, 0); 51 | // This is a good place to validate, because it gets called fairly 52 | // often. 53 | vl(); 54 | } 55 | 56 | void *MemRealloc(void *p, size_t n) { 57 | if(!p) { 58 | return MemAlloc(n); 59 | } 60 | 61 | p = HeapReAlloc(PermHeap, HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY, p, n); 62 | if(!p) oops(); 63 | return p; 64 | } 65 | void *MemAlloc(size_t n) { 66 | void *p = HeapAlloc(PermHeap, HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY, n); 67 | if(!p) oops(); 68 | return p; 69 | } 70 | void MemFree(void *p) { 71 | HeapFree(PermHeap, HEAP_NO_SERIALIZE, p); 72 | } 73 | 74 | void vl(void) { 75 | if(!HeapValidate(TempHeap, HEAP_NO_SERIALIZE, NULL)) oops(); 76 | if(!HeapValidate(PermHeap, HEAP_NO_SERIALIZE, NULL)) oops(); 77 | } 78 | 79 | void InitHeaps(void) { 80 | // Create the heap used for long-lived stuff (that gets freed piecewise). 81 | PermHeap = HeapCreate(HEAP_NO_SERIALIZE, 1024*1024*20, 0); 82 | // Create the heap that we use to store Exprs and other temp stuff. 83 | FreeAllTemporary(); 84 | } 85 | } -------------------------------------------------------------------------------- /src/unix/gloffscreen.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Offscreen rendering in OpenGL using framebuffer objects. 3 | // 4 | // Copyright 2015 5 | //----------------------------------------------------------------------------- 6 | #ifdef __APPLE__ 7 | #include 8 | #else 9 | #include 10 | #endif 11 | 12 | #include "gloffscreen.h" 13 | #include "solvespace.h" 14 | 15 | GLOffscreen::GLOffscreen() : _pixels(NULL), _pixels_inv(NULL) { 16 | #ifndef __APPLE__ 17 | if(glewInit() != GLEW_OK) 18 | oops(); 19 | #endif 20 | 21 | if(!GL_EXT_framebuffer_object) 22 | oops(); 23 | 24 | glGenFramebuffersEXT(1, &_framebuffer); 25 | glGenRenderbuffersEXT(1, &_color_renderbuffer); 26 | glGenRenderbuffersEXT(1, &_depth_renderbuffer); 27 | } 28 | 29 | GLOffscreen::~GLOffscreen() { 30 | glDeleteRenderbuffersEXT(1, &_depth_renderbuffer); 31 | glDeleteRenderbuffersEXT(1, &_color_renderbuffer); 32 | glDeleteFramebuffersEXT(1, &_framebuffer); 33 | } 34 | 35 | bool GLOffscreen::begin(int width, int height) { 36 | if(_width != width || _height != height) { 37 | delete[] _pixels; 38 | delete[] _pixels_inv; 39 | 40 | _pixels = new uint32_t[width * height * 4]; 41 | _pixels_inv = new uint32_t[width * height * 4]; 42 | 43 | _width = width; 44 | _height = height; 45 | } 46 | 47 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _framebuffer); 48 | 49 | glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, _color_renderbuffer); 50 | glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA8, _width, _height); 51 | glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, 52 | GL_RENDERBUFFER_EXT, _color_renderbuffer); 53 | 54 | glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, _depth_renderbuffer); 55 | glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, _width, _height); 56 | glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, 57 | GL_RENDERBUFFER_EXT, _depth_renderbuffer); 58 | 59 | if(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT) 60 | return true; 61 | 62 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); 63 | return false; 64 | } 65 | 66 | uint8_t *GLOffscreen::end(bool flip) { 67 | uint32_t *pixels_tgt = flip ? _pixels_inv : _pixels; 68 | 69 | #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 70 | glReadPixels(0, 0, _width, _height, 71 | GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, _pixels_inv); 72 | #else 73 | glReadPixels(0, 0, _width, _height, 74 | GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, _pixels_inv); 75 | #endif 76 | 77 | if(flip) { 78 | /* in OpenGL coordinates, bottom is zero Y */ 79 | for(int i = 0; i < _height; i++) 80 | memcpy(&_pixels[_width * i], &_pixels_inv[_width * (_height - i - 1)], _width * 4); 81 | } 82 | 83 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); 84 | 85 | return (uint8_t*) (flip ? _pixels : _pixels_inv); 86 | } 87 | -------------------------------------------------------------------------------- /extlib/si/spwerror.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------- 2 | * spwerror.h -- Standard Spacetec IMC function return values 3 | * 4 | * $Id: spwerror.h,v 1.10.4.1 1998/05/26 17:30:21 equerze Exp $ 5 | * 6 | * This file contains all the Spacetec IMC standard error return 7 | * return values for functions 8 | * 9 | *---------------------------------------------------------------------- 10 | * 11 | * (C) 1998-2001 3Dconnexion. All rights reserved. 12 | * Permission to use, copy, modify, and distribute this software for all 13 | * purposes and without fees is hereby grated provided that this copyright 14 | * notice appears in all copies. Permission to modify this software is granted 15 | * and 3Dconnexion will support such modifications only is said modifications are 16 | * approved by 3Dconnexion. 17 | * 18 | */ 19 | 20 | #ifndef _SPWERROR_H_ 21 | #define _SPWERROR_H_ 22 | 23 | #include "spwdata.h" 24 | 25 | static char spwerrorCvsId[]="(C) 1996 Spacetec IMC Corporation: $Id: spwerror.h,v 1.10.4.1 1998/05/26 17:30:21 equerze Exp $"; 26 | 27 | enum SpwRetVal /* Error return values. */ 28 | { 29 | SPW_NO_ERROR, /* No error. */ 30 | SPW_ERROR, /* Error -- function failed. */ 31 | SI_BAD_HANDLE, /* Invalid SpaceWare handle. */ 32 | SI_BAD_ID, /* Invalid device ID. */ 33 | SI_BAD_VALUE, /* Invalid argument value. */ 34 | SI_IS_EVENT, /* Event is a SpaceWare event. */ 35 | SI_SKIP_EVENT, /* Skip this SpaceWare event. */ 36 | SI_NOT_EVENT, /* Event is not a SpaceWare event. */ 37 | SI_NO_DRIVER, /* SpaceWare driver is not running. */ 38 | SI_NO_RESPONSE, /* SpaceWare driver is not responding. */ 39 | SI_UNSUPPORTED, /* The function is unsupported by this version. */ 40 | SI_UNINITIALIZED, /* SpaceWare input library is uninitialized. */ 41 | SI_WRONG_DRIVER, /* Driver is incorrect for this SpaceWare version.*/ 42 | SI_INTERNAL_ERROR, /* Internal SpaceWare error. */ 43 | SI_BAD_PROTOCOL, /* The transport protocol is unknown. */ 44 | SI_OUT_OF_MEMORY, /* Unable to malloc space required. */ 45 | SPW_DLL_LOAD_ERROR, /* Could not load siapp dlls */ 46 | SI_NOT_OPEN, /* Spaceball device not open */ 47 | SI_ITEM_NOT_FOUND, /* Item not found */ 48 | SI_UNSUPPORTED_DEVICE, /* The device is not supported */ 49 | SI_NOT_ENOUGH_MEMORY, /* Not enough memory (but not a malloc problem) */ 50 | SI_SYNC_WRONG_HASHCODE /* Wrong hash code sent to a Sync function */ 51 | }; 52 | 53 | typedef enum SpwRetVal SpwReturnValue; 54 | 55 | #ifdef __cplusplus 56 | extern "C" { 57 | #endif 58 | 59 | 60 | #ifdef __cplusplus 61 | } 62 | #endif 63 | 64 | #endif /* _SPWERROR_H_ */ 65 | -------------------------------------------------------------------------------- /src/unix/unixutil.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Utility functions used by the Unix port. Notably, our memory allocation; 3 | // we use two separate allocators, one for long-lived stuff and one for 4 | // stuff that gets freed after every regeneration of the model, to save us 5 | // the trouble of freeing the latter explicitly. 6 | // 7 | // Copyright 2008-2013 Jonathan Westhues. 8 | // Copyright 2013 Daniel Richard G. 9 | //----------------------------------------------------------------------------- 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include "solvespace.h" 18 | 19 | namespace SolveSpace { 20 | 21 | void dbp(const char *str, ...) 22 | { 23 | va_list f; 24 | static char buf[1024*50]; 25 | va_start(f, str); 26 | vsnprintf(buf, sizeof(buf), str, f); 27 | va_end(f); 28 | 29 | fputs(buf, stderr); 30 | fputc('\n', stderr); 31 | } 32 | 33 | void GetAbsoluteFilename(char *file) 34 | { 35 | char expanded[MAX_PATH]; 36 | realpath(file, expanded); 37 | strcpy(file, expanded); 38 | } 39 | 40 | int64_t GetUnixTime(void) 41 | { 42 | time_t ret; 43 | time(&ret); 44 | return (int64_t)ret; 45 | } 46 | 47 | //----------------------------------------------------------------------------- 48 | // A separate heap, on which we allocate expressions. Maybe a bit faster, 49 | // since fragmentation is less of a concern, and it also makes it possible 50 | // to be sloppy with our memory management, and just free everything at once 51 | // at the end. 52 | //----------------------------------------------------------------------------- 53 | 54 | typedef struct _AllocTempHeader AllocTempHeader; 55 | 56 | typedef struct _AllocTempHeader { 57 | AllocTempHeader *prev; 58 | AllocTempHeader *next; 59 | } AllocTempHeader; 60 | 61 | static AllocTempHeader *Head = NULL; 62 | 63 | void *AllocTemporary(size_t n) 64 | { 65 | AllocTempHeader *h = 66 | (AllocTempHeader *)malloc(n + sizeof(AllocTempHeader)); 67 | h->prev = NULL; 68 | h->next = Head; 69 | Head = h; 70 | memset(&h[1], 0, n); 71 | return (void *)&h[1]; 72 | } 73 | 74 | void FreeTemporary(void *p) 75 | { 76 | AllocTempHeader *h = (AllocTempHeader *)p - 1; 77 | if(h->prev) { 78 | h->prev->next = h->next; 79 | } else { 80 | Head = h->next; 81 | } 82 | if(h->next) h->next->prev = h->prev; 83 | free(h); 84 | } 85 | 86 | void FreeAllTemporary(void) 87 | { 88 | AllocTempHeader *h = Head; 89 | while(h) { 90 | AllocTempHeader *f = h; 91 | h = h->next; 92 | free(f); 93 | } 94 | Head = NULL; 95 | } 96 | 97 | void *MemRealloc(void *p, size_t n) { 98 | if(!p) { 99 | return MemAlloc(n); 100 | } 101 | 102 | p = realloc(p, n); 103 | if(!p) oops(); 104 | return p; 105 | } 106 | 107 | void *MemAlloc(size_t n) { 108 | void *p = malloc(n); 109 | if(!p) oops(); 110 | return p; 111 | } 112 | 113 | void MemFree(void *p) { 114 | free(p); 115 | } 116 | 117 | void InitHeaps(void) { 118 | /* nothing to do */ 119 | } 120 | 121 | }; 122 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | SolveSpace 2 | ========== 3 | 4 | This repository contains the official repository of [SolveSpace][]. 5 | 6 | [solvespace]: http://solvespace.com 7 | 8 | Installation 9 | ------------ 10 | 11 | ### Debian (>=jessie) and Ubuntu (>=trusty) 12 | 13 | Binary packages for Ubuntu trusty and later versions are available 14 | in [~whitequark/solvespace PPA][ppa]. 15 | 16 | [ppa]: https://launchpad.net/~whitequark/+archive/ubuntu/solvespace 17 | 18 | ### Mac OS X (>=10.6 64-bit) 19 | 20 | Binary packages for Mac OS X are available via [GitHub releases][rel]. 21 | 22 | [rel]: https://github.com/whitequark/solvespace/releases 23 | 24 | ### Other systems 25 | 26 | See below. 27 | 28 | Building on Linux 29 | ----------------- 30 | 31 | ### Building for Linux 32 | 33 | You will need CMake, libpng, zlib, json-c, fontconfig, gtkmm 2.4, pangomm 1.4, 34 | OpenGL and OpenGL GLU. 35 | On a Debian derivative (e.g. Ubuntu) these can be installed with: 36 | 37 | apt-get install libpng12-dev libjson-c-dev libfontconfig1-dev \ 38 | libgtkmm-2.4-dev libpangomm-1.4-dev libgl-dev libglu-dev \ 39 | libglew-dev cmake 40 | 41 | After that, build SolveSpace as following: 42 | 43 | mkdir cbuild 44 | cd cbuild 45 | cmake .. 46 | make 47 | sudo make install 48 | 49 | A fully functional port to GTK3 is available, but not recommended 50 | for use due to bugs in this toolkit. 51 | 52 | ### Building for Windows 53 | 54 | You will need CMake and a Windows cross-compiler. 55 | On a Debian derivative (e.g. Ubuntu) these can be installed with: 56 | 57 | apt-get install mingw-w64 cmake 58 | 59 | Before building, check out the submodules: 60 | 61 | git submodule update --init 62 | 63 | After that, build 32-bit SolveSpace as following: 64 | 65 | mkdir cbuild 66 | cd cbuild 67 | cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-mingw32.cmake .. 68 | make solvespace 69 | 70 | Or, build 64-bit SolveSpace as following: 71 | 72 | mkdir cbuild 73 | cd cbuild 74 | cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-mingw64.cmake .. 75 | make solvespace 76 | 77 | The application is built as `cbuild/src/solvespace.exe`. 78 | 79 | Space Navigator support will not be available. 80 | 81 | Building on Mac OS X 82 | -------------------- 83 | 84 | You will need XCode tools, CMake and libpng. Assuming you use [homebrew][], 85 | these can be installed with: 86 | 87 | brew install cmake libpng 88 | 89 | XCode has to be installed via AppStore; it requires a free Apple ID. 90 | 91 | After that, build SolveSpace as following: 92 | 93 | mkdir cbuild 94 | cd cbuild 95 | cmake .. 96 | make 97 | 98 | The app bundle is built in `cbuild/src/solvespace.app`. 99 | 100 | [homebrew]: http://brew.sh/ 101 | 102 | Building on Windows 103 | ------------------- 104 | 105 | You will need [cmake][cmakewin] and Visual C++. 106 | 107 | You will also need to check out the git submodules. 108 | 109 | After installing them, create a directory `build` in the source tree 110 | and point cmake-gui to the source tree and that directory. Press 111 | "Configure" and "Generate", then open `build\solvespace.sln` with 112 | Visual C++ and build it. 113 | 114 | [cmakewin]: http://www.cmake.org/download/#latest 115 | 116 | License 117 | ------- 118 | 119 | SolveSpace is distributed under the terms of the [GPL3 license](COPYING.txt). 120 | -------------------------------------------------------------------------------- /src/cocoa/SaveFormatAccessory.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # cmake configuration 2 | 3 | cmake_minimum_required(VERSION 2.8.12) 4 | cmake_policy(VERSION 2.8.12) 5 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} 6 | "${CMAKE_SOURCE_DIR}/cmake/") 7 | 8 | include(CheckIncludeFile) 9 | 10 | # for /MT on MSVC 11 | set(CMAKE_USER_MAKE_RULES_OVERRIDE 12 | "${CMAKE_SOURCE_DIR}/cmake/c_flag_overrides.cmake") 13 | set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX 14 | "${CMAKE_SOURCE_DIR}/cmake/cxx_flag_overrides.cmake") 15 | 16 | # project 17 | 18 | project(solvespace) 19 | set(solvespace_VERSION_MAJOR 2) 20 | set(solvespace_VERSION_MINOR 1) 21 | 22 | if(WIN32) 23 | # ttf2c takes 10 minutes (!) on Appveyor CI 24 | set(DISABLE_TTF2C CACHE BOOL "Disable font regeneration with ttf2c, for use on CI") 25 | endif() 26 | 27 | if(NOT WIN32) 28 | set(GUI gtk2 CACHE STRING "GUI toolkit to use (one of: gtk2 gtk3)") 29 | endif() 30 | 31 | # compiler 32 | 33 | if(WIN32) 34 | add_definitions( 35 | -D_CRT_SECURE_NO_DEPRECATE=1 36 | -D_CRT_SECURE_NO_WARNINGS=1 37 | -D_WIN32_WINNT=0x500 38 | -D_WIN32_IE=_WIN32_WINNT 39 | -DISOLATION_AWARE_ENABLED=1 40 | -DWIN32=1 41 | -DWIN32_LEAN_AND_MEAN=1) 42 | endif() 43 | 44 | if((CMAKE_CXX_PLATFORM_ID STREQUAL "Linux") AND CMAKE_COMPILER_IS_GNUCC) 45 | set(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed ${CMAKE_EXE_LINKER_FLAGS}") 46 | endif() 47 | 48 | if(MINGW) 49 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static-libgcc") 50 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++") 51 | endif() 52 | 53 | # dependencies 54 | 55 | CHECK_INCLUDE_FILE("stdint.h" HAVE_STDINT_H) 56 | 57 | find_package(OpenGL REQUIRED) 58 | 59 | find_package(Perl) 60 | find_package(PerlModules COMPONENTS GD) 61 | if(NOT (PERL_FOUND AND PERLMODULES_FOUND)) 62 | message(STATUS "Perl with GD not found; icons will not be regenerated if modified") 63 | endif() 64 | 65 | if(WIN32) 66 | find_package(PNG) 67 | 68 | if(NOT PNG_FOUND) 69 | message(STATUS "Using in-tree libpng") 70 | 71 | add_subdirectory(extlib/zlib) 72 | 73 | message(STATUS "Using in-tree libpng") 74 | 75 | set(ZLIB_LIBRARY 76 | zlibstatic) 77 | set(ZLIB_INCLUDE_DIR 78 | "${CMAKE_SOURCE_DIR}/extlib/zlib" 79 | "${CMAKE_BINARY_DIR}/extlib/zlib") 80 | set(SKIP_INSTALL_ALL 81 | ON) 82 | add_subdirectory(extlib/libpng) 83 | 84 | set(PNG_FOUND TRUE) 85 | set(PNG_LIBRARIES 86 | png16_static 87 | zlibstatic) 88 | set(PNG_INCLUDE_DIRS 89 | "${CMAKE_SOURCE_DIR}/extlib/libpng" 90 | "${CMAKE_BINARY_DIR}/extlib/libpng" 91 | "${CMAKE_SOURCE_DIR}/extlib/zlib" 92 | "${CMAKE_BINARY_DIR}/extlib/zlib") 93 | endif() 94 | 95 | if(NOT MINGW) 96 | message(STATUS "Using prebuilt SpaceWare") 97 | set(SPACEWARE_FOUND TRUE) 98 | set(SPACEWARE_INCLUDE_DIR 99 | "${CMAKE_SOURCE_DIR}/extlib/si") 100 | set(SPACEWARE_LIBRARIES 101 | "${CMAKE_SOURCE_DIR}/extlib/si/siapp.lib") 102 | endif() 103 | elseif(APPLE) 104 | find_package(PNG REQUIRED) 105 | find_library(APPKIT_LIBRARY AppKit REQUIRED) 106 | else() # Linux and compatible systems 107 | find_package(SpaceWare) 108 | 109 | # Use freedesktop's pkg-config to locate everything. 110 | find_package(PkgConfig REQUIRED) 111 | pkg_check_modules(PNG REQUIRED libpng) 112 | pkg_check_modules(FONTCONFIG REQUIRED fontconfig) 113 | pkg_check_modules(JSONC REQUIRED json-c) 114 | pkg_check_modules(GLEW REQUIRED glew) 115 | 116 | set(HAVE_GTK TRUE) 117 | if(GUI STREQUAL "gtk3") 118 | set(HAVE_GTK3 TRUE) 119 | pkg_check_modules(GTKMM REQUIRED gtkmm-3.0 pangomm-1.4 x11) 120 | elseif(GUI STREQUAL "gtk2") 121 | set(HAVE_GTK2 TRUE) 122 | pkg_check_modules(GTKMM REQUIRED gtkmm-2.4 pangomm-1.4 x11) 123 | else() 124 | message(FATAL_ERROR "GUI unrecognized: ${GUI}") 125 | endif() 126 | endif() 127 | 128 | # components 129 | 130 | if(WIN32) 131 | add_subdirectory(tools) 132 | endif() 133 | 134 | add_subdirectory(src) 135 | add_subdirectory(exposed) 136 | -------------------------------------------------------------------------------- /src/cocoa/MainMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /src/view.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // The View menu, stuff to snap to certain special vews of the model, and to 3 | // display our current view of the model to the user. 4 | // 5 | // Copyright 2008-2013 Jonathan Westhues. 6 | //----------------------------------------------------------------------------- 7 | #include "solvespace.h" 8 | 9 | void TextWindow::ShowEditView(void) { 10 | Printf(true, "%Ft3D VIEW PARAMETERS%E"); 11 | 12 | Printf(true, "%Bd %Ftoverall scale factor%E"); 13 | Printf(false, "%Ba %# px/%s %Fl%Ll%f[edit]%E", 14 | SS.GW.scale * SS.MmPerUnit(), 15 | SS.UnitName(), 16 | &ScreenChangeViewScale); 17 | Printf(false, ""); 18 | 19 | Printf(false, "%Bd %Ftorigin (maps to center of screen)%E"); 20 | Printf(false, "%Ba (%s, %s, %s) %Fl%Ll%f[edit]%E", 21 | SS.MmToString(-SS.GW.offset.x), 22 | SS.MmToString(-SS.GW.offset.y), 23 | SS.MmToString(-SS.GW.offset.z), 24 | &ScreenChangeViewOrigin); 25 | Printf(false, ""); 26 | 27 | Vector n = (SS.GW.projRight).Cross(SS.GW.projUp); 28 | Printf(false, "%Bd %Ftprojection onto screen%E"); 29 | Printf(false, "%Ba %Ftright%E (%3, %3, %3) %Fl%Ll%f[edit]%E", 30 | CO(SS.GW.projRight), 31 | &ScreenChangeViewProjection); 32 | Printf(false, "%Bd %Ftup%E (%3, %3, %3)", CO(SS.GW.projUp)); 33 | Printf(false, "%Ba %Ftout%E (%3, %3, %3)", CO(n)); 34 | Printf(false, ""); 35 | 36 | Printf(false, "The perspective may be changed in the"); 37 | Printf(false, "configuration screen."); 38 | } 39 | 40 | void TextWindow::ScreenChangeViewScale(int link, uint32_t v) { 41 | char buf[1024]; 42 | sprintf(buf, "%.3f", SS.GW.scale * SS.MmPerUnit()); 43 | 44 | SS.TW.edit.meaning = EDIT_VIEW_SCALE; 45 | SS.TW.ShowEditControl(12, 3, buf); 46 | } 47 | 48 | void TextWindow::ScreenChangeViewOrigin(int link, uint32_t v) { 49 | char buf[1024]; 50 | sprintf(buf, "%s, %s, %s", 51 | SS.MmToString(-SS.GW.offset.x), 52 | SS.MmToString(-SS.GW.offset.y), 53 | SS.MmToString(-SS.GW.offset.z)); 54 | 55 | SS.TW.edit.meaning = EDIT_VIEW_ORIGIN; 56 | SS.TW.ShowEditControl(18, 3, buf); 57 | } 58 | 59 | void TextWindow::ScreenChangeViewProjection(int link, uint32_t v) { 60 | char buf[1024]; 61 | sprintf(buf, "%.3f, %.3f, %.3f", CO(SS.GW.projRight)); 62 | SS.TW.edit.meaning = EDIT_VIEW_PROJ_RIGHT; 63 | SS.TW.ShowEditControl(24, 10, buf); 64 | } 65 | 66 | bool TextWindow::EditControlDoneForView(const char *s) { 67 | switch(edit.meaning) { 68 | case EDIT_VIEW_SCALE: { 69 | Expr *e = Expr::From(s, true); 70 | if(e) { 71 | double v = e->Eval() / SS.MmPerUnit(); 72 | if(v > LENGTH_EPS) { 73 | SS.GW.scale = v; 74 | } else { 75 | Error("Scale cannot be zero or negative."); 76 | } 77 | } 78 | break; 79 | } 80 | 81 | case EDIT_VIEW_ORIGIN: { 82 | Vector pt; 83 | if(sscanf(s, "%lf, %lf, %lf", &pt.x, &pt.y, &pt.z) == 3) { 84 | pt = pt.ScaledBy(SS.MmPerUnit()); 85 | SS.GW.offset = pt.ScaledBy(-1); 86 | } else { 87 | Error("Bad format: specify x, y, z"); 88 | } 89 | break; 90 | } 91 | 92 | case EDIT_VIEW_PROJ_RIGHT: 93 | case EDIT_VIEW_PROJ_UP: { 94 | Vector pt; 95 | if(sscanf(s, "%lf, %lf, %lf", &pt.x, &pt.y, &pt.z) != 3) { 96 | Error("Bad format: specify x, y, z"); 97 | break; 98 | } 99 | if(edit.meaning == EDIT_VIEW_PROJ_RIGHT) { 100 | SS.GW.projRight = pt; 101 | SS.GW.NormalizeProjectionVectors(); 102 | edit.meaning = EDIT_VIEW_PROJ_UP; 103 | char buf[1024]; 104 | sprintf(buf, "%.3f, %.3f, %.3f", CO(SS.GW.projUp)); 105 | HideEditControl(); 106 | ShowEditControl(26, 10, buf); 107 | edit.showAgain = true; 108 | } else { 109 | SS.GW.projUp = pt; 110 | SS.GW.NormalizeProjectionVectors(); 111 | } 112 | break; 113 | } 114 | 115 | default: 116 | return false; 117 | } 118 | return true; 119 | } 120 | 121 | -------------------------------------------------------------------------------- /src/undoredo.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // The user-visible undo/redo operation; whenever they change something, we 3 | // record our state and push it on a stack, and we pop the stack when they 4 | // select undo. 5 | // 6 | // Copyright 2008-2013 Jonathan Westhues. 7 | //----------------------------------------------------------------------------- 8 | #include "solvespace.h" 9 | 10 | void SolveSpaceUI::UndoRemember(void) { 11 | unsaved = true; 12 | PushFromCurrentOnto(&undo); 13 | UndoClearStack(&redo); 14 | UndoEnableMenus(); 15 | } 16 | 17 | void SolveSpaceUI::UndoUndo(void) { 18 | if(undo.cnt <= 0) return; 19 | 20 | PushFromCurrentOnto(&redo); 21 | PopOntoCurrentFrom(&undo); 22 | UndoEnableMenus(); 23 | } 24 | 25 | void SolveSpaceUI::UndoRedo(void) { 26 | if(redo.cnt <= 0) return; 27 | 28 | PushFromCurrentOnto(&undo); 29 | PopOntoCurrentFrom(&redo); 30 | UndoEnableMenus(); 31 | } 32 | 33 | void SolveSpaceUI::UndoEnableMenus(void) { 34 | EnableMenuById(GraphicsWindow::MNU_UNDO, undo.cnt > 0); 35 | EnableMenuById(GraphicsWindow::MNU_REDO, redo.cnt > 0); 36 | } 37 | 38 | void SolveSpaceUI::PushFromCurrentOnto(UndoStack *uk) { 39 | int i; 40 | 41 | if(uk->cnt == MAX_UNDO) { 42 | UndoClearState(&(uk->d[uk->write])); 43 | // And then write in to this one again 44 | } else { 45 | (uk->cnt)++; 46 | } 47 | 48 | UndoState *ut = &(uk->d[uk->write]); 49 | ZERO(ut); 50 | for(i = 0; i < SK.group.n; i++) { 51 | Group *src = &(SK.group.elem[i]); 52 | Group dest = *src; 53 | // And then clean up all the stuff that needs to be a deep copy, 54 | // and zero out all the dynamic stuff that will get regenerated. 55 | dest.clean = false; 56 | ZERO(&(dest.solved)); 57 | ZERO(&(dest.polyLoops)); 58 | ZERO(&(dest.bezierLoops)); 59 | ZERO(&(dest.bezierOpens)); 60 | ZERO(&(dest.polyError)); 61 | ZERO(&(dest.thisMesh)); 62 | ZERO(&(dest.runningMesh)); 63 | ZERO(&(dest.thisShell)); 64 | ZERO(&(dest.runningShell)); 65 | ZERO(&(dest.displayMesh)); 66 | ZERO(&(dest.displayEdges)); 67 | 68 | ZERO(&(dest.remap)); 69 | src->remap.DeepCopyInto(&(dest.remap)); 70 | 71 | ZERO(&(dest.impMesh)); 72 | ZERO(&(dest.impShell)); 73 | ZERO(&(dest.impEntity)); 74 | ut->group.Add(&dest); 75 | } 76 | for(i = 0; i < SK.request.n; i++) { 77 | ut->request.Add(&(SK.request.elem[i])); 78 | } 79 | for(i = 0; i < SK.constraint.n; i++) { 80 | Constraint *src = &(SK.constraint.elem[i]); 81 | Constraint dest = *src; 82 | ZERO(&(dest.dogd)); 83 | ut->constraint.Add(&dest); 84 | } 85 | for(i = 0; i < SK.param.n; i++) { 86 | ut->param.Add(&(SK.param.elem[i])); 87 | } 88 | for(i = 0; i < SK.style.n; i++) { 89 | ut->style.Add(&(SK.style.elem[i])); 90 | } 91 | ut->activeGroup = SS.GW.activeGroup; 92 | 93 | uk->write = WRAP(uk->write + 1, MAX_UNDO); 94 | } 95 | 96 | void SolveSpaceUI::PopOntoCurrentFrom(UndoStack *uk) { 97 | if(uk->cnt <= 0) oops(); 98 | (uk->cnt)--; 99 | uk->write = WRAP(uk->write - 1, MAX_UNDO); 100 | 101 | UndoState *ut = &(uk->d[uk->write]); 102 | 103 | // Free everything in the main copy of the program before replacing it 104 | Group *g; 105 | for(g = SK.group.First(); g; g = SK.group.NextAfter(g)) { 106 | g->Clear(); 107 | } 108 | SK.group.Clear(); 109 | SK.request.Clear(); 110 | SK.constraint.Clear(); 111 | SK.param.Clear(); 112 | SK.style.Clear(); 113 | 114 | // And then do a shallow copy of the state from the undo list 115 | ut->group.MoveSelfInto(&(SK.group)); 116 | ut->request.MoveSelfInto(&(SK.request)); 117 | ut->constraint.MoveSelfInto(&(SK.constraint)); 118 | ut->param.MoveSelfInto(&(SK.param)); 119 | ut->style.MoveSelfInto(&(SK.style)); 120 | SS.GW.activeGroup = ut->activeGroup; 121 | 122 | // No need to free it, since a shallow copy was made above 123 | ZERO(ut); 124 | 125 | // And reset the state everywhere else in the program, since the 126 | // sketch just changed a lot. 127 | SS.GW.ClearSuper(); 128 | SS.TW.ClearSuper(); 129 | SS.ReloadAllImported(); 130 | SS.GenerateAll(0, INT_MAX); 131 | SS.ScheduleShowTW(); 132 | } 133 | 134 | void SolveSpaceUI::UndoClearStack(UndoStack *uk) { 135 | while(uk->cnt > 0) { 136 | uk->write = WRAP(uk->write - 1, MAX_UNDO); 137 | (uk->cnt)--; 138 | UndoClearState(&(uk->d[uk->write])); 139 | } 140 | ZERO(uk); // for good measure 141 | } 142 | 143 | void SolveSpaceUI::UndoClearState(UndoState *ut) { 144 | int i; 145 | for(i = 0; i < ut->group.n; i++) { 146 | Group *g = &(ut->group.elem[i]); 147 | 148 | g->remap.Clear(); 149 | } 150 | ut->group.Clear(); 151 | ut->request.Clear(); 152 | ut->constraint.Clear(); 153 | ut->param.Clear(); 154 | ut->style.Clear(); 155 | ZERO(ut); 156 | } 157 | 158 | -------------------------------------------------------------------------------- /src/built/bitmapextra.table.h: -------------------------------------------------------------------------------- 1 | /**** This is a generated file - do not edit ****/ 2 | 3 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5 | 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 6 | 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 7 | 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 8 | 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 9 | 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 10 | 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 11 | 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 12 | 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 13 | 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 14 | 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 15 | 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 16 | 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 17 | 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 18 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19 | 20 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22 | 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 23 | 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 24 | 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 25 | 0, 0, 255, 255, 0, 0, 0, 255, 255, 255, 0, 0, 0, 255, 255, 0, 26 | 0, 0, 255, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0, 255, 255, 0, 27 | 0, 0, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 0, 255, 255, 0, 28 | 0, 0, 255, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0, 255, 255, 0, 29 | 0, 0, 255, 255, 0, 0, 0, 255, 255, 255, 0, 0, 0, 255, 255, 0, 30 | 0, 0, 255, 255, 0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 255, 0, 31 | 0, 0, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 0, 32 | 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 33 | 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 34 | 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 35 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36 | 37 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39 | 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 40 | 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 41 | 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 42 | 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 43 | 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 44 | 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 45 | 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 46 | 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 47 | 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 48 | 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 49 | 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 50 | 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 51 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53 | 54 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56 | 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 57 | 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 58 | 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 59 | 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 60 | 0, 0, 255, 255, 0, 0, 0, 255, 255, 0, 0, 0, 255, 255, 0, 0, 61 | 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 0, 0, 255, 255, 0, 0, 62 | 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 0, 0, 255, 255, 0, 0, 63 | 0, 0, 255, 255, 0, 0, 0, 255, 255, 0, 0, 0, 255, 255, 0, 0, 64 | 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 65 | 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 66 | 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 67 | 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 68 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70 | 71 | -------------------------------------------------------------------------------- /src/srf/merge.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Routines to merge multiple coincident surfaces (each with their own trim 3 | // curves) into a single surface, with all of the trim curves. 4 | // 5 | // Copyright 2008-2013 Jonathan Westhues. 6 | //----------------------------------------------------------------------------- 7 | #include "../solvespace.h" 8 | 9 | void SShell::MergeCoincidentSurfaces(void) { 10 | surface.ClearTags(); 11 | 12 | int i, j; 13 | SSurface *si, *sj; 14 | 15 | for(i = 0; i < surface.n; i++) { 16 | si = &(surface.elem[i]); 17 | if(si->tag) continue; 18 | // Let someone else clean up the empty surfaces; we can certainly merge 19 | // them, but we don't know how to calculate a reasonable bounding box. 20 | if(si->trim.n == 0) continue; 21 | // And for now we handle only coincident planes, so no sense wasting 22 | // time on other surfaces. 23 | if(si->degm != 1 || si->degn != 1) continue; 24 | 25 | SEdgeList sel; 26 | ZERO(&sel); 27 | si->MakeEdgesInto(this, &sel, SSurface::AS_XYZ); 28 | 29 | bool mergedThisTime, merged = false; 30 | do { 31 | mergedThisTime = false; 32 | 33 | for(j = i + 1; j < surface.n; j++) { 34 | sj = &(surface.elem[j]); 35 | if(sj->tag) continue; 36 | if(!sj->CoincidentWith(si, true)) continue; 37 | if(!sj->color.Equals(si->color)) continue; 38 | // But we do merge surfaces with different face entities, since 39 | // otherwise we'd hardly ever merge anything. 40 | 41 | // This surface is coincident. But let's not merge coincident 42 | // surfaces if they contain disjoint contours; that just makes 43 | // the bounding box tests less effective, and possibly things 44 | // less robust. 45 | SEdgeList tel; 46 | ZERO(&tel); 47 | sj->MakeEdgesInto(this, &tel, SSurface::AS_XYZ); 48 | if(!sel.ContainsEdgeFrom(&tel)) { 49 | tel.Clear(); 50 | continue; 51 | } 52 | tel.Clear(); 53 | 54 | sj->tag = 1; 55 | merged = true; 56 | mergedThisTime = true; 57 | sj->MakeEdgesInto(this, &sel, SSurface::AS_XYZ); 58 | sj->trim.Clear(); 59 | 60 | // All the references to this surface get replaced with the 61 | // new srf 62 | SCurve *sc; 63 | for(sc = curve.First(); sc; sc = curve.NextAfter(sc)) { 64 | if(sc->surfA.v == sj->h.v) sc->surfA = si->h; 65 | if(sc->surfB.v == sj->h.v) sc->surfB = si->h; 66 | } 67 | } 68 | 69 | // If this iteration merged a contour onto ours, then we have to 70 | // go through the surfaces again; that might have made a new 71 | // surface touch us. 72 | } while(mergedThisTime); 73 | 74 | if(merged) { 75 | sel.CullExtraneousEdges(); 76 | si->trim.Clear(); 77 | si->TrimFromEdgeList(&sel, false); 78 | 79 | // And we must choose control points such that all the trims lie 80 | // with u and v in [0, 1], so that the bbox tests work. 81 | Vector u, v, n; 82 | si->TangentsAt(0.5, 0.5, &u, &v); 83 | u = u.WithMagnitude(1); 84 | v = v.WithMagnitude(1); 85 | n = si->NormalAt(0.5, 0.5).WithMagnitude(1); 86 | v = (n.Cross(u)).WithMagnitude(1); 87 | 88 | double umax = VERY_NEGATIVE, umin = VERY_POSITIVE, 89 | vmax = VERY_NEGATIVE, vmin = VERY_POSITIVE; 90 | SEdge *se; 91 | for(se = sel.l.First(); se; se = sel.l.NextAfter(se)) { 92 | double ut = (se->a).Dot(u), vt = (se->a).Dot(v); 93 | umax = max(umax, ut); 94 | vmax = max(vmax, vt); 95 | umin = min(umin, ut); 96 | vmin = min(vmin, vt); 97 | } 98 | 99 | // An interesting problem here; the real curve could extend 100 | // slightly beyond the bounding box of the piecewise linear 101 | // bits. Not a problem for us, but some apps won't import STEP 102 | // in that case. So give a bit of extra room; in theory just 103 | // a chord tolerance, but more can't hurt. 104 | double muv = max((umax - umin), (vmax - vmin)); 105 | double tol = muv/50 + 3*SS.ChordTolMm(); 106 | umax += tol; 107 | vmax += tol; 108 | umin -= tol; 109 | vmin -= tol; 110 | 111 | // We move in the +v direction as v goes from 0 to 1, and in the 112 | // +u direction as u goes from 0 to 1. So our normal ends up 113 | // pointed the same direction. 114 | double nt = (si->ctrl[0][0]).Dot(n); 115 | si->ctrl[0][0] = 116 | Vector::From(umin, vmin, nt).ScaleOutOfCsys(u, v, n); 117 | si->ctrl[0][1] = 118 | Vector::From(umin, vmax, nt).ScaleOutOfCsys(u, v, n); 119 | si->ctrl[1][1] = 120 | Vector::From(umax, vmax, nt).ScaleOutOfCsys(u, v, n); 121 | si->ctrl[1][0] = 122 | Vector::From(umax, vmin, nt).ScaleOutOfCsys(u, v, n); 123 | } 124 | sel.Clear(); 125 | } 126 | 127 | surface.RemoveTagged(); 128 | } 129 | 130 | -------------------------------------------------------------------------------- /src/expr.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // An expression in our symbolic algebra system, used to write, linearize, 3 | // and solve our constraint equations. 4 | // 5 | // Copyright 2008-2013 Jonathan Westhues. 6 | //----------------------------------------------------------------------------- 7 | 8 | #ifndef __EXPR_H 9 | #define __EXPR_H 10 | 11 | class Expr; 12 | 13 | class Expr { 14 | public: 15 | uint32_t marker; 16 | 17 | enum { 18 | // A parameter, by the hParam handle 19 | PARAM = 0, 20 | // A parameter, by a pointer straight in to the param table (faster, 21 | // if we know that the param table won't move around) 22 | PARAM_PTR = 1, 23 | 24 | // These are used only for user-entered expressions. 25 | POINT = 10, 26 | ENTITY = 11, 27 | 28 | CONSTANT = 20, 29 | 30 | PLUS = 100, 31 | MINUS = 101, 32 | TIMES = 102, 33 | DIV = 103, 34 | NEGATE = 104, 35 | SQRT = 105, 36 | SQUARE = 106, 37 | SIN = 107, 38 | COS = 108, 39 | ASIN = 109, 40 | ACOS = 110, 41 | 42 | // Special helpers for when we're parsing an expression from text. 43 | // Initially, literals (like a constant number) appear in the same 44 | // format as they will in the finished expression, but the operators 45 | // are different until the parser fixes things up (and builds the 46 | // tree from the flat list that the lexer outputs). 47 | ALL_RESOLVED = 1000, 48 | PAREN = 1001, 49 | BINARY_OP = 1002, 50 | UNARY_OP = 1003 51 | }; 52 | 53 | int op; 54 | Expr *a; 55 | Expr *b; 56 | union { 57 | double v; 58 | hParam parh; 59 | Param *parp; 60 | hEntity entity; 61 | 62 | // For use while parsing 63 | char c; 64 | } x; 65 | 66 | static inline Expr *AllocExpr(void) 67 | { return (Expr *)AllocTemporary(sizeof(Expr)); } 68 | 69 | static Expr *From(hParam p); 70 | static Expr *From(double v); 71 | 72 | Expr *AnyOp(int op, Expr *b); 73 | inline Expr *Plus (Expr *b_) { return AnyOp(PLUS, b_); } 74 | inline Expr *Minus(Expr *b_) { return AnyOp(MINUS, b_); } 75 | inline Expr *Times(Expr *b_) { return AnyOp(TIMES, b_); } 76 | inline Expr *Div (Expr *b_) { return AnyOp(DIV, b_); } 77 | 78 | inline Expr *Negate(void) { return AnyOp(NEGATE, NULL); } 79 | inline Expr *Sqrt (void) { return AnyOp(SQRT, NULL); } 80 | inline Expr *Square(void) { return AnyOp(SQUARE, NULL); } 81 | inline Expr *Sin (void) { return AnyOp(SIN, NULL); } 82 | inline Expr *Cos (void) { return AnyOp(COS, NULL); } 83 | inline Expr *ASin (void) { return AnyOp(ASIN, NULL); } 84 | inline Expr *ACos (void) { return AnyOp(ACOS, NULL); } 85 | 86 | Expr *PartialWrt(hParam p); 87 | double Eval(void); 88 | uint64_t ParamsUsed(void); 89 | bool DependsOn(hParam p); 90 | static bool Tol(double a, double b); 91 | Expr *FoldConstants(void); 92 | void Substitute(hParam oldh, hParam newh); 93 | 94 | static const hParam NO_PARAMS, MULTIPLE_PARAMS; 95 | hParam ReferencedParams(ParamList *pl); 96 | 97 | void ParamsToPointers(void); 98 | 99 | void App(const char *str, ...); 100 | const char *Print(void); 101 | void PrintW(void); // worker 102 | 103 | // number of child nodes: 0 (e.g. constant), 1 (sqrt), or 2 (+) 104 | int Children(void); 105 | // total number of nodes in the tree 106 | int Nodes(void); 107 | 108 | // Make a simple copy 109 | Expr *DeepCopy(void); 110 | // Make a copy, with the parameters (usually referenced by hParam) 111 | // resolved to pointers to the actual value. This speeds things up 112 | // considerably. 113 | Expr *DeepCopyWithParamsAsPointers(IdList *firstTry, 114 | IdList *thenTry); 115 | 116 | static Expr *From(const char *in, bool popUpError); 117 | static void Lex(const char *in); 118 | static Expr *Next(void); 119 | static void Consume(void); 120 | 121 | static void PushOperator(Expr *e); 122 | static Expr *PopOperator(void); 123 | static Expr *TopOperator(void); 124 | static void PushOperand(Expr *e); 125 | static Expr *PopOperand(void); 126 | 127 | static void Reduce(void); 128 | static void ReduceAndPush(Expr *e); 129 | static int Precedence(Expr *e); 130 | 131 | static int Precedence(int op); 132 | static void Parse(void); 133 | }; 134 | 135 | class ExprVector { 136 | public: 137 | Expr *x, *y, *z; 138 | 139 | static ExprVector From(Expr *x, Expr *y, Expr *z); 140 | static ExprVector From(Vector vn); 141 | static ExprVector From(hParam x, hParam y, hParam z); 142 | static ExprVector From(double x, double y, double z); 143 | 144 | ExprVector Plus(ExprVector b); 145 | ExprVector Minus(ExprVector b); 146 | Expr *Dot(ExprVector b); 147 | ExprVector Cross(ExprVector b); 148 | ExprVector ScaledBy(Expr *s); 149 | ExprVector WithMagnitude(Expr *s); 150 | Expr *Magnitude(void); 151 | 152 | Vector Eval(void); 153 | }; 154 | 155 | class ExprQuaternion { 156 | public: 157 | Expr *w, *vx, *vy, *vz; 158 | 159 | static ExprQuaternion From(Expr *w, Expr *vx, Expr *vy, Expr *vz); 160 | static ExprQuaternion From(Quaternion qn); 161 | static ExprQuaternion From(hParam w, hParam vx, hParam vy, hParam vz); 162 | 163 | ExprVector RotationU(void); 164 | ExprVector RotationV(void); 165 | ExprVector RotationN(void); 166 | 167 | ExprVector Rotate(ExprVector p); 168 | ExprQuaternion Times(ExprQuaternion b); 169 | 170 | Expr *Magnitude(void); 171 | }; 172 | 173 | #endif 174 | 175 | -------------------------------------------------------------------------------- /extlib/si/siapp.h: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------- 2 | * 3 | * siapp.h -- Si static library interface header file 4 | * 5 | * $Id: siapp.h,v 1.3 2001/01/16 01:18:49 HJin Exp $ 6 | * 7 | * Contains function headers and type definitions for siapp.c. 8 | * 9 | *----------------------------------------------------------------------------- 10 | * 11 | * (c) 1998-2005 3Dconnexion. All rights reserved. 12 | * Permission to use, copy, modify, and distribute this software for all 13 | * purposes and without fees is hereby grated provided that this copyright 14 | * notice appears in all copies. Permission to modify this software is granted 15 | * and 3Dconnexion will support such modifications only if said modifications are 16 | * approved by 3Dconnexion. 17 | * 18 | */ 19 | 20 | #ifndef SIAPP_H 21 | #define SIAPP_H 22 | 23 | 24 | static char SiAppCvsId[]="(c) 1998-2005 3Dconnexion: $Id: siapp.h,v 1.3 2001/01/16 01:18:49 HJin Exp $"; 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | 31 | /* some enumerated types used in siapp.c */ 32 | 33 | enum InitResult 34 | { 35 | NOT_LOADED, 36 | FAILED, 37 | LOADED 38 | }; 39 | 40 | enum ErrorCode 41 | { 42 | NO_DLL_ERROR=0, 43 | DLL_LOAD_FAILURE, 44 | DLL_FUNCTION_LOAD_FAILURE, 45 | DLL_VAR_LOAD_FAILURE 46 | }; 47 | 48 | 49 | /* externally used functions */ 50 | 51 | enum SpwRetVal SiInitialize(void); 52 | void SiTerminate(void); 53 | int SiGetNumDevices (void); 54 | SiDevID SiDeviceIndex (int idx); 55 | int SiDispatch (SiHdl hdl, SiGetEventData *pData, 56 | SiSpwEvent *pEvent, SiSpwHandlers *pDHandlers); 57 | void SiOpenWinInit (SiOpenData *pData, HWND hWnd); 58 | SiHdl SiOpen (char *pAppName, SiDevID devID, SiTypeMask *pTMask, int mode, 59 | SiOpenData *pData); 60 | enum SpwRetVal SiClose (SiHdl hdl); 61 | void SiGetEventWinInit (SiGetEventData *pData, 62 | UINT msg, WPARAM wParam, LPARAM lParam); 63 | enum SpwRetVal SiGetEvent (SiHdl hdl, int flags, SiGetEventData *pData, 64 | SiSpwEvent *pEvent); 65 | enum SpwRetVal SiBeep (SiHdl hdl, char *string); 66 | enum SpwRetVal SiRezero (SiHdl hdl); 67 | enum SpwRetVal SiGrabDevice (SiHdl hdl, SPWbool exclusive); 68 | enum SpwRetVal SiReleaseDevice (SiHdl hdl); 69 | int SiButtonPressed (SiSpwEvent *pEvent); 70 | int SiButtonReleased (SiSpwEvent *pEvent); 71 | enum SpwRetVal SiSetUiMode (SiHdl hdl, SPWuint32 mode); 72 | enum SpwRetVal SiSetTypeMask (SiTypeMask *pTMask, int type1, ...); 73 | enum SpwRetVal SiGetDevicePort (SiDevID devID, SiDevPort *pPort); 74 | enum SpwRetVal SiGetDriverInfo (SiVerInfo *pInfo); 75 | void SiGetLibraryInfo (SiVerInfo *pInfo); 76 | enum SpwRetVal SiGetDeviceInfo (SiHdl hdl, SiDevInfo *pInfo); 77 | char * SpwErrorString (enum SpwRetVal val); 78 | enum SpwRetVal SiSyncSendQuery(SiHdl hdl); 79 | enum SpwRetVal SiSyncGetVersion(SiHdl hdl, SPWuint32 *pmajor, SPWuint32 *pminor); 80 | enum SpwRetVal SiSyncGetNumberOfFunctions(SiHdl hdl, SPWuint32 *pnumberOfFunctions); 81 | enum SpwRetVal SiSyncGetFunction(SiHdl hdl, SPWuint32 index, SPWint32 *pabsoluteFunctionNumber, WCHAR name[], SPWuint32 *pmaxNameLen); 82 | enum SpwRetVal SiSyncGetButtonAssignment(SiHdl hdl, SPWuint32 buttonNumber, SPWint32 *passignedFunctionIndex); 83 | enum SpwRetVal SiSyncSetButtonAssignment(SiHdl hdl, SPWuint32 buttonNumber, SPWint32 functionIndex); 84 | enum SpwRetVal SiSyncSetButtonAssignmentAbsolute(SiHdl hdl, SPWuint32 buttonNumber, SPWint32 absoluteFunctionNumber ); 85 | enum SpwRetVal SiSyncSetButtonName(SiHdl hdl, SPWuint32 buttonNumber, WCHAR name[]); 86 | enum SpwRetVal SiSyncGetAxisLabel (SiHdl hdl, SPWuint32 axisNumber, WCHAR name[], SPWuint32 *pmaxNameLen ); 87 | enum SpwRetVal SiSyncSetAxisLabel (SiHdl hdl, SPWuint32 axisNumber, WCHAR name[] ); 88 | enum SpwRetVal SiSyncGetOrientation (SiHdl hdl, SPWint32 axes[6] ); 89 | enum SpwRetVal SiSyncSetOrientation (SiHdl hdl, SPWint32 axes[6] ); 90 | enum SpwRetVal SiSyncGetFilter (SiHdl hdl, SiSyncFilter i, SiSyncFilterValue *pv ); 91 | enum SpwRetVal SiSyncSetFilter (SiHdl hdl, SiSyncFilter i, SiSyncFilterValue v ); 92 | enum SpwRetVal SiSyncGetAxesState (SiHdl hdl, SiSyncAxesState *pa ); 93 | enum SpwRetVal SiSyncSetAxesState (SiHdl hdl, SiSyncAxesState a ); 94 | enum SpwRetVal SiSyncSetInfoLine (SiHdl hdl, SPWint32 duration, WCHAR text[] ); 95 | enum SpwRetVal SiSyncGetScaleOverall (SiHdl hdl, SPWfloat32 *pv ); 96 | enum SpwRetVal SiSyncSetScaleOverall (SiHdl hdl, SPWfloat32 v ); 97 | enum SpwRetVal SiSyncGetScaleTx (SiHdl hdl, SPWfloat32 *pv ); 98 | enum SpwRetVal SiSyncSetScaleTx (SiHdl hdl, SPWfloat32 v ); 99 | enum SpwRetVal SiSyncGetScaleTy (SiHdl hdl, SPWfloat32 *pv ); 100 | enum SpwRetVal SiSyncSetScaleTy (SiHdl hdl, SPWfloat32 v ); 101 | enum SpwRetVal SiSyncGetScaleTz (SiHdl hdl, SPWfloat32 *pv ); 102 | enum SpwRetVal SiSyncSetScaleTz (SiHdl hdl, SPWfloat32 v ); 103 | enum SpwRetVal SiSyncGetScaleRx (SiHdl hdl, SPWfloat32 *pv ); 104 | enum SpwRetVal SiSyncSetScaleRx (SiHdl hdl, SPWfloat32 v ); 105 | enum SpwRetVal SiSyncGetScaleRy (SiHdl hdl, SPWfloat32 *pv ); 106 | enum SpwRetVal SiSyncSetScaleRy (SiHdl hdl, SPWfloat32 v ); 107 | enum SpwRetVal SiSyncGetScaleRz (SiHdl hdl, SPWfloat32 *pv ); 108 | enum SpwRetVal SiSyncSetScaleRz (SiHdl hdl, SPWfloat32 v ); 109 | enum SpwRetVal SiSyncInvokeAbsoluteFunction (SiHdl hdl, SiSyncAbsFunctionNumber i ); 110 | enum SpwRetVal SiSyncSetButtonState (SiHdl hdl, SPWuint32 buttonNumber, SiSyncButtonState state ); 111 | enum SpwRetVal SiGetButtonName (SiHdl hdl, SPWuint32 buttonNumber, SiButtonName *pname); 112 | enum SpwRetVal SiGetDeviceName (SiHdl hdl, SiDeviceName *pname); 113 | enum SpwRetVal SiGetDeviceImageFileName (SiHdl hdl, char name[], SPWuint32 *pmaxNameLen); 114 | HICON SiGetCompanyIcon(void); 115 | enum SpwRetVal SiGetCompanyLogoFileName (char name[], SPWuint32 *pmaxNameLen); 116 | 117 | #ifdef __cplusplus 118 | } 119 | #endif 120 | 121 | #endif /* #ifndef SIAPP_H */ 122 | -------------------------------------------------------------------------------- /extlib/si/siSyncPriv.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------- 2 | * siSyncPriv.h -- 3DxWare GUI Synchronization Private header 3 | * 4 | * Written: June 2005 5 | * Author: Jim Wick 6 | * 7 | *---------------------------------------------------------------------- 8 | * 9 | * (c) 1998-2005 3Dconnexion. All rights reserved. 10 | * Permission to use, copy, modify, and distribute this software for all 11 | * purposes and without fees is hereby grated provided that this copyright 12 | * notice appears in all copies. Permission to modify this software is granted 13 | * and 3Dconnexion will support such modifications only is said modifications are 14 | * approved by 3Dconnexion. 15 | * 16 | */ 17 | 18 | 19 | #ifndef _SISYNCPRIV_H_ 20 | #define _SISYNCPRIV_H_ 21 | 22 | 23 | /* 24 | * All packets start with the same fields. 25 | * Many packets have data following the itemCode. 26 | */ 27 | typedef struct /* Sync Packet */ 28 | { 29 | SPWuint32 size; /* total packet size */ 30 | SPWuint32 hashCode; /* Hash code that syncs a question with an answer */ 31 | SiSyncOpCode opCode; /* OpCode */ 32 | SiSyncItemCode itemCode; /* itemCode */ 33 | /* There will, generally, be more data starting here. 34 | * There will not be any pointers, the data will be in here. 35 | */ 36 | } SiSyncPacketHeader; 37 | 38 | /* 39 | * I've enumerated all the possible packets here, not because they are all different, 40 | * but mostly just for documentation. So the developer knows what parameters are 41 | * expected with which packet type. 42 | */ 43 | typedef struct { SiSyncPacketHeader h; } SiSyncGetVersionPacket; 44 | typedef struct { SiSyncPacketHeader h; SPWint32 major; SPWint32 minor; } SiSyncSetVersionPacket; 45 | typedef struct { SiSyncPacketHeader h; } SiSyncCommandQueryPacket; 46 | typedef struct { SiSyncPacketHeader h; } SiSyncCommandSaveConfigPacket; 47 | typedef struct { SiSyncPacketHeader h; } SiSyncGetNumberOfFunctionsPacket; 48 | typedef struct { SiSyncPacketHeader h; SPWint32 n; } SiSyncSetNumberOfFunctionsPacket; 49 | typedef struct { SiSyncPacketHeader h; SPWint32 i; } SiSyncGetFunctionPacket; 50 | typedef struct { SiSyncPacketHeader h; SPWint32 i; SPWint32 n; WCHAR name[1];} SiSyncSetFunctionPacket; 51 | typedef struct { SiSyncPacketHeader h; SPWint32 i; } SiSyncGetButtonAssignmentPacket; 52 | typedef struct { SiSyncPacketHeader h; SPWint32 i; SPWint32 n; } SiSyncSetButtonAssignmentPacket; 53 | typedef struct { SiSyncPacketHeader h; SPWint32 i; SPWint32 n; } SiSyncSetButtonAssignmentAbsolutePacket; 54 | typedef struct { SiSyncPacketHeader h; SPWint32 i; WCHAR name[1]; } SiSyncSetButtonNamePacket; 55 | typedef struct { SiSyncPacketHeader h; SPWint32 i; } SiSyncGetAxisLabelPacket; 56 | typedef struct { SiSyncPacketHeader h; SPWint32 i; WCHAR name[1]; } SiSyncSetAxisLabelPacket; 57 | typedef struct { SiSyncPacketHeader h; } SiSyncGetOrientationPacket; 58 | typedef struct { SiSyncPacketHeader h; SPWint32 a[6]; } SiSyncSetOrientationPacket; 59 | typedef struct { SiSyncPacketHeader h; SiSyncFilter i; } SiSyncGetFilterPacket; 60 | typedef struct { SiSyncPacketHeader h; SiSyncFilter i; SiSyncFilterValue v; } SiSyncSetFilterPacket; 61 | typedef struct { SiSyncPacketHeader h; } SiSyncGetAxesStatePacket; 62 | typedef struct { SiSyncPacketHeader h; SiSyncAxesState a; } SiSyncSetAxesStatePacket; 63 | typedef struct { SiSyncPacketHeader h; SPWint32 duration; WCHAR s[1]; } SiSyncSetInfoLinePacket; 64 | typedef struct { SiSyncPacketHeader h; } SiSyncGetScaleOverallPacket; 65 | typedef struct { SiSyncPacketHeader h; SPWfloat32 v; } SiSyncSetScaleOverallPacket; 66 | typedef struct { SiSyncPacketHeader h; } SiSyncGetScaleTxPacket; 67 | typedef struct { SiSyncPacketHeader h; SPWfloat32 v; } SiSyncSetScaleTxPacket; 68 | typedef struct { SiSyncPacketHeader h; } SiSyncGetScaleTyPacket; 69 | typedef struct { SiSyncPacketHeader h; SPWfloat32 v; } SiSyncSetScaleTyPacket; 70 | typedef struct { SiSyncPacketHeader h; } SiSyncGetScaleTzPacket; 71 | typedef struct { SiSyncPacketHeader h; SPWfloat32 v; } SiSyncSetScaleTzPacket; 72 | typedef struct { SiSyncPacketHeader h; } SiSyncGetScaleRxPacket; 73 | typedef struct { SiSyncPacketHeader h; SPWfloat32 v; } SiSyncSetScaleRxPacket; 74 | typedef struct { SiSyncPacketHeader h; } SiSyncGetScaleRyPacket; 75 | typedef struct { SiSyncPacketHeader h; SPWfloat32 v; } SiSyncSetScaleRyPacket; 76 | typedef struct { SiSyncPacketHeader h; } SiSyncGetScaleRzPacket; 77 | typedef struct { SiSyncPacketHeader h; SPWfloat32 v; } SiSyncSetScaleRzPacket; 78 | typedef struct { SiSyncPacketHeader h; SiSyncAbsFunctionNumber i; } SiSyncAbsFunctionPacket; 79 | typedef struct { SiSyncPacketHeader h; SPWint32 i; SPWbool state; } SiSyncSetButtonStatePacket; 80 | 81 | typedef struct 82 | { 83 | union 84 | { 85 | SiSyncPacketHeader h; 86 | SiSyncGetVersionPacket gv; 87 | SiSyncSetVersionPacket sv; 88 | SiSyncCommandQueryPacket cq; 89 | SiSyncCommandSaveConfigPacket cs; 90 | SiSyncGetNumberOfFunctionsPacket gnf; 91 | SiSyncSetNumberOfFunctionsPacket snf; 92 | SiSyncGetFunctionPacket gf; 93 | SiSyncSetFunctionPacket sf; 94 | SiSyncGetButtonAssignmentPacket gba; 95 | SiSyncSetButtonAssignmentPacket sba; 96 | SiSyncSetButtonAssignmentAbsolutePacket sbaa; 97 | SiSyncSetButtonNamePacket sbn; 98 | SiSyncGetAxisLabelPacket ga; 99 | SiSyncSetAxisLabelPacket sa; 100 | SiSyncGetOrientationPacket go; 101 | SiSyncSetOrientationPacket so; 102 | SiSyncGetFilterPacket gfi; 103 | SiSyncSetFilterPacket sfi; 104 | SiSyncGetAxesStatePacket gas; 105 | SiSyncSetAxesStatePacket sas; 106 | SiSyncSetInfoLinePacket si; 107 | SiSyncGetScaleOverallPacket gso; 108 | SiSyncSetScaleOverallPacket sso; 109 | SiSyncGetScaleTxPacket gtx; 110 | SiSyncSetScaleTxPacket stx; 111 | SiSyncGetScaleTyPacket gty; 112 | SiSyncSetScaleTyPacket sty; 113 | SiSyncGetScaleTzPacket gtz; 114 | SiSyncSetScaleTzPacket stz; 115 | SiSyncGetScaleRxPacket grx; 116 | SiSyncSetScaleRxPacket srx; 117 | SiSyncGetScaleRyPacket gry; 118 | SiSyncSetScaleRyPacket sry; 119 | SiSyncGetScaleRzPacket grz; 120 | SiSyncSetScaleRzPacket srz; 121 | SiSyncAbsFunctionPacket absf; 122 | SiSyncSetButtonStatePacket sbs; 123 | }; 124 | } SiSyncPacket; 125 | 126 | 127 | #endif /* _SI_SYNCPRIV_H_ */ 128 | -------------------------------------------------------------------------------- /extlib/si/siSync.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------- 2 | * siSync.h -- 3DxWare GUI Synchronization header 3 | * 4 | * Written: September 2004 5 | * Author: Jim Wick 6 | * 7 | *---------------------------------------------------------------------- 8 | * 9 | * (c) 1998-2005 3Dconnexion. All rights reserved. 10 | * Permission to use, copy, modify, and distribute this software for all 11 | * purposes and without fees is hereby grated provided that this copyright 12 | * notice appears in all copies. Permission to modify this software is granted 13 | * and 3Dconnexion will support such modifications only is said modifications are 14 | * approved by 3Dconnexion. 15 | * 16 | */ 17 | 18 | 19 | #ifndef _SISYNC_H_ 20 | #define _SISYNC_H_ 21 | 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | 27 | /* 28 | * Constants 29 | */ 30 | #define SI_SYNC_PACKET_ID 27711 31 | #define SI_SYNC_VERSION_MAJOR 1 32 | #define SI_SYNC_VERSION_MINOR 0 33 | 34 | 35 | /* 36 | * Absolute Internal Function Numbers 37 | * These are function numbers that will never change. 38 | * For use with Set BUTTON_ASSIGNMENT_ABSOLUTE packets, and some INVOKE items. 39 | * Some functions (keys) can not be INVOKED because there is a separate 40 | * press and release and that difference is not exposed. 41 | */ 42 | typedef enum 43 | { 44 | SI_SYNC_FUNCTION_MENU_TOGGLE = 12, 45 | SI_SYNC_FUNCTION_TRANS_TOGGLE = 13, 46 | SI_SYNC_FUNCTION_ROT_TOGGLE = 14, 47 | SI_SYNC_FUNCTION_HPV_TOGGLE = 15, 48 | SI_SYNC_FUNCTION_DEC_SENS = 16, 49 | SI_SYNC_FUNCTION_INC_SENS = 17, 50 | SI_SYNC_FUNCTION_RESTORE_DEF = 18, 51 | SI_SYNC_FUNCTION_PAN = 19, 52 | SI_SYNC_FUNCTION_ZOOM = 20, 53 | SI_SYNC_FUNCTION_TX = 21, 54 | SI_SYNC_FUNCTION_TY = 22, 55 | SI_SYNC_FUNCTION_TZ = 23, 56 | SI_SYNC_FUNCTION_RX = 24, 57 | SI_SYNC_FUNCTION_RY = 25, 58 | SI_SYNC_FUNCTION_RZ = 26, 59 | SI_SYNC_FUNCTION_REZERO_DEVICE = 27, 60 | SI_SYNC_FUNCTION_SAVE = 33, 61 | SI_SYNC_FUNCTION_RELOAD = 57, 62 | SI_SYNC_FUNCTION_SHIFT_KEY = 60, 63 | SI_SYNC_FUNCTION_CTRL_KEY = 61, 64 | SI_SYNC_FUNCTION_ALT_KEY = 62, 65 | SI_SYNC_FUNCTION_RESTORE_SENS = 63, 66 | SI_SYNC_FUNCTION_SPACE_KEY = 64, 67 | SI_SYNC_FUNCTION_CTRL_SHIFT_KEY = 65, 68 | SI_SYNC_FUNCTION_CTRL_ALT_KEY = 66, 69 | SI_SYNC_FUNCTION_SHIFT_ALT_KEY = 67, 70 | SI_SYNC_FUNCTION_TAB_KEY = 68, 71 | SI_SYNC_FUNCTION_RETURN_KEY = 69, 72 | SI_SYNC_FUNCTION_DEC_TRANS_SENS = 70, 73 | SI_SYNC_FUNCTION_INC_TRANS_SENS = 71, 74 | SI_SYNC_FUNCTION_DEC_ROT_SENS = 72, 75 | SI_SYNC_FUNCTION_INC_ROT_SENS = 73, 76 | SI_SYNC_FUNCTION_DEC_PAN_SENS = 74, 77 | SI_SYNC_FUNCTION_INC_PAN_SENS = 75, 78 | SI_SYNC_FUNCTION_DEC_ZOOM_SENS = 76, 79 | SI_SYNC_FUNCTION_INC_ZOOM_SENS = 77, 80 | SI_SYNC_FUNCTION_ESC_KEY = 78, 81 | SI_SYNC_FUNCTION_3DX_HELP = 94, 82 | SI_SYNC_FUNCTION_APP_HELP = 95, 83 | SI_SYNC_FUNCTION_DIALOG_TOGGLE_FN= 96, 84 | SI_SYNC_FUNCTION_FIT_FN = 97 85 | } SiSyncAbsFunctionNumber; 86 | 87 | 88 | /* 89 | * Sync Op Codes 90 | */ 91 | typedef enum 92 | { 93 | SI_SYNC_OP_COMMAND = 1, 94 | SI_SYNC_OP_GET = 2, 95 | SI_SYNC_OP_SET = 3 96 | } SiSyncOpCode; 97 | 98 | /* 99 | * Sync Item Codes 100 | */ 101 | typedef enum 102 | { 103 | SI_SYNC_ITEM_VERSION = 1, 104 | SI_SYNC_ITEM_QUERY = 2, 105 | SI_SYNC_ITEM_SAVE_CONFIG = 3, 106 | SI_SYNC_ITEM_NUMBER_OF_FUNCTIONS = 4, 107 | SI_SYNC_ITEM_FUNCTION = 5, 108 | SI_SYNC_ITEM_BUTTON_ASSIGNMENT = 6, 109 | SI_SYNC_ITEM_BUTTON_ASSIGNMENT_ABSOLUTE = 7, 110 | SI_SYNC_ITEM_BUTTON_NAME = 8, 111 | SI_SYNC_ITEM_AXIS_LABEL = 9, 112 | SI_SYNC_ITEM_ORIENTATION = 10, 113 | SI_SYNC_ITEM_FILTER = 11, 114 | SI_SYNC_ITEM_AXES_STATE = 12, 115 | SI_SYNC_ITEM_INFO_LINE = 13, 116 | SI_SYNC_ITEM_SCALE_OVERALL = 14, 117 | SI_SYNC_ITEM_SCALE_TX = 15, 118 | SI_SYNC_ITEM_SCALE_TY = 16, 119 | SI_SYNC_ITEM_SCALE_TZ = 17, 120 | SI_SYNC_ITEM_SCALE_RX = 18, 121 | SI_SYNC_ITEM_SCALE_RY = 19, 122 | SI_SYNC_ITEM_SCALE_RZ = 20, 123 | SI_SYNC_ITEM_INVOKE_ABSOLUTE_FUNCTION = 21, 124 | SI_SYNC_ITEM_BUTTON_STATE = 22 125 | } SiSyncItemCode; 126 | 127 | /* 128 | * Filters 129 | */ 130 | typedef enum 131 | { 132 | SI_SYNC_FILTER_TRANSLATIONS = 1, 133 | SI_SYNC_FILTER_ROTATIONS = 2, 134 | SI_SYNC_FILTER_DOMINANT = 3 135 | } SiSyncFilter; 136 | 137 | typedef enum 138 | { 139 | SI_SYNC_FILTER_OFF = 0, 140 | SI_SYNC_FILTER_ON = 1, 141 | SI_SYNC_FILTER_IN_BETWEEN = 2 142 | } SiSyncFilterValue; 143 | 144 | /* 145 | * Axes State 146 | */ 147 | typedef enum 148 | { 149 | SI_SYNC_AXES_STATE_TX = (1<<0), 150 | SI_SYNC_AXES_STATE_TY = (1<<1), 151 | SI_SYNC_AXES_STATE_TZ = (1<<2), 152 | SI_SYNC_AXES_STATE_RX = (1<<3), 153 | SI_SYNC_AXES_STATE_RY = (1<<4), 154 | SI_SYNC_AXES_STATE_RZ = (1<<5) 155 | } SiSyncAxesStateBits; 156 | 157 | typedef struct 158 | { 159 | int state; /* VURZYX (Tx = LSB (& 1<<0) */ 160 | } SiSyncAxesState; 161 | 162 | /* 163 | * Button State 164 | * For indicating the state of whatever the button sets (in the LCD at this point). 165 | * E.g., to show that Translations are currently OFF for the Translations Toggle button. 166 | * OFF: reverse video, flag is not set 167 | * ON: normal video, flag is set 168 | * DISABLED: (greyed), status of flag is invalid at this time 169 | */ 170 | typedef enum 171 | { 172 | SI_SYNC_BUTTON_STATE_OFF = 0, 173 | SI_SYNC_BUTTON_STATE_ON = 1, 174 | SI_SYNC_BUTTON_STATE_DISABLED = 2, 175 | } SiSyncButtonState; 176 | 177 | 178 | /* 179 | * Private / implementation structures 180 | * 181 | * We suggest you leave these hidden and use the accessor functions rather than 182 | * directly accessing the structures. 183 | */ 184 | #include "siSyncPriv.h" 185 | 186 | 187 | /* 188 | * Accessor Function headers 189 | */ 190 | SPWuint32 SiSyncGetSize(SiSyncPacket p); 191 | void SiSyncSetSize(SiSyncPacket *p, SPWuint32 size); 192 | 193 | SPWuint32 SiSyncGetHashCode(SiSyncPacket p); 194 | void SiSyncSetHashCode(SiSyncPacket *p, SPWuint32 hashCode); 195 | 196 | SiSyncOpCode SiSyncGetOpCode(SiSyncPacket p); 197 | void SiSyncSetOpCode(SiSyncPacket *p, SPWuint32 opCode); 198 | 199 | SiSyncItemCode SiSyncGetItemCode(SiSyncPacket p); 200 | void SiSyncSetItemCode(SiSyncPacket *p, SPWuint32 itemCode); 201 | 202 | #ifdef __cplusplus 203 | } 204 | #endif 205 | 206 | #endif /* _SI_SYNC_H_ */ 207 | -------------------------------------------------------------------------------- /src/win32/freeze.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * A library for storing parameters in the registry. 3 | * 4 | * Jonathan Westhues, 2002 5 | */ 6 | #include 7 | #include 8 | #include 9 | 10 | #define FREEZE_SUBKEY ---- 11 | #include "freeze.h" 12 | 13 | /* 14 | * store a window's position in the registry, or fail silently if the registry calls don't work 15 | */ 16 | void FreezeWindowPosF(HWND hwnd, const char *subKey, const char *name) 17 | { 18 | RECT r; 19 | GetWindowRect(hwnd, &r); 20 | 21 | HKEY software; 22 | if(RegOpenKeyEx(HKEY_CURRENT_USER, "Software", 0, KEY_ALL_ACCESS, &software) != ERROR_SUCCESS) 23 | return; 24 | 25 | char *keyName = (char *)malloc(strlen(name) + 30); 26 | if(!keyName) 27 | return; 28 | 29 | HKEY sub; 30 | if(RegCreateKeyEx(software, subKey, 0, (LPTSTR)"", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &sub, NULL) != ERROR_SUCCESS) 31 | return; 32 | 33 | sprintf(keyName, "%s_left", name); 34 | if(RegSetValueEx(sub, keyName, 0, REG_DWORD, (BYTE *)&(r.left), sizeof(DWORD)) != ERROR_SUCCESS) 35 | return; 36 | 37 | sprintf(keyName, "%s_right", name); 38 | if(RegSetValueEx(sub, keyName, 0, REG_DWORD, (BYTE *)&(r.right), sizeof(DWORD)) != ERROR_SUCCESS) 39 | return; 40 | 41 | sprintf(keyName, "%s_top", name); 42 | if(RegSetValueEx(sub, keyName, 0, REG_DWORD, (BYTE *)&(r.top), sizeof(DWORD)) != ERROR_SUCCESS) 43 | return; 44 | 45 | sprintf(keyName, "%s_bottom", name); 46 | if(RegSetValueEx(sub, keyName, 0, REG_DWORD, (BYTE *)&(r.bottom), sizeof(DWORD)) != ERROR_SUCCESS) 47 | return; 48 | 49 | sprintf(keyName, "%s_maximized", name); 50 | DWORD v = IsZoomed(hwnd); 51 | if(RegSetValueEx(sub, keyName, 0, REG_DWORD, (BYTE *)&(v), sizeof(DWORD)) != ERROR_SUCCESS) 52 | return; 53 | 54 | free(keyName); 55 | } 56 | 57 | static void Clamp(LONG *v, LONG min, LONG max) 58 | { 59 | if(*v < min) *v = min; 60 | if(*v > max) *v = max; 61 | } 62 | 63 | /* 64 | * retrieve a window's position from the registry, or do nothing if there is no info saved 65 | */ 66 | void ThawWindowPosF(HWND hwnd, const char *subKey, const char *name) 67 | { 68 | HKEY software; 69 | if(RegOpenKeyEx(HKEY_CURRENT_USER, "Software", 0, KEY_ALL_ACCESS, &software) != ERROR_SUCCESS) 70 | return; 71 | 72 | HKEY sub; 73 | if(RegOpenKeyEx(software, subKey, 0, KEY_ALL_ACCESS, &sub) != ERROR_SUCCESS) 74 | return; 75 | 76 | char *keyName = (char *)malloc(strlen(name) + 30); 77 | if(!keyName) 78 | return; 79 | 80 | DWORD l; 81 | RECT r; 82 | 83 | sprintf(keyName, "%s_left", name); 84 | l = sizeof(DWORD); 85 | if(RegQueryValueEx(sub, keyName, NULL, NULL, (BYTE *)&(r.left), &l) != ERROR_SUCCESS) 86 | return; 87 | 88 | sprintf(keyName, "%s_right", name); 89 | l = sizeof(DWORD); 90 | if(RegQueryValueEx(sub, keyName, NULL, NULL, (BYTE *)&(r.right), &l) != ERROR_SUCCESS) 91 | return; 92 | 93 | sprintf(keyName, "%s_top", name); 94 | l = sizeof(DWORD); 95 | if(RegQueryValueEx(sub, keyName, NULL, NULL, (BYTE *)&(r.top), &l) != ERROR_SUCCESS) 96 | return; 97 | 98 | sprintf(keyName, "%s_bottom", name); 99 | l = sizeof(DWORD); 100 | if(RegQueryValueEx(sub, keyName, NULL, NULL, (BYTE *)&(r.bottom), &l) != ERROR_SUCCESS) 101 | return; 102 | 103 | sprintf(keyName, "%s_maximized", name); 104 | DWORD v; 105 | l = sizeof(DWORD); 106 | if(RegQueryValueEx(sub, keyName, NULL, NULL, (BYTE *)&v, &l) != ERROR_SUCCESS) 107 | return; 108 | if(v) 109 | ShowWindow(hwnd, SW_MAXIMIZE); 110 | 111 | 112 | HMONITOR hMonitor; 113 | MONITORINFO mi; 114 | RECT dr; 115 | 116 | hMonitor = MonitorFromRect(&r, MONITOR_DEFAULTTONEAREST); 117 | 118 | mi.cbSize = sizeof(mi); 119 | GetMonitorInfo(hMonitor, &mi); 120 | dr = mi.rcMonitor; 121 | 122 | // If it somehow ended up off-screen, then put it back. 123 | Clamp(&(r.left), dr.left, dr.right); 124 | Clamp(&(r.right), dr.left, dr.right); 125 | Clamp(&(r.top), dr.top, dr.bottom); 126 | Clamp(&(r.bottom), dr.top, dr.bottom); 127 | if(r.right - r.left < 100) { 128 | r.left -= 300; r.right += 300; 129 | } 130 | if(r.bottom - r.top < 100) { 131 | r.top -= 300; r.bottom += 300; 132 | } 133 | Clamp(&(r.left), dr.left, dr.right); 134 | Clamp(&(r.right), dr.left, dr.right); 135 | Clamp(&(r.top), dr.top, dr.bottom); 136 | Clamp(&(r.bottom), dr.top, dr.bottom); 137 | 138 | MoveWindow(hwnd, r.left, r.top, r.right - r.left, r.bottom - r.top, TRUE); 139 | 140 | free(keyName); 141 | } 142 | 143 | /* 144 | * store a DWORD setting in the registry 145 | */ 146 | void FreezeDWORDF(DWORD val, const char *subKey, const char *name) 147 | { 148 | HKEY software; 149 | if(RegOpenKeyEx(HKEY_CURRENT_USER, "Software", 0, KEY_ALL_ACCESS, &software) != ERROR_SUCCESS) 150 | return; 151 | 152 | HKEY sub; 153 | if(RegCreateKeyEx(software, subKey, 0, (LPTSTR)"", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &sub, NULL) != ERROR_SUCCESS) 154 | return; 155 | 156 | if(RegSetValueEx(sub, name, 0, REG_DWORD, (BYTE *)&val, sizeof(DWORD)) != ERROR_SUCCESS) 157 | return; 158 | } 159 | 160 | /* 161 | * retrieve a DWORD setting, or return the default if that setting is unavailable 162 | */ 163 | DWORD ThawDWORDF(DWORD val, const char *subKey, const char *name) 164 | { 165 | HKEY software; 166 | if(RegOpenKeyEx(HKEY_CURRENT_USER, "Software", 0, KEY_ALL_ACCESS, &software) != ERROR_SUCCESS) 167 | return val; 168 | 169 | HKEY sub; 170 | if(RegOpenKeyEx(software, subKey, 0, KEY_ALL_ACCESS, &sub) != ERROR_SUCCESS) 171 | return val; 172 | 173 | DWORD l = sizeof(DWORD); 174 | DWORD v; 175 | if(RegQueryValueEx(sub, name, NULL, NULL, (BYTE *)&v, &l) != ERROR_SUCCESS) 176 | return val; 177 | 178 | return v; 179 | } 180 | 181 | /* 182 | * store a string setting in the registry 183 | */ 184 | void FreezeStringF(const char *val, const char *subKey, const char *name) 185 | { 186 | HKEY software; 187 | if(RegOpenKeyEx(HKEY_CURRENT_USER, "Software", 0, KEY_ALL_ACCESS, &software) != ERROR_SUCCESS) 188 | return; 189 | 190 | HKEY sub; 191 | if(RegCreateKeyEx(software, subKey, 0, (LPTSTR)"", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &sub, NULL) != ERROR_SUCCESS) 192 | return; 193 | 194 | if(RegSetValueEx(sub, name, 0, REG_SZ, (const BYTE *)val, (DWORD)strlen(val)+1) != ERROR_SUCCESS) 195 | return; 196 | } 197 | 198 | /* 199 | * retrieve a string setting, or return the default if that setting is unavailable 200 | */ 201 | void ThawStringF(char *val, int max, const char *subKey, const char *name) 202 | { 203 | HKEY software; 204 | if(RegOpenKeyEx(HKEY_CURRENT_USER, "Software", 0, KEY_ALL_ACCESS, &software) != ERROR_SUCCESS) 205 | return; 206 | 207 | HKEY sub; 208 | if(RegOpenKeyEx(software, subKey, 0, KEY_ALL_ACCESS, &sub) != ERROR_SUCCESS) 209 | return; 210 | 211 | DWORD l = max; 212 | if(RegQueryValueEx(sub, name, NULL, NULL, (BYTE *)val, &l) != ERROR_SUCCESS) 213 | return; 214 | if(l >= (DWORD)max) return; 215 | 216 | val[l] = '\0'; 217 | return; 218 | } 219 | 220 | -------------------------------------------------------------------------------- /src/request.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Implementation of our Request class; a request is a user-created thing 3 | // that will generate an entity (line, curve) when the sketch is generated, 4 | // in the same way that other entities are generated automatically, like 5 | // by an extrude or a step and repeat. 6 | // 7 | // Copyright 2008-2013 Jonathan Westhues. 8 | //----------------------------------------------------------------------------- 9 | #include "solvespace.h" 10 | 11 | const hRequest Request::HREQUEST_REFERENCE_XY = { 1 }; 12 | const hRequest Request::HREQUEST_REFERENCE_YZ = { 2 }; 13 | const hRequest Request::HREQUEST_REFERENCE_ZX = { 3 }; 14 | 15 | const EntReqTable::TableEntry EntReqTable::Table[] = { 16 | // request type entity type pts xtra? norml dist description 17 | { Request::WORKPLANE, Entity::WORKPLANE, 1, false, true, false, "workplane" }, 18 | { Request::DATUM_POINT, 0, 1, false, false, false, "datum-point" }, 19 | { Request::LINE_SEGMENT, Entity::LINE_SEGMENT, 2, false, false, false, "line-segment" }, 20 | { Request::CUBIC, Entity::CUBIC, 4, true, false, false, "cubic-bezier" }, 21 | { Request::CUBIC_PERIODIC, Entity::CUBIC_PERIODIC, 3, true, false, false, "periodic-cubic" }, 22 | { Request::CIRCLE, Entity::CIRCLE, 1, false, true, true, "circle" }, 23 | { Request::ARC_OF_CIRCLE, Entity::ARC_OF_CIRCLE, 3, false, true, false, "arc-of-circle" }, 24 | { Request::TTF_TEXT, Entity::TTF_TEXT, 2, false, true, false, "ttf-text" }, 25 | { 0, 0, 0, false, false, false, 0 }, 26 | }; 27 | 28 | const char *EntReqTable::DescriptionForRequest(int req) { 29 | for(int i = 0; Table[i].reqType; i++) { 30 | if(req == Table[i].reqType) { 31 | return Table[i].description; 32 | } 33 | } 34 | return "???"; 35 | } 36 | 37 | void EntReqTable::CopyEntityInfo(const TableEntry *te, int extraPoints, 38 | int *ent, int *req, int *pts, bool *hasNormal, bool *hasDistance) 39 | { 40 | int points = te->points; 41 | if(te->useExtraPoints) points += extraPoints; 42 | 43 | if(ent) *ent = te->entType; 44 | if(req) *req = te->reqType; 45 | if(pts) *pts = points; 46 | if(hasNormal) *hasNormal = te->hasNormal; 47 | if(hasDistance) *hasDistance = te->hasDistance; 48 | } 49 | 50 | bool EntReqTable::GetRequestInfo(int req, int extraPoints, 51 | int *ent, int *pts, bool *hasNormal, bool *hasDistance) 52 | { 53 | for(int i = 0; Table[i].reqType; i++) { 54 | const TableEntry *te = &(Table[i]); 55 | if(req == te->reqType) { 56 | CopyEntityInfo(te, extraPoints, 57 | ent, NULL, pts, hasNormal, hasDistance); 58 | return true; 59 | } 60 | } 61 | return false; 62 | } 63 | 64 | bool EntReqTable::GetEntityInfo(int ent, int extraPoints, 65 | int *req, int *pts, bool *hasNormal, bool *hasDistance) 66 | { 67 | for(int i = 0; Table[i].reqType; i++) { 68 | const TableEntry *te = &(Table[i]); 69 | if(ent == te->entType) { 70 | CopyEntityInfo(te, extraPoints, 71 | NULL, req, pts, hasNormal, hasDistance); 72 | return true; 73 | } 74 | } 75 | return false; 76 | } 77 | 78 | int EntReqTable::GetRequestForEntity(int ent) { 79 | int req = 0; 80 | GetEntityInfo(ent, 0, &req, NULL, NULL, NULL); 81 | return req; 82 | } 83 | 84 | 85 | void Request::Generate(IdList *entity, 86 | IdList *param) 87 | { 88 | int points = 0; 89 | int et = 0; 90 | bool hasNormal = false; 91 | bool hasDistance = false; 92 | int i; 93 | 94 | Entity e; 95 | ZERO(&e); 96 | EntReqTable::GetRequestInfo(type, extraPoints, 97 | &et, &points, &hasNormal, &hasDistance); 98 | 99 | // Generate the entity that's specific to this request. 100 | e.type = et; 101 | e.extraPoints = extraPoints; 102 | e.group = group; 103 | e.style = style; 104 | e.workplane = workplane; 105 | e.construction = construction; 106 | e.str.strcpy(str.str); 107 | e.font.strcpy(font.str); 108 | e.h = h.entity(0); 109 | 110 | // And generate entities for the points 111 | for(i = 0; i < points; i++) { 112 | Entity p; 113 | memset(&p, 0, sizeof(p)); 114 | p.workplane = workplane; 115 | // points start from entity 1, except for datum point case 116 | p.h = h.entity(i+(et ? 1 : 0)); 117 | p.group = group; 118 | p.style = style; 119 | 120 | if(workplane.v == Entity::FREE_IN_3D.v) { 121 | p.type = Entity::POINT_IN_3D; 122 | // params for x y z 123 | p.param[0] = AddParam(param, h.param(16 + 3*i + 0)); 124 | p.param[1] = AddParam(param, h.param(16 + 3*i + 1)); 125 | p.param[2] = AddParam(param, h.param(16 + 3*i + 2)); 126 | } else { 127 | p.type = Entity::POINT_IN_2D; 128 | // params for u v 129 | p.param[0] = AddParam(param, h.param(16 + 3*i + 0)); 130 | p.param[1] = AddParam(param, h.param(16 + 3*i + 1)); 131 | } 132 | entity->Add(&p); 133 | e.point[i] = p.h; 134 | } 135 | if(hasNormal) { 136 | Entity n; 137 | memset(&n, 0, sizeof(n)); 138 | n.workplane = workplane; 139 | n.h = h.entity(32); 140 | n.group = group; 141 | n.style = style; 142 | if(workplane.v == Entity::FREE_IN_3D.v) { 143 | n.type = Entity::NORMAL_IN_3D; 144 | n.param[0] = AddParam(param, h.param(32+0)); 145 | n.param[1] = AddParam(param, h.param(32+1)); 146 | n.param[2] = AddParam(param, h.param(32+2)); 147 | n.param[3] = AddParam(param, h.param(32+3)); 148 | } else { 149 | n.type = Entity::NORMAL_IN_2D; 150 | // and this is just a copy of the workplane quaternion, 151 | // so no params required 152 | } 153 | if(points < 1) oops(); 154 | // The point determines where the normal gets displayed on-screen; 155 | // it's entirely cosmetic. 156 | n.point[0] = e.point[0]; 157 | entity->Add(&n); 158 | e.normal = n.h; 159 | } 160 | if(hasDistance) { 161 | Entity d; 162 | memset(&d, 0, sizeof(d)); 163 | d.workplane = workplane; 164 | d.h = h.entity(64); 165 | d.group = group; 166 | d.style = style; 167 | d.type = Entity::DISTANCE; 168 | d.param[0] = AddParam(param, h.param(64)); 169 | entity->Add(&d); 170 | e.distance = d.h; 171 | } 172 | 173 | if(et) entity->Add(&e); 174 | } 175 | 176 | char *Request::DescriptionString(void) { 177 | const char *s; 178 | if(h.v == Request::HREQUEST_REFERENCE_XY.v) { 179 | s = "#XY"; 180 | } else if(h.v == Request::HREQUEST_REFERENCE_YZ.v) { 181 | s = "#YZ"; 182 | } else if(h.v == Request::HREQUEST_REFERENCE_ZX.v) { 183 | s = "#ZX"; 184 | } else { 185 | s = EntReqTable::DescriptionForRequest(type); 186 | } 187 | static char ret[100]; 188 | sprintf(ret, "r%03x-%s", h.v, s); 189 | return ret; 190 | } 191 | 192 | hParam Request::AddParam(IdList *param, hParam hp) { 193 | Param pa; 194 | memset(&pa, 0, sizeof(pa)); 195 | pa.h = hp; 196 | param->Add(&pa); 197 | return hp; 198 | } 199 | 200 | -------------------------------------------------------------------------------- /src/polygon.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Anything relating to plane polygons and triangles, and (generally, non- 3 | // planar) meshes thereof. 4 | // 5 | // Copyright 2008-2013 Jonathan Westhues. 6 | //----------------------------------------------------------------------------- 7 | 8 | #ifndef __POLYGON_H 9 | #define __POLYGON_H 10 | 11 | class SPointList; 12 | class SPolygon; 13 | class SContour; 14 | class SMesh; 15 | class SBsp3; 16 | 17 | class SEdge { 18 | public: 19 | int tag; 20 | int auxA, auxB; 21 | Vector a, b; 22 | 23 | static SEdge From(Vector a, Vector b); 24 | bool EdgeCrosses(Vector a, Vector b, Vector *pi=NULL, SPointList *spl=NULL); 25 | }; 26 | 27 | class SEdgeList { 28 | public: 29 | List l; 30 | 31 | void Clear(void); 32 | void AddEdge(Vector a, Vector b, int auxA=0, int auxB=0); 33 | bool AssemblePolygon(SPolygon *dest, SEdge *errorAt, bool keepDir=false); 34 | bool AssembleContour(Vector first, Vector last, SContour *dest, 35 | SEdge *errorAt, bool keepDir); 36 | int AnyEdgeCrossings(Vector a, Vector b, 37 | Vector *pi=NULL, SPointList *spl=NULL); 38 | bool ContainsEdgeFrom(SEdgeList *sel); 39 | bool ContainsEdge(SEdge *se); 40 | void CullExtraneousEdges(void); 41 | void MergeCollinearSegments(Vector a, Vector b); 42 | }; 43 | 44 | // A kd-tree element needs to go on a side of a node if it's when KDTREE_EPS 45 | // of the boundary. So increasing this number never breaks anything, but may 46 | // result in more duplicated elements. So it's conservative to be sloppy here. 47 | #define KDTREE_EPS (20*LENGTH_EPS) 48 | 49 | class SEdgeLl { 50 | public: 51 | SEdge *se; 52 | SEdgeLl *next; 53 | 54 | static SEdgeLl *Alloc(void); 55 | }; 56 | 57 | class SKdNodeEdges { 58 | public: 59 | int which; // whether c is x, y, or z 60 | double c; 61 | SKdNodeEdges *gt; 62 | SKdNodeEdges *lt; 63 | 64 | SEdgeLl *edges; 65 | 66 | static SKdNodeEdges *From(SEdgeList *sel); 67 | static SKdNodeEdges *From(SEdgeLl *sell); 68 | static SKdNodeEdges *Alloc(void); 69 | int AnyEdgeCrossings(Vector a, Vector b, int cnt, 70 | Vector *pi=NULL, SPointList *spl=NULL); 71 | }; 72 | 73 | class SPoint { 74 | public: 75 | int tag; 76 | 77 | enum { 78 | UNKNOWN = 0, 79 | NOT_EAR = 1, 80 | EAR = 2 81 | }; 82 | int ear; 83 | 84 | Vector p; 85 | Vector auxv; 86 | }; 87 | 88 | class SPointList { 89 | public: 90 | List l; 91 | 92 | void Clear(void); 93 | bool ContainsPoint(Vector pt); 94 | int IndexForPoint(Vector pt); 95 | void IncrementTagFor(Vector pt); 96 | void Add(Vector pt); 97 | }; 98 | 99 | class SContour { 100 | public: 101 | int tag; 102 | int timesEnclosed; 103 | Vector xminPt; 104 | List l; 105 | 106 | void AddPoint(Vector p); 107 | void MakeEdgesInto(SEdgeList *el); 108 | void Reverse(void); 109 | Vector ComputeNormal(void); 110 | double SignedAreaProjdToNormal(Vector n); 111 | bool IsClockwiseProjdToNormal(Vector n); 112 | bool ContainsPointProjdToNormal(Vector n, Vector p); 113 | void OffsetInto(SContour *dest, double r); 114 | void CopyInto(SContour *dest); 115 | void FindPointWithMinX(void); 116 | Vector AnyEdgeMidpoint(void); 117 | 118 | bool IsEar(int bp, double scaledEps); 119 | bool BridgeToContour(SContour *sc, SEdgeList *el, List *vl); 120 | void ClipEarInto(SMesh *m, int bp, double scaledEps); 121 | void UvTriangulateInto(SMesh *m, SSurface *srf); 122 | }; 123 | 124 | typedef struct { 125 | uint32_t face; 126 | RgbaColor color; 127 | } STriMeta; 128 | 129 | class SPolygon { 130 | public: 131 | List l; 132 | Vector normal; 133 | 134 | Vector ComputeNormal(void); 135 | void AddEmptyContour(void); 136 | int WindingNumberForPoint(Vector p); 137 | double SignedArea(void); 138 | bool ContainsPoint(Vector p); 139 | void MakeEdgesInto(SEdgeList *el); 140 | void FixContourDirections(void); 141 | void Clear(void); 142 | bool SelfIntersecting(Vector *intersectsAt); 143 | bool IsEmpty(void); 144 | Vector AnyPoint(void); 145 | void OffsetInto(SPolygon *dest, double r); 146 | void UvTriangulateInto(SMesh *m, SSurface *srf); 147 | void UvGridTriangulateInto(SMesh *m, SSurface *srf); 148 | }; 149 | 150 | class STriangle { 151 | public: 152 | int tag; 153 | STriMeta meta; 154 | Vector a, b, c; 155 | Vector an, bn, cn; 156 | 157 | static STriangle From(STriMeta meta, Vector a, Vector b, Vector c); 158 | Vector Normal(void); 159 | void FlipNormal(void); 160 | double MinAltitude(void); 161 | int WindingNumberForPoint(Vector p); 162 | bool ContainsPoint(Vector p); 163 | bool ContainsPointProjd(Vector n, Vector p); 164 | }; 165 | 166 | class SBsp2 { 167 | public: 168 | Vector np; // normal to the plane 169 | 170 | Vector no; // outer normal to the edge 171 | double d; 172 | SEdge edge; 173 | 174 | SBsp2 *pos; 175 | SBsp2 *neg; 176 | 177 | SBsp2 *more; 178 | 179 | enum { POS = 100, NEG = 101, COPLANAR = 200 }; 180 | void InsertTriangleHow(int how, STriangle *tr, SMesh *m, SBsp3 *bsp3); 181 | void InsertTriangle(STriangle *tr, SMesh *m, SBsp3 *bsp3); 182 | Vector IntersectionWith(Vector a, Vector b); 183 | SBsp2 *InsertEdge(SEdge *nedge, Vector nnp, Vector out); 184 | static SBsp2 *Alloc(void); 185 | 186 | void DebugDraw(Vector n, double d); 187 | }; 188 | 189 | class SBsp3 { 190 | public: 191 | Vector n; 192 | double d; 193 | 194 | STriangle tri; 195 | SBsp3 *pos; 196 | SBsp3 *neg; 197 | 198 | SBsp3 *more; 199 | 200 | SBsp2 *edges; 201 | 202 | static SBsp3 *Alloc(void); 203 | static SBsp3 *FromMesh(SMesh *m); 204 | 205 | Vector IntersectionWith(Vector a, Vector b); 206 | 207 | enum { POS = 100, NEG = 101, COPLANAR = 200 }; 208 | void InsertHow(int how, STriangle *str, SMesh *instead); 209 | SBsp3 *Insert(STriangle *str, SMesh *instead); 210 | 211 | void InsertConvexHow(int how, STriMeta meta, Vector *vertex, int n, 212 | SMesh *instead); 213 | SBsp3 *InsertConvex(STriMeta meta, Vector *vertex, int n, SMesh *instead); 214 | 215 | void InsertInPlane(bool pos2, STriangle *tr, SMesh *m); 216 | 217 | void GenerateInPaintOrder(SMesh *m); 218 | 219 | void DebugDraw(void); 220 | }; 221 | 222 | class SMesh { 223 | public: 224 | List l; 225 | 226 | bool flipNormal; 227 | bool keepCoplanar; 228 | bool atLeastOneDiscarded; 229 | bool isTransparent; 230 | 231 | void Clear(void); 232 | void AddTriangle(STriangle *st); 233 | void AddTriangle(STriMeta meta, Vector a, Vector b, Vector c); 234 | void AddTriangle(STriMeta meta, Vector n, Vector a, Vector b, Vector c); 235 | void DoBounding(Vector v, Vector *vmax, Vector *vmin); 236 | void GetBounding(Vector *vmax, Vector *vmin); 237 | 238 | void Simplify(int start); 239 | 240 | void AddAgainstBsp(SMesh *srcm, SBsp3 *bsp3); 241 | void MakeFromUnionOf(SMesh *a, SMesh *b); 242 | void MakeFromDifferenceOf(SMesh *a, SMesh *b); 243 | 244 | void MakeFromCopyOf(SMesh *a); 245 | void MakeFromTransformationOf(SMesh *a, 246 | Vector trans, Quaternion q, double scale); 247 | void MakeFromAssemblyOf(SMesh *a, SMesh *b); 248 | 249 | void MakeEdgesInPlaneInto(SEdgeList *sel, Vector n, double d); 250 | void MakeEmphasizedEdgesInto(SEdgeList *sel); 251 | 252 | bool IsEmpty(void); 253 | void RemapFaces(Group *g, int remap); 254 | 255 | uint32_t FirstIntersectionWith(Point2d mp); 256 | }; 257 | 258 | // A linked list of triangles 259 | class STriangleLl { 260 | public: 261 | STriangle *tri; 262 | 263 | STriangleLl *next; 264 | 265 | static STriangleLl *Alloc(void); 266 | }; 267 | 268 | class SKdNode { 269 | public: 270 | int which; // whether c is x, y, or z 271 | double c; 272 | 273 | SKdNode *gt; 274 | SKdNode *lt; 275 | 276 | STriangleLl *tris; 277 | 278 | static SKdNode *Alloc(void); 279 | static SKdNode *From(SMesh *m); 280 | static SKdNode *From(STriangleLl *tll); 281 | 282 | void AddTriangle(STriangle *tr); 283 | void MakeMeshInto(SMesh *m); 284 | void ClearTags(void); 285 | 286 | void FindEdgeOn(Vector a, Vector b, int *n, int cnt, bool coplanarIsInter, 287 | bool *inter, bool *fwd, 288 | uint32_t *face); 289 | enum { 290 | NAKED_OR_SELF_INTER_EDGES = 100, 291 | SELF_INTER_EDGES = 200, 292 | TURNING_EDGES = 300, 293 | EMPHASIZED_EDGES = 400 294 | }; 295 | void MakeCertainEdgesInto(SEdgeList *sel, int how, bool coplanarIsInter, 296 | bool *inter, bool *leaky); 297 | 298 | void OcclusionTestLine(SEdge orig, SEdgeList *sel, int cnt); 299 | void SplitLinesAgainstTriangle(SEdgeList *sel, STriangle *tr); 300 | 301 | void SnapToMesh(SMesh *m); 302 | void SnapToVertex(Vector v, SMesh *extras); 303 | }; 304 | 305 | #endif 306 | 307 | -------------------------------------------------------------------------------- /src/lib.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // A library wrapper around SolveSpace, to permit someone to use its constraint 3 | // solver without coupling their program too much to SolveSpace's internals. 4 | // 5 | // Copyright 2008-2013 Jonathan Westhues. 6 | //----------------------------------------------------------------------------- 7 | #include "solvespace.h" 8 | #define EXPORT_DLL 9 | #include 10 | 11 | Sketch SolveSpace::SK; 12 | static System SYS; 13 | 14 | static int IsInit = 0; 15 | 16 | void Group::GenerateEquations(IdList *l) { 17 | // Nothing to do for now. 18 | } 19 | 20 | void SolveSpace::CnfFreezeInt(uint32_t v, const char *name) 21 | { 22 | abort(); 23 | } 24 | 25 | uint32_t SolveSpace::CnfThawInt(uint32_t v, const char *name) 26 | { 27 | abort(); 28 | return 0; 29 | } 30 | 31 | void SolveSpace::DoMessageBox(const char *str, int rows, int cols, bool error) 32 | { 33 | abort(); 34 | } 35 | 36 | extern "C" { 37 | 38 | void Slvs_QuaternionU(double qw, double qx, double qy, double qz, 39 | double *x, double *y, double *z) 40 | { 41 | Quaternion q = Quaternion::From(qw, qx, qy, qz); 42 | Vector v = q.RotationU(); 43 | *x = v.x; 44 | *y = v.y; 45 | *z = v.z; 46 | } 47 | 48 | void Slvs_QuaternionV(double qw, double qx, double qy, double qz, 49 | double *x, double *y, double *z) 50 | { 51 | Quaternion q = Quaternion::From(qw, qx, qy, qz); 52 | Vector v = q.RotationV(); 53 | *x = v.x; 54 | *y = v.y; 55 | *z = v.z; 56 | } 57 | 58 | void Slvs_QuaternionN(double qw, double qx, double qy, double qz, 59 | double *x, double *y, double *z) 60 | { 61 | Quaternion q = Quaternion::From(qw, qx, qy, qz); 62 | Vector v = q.RotationN(); 63 | *x = v.x; 64 | *y = v.y; 65 | *z = v.z; 66 | } 67 | 68 | void Slvs_MakeQuaternion(double ux, double uy, double uz, 69 | double vx, double vy, double vz, 70 | double *qw, double *qx, double *qy, double *qz) 71 | { 72 | Vector u = Vector::From(ux, uy, uz), 73 | v = Vector::From(vx, vy, vz); 74 | Quaternion q = Quaternion::From(u, v); 75 | *qw = q.w; 76 | *qx = q.vx; 77 | *qy = q.vy; 78 | *qz = q.vz; 79 | } 80 | 81 | void Slvs_Solve(Slvs_System *ssys, Slvs_hGroup shg) 82 | { 83 | if(!IsInit) { 84 | InitHeaps(); 85 | IsInit = 1; 86 | } 87 | 88 | int i; 89 | for(i = 0; i < ssys->params; i++) { 90 | Slvs_Param *sp = &(ssys->param[i]); 91 | Param p; 92 | ZERO(&p); 93 | 94 | p.h.v = sp->h; 95 | p.val = sp->val; 96 | SK.param.Add(&p); 97 | if(sp->group == shg) { 98 | SYS.param.Add(&p); 99 | } 100 | } 101 | 102 | for(i = 0; i < ssys->entities; i++) { 103 | Slvs_Entity *se = &(ssys->entity[i]); 104 | EntityBase e; 105 | ZERO(&e); 106 | 107 | switch(se->type) { 108 | case SLVS_E_POINT_IN_3D: e.type = Entity::POINT_IN_3D; break; 109 | case SLVS_E_POINT_IN_2D: e.type = Entity::POINT_IN_2D; break; 110 | case SLVS_E_NORMAL_IN_3D: e.type = Entity::NORMAL_IN_3D; break; 111 | case SLVS_E_NORMAL_IN_2D: e.type = Entity::NORMAL_IN_2D; break; 112 | case SLVS_E_DISTANCE: e.type = Entity::DISTANCE; break; 113 | case SLVS_E_WORKPLANE: e.type = Entity::WORKPLANE; break; 114 | case SLVS_E_LINE_SEGMENT: e.type = Entity::LINE_SEGMENT; break; 115 | case SLVS_E_CUBIC: e.type = Entity::CUBIC; break; 116 | case SLVS_E_CIRCLE: e.type = Entity::CIRCLE; break; 117 | case SLVS_E_ARC_OF_CIRCLE: e.type = Entity::ARC_OF_CIRCLE; break; 118 | 119 | default: dbp("bad entity type %d", se->type); return; 120 | } 121 | e.h.v = se->h; 122 | e.group.v = se->group; 123 | e.workplane.v = se->wrkpl; 124 | e.point[0].v = se->point[0]; 125 | e.point[1].v = se->point[1]; 126 | e.point[2].v = se->point[2]; 127 | e.point[3].v = se->point[3]; 128 | e.normal.v = se->normal; 129 | e.distance.v = se->distance; 130 | e.param[0].v = se->param[0]; 131 | e.param[1].v = se->param[1]; 132 | e.param[2].v = se->param[2]; 133 | e.param[3].v = se->param[3]; 134 | 135 | SK.entity.Add(&e); 136 | } 137 | 138 | for(i = 0; i < ssys->constraints; i++) { 139 | Slvs_Constraint *sc = &(ssys->constraint[i]); 140 | ConstraintBase c; 141 | ZERO(&c); 142 | 143 | int t; 144 | switch(sc->type) { 145 | case SLVS_C_POINTS_COINCIDENT: t = Constraint::POINTS_COINCIDENT; break; 146 | case SLVS_C_PT_PT_DISTANCE: t = Constraint::PT_PT_DISTANCE; break; 147 | case SLVS_C_PT_PLANE_DISTANCE: t = Constraint::PT_PLANE_DISTANCE; break; 148 | case SLVS_C_PT_LINE_DISTANCE: t = Constraint::PT_LINE_DISTANCE; break; 149 | case SLVS_C_PT_FACE_DISTANCE: t = Constraint::PT_FACE_DISTANCE; break; 150 | case SLVS_C_PT_IN_PLANE: t = Constraint::PT_IN_PLANE; break; 151 | case SLVS_C_PT_ON_LINE: t = Constraint::PT_ON_LINE; break; 152 | case SLVS_C_PT_ON_FACE: t = Constraint::PT_ON_FACE; break; 153 | case SLVS_C_EQUAL_LENGTH_LINES: t = Constraint::EQUAL_LENGTH_LINES; break; 154 | case SLVS_C_LENGTH_RATIO: t = Constraint::LENGTH_RATIO; break; 155 | case SLVS_C_EQ_LEN_PT_LINE_D: t = Constraint::EQ_LEN_PT_LINE_D; break; 156 | case SLVS_C_EQ_PT_LN_DISTANCES: t = Constraint::EQ_PT_LN_DISTANCES; break; 157 | case SLVS_C_EQUAL_ANGLE: t = Constraint::EQUAL_ANGLE; break; 158 | case SLVS_C_EQUAL_LINE_ARC_LEN: t = Constraint::EQUAL_LINE_ARC_LEN; break; 159 | case SLVS_C_SYMMETRIC: t = Constraint::SYMMETRIC; break; 160 | case SLVS_C_SYMMETRIC_HORIZ: t = Constraint::SYMMETRIC_HORIZ; break; 161 | case SLVS_C_SYMMETRIC_VERT: t = Constraint::SYMMETRIC_VERT; break; 162 | case SLVS_C_SYMMETRIC_LINE: t = Constraint::SYMMETRIC_LINE; break; 163 | case SLVS_C_AT_MIDPOINT: t = Constraint::AT_MIDPOINT; break; 164 | case SLVS_C_HORIZONTAL: t = Constraint::HORIZONTAL; break; 165 | case SLVS_C_VERTICAL: t = Constraint::VERTICAL; break; 166 | case SLVS_C_DIAMETER: t = Constraint::DIAMETER; break; 167 | case SLVS_C_PT_ON_CIRCLE: t = Constraint::PT_ON_CIRCLE; break; 168 | case SLVS_C_SAME_ORIENTATION: t = Constraint::SAME_ORIENTATION; break; 169 | case SLVS_C_ANGLE: t = Constraint::ANGLE; break; 170 | case SLVS_C_PARALLEL: t = Constraint::PARALLEL; break; 171 | case SLVS_C_PERPENDICULAR: t = Constraint::PERPENDICULAR; break; 172 | case SLVS_C_ARC_LINE_TANGENT: t = Constraint::ARC_LINE_TANGENT; break; 173 | case SLVS_C_CUBIC_LINE_TANGENT: t = Constraint::CUBIC_LINE_TANGENT; break; 174 | case SLVS_C_EQUAL_RADIUS: t = Constraint::EQUAL_RADIUS; break; 175 | case SLVS_C_PROJ_PT_DISTANCE: t = Constraint::PROJ_PT_DISTANCE; break; 176 | case SLVS_C_WHERE_DRAGGED: t = Constraint::WHERE_DRAGGED; break; 177 | case SLVS_C_CURVE_CURVE_TANGENT:t = Constraint::CURVE_CURVE_TANGENT; break; 178 | 179 | default: dbp("bad constraint type %d", sc->type); return; 180 | } 181 | 182 | c.type = t; 183 | 184 | c.h.v = sc->h; 185 | c.group.v = sc->group; 186 | c.workplane.v = sc->wrkpl; 187 | c.valA = sc->valA; 188 | c.ptA.v = sc->ptA; 189 | c.ptB.v = sc->ptB; 190 | c.entityA.v = sc->entityA; 191 | c.entityB.v = sc->entityB; 192 | c.entityC.v = sc->entityC; 193 | c.entityD.v = sc->entityD; 194 | c.other = (sc->other) ? true : false; 195 | c.other2 = (sc->other2) ? true : false; 196 | 197 | SK.constraint.Add(&c); 198 | } 199 | 200 | for(i = 0; i < (int)arraylen(ssys->dragged); i++) { 201 | if(ssys->dragged[i]) { 202 | hParam hp = { ssys->dragged[i] }; 203 | SYS.dragged.Add(&hp); 204 | } 205 | } 206 | 207 | Group g; 208 | ZERO(&g); 209 | g.h.v = shg; 210 | 211 | List bad; 212 | ZERO(&bad); 213 | 214 | // Now we're finally ready to solve! 215 | bool andFindBad = ssys->calculateFaileds ? true : false; 216 | int how = SYS.Solve(&g, &(ssys->dof), &bad, andFindBad, false); 217 | 218 | switch(how) { 219 | case System::SOLVED_OKAY: 220 | ssys->result = SLVS_RESULT_OKAY; 221 | break; 222 | 223 | case System::DIDNT_CONVERGE: 224 | ssys->result = SLVS_RESULT_DIDNT_CONVERGE; 225 | break; 226 | 227 | case System::SINGULAR_JACOBIAN: 228 | ssys->result = SLVS_RESULT_INCONSISTENT; 229 | break; 230 | 231 | case System::TOO_MANY_UNKNOWNS: 232 | ssys->result = SLVS_RESULT_TOO_MANY_UNKNOWNS; 233 | break; 234 | 235 | default: oops(); 236 | } 237 | 238 | // Write the new parameter values back to our caller. 239 | for(i = 0; i < ssys->params; i++) { 240 | Slvs_Param *sp = &(ssys->param[i]); 241 | hParam hp = { sp->h }; 242 | sp->val = SK.GetParam(hp)->val; 243 | } 244 | 245 | if(ssys->failed) { 246 | // Copy over any the list of problematic constraints. 247 | for(i = 0; i < ssys->faileds && i < bad.n; i++) { 248 | ssys->failed[i] = bad.elem[i].v; 249 | } 250 | ssys->faileds = bad.n; 251 | } 252 | 253 | bad.Clear(); 254 | SYS.param.Clear(); 255 | SYS.entity.Clear(); 256 | SYS.eq.Clear(); 257 | SYS.dragged.Clear(); 258 | 259 | SK.param.Clear(); 260 | SK.entity.Clear(); 261 | SK.constraint.Clear(); 262 | 263 | FreeAllTemporary(); 264 | } 265 | 266 | } /* extern "C" */ 267 | -------------------------------------------------------------------------------- /src/toolbar.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // The toolbar that appears at the top left of the graphics window, where the 3 | // user can select icons with the mouse, to perform operations equivalent to 4 | // selecting a menu item or using a keyboard shortcut. 5 | // 6 | // Copyright 2008-2013 Jonathan Westhues. 7 | //----------------------------------------------------------------------------- 8 | #include "solvespace.h" 9 | #include 10 | #include 11 | 12 | static uint8_t SPACER[1]; 13 | static const struct { 14 | uint8_t *image; 15 | int menu; 16 | const char *tip; 17 | } Toolbar[] = { 18 | { Icon_line, GraphicsWindow::MNU_LINE_SEGMENT, "Sketch line segment" }, 19 | { Icon_rectangle, GraphicsWindow::MNU_RECTANGLE, "Sketch rectangle" }, 20 | { Icon_circle, GraphicsWindow::MNU_CIRCLE, "Sketch circle" }, 21 | { Icon_arc, GraphicsWindow::MNU_ARC, "Sketch arc of a circle" }, 22 | { Icon_text, GraphicsWindow::MNU_TTF_TEXT, "Sketch curves from text in a TrueType font" }, 23 | { Icon_tangent_arc, GraphicsWindow::MNU_TANGENT_ARC, "Create tangent arc at selected point" }, 24 | { Icon_bezier, GraphicsWindow::MNU_CUBIC, "Sketch cubic Bezier spline" }, 25 | { Icon_point, GraphicsWindow::MNU_DATUM_POINT, "Sketch datum point" }, 26 | { Icon_construction, GraphicsWindow::MNU_CONSTRUCTION, "Toggle construction" }, 27 | { Icon_trim, GraphicsWindow::MNU_SPLIT_CURVES, "Split lines / curves where they intersect" }, 28 | { SPACER, 0, 0 }, 29 | 30 | { Icon_length, GraphicsWindow::MNU_DISTANCE_DIA, "Constrain distance / diameter / length" }, 31 | { Icon_angle, GraphicsWindow::MNU_ANGLE, "Constrain angle" }, 32 | { Icon_horiz, GraphicsWindow::MNU_HORIZONTAL, "Constrain to be horizontal" }, 33 | { Icon_vert, GraphicsWindow::MNU_VERTICAL, "Constrain to be vertical" }, 34 | { Icon_parallel, GraphicsWindow::MNU_PARALLEL, "Constrain to be parallel or tangent" }, 35 | { Icon_perpendicular, GraphicsWindow::MNU_PERPENDICULAR, "Constrain to be perpendicular" }, 36 | { Icon_pointonx, GraphicsWindow::MNU_ON_ENTITY, "Constrain point on line / curve / plane / point" }, 37 | { Icon_symmetric, GraphicsWindow::MNU_SYMMETRIC, "Constrain symmetric" }, 38 | { Icon_equal, GraphicsWindow::MNU_EQUAL, "Constrain equal length / radius / angle" }, 39 | { Icon_same_orientation,GraphicsWindow::MNU_ORIENTED_SAME, "Constrain normals in same orientation" }, 40 | { Icon_other_supp, GraphicsWindow::MNU_OTHER_ANGLE, "Other supplementary angle" }, 41 | { Icon_ref, GraphicsWindow::MNU_REFERENCE, "Toggle reference dimension" }, 42 | { SPACER, 0, 0 }, 43 | 44 | { Icon_extrude, GraphicsWindow::MNU_GROUP_EXTRUDE, "New group extruding active sketch" }, 45 | { Icon_sketch_in_plane, GraphicsWindow::MNU_GROUP_WRKPL, "New group in new workplane (thru given entities)" }, 46 | { Icon_step_rotate, GraphicsWindow::MNU_GROUP_ROT, "New group step and repeat rotating" }, 47 | { Icon_step_translate, GraphicsWindow::MNU_GROUP_TRANS, "New group step and repeat translating" }, 48 | { Icon_sketch_in_3d, GraphicsWindow::MNU_GROUP_3D, "New group in 3d" }, 49 | { Icon_assemble, GraphicsWindow::MNU_GROUP_IMPORT, "New group importing / assembling file" }, 50 | { SPACER, 0, 0 }, 51 | 52 | { Icon_in3d, GraphicsWindow::MNU_NEAREST_ISO, "Nearest isometric view" }, 53 | { Icon_ontoworkplane, GraphicsWindow::MNU_ONTO_WORKPLANE, "Align view to active workplane" }, 54 | { NULL, 0, 0 } 55 | }; 56 | 57 | void GraphicsWindow::ToolbarDraw(void) { 58 | ToolbarDrawOrHitTest(0, 0, true, NULL); 59 | } 60 | 61 | bool GraphicsWindow::ToolbarMouseMoved(int x, int y) { 62 | x += ((int)width/2); 63 | y += ((int)height/2); 64 | 65 | int nh = 0; 66 | bool withinToolbar = ToolbarDrawOrHitTest(x, y, false, &nh); 67 | if(!withinToolbar) nh = 0; 68 | 69 | if(nh != toolbarTooltipped) { 70 | // Don't let the tool tip move around if the mouse moves within the 71 | // same item. 72 | toolbarMouseX = x; 73 | toolbarMouseY = y; 74 | toolbarTooltipped = 0; 75 | } 76 | 77 | if(nh != toolbarHovered) { 78 | toolbarHovered = nh; 79 | SetTimerFor(1000); 80 | PaintGraphics(); 81 | } 82 | // So if we moved off the toolbar, then toolbarHovered is now equal to 83 | // zero, so it doesn't matter if the tool tip timer expires. And if 84 | // we moved from one item to another, we reset the timer, so also okay. 85 | return withinToolbar; 86 | } 87 | 88 | bool GraphicsWindow::ToolbarMouseDown(int x, int y) { 89 | x += ((int)width/2); 90 | y += ((int)height/2); 91 | 92 | int nh = -1; 93 | bool withinToolbar = ToolbarDrawOrHitTest(x, y, false, &nh); 94 | // They might have clicked within the toolbar, but not on a button. 95 | if(withinToolbar && nh >= 0) { 96 | for(int i = 0; SS.GW.menu[i].level >= 0; i++) { 97 | if(nh == SS.GW.menu[i].id) { 98 | (SS.GW.menu[i].fn)((GraphicsWindow::MenuId)SS.GW.menu[i].id); 99 | break; 100 | } 101 | } 102 | } 103 | return withinToolbar; 104 | } 105 | 106 | bool GraphicsWindow::ToolbarDrawOrHitTest(int mx, int my, 107 | bool paint, int *menuHit) 108 | { 109 | int i; 110 | int x = 17, y = (int)(height - 52); 111 | 112 | int fudge = 8; 113 | int h = 32*15 + 3*16 + fudge; 114 | int aleft = 0, aright = 66, atop = y+16+fudge/2, abot = y+16-h; 115 | 116 | bool withinToolbar = 117 | (mx >= aleft && mx <= aright && my <= atop && my >= abot); 118 | 119 | if(!paint && !withinToolbar) { 120 | // This gets called every MouseMove event, so return quickly. 121 | return false; 122 | } 123 | 124 | if(paint) { 125 | glMatrixMode(GL_MODELVIEW); 126 | glLoadIdentity(); 127 | glMatrixMode(GL_PROJECTION); 128 | glLoadIdentity(); 129 | glTranslated(-1, -1, 0); 130 | glScaled(2.0/width, 2.0/height, 0); 131 | glDisable(GL_LIGHTING); 132 | 133 | double c = 30.0/255; 134 | glColor4d(c, c, c, 1.0); 135 | ssglAxisAlignedQuad(aleft, aright, atop, abot); 136 | } 137 | 138 | struct { 139 | bool show; 140 | const char *str; 141 | } toolTip = { false, NULL }; 142 | 143 | bool leftpos = true; 144 | for(i = 0; Toolbar[i].image; i++) { 145 | if(Toolbar[i].image == SPACER) { 146 | if(!leftpos) { 147 | leftpos = true; 148 | y -= 32; 149 | x -= 32; 150 | } 151 | y -= 16; 152 | 153 | if(paint) { 154 | // Draw a separator bar in a slightly different color. 155 | int divw = 30, divh = 2; 156 | glColor4d(0.17, 0.17, 0.17, 1); 157 | x += 16; 158 | y += 24; 159 | ssglAxisAlignedQuad(x+divw, x-divw, y+divh, y-divh); 160 | x -= 16; 161 | y -= 24; 162 | } 163 | 164 | continue; 165 | } 166 | 167 | if(paint) { 168 | glRasterPos2i(x - 12, y - 12); 169 | glDrawPixels(24, 24, GL_RGB, GL_UNSIGNED_BYTE, Toolbar[i].image); 170 | 171 | if(toolbarHovered == Toolbar[i].menu || 172 | pending.operation == Toolbar[i].menu) { 173 | // Highlight the hovered or pending item. 174 | glColor4d(1, 1, 0, 0.3); 175 | int boxhw = 15; 176 | ssglAxisAlignedQuad(x+boxhw, x-boxhw, y+boxhw, y-boxhw); 177 | } 178 | 179 | if(toolbarTooltipped == Toolbar[i].menu) { 180 | // Display the tool tip for this item; postpone till later 181 | // so that no one draws over us. Don't need position since 182 | // that's just wherever the mouse is. 183 | toolTip.show = true; 184 | toolTip.str = Toolbar[i].tip; 185 | } 186 | } else { 187 | int boxhw = 16; 188 | if(mx < (x+boxhw) && mx > (x - boxhw) && 189 | my < (y+boxhw) && my > (y - boxhw)) 190 | { 191 | if(menuHit) *menuHit = Toolbar[i].menu; 192 | } 193 | } 194 | 195 | if(leftpos) { 196 | x += 32; 197 | leftpos = false; 198 | } else { 199 | x -= 32; 200 | y -= 32; 201 | leftpos = true; 202 | } 203 | } 204 | 205 | if(paint) { 206 | // Do this last so that nothing can draw over it. 207 | if(toolTip.show) { 208 | ssglCreateBitmapFont(); 209 | char str[1024]; 210 | if(strlen(toolTip.str) >= 200) oops(); 211 | strcpy(str, toolTip.str); 212 | 213 | for(i = 0; SS.GW.menu[i].level >= 0; i++) { 214 | if(toolbarTooltipped == SS.GW.menu[i].id) { 215 | char accelbuf[40]; 216 | if(MakeAcceleratorLabel(SS.GW.menu[i].accel, accelbuf)) { 217 | sprintf(str+strlen(str), " (%s)", accelbuf); 218 | } 219 | break; 220 | } 221 | } 222 | 223 | int tw = (int)strlen(str)*SS.TW.CHAR_WIDTH + 10, 224 | th = SS.TW.LINE_HEIGHT + 2; 225 | 226 | double ox = toolbarMouseX + 3, oy = toolbarMouseY + 3; 227 | glLineWidth(1); 228 | glColor4d(1.0, 1.0, 0.6, 1.0); 229 | ssglAxisAlignedQuad(ox, ox+tw, oy, oy+th); 230 | glColor4d(0.0, 0.0, 0.0, 1.0); 231 | ssglAxisAlignedLineLoop(ox, ox+tw, oy, oy+th); 232 | 233 | glColor4d(0, 0, 0, 1); 234 | glPushMatrix(); 235 | glTranslated(ox+5, oy+3, 0); 236 | glScaled(1, -1, 1); 237 | ssglBitmapText(str, Vector::From(0, 0, 0)); 238 | glPopMatrix(); 239 | } 240 | ssglDepthRangeLockToFront(false); 241 | } 242 | 243 | return withinToolbar; 244 | } 245 | 246 | void GraphicsWindow::TimerCallback(void) { 247 | SS.GW.toolbarTooltipped = SS.GW.toolbarHovered; 248 | PaintGraphics(); 249 | } 250 | 251 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # global 2 | 3 | include_directories( 4 | ${OPENGL_INCLUDE_DIR} 5 | ${PNG_INCLUDE_DIRS}) 6 | 7 | link_directories( 8 | ${PNG_LIBRARY_DIRS}) 9 | 10 | add_definitions( 11 | ${PNG_CFLAGS_OTHER}) 12 | 13 | link_directories( 14 | ${PNG_LIBRARY_DIRS}) 15 | 16 | add_definitions( 17 | ${PNG_CFLAGS_OTHER}) 18 | 19 | include_directories( 20 | "${CMAKE_CURRENT_SOURCE_DIR}" 21 | "${CMAKE_CURRENT_SOURCE_DIR}/built" 22 | "${CMAKE_CURRENT_BINARY_DIR}") 23 | 24 | if(SPACEWARE_FOUND) 25 | include_directories( 26 | "${SPACEWARE_INCLUDE_DIR}") 27 | endif() 28 | 29 | set(HAVE_SPACEWARE ${SPACEWARE_FOUND}) 30 | set(HAVE_GTK ${GTKMM_FOUND}) 31 | configure_file("${CMAKE_CURRENT_SOURCE_DIR}/config.h.in" 32 | "${CMAKE_CURRENT_BINARY_DIR}/config.h") 33 | 34 | # platform utilities 35 | 36 | if(WIN32) 37 | set(util_SOURCES 38 | win32/w32util.cpp) 39 | else() 40 | set(util_SOURCES 41 | unix/unixutil.cpp) 42 | endif() 43 | 44 | # libslvs 45 | 46 | set(libslvs_SOURCES 47 | util.cpp 48 | entity.cpp 49 | expr.cpp 50 | constraint.cpp 51 | constrainteq.cpp 52 | system.cpp) 53 | 54 | set(libslvs_HEADERS 55 | solvespace.h) 56 | 57 | add_library(slvs SHARED 58 | ${libslvs_SOURCES} 59 | ${libslvs_HEADERS} 60 | ${util_SOURCES} 61 | lib.cpp) 62 | 63 | target_compile_definitions(slvs 64 | PRIVATE -DLIBRARY) 65 | 66 | target_include_directories(slvs 67 | PUBLIC "${CMAKE_SOURCE_DIR}/include") 68 | 69 | set_target_properties(slvs PROPERTIES 70 | PUBLIC_HEADER "${CMAKE_SOURCE_DIR}/include/slvs.h" 71 | VERSION ${solvespace_VERSION_MAJOR}.${solvespace_VERSION_MINOR} 72 | SOVERSION 1) 73 | 74 | if(NOT WIN32) 75 | install(TARGETS slvs 76 | LIBRARY DESTINATION lib/${CMAKE_LIBRARY_PATH} # multiarch 77 | PUBLIC_HEADER DESTINATION include) 78 | endif() 79 | 80 | # generated files 81 | 82 | file(GLOB icons "${CMAKE_CURRENT_SOURCE_DIR}/icons/*.png") 83 | 84 | if(PERL_FOUND AND PERLMODULES_FOUND) 85 | add_custom_command( 86 | OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/built/icons.h" 87 | "${CMAKE_CURRENT_SOURCE_DIR}/built/icons-proto.h" 88 | COMMAND "${PERL_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/png2c.pl" 89 | "${CMAKE_CURRENT_SOURCE_DIR}/built/icons.h" 90 | "${CMAKE_CURRENT_SOURCE_DIR}/built/icons-proto.h" 91 | "${CMAKE_CURRENT_SOURCE_DIR}" 92 | MAIN_DEPENDENCY "${CMAKE_CURRENT_SOURCE_DIR}/png2c.pl" 93 | DEPENDENCIES ${icons}) 94 | 95 | add_custom_command( 96 | OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/built/bitmapextra.table.h" 97 | COMMAND "${PERL_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/pngchar2c.pl" 98 | "${CMAKE_CURRENT_SOURCE_DIR}/built/bitmapextra.table.h" 99 | "${CMAKE_CURRENT_SOURCE_DIR}" 100 | MAIN_DEPENDENCY "${CMAKE_CURRENT_SOURCE_DIR}/pngchar2c.pl" 101 | DEPENDENCIES ${icons}) 102 | endif() 103 | 104 | if(WIN32 AND NOT DISABLE_TTF2C) 105 | add_custom_command( 106 | OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/built/bitmapfont.table.h" 107 | COMMAND ttf2c "${CMAKE_CURRENT_SOURCE_DIR}/built/bitmapfont.table.h") 108 | endif() 109 | 110 | set(generated_HEADERS 111 | built/bitmapextra.table.h 112 | built/bitmapfont.table.h 113 | built/icons-proto.h 114 | built/icons.h) 115 | 116 | set_source_files_properties(${generated_HEADERS} 117 | PROPERTIES GENERATED TRUE) 118 | 119 | # platform dependencies 120 | 121 | if(WIN32) 122 | set(platform_HEADERS 123 | win32/freeze.h) 124 | 125 | set(platform_SOURCES 126 | win32/freeze.cpp 127 | win32/w32main.cpp 128 | win32/resource.rc) 129 | 130 | set(platform_LIBRARIES 131 | comctl32) 132 | elseif(APPLE) 133 | add_definitions( 134 | -mmacosx-version-min=10.6 135 | -fobjc-arc) 136 | 137 | set(platform_SOURCES 138 | cocoa/cocoamain.mm 139 | unix/gloffscreen.cpp) 140 | 141 | set(platform_XIBS 142 | cocoa/MainMenu.xib 143 | cocoa/SaveFormatAccessory.xib) 144 | 145 | set(platform_ICONS 146 | cocoa/AppIcon.iconset) 147 | 148 | set(platform_RESOURCES 149 | unix/solvespace-48x48.png) 150 | 151 | set(platform_BUNDLED_LIBS 152 | ${PNG_LIBRARY}) 153 | 154 | set(platform_LIBRARIES 155 | ${APPKIT_LIBRARY}) 156 | elseif(HAVE_GTK) 157 | include_directories( 158 | ${GTKMM_INCLUDE_DIRS} 159 | ${JSONC_INCLUDE_DIRS} 160 | ${FONTCONFIG_INCLUDE_DIRS} 161 | ${GLEW_INCLUDE_DIRS}) 162 | 163 | link_directories( 164 | ${GTKMM_LIBRARY_DIRS} 165 | ${JSONC_LIBRARY_DIRS} 166 | ${FONTCONFIG_LIBRARY_DIRS} 167 | ${GLEW_LIBRARY_DIRS}) 168 | 169 | add_definitions( 170 | ${GTKMM_CFLAGS_OTHER} 171 | ${JSONC_CFLAGS_OTHER} 172 | ${FONTCONFIG_CFLAGS_OTHER} 173 | ${GLEW_CFLAGS_OTHER}) 174 | 175 | set(platform_SOURCES 176 | gtk/gtkmain.cpp 177 | unix/gloffscreen.cpp) 178 | 179 | set(platform_LIBRARIES 180 | ${GTKMM_LIBRARIES} 181 | ${JSONC_LIBRARIES} 182 | ${FONTCONFIG_LIBRARIES} 183 | ${GLEW_LIBRARIES}) 184 | endif() 185 | 186 | set(platform_BUNDLED_RESOURCES) 187 | 188 | foreach(xib ${platform_XIBS}) 189 | get_filename_component(nib ${xib} NAME_WE) 190 | set(source ${CMAKE_CURRENT_SOURCE_DIR}/${xib}) 191 | set(target ${CMAKE_CURRENT_BINARY_DIR}/solvespace.app/Contents/Resources/${nib}.nib) 192 | list(APPEND platform_BUNDLED_RESOURCES ${target}) 193 | 194 | add_custom_command( 195 | OUTPUT ${target} 196 | COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/solvespace.app/Contents/Resources 197 | COMMAND ibtool --errors --warnings --notices 198 | --output-format human-readable-text --compile 199 | ${target} ${source} 200 | COMMENT "Building Interface Builder file ${xib}" 201 | DEPENDS ${xib}) 202 | endforeach() 203 | 204 | foreach(icon ${platform_ICONS}) 205 | get_filename_component(name ${icon} NAME_WE) 206 | set(source ${CMAKE_CURRENT_SOURCE_DIR}/${icon}) 207 | set(target ${CMAKE_CURRENT_BINARY_DIR}/solvespace.app/Contents/Resources/${name}.icns) 208 | list(APPEND platform_BUNDLED_RESOURCES ${target}) 209 | 210 | add_custom_command( 211 | OUTPUT ${target} 212 | COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/solvespace.app/Contents/Resources 213 | COMMAND iconutil -c icns -o ${target} ${source} 214 | COMMENT "Building icon set ${icon}" 215 | DEPENDS ${source}) 216 | endforeach() 217 | 218 | foreach(res ${platform_RESOURCES}) 219 | get_filename_component(name ${res} NAME) 220 | set(source ${CMAKE_CURRENT_SOURCE_DIR}/${res}) 221 | set(target ${CMAKE_CURRENT_BINARY_DIR}/solvespace.app/Contents/Resources/${name}) 222 | list(APPEND platform_BUNDLED_RESOURCES ${target}) 223 | 224 | add_custom_command( 225 | OUTPUT ${target} 226 | COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/solvespace.app/Contents/Resources 227 | COMMAND ${CMAKE_COMMAND} -E copy ${source} ${target} 228 | COMMENT "Copying resource file ${res}" 229 | DEPENDS ${res}) 230 | endforeach() 231 | 232 | foreach(lib ${platform_BUNDLED_LIBS}) 233 | get_filename_component(name ${lib} NAME) 234 | set(target ${CMAKE_CURRENT_BINARY_DIR}/solvespace.app/Contents/MacOS/${name}) 235 | list(APPEND platform_BUNDLED_RESOURCES ${target}) 236 | 237 | add_custom_command( 238 | OUTPUT ${target} 239 | COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/solvespace.app/Contents/Resources 240 | COMMAND ${CMAKE_COMMAND} -E copy ${lib} ${target} 241 | COMMENT "Bundling shared library ${lib}" 242 | DEPENDS ${lib}) 243 | endforeach() 244 | 245 | # solvespace executable 246 | 247 | set(solvespace_HEADERS 248 | config.h 249 | dsc.h 250 | expr.h 251 | font.table.h 252 | polygon.h 253 | sketch.h 254 | solvespace.h 255 | ui.h 256 | srf/surface.h) 257 | 258 | set(solvespace_SOURCES 259 | bsp.cpp 260 | clipboard.cpp 261 | confscreen.cpp 262 | constraint.cpp 263 | constrainteq.cpp 264 | describescreen.cpp 265 | draw.cpp 266 | drawconstraint.cpp 267 | drawentity.cpp 268 | entity.cpp 269 | export.cpp 270 | exportstep.cpp 271 | exportvector.cpp 272 | expr.cpp 273 | file.cpp 274 | generate.cpp 275 | glhelper.cpp 276 | graphicswin.cpp 277 | group.cpp 278 | groupmesh.cpp 279 | mesh.cpp 280 | modify.cpp 281 | mouse.cpp 282 | polygon.cpp 283 | request.cpp 284 | solvespace.cpp 285 | style.cpp 286 | system.cpp 287 | textscreens.cpp 288 | textwin.cpp 289 | toolbar.cpp 290 | ttf.cpp 291 | undoredo.cpp 292 | util.cpp 293 | view.cpp 294 | srf/boolean.cpp 295 | srf/curve.cpp 296 | srf/merge.cpp 297 | srf/ratpoly.cpp 298 | srf/raycast.cpp 299 | srf/surface.cpp 300 | srf/surfinter.cpp 301 | srf/triangulate.cpp) 302 | 303 | add_executable(solvespace WIN32 MACOSX_BUNDLE 304 | ${libslvs_HEADERS} 305 | ${libslvs_SOURCES} 306 | ${util_SOURCES} 307 | ${platform_HEADERS} 308 | ${platform_SOURCES} 309 | ${platform_BUNDLED_RESOURCES} 310 | ${generated_HEADERS} 311 | ${solvespace_HEADERS} 312 | ${solvespace_SOURCES}) 313 | 314 | target_link_libraries(solvespace 315 | "${OPENGL_LIBRARIES}" 316 | "${PNG_LIBRARIES}" 317 | "${platform_LIBRARIES}") 318 | 319 | if(WIN32 AND NOT MINGW) 320 | set_target_properties(solvespace PROPERTIES 321 | LINK_FLAGS "/MANIFEST:NO /SAFESEH:NO") 322 | endif() 323 | 324 | if(SPACEWARE_FOUND) 325 | target_link_libraries(solvespace 326 | "${SPACEWARE_LIBRARIES}") 327 | endif() 328 | 329 | if(APPLE) 330 | set_target_properties(solvespace PROPERTIES INSTALL_RPATH ON) 331 | 332 | set(fixups) 333 | foreach(lib ${platform_BUNDLED_LIBS}) 334 | execute_process(COMMAND otool -XD ${lib} 335 | OUTPUT_VARIABLE canonical_lib OUTPUT_STRIP_TRAILING_WHITESPACE) 336 | add_custom_command(TARGET solvespace POST_BUILD 337 | COMMAND install_name_tool -change "${canonical_lib}" "@executable_path/${name}" 338 | $ 339 | COMMENT "Fixing up rpath for dylib ${name}") 340 | endforeach() 341 | 342 | set(bundle solvespace) 343 | add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/${bundle}.dmg 344 | COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_BINARY_DIR}/${bundle}.dmg 345 | COMMAND hdiutil create -srcfolder ${CMAKE_CURRENT_BINARY_DIR}/${bundle}.app 346 | ${CMAKE_BINARY_DIR}/${bundle}.dmg 347 | DEPENDS $ 348 | COMMENT "Building ${bundle}.dmg") 349 | 350 | add_custom_target(${bundle}-dmg ALL 351 | DEPENDS ${CMAKE_BINARY_DIR}/${bundle}.dmg) 352 | endif() 353 | 354 | install(TARGETS solvespace 355 | RUNTIME DESTINATION bin 356 | BUNDLE DESTINATION .) 357 | 358 | install(FILES unix/solvespace.desktop 359 | DESTINATION share/applications) 360 | foreach(SIZE 16x16 24x24 32x32 48x48) 361 | install(FILES unix/solvespace-${SIZE}.png 362 | DESTINATION share/icons/hicolor/${SIZE}/apps 363 | RENAME solvespace.png) 364 | install(FILES unix/solvespace-${SIZE}.png 365 | DESTINATION share/icons/hicolor/${SIZE}/mimetypes 366 | RENAME application.x-solvespace.png) 367 | endforeach() 368 | 369 | # valgrind 370 | 371 | add_custom_target(solvespace-valgrind 372 | valgrind 373 | --tool=memcheck 374 | --verbose 375 | --track-fds=yes 376 | --log-file=vg.%p.out 377 | --num-callers=50 378 | --error-limit=no 379 | --read-var-info=yes 380 | --leak-check=full 381 | --leak-resolution=high 382 | --show-reachable=yes 383 | --track-origins=yes 384 | --malloc-fill=0xac 385 | --free-fill=0xde 386 | $) 387 | -------------------------------------------------------------------------------- /exposed/CDemo.c: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------- 2 | * Some sample code for slvs.dll. We draw some geometric entities, provide 3 | * initial guesses for their positions, and then constrain them. The solver 4 | * calculates their new positions, in order to satisfy the constraints. 5 | * 6 | * Copyright 2008-2013 Jonathan Westhues. 7 | *---------------------------------------------------------------------------*/ 8 | #ifdef HAVE_CONFIG_H 9 | # include 10 | #endif 11 | #ifdef WIN32 12 | # include 13 | #endif 14 | #include 15 | #include 16 | #include 17 | #ifdef HAVE_STDINT_H 18 | # include 19 | #endif 20 | 21 | #include 22 | 23 | static Slvs_System sys; 24 | 25 | static void *CheckMalloc(size_t n) 26 | { 27 | void *r = malloc(n); 28 | if(!r) { 29 | printf("out of memory!\n"); 30 | exit(-1); 31 | } 32 | return r; 33 | } 34 | 35 | /*----------------------------------------------------------------------------- 36 | * An example of a constraint in 3d. We create a single group, with some 37 | * entities and constraints. 38 | *---------------------------------------------------------------------------*/ 39 | static void Example3d(void) 40 | { 41 | /* This will contain a single group, which will arbitrarily number 1. */ 42 | Slvs_hGroup g = 1; 43 | 44 | /* A point, initially at (x y z) = (10 10 10) */ 45 | sys.param[sys.params++] = Slvs_MakeParam(1, g, 10.0); 46 | sys.param[sys.params++] = Slvs_MakeParam(2, g, 10.0); 47 | sys.param[sys.params++] = Slvs_MakeParam(3, g, 10.0); 48 | sys.entity[sys.entities++] = Slvs_MakePoint3d(101, g, 1, 2, 3); 49 | /* and a second point at (20 20 20) */ 50 | sys.param[sys.params++] = Slvs_MakeParam(4, g, 20.0); 51 | sys.param[sys.params++] = Slvs_MakeParam(5, g, 20.0); 52 | sys.param[sys.params++] = Slvs_MakeParam(6, g, 20.0); 53 | sys.entity[sys.entities++] = Slvs_MakePoint3d(102, g, 4, 5, 6); 54 | /* and a line segment connecting them. */ 55 | sys.entity[sys.entities++] = Slvs_MakeLineSegment(200, g, 56 | SLVS_FREE_IN_3D, 101, 102); 57 | 58 | /* The distance between the points should be 30.0 units. */ 59 | sys.constraint[sys.constraints++] = Slvs_MakeConstraint( 60 | 1, g, 61 | SLVS_C_PT_PT_DISTANCE, 62 | SLVS_FREE_IN_3D, 63 | 30.0, 64 | 101, 102, 0, 0); 65 | 66 | /* Let's tell the solver to keep the second point as close to constant 67 | * as possible, instead moving the first point. */ 68 | sys.dragged[0] = 4; 69 | sys.dragged[1] = 5; 70 | sys.dragged[2] = 6; 71 | 72 | /* Now that we have written our system, we solve. */ 73 | Slvs_Solve(&sys, g); 74 | 75 | if(sys.result == SLVS_RESULT_OKAY) { 76 | printf("okay; now at (%.3f %.3f %.3f)\n" 77 | " (%.3f %.3f %.3f)\n", 78 | sys.param[0].val, sys.param[1].val, sys.param[2].val, 79 | sys.param[3].val, sys.param[4].val, sys.param[5].val); 80 | printf("%d DOF\n", sys.dof); 81 | } else { 82 | printf("solve failed"); 83 | } 84 | } 85 | 86 | /*----------------------------------------------------------------------------- 87 | * An example of a constraint in 2d. In our first group, we create a workplane 88 | * along the reference frame's xy plane. In a second group, we create some 89 | * entities in that group and dimension them. 90 | *---------------------------------------------------------------------------*/ 91 | static void Example2d(void) 92 | { 93 | Slvs_hGroup g; 94 | double qw, qx, qy, qz; 95 | 96 | g = 1; 97 | /* First, we create our workplane. Its origin corresponds to the origin 98 | * of our base frame (x y z) = (0 0 0) */ 99 | sys.param[sys.params++] = Slvs_MakeParam(1, g, 0.0); 100 | sys.param[sys.params++] = Slvs_MakeParam(2, g, 0.0); 101 | sys.param[sys.params++] = Slvs_MakeParam(3, g, 0.0); 102 | sys.entity[sys.entities++] = Slvs_MakePoint3d(101, g, 1, 2, 3); 103 | /* and it is parallel to the xy plane, so it has basis vectors (1 0 0) 104 | * and (0 1 0). */ 105 | Slvs_MakeQuaternion(1, 0, 0, 106 | 0, 1, 0, &qw, &qx, &qy, &qz); 107 | sys.param[sys.params++] = Slvs_MakeParam(4, g, qw); 108 | sys.param[sys.params++] = Slvs_MakeParam(5, g, qx); 109 | sys.param[sys.params++] = Slvs_MakeParam(6, g, qy); 110 | sys.param[sys.params++] = Slvs_MakeParam(7, g, qz); 111 | sys.entity[sys.entities++] = Slvs_MakeNormal3d(102, g, 4, 5, 6, 7); 112 | 113 | sys.entity[sys.entities++] = Slvs_MakeWorkplane(200, g, 101, 102); 114 | 115 | /* Now create a second group. We'll solve group 2, while leaving group 1 116 | * constant; so the workplane that we've created will be locked down, 117 | * and the solver can't move it. */ 118 | g = 2; 119 | /* These points are represented by their coordinates (u v) within the 120 | * workplane, so they need only two parameters each. */ 121 | sys.param[sys.params++] = Slvs_MakeParam(11, g, 10.0); 122 | sys.param[sys.params++] = Slvs_MakeParam(12, g, 20.0); 123 | sys.entity[sys.entities++] = Slvs_MakePoint2d(301, g, 200, 11, 12); 124 | 125 | sys.param[sys.params++] = Slvs_MakeParam(13, g, 20.0); 126 | sys.param[sys.params++] = Slvs_MakeParam(14, g, 10.0); 127 | sys.entity[sys.entities++] = Slvs_MakePoint2d(302, g, 200, 13, 14); 128 | 129 | /* And we create a line segment with those endpoints. */ 130 | sys.entity[sys.entities++] = Slvs_MakeLineSegment(400, g, 131 | 200, 301, 302); 132 | 133 | /* Now three more points. */ 134 | sys.param[sys.params++] = Slvs_MakeParam(15, g, 100.0); 135 | sys.param[sys.params++] = Slvs_MakeParam(16, g, 120.0); 136 | sys.entity[sys.entities++] = Slvs_MakePoint2d(303, g, 200, 15, 16); 137 | 138 | sys.param[sys.params++] = Slvs_MakeParam(17, g, 120.0); 139 | sys.param[sys.params++] = Slvs_MakeParam(18, g, 110.0); 140 | sys.entity[sys.entities++] = Slvs_MakePoint2d(304, g, 200, 17, 18); 141 | 142 | sys.param[sys.params++] = Slvs_MakeParam(19, g, 115.0); 143 | sys.param[sys.params++] = Slvs_MakeParam(20, g, 115.0); 144 | sys.entity[sys.entities++] = Slvs_MakePoint2d(305, g, 200, 19, 20); 145 | 146 | /* And arc, centered at point 303, starting at point 304, ending at 147 | * point 305. */ 148 | sys.entity[sys.entities++] = Slvs_MakeArcOfCircle(401, g, 200, 102, 149 | 303, 304, 305); 150 | 151 | /* Now one more point, and a distance */ 152 | sys.param[sys.params++] = Slvs_MakeParam(21, g, 200.0); 153 | sys.param[sys.params++] = Slvs_MakeParam(22, g, 200.0); 154 | sys.entity[sys.entities++] = Slvs_MakePoint2d(306, g, 200, 21, 22); 155 | 156 | sys.param[sys.params++] = Slvs_MakeParam(23, g, 30.0); 157 | sys.entity[sys.entities++] = Slvs_MakeDistance(307, g, 200, 23); 158 | 159 | /* And a complete circle, centered at point 306 with radius equal to 160 | * distance 307. The normal is 102, the same as our workplane. */ 161 | sys.entity[sys.entities++] = Slvs_MakeCircle(402, g, 200, 162 | 306, 102, 307); 163 | 164 | 165 | /* The length of our line segment is 30.0 units. */ 166 | sys.constraint[sys.constraints++] = Slvs_MakeConstraint( 167 | 1, g, 168 | SLVS_C_PT_PT_DISTANCE, 169 | 200, 170 | 30.0, 171 | 301, 302, 0, 0); 172 | 173 | /* And the distance from our line segment to the origin is 10.0 units. */ 174 | sys.constraint[sys.constraints++] = Slvs_MakeConstraint( 175 | 2, g, 176 | SLVS_C_PT_LINE_DISTANCE, 177 | 200, 178 | 10.0, 179 | 101, 0, 400, 0); 180 | /* And the line segment is vertical. */ 181 | sys.constraint[sys.constraints++] = Slvs_MakeConstraint( 182 | 3, g, 183 | SLVS_C_VERTICAL, 184 | 200, 185 | 0.0, 186 | 0, 0, 400, 0); 187 | /* And the distance from one endpoint to the origin is 15.0 units. */ 188 | sys.constraint[sys.constraints++] = Slvs_MakeConstraint( 189 | 4, g, 190 | SLVS_C_PT_PT_DISTANCE, 191 | 200, 192 | 15.0, 193 | 301, 101, 0, 0); 194 | #if 0 195 | /* And same for the other endpoint; so if you add this constraint then 196 | * the sketch is overconstrained and will signal an error. */ 197 | sys.constraint[sys.constraints++] = Slvs_MakeConstraint( 198 | 5, g, 199 | SLVS_C_PT_PT_DISTANCE, 200 | 200, 201 | 18.0, 202 | 302, 101, 0, 0); 203 | #endif /* 0 */ 204 | 205 | /* The arc and the circle have equal radius. */ 206 | sys.constraint[sys.constraints++] = Slvs_MakeConstraint( 207 | 6, g, 208 | SLVS_C_EQUAL_RADIUS, 209 | 200, 210 | 0.0, 211 | 0, 0, 401, 402); 212 | /* The arc has radius 17.0 units. */ 213 | sys.constraint[sys.constraints++] = Slvs_MakeConstraint( 214 | 7, g, 215 | SLVS_C_DIAMETER, 216 | 200, 217 | 17.0*2, 218 | 0, 0, 401, 0); 219 | 220 | /* If the solver fails, then ask it to report which constraints caused 221 | * the problem. */ 222 | sys.calculateFaileds = 1; 223 | 224 | /* And solve. */ 225 | Slvs_Solve(&sys, g); 226 | 227 | if(sys.result == SLVS_RESULT_OKAY) { 228 | printf("solved okay\n"); 229 | printf("line from (%.3f %.3f) to (%.3f %.3f)\n", 230 | sys.param[7].val, sys.param[8].val, 231 | sys.param[9].val, sys.param[10].val); 232 | 233 | printf("arc center (%.3f %.3f) start (%.3f %.3f) finish (%.3f %.3f)\n", 234 | sys.param[11].val, sys.param[12].val, 235 | sys.param[13].val, sys.param[14].val, 236 | sys.param[15].val, sys.param[16].val); 237 | 238 | printf("circle center (%.3f %.3f) radius %.3f\n", 239 | sys.param[17].val, sys.param[18].val, 240 | sys.param[19].val); 241 | printf("%d DOF\n", sys.dof); 242 | } else { 243 | int i; 244 | printf("solve failed: problematic constraints are:"); 245 | for(i = 0; i < sys.faileds; i++) { 246 | printf(" %d", sys.failed[i]); 247 | } 248 | printf("\n"); 249 | if(sys.result == SLVS_RESULT_INCONSISTENT) { 250 | printf("system inconsistent\n"); 251 | } else { 252 | printf("system nonconvergent\n"); 253 | } 254 | } 255 | } 256 | 257 | int main(void) 258 | { 259 | memset(&sys, 0, sizeof(sys)); 260 | sys.param = CheckMalloc(50*sizeof(sys.param[0])); 261 | sys.entity = CheckMalloc(50*sizeof(sys.entity[0])); 262 | sys.constraint = CheckMalloc(50*sizeof(sys.constraint[0])); 263 | 264 | sys.failed = CheckMalloc(50*sizeof(sys.failed[0])); 265 | sys.faileds = 50; 266 | 267 | /*Example3d();*/ 268 | for(;;) { 269 | Example2d(); 270 | sys.params = sys.constraints = sys.entities = 0; 271 | break; 272 | } 273 | return 0; 274 | } 275 | 276 | -------------------------------------------------------------------------------- /extlib/si/si.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------- 2 | * si.h -- SpaceWare input library header 3 | * 4 | * $Id: si.h,v 1.22 1998/03/12 11:07:03 mfarr Exp $ 5 | * 6 | * SpaceWare input library 7 | * 8 | *---------------------------------------------------------------------- 9 | * 10 | * (C) 1998-2001 3Dconnexion. All rights reserved. 11 | * Permission to use, copy, modify, and distribute this software for all 12 | * purposes and without fees is hereby grated provided that this copyright 13 | * notice appears in all copies. Permission to modify this software is granted 14 | * and 3Dconnexion will support such modifications only is said modifications are 15 | * approved by 3Dconnexion. 16 | * 17 | */ 18 | 19 | 20 | #ifndef _SI_H_ 21 | #define _SI_H_ 22 | 23 | static char incFileNameCvsId[]="(C) 1996 Spacetec IMC Corporation: $Id: si.h,v 1.22 1998/03/12 11:07:03 mfarr Exp $"; 24 | 25 | #include 26 | 27 | #include "spwmacro.h" 28 | #include "spwdata.h" 29 | #include "siSync.h" 30 | 31 | #include 32 | #include "spwerror.h" 33 | 34 | /* 35 | * UI modes 36 | */ 37 | #define SI_UI_ALL_CONTROLS 0xffffffffL 38 | #define SI_UI_NO_CONTROLS 0x00000000L 39 | 40 | /* 41 | * These UI modes are left here for legacy applications. 42 | */ 43 | #define SI_UI_FILTERS 0x00000001L 44 | #define SI_UI_FUNC_BUTTONS 0x00000002L 45 | #define SI_UI_RESET_BUTTONS 0x00000004L 46 | #define SI_UI_SENSITIVITY 0x00000008L 47 | #define SI_UI_TUNING 0x00000010L 48 | #define SI_UI_DIALOG_POPUP 0x00000020L 49 | 50 | /* 51 | * Device types and classes 52 | */ 53 | typedef enum 54 | { 55 | SI_ALL_TYPES = -1, 56 | SI_UNKNOWN_DEVICE = 0, 57 | SI_SPACEBALL_2003 = 1, 58 | SI_SPACEBALL_3003 = 2, 59 | SI_SPACE_CONTROLLER = 3, 60 | SI_AVENGER = 4, 61 | SI_SPACEORB_360 = 5, 62 | SI_NAVIGATOR = 6, 63 | SI_SPACEBALL_2003A = 7, 64 | SI_SPACEBALL_2003B = 8, 65 | SI_SPACEBALL_2003C = 9, 66 | SI_SPACEBALL_3003A = 10, 67 | SI_SPACEBALL_3003B = 11, 68 | SI_SPACEBALL_3003C = 12, 69 | SI_SPACEBALL_4000 = 13, 70 | SI_SPACEMOUSE_CLASSIC = 14, 71 | SI_SPACEMOUSE_PLUS = 15, 72 | SI_SPACEMOUSE_XT = 16, 73 | SI_CYBERMAN = 17, 74 | SI_CADMAN = 18, 75 | SI_SPACEMOUSE_CLASSIC_PROMO = 19, 76 | SI_SERIAL_CADMAN = 20, 77 | SI_SPACEBALL_5000 = 21, 78 | SI_TEST_NO_DEVICE = 22, 79 | SI_3DX_KEYBOARD_BLACK = 23, 80 | SI_3DX_KEYBOARD_WHITE = 24, 81 | SI_TRAVELER = 25, 82 | SI_TRAVELER1 = 26, 83 | SI_SPACEBALL_5000A = 27, 84 | SI_SPACEDRAGON = 28, 85 | SI_SPACEPILOT = 29, 86 | SI_NUM_DEV_TYPES /* Leave this last, add before it */ 87 | } SiDevType; 88 | 89 | /* 90 | * These defintions of device classes are left in for legacy applications. 91 | */ 92 | #define SI_HIGH_END 63 93 | #define SI_MED_END 62 94 | #define SI_LOW_END 61 95 | 96 | /* 97 | * Data retrieval mode, only SI_EVENT is currently supported. 98 | */ 99 | #define SI_EVENT 0x0001 100 | #define SI_POLL 0x0002 101 | 102 | /* 103 | * Get event flags 104 | */ 105 | #define SI_AVERAGE_EVENTS 0x0001 106 | 107 | /* 108 | * This is an INTERNAL flag used by the polling mechanism, user applications 109 | * should NOT send this flag. 110 | */ 111 | #define SI_POLLED_REQUEST 0x0100 112 | 113 | /* 114 | * SpaceWare event types 115 | */ 116 | typedef enum 117 | { 118 | SI_BUTTON_EVENT = 1, 119 | SI_MOTION_EVENT, 120 | SI_COMBO_EVENT, /* Not implemented */ 121 | SI_ZERO_EVENT, 122 | SI_EXCEPTION_EVENT, 123 | SI_OUT_OF_BAND, 124 | SI_ORIENTATION_EVENT, 125 | SI_KEYBOARD_EVENT, 126 | SI_LPFK_EVENT, 127 | SI_APP_EVENT, /* Application functions */ 128 | SI_SYNC_EVENT, /* GUI synchronization events */ 129 | SI_BUTTON_PRESS_EVENT, /* Single button events (replace SI_BUTTON_EVENT) */ 130 | SI_BUTTON_RELEASE_EVENT /* Single button events (replace SI_BUTTON_EVENT) */ 131 | } SiEventType; 132 | 133 | /* 134 | * Data modes 135 | */ 136 | #define SI_MODE_NORMALIZE 0x0001 137 | #define SI_MODE_COMPRESS 0x0002 138 | #define SI_MODE_SENSITIVITY 0x0004 139 | #define SI_MODE_TUNING 0x0008 140 | 141 | /* 142 | * Motion data offsets 143 | */ 144 | #define SI_TX 0 /* Translation X value */ 145 | #define SI_TY 1 /* Translation Y value */ 146 | #define SI_TZ 2 /* Translation Z value */ 147 | #define SI_RX 3 /* Rotation X value */ 148 | #define SI_RY 4 /* Rotation Y value */ 149 | #define SI_RZ 5 /* Rotation Z value */ 150 | 151 | /* 152 | * Reserved buttons 153 | */ 154 | 155 | #define SI_RESET_DEVICE_BIT 0x00000001L 156 | #define SI_APP_FIT_BIT 0x80000000L 157 | #define SI_APP_DIALOG_BIT 0x40000000L 158 | 159 | #define SI_RESET_DEVICE_BUTTON 0 160 | #define SI_APP_FIT_BUTTON 31 161 | #define SI_APP_DIALOG_BUTTON 30 162 | 163 | /* 164 | * Miscellaneous 165 | */ 166 | #define SI_END_ARGS 0 167 | #define SI_NO_HANDLE ((SiHdl) NULL) 168 | #define SI_ALL_HANDLES ((SiHdl) NULL) 169 | #define SI_ANY_HANDLE ((SiHdl) NULL) 170 | #define SI_NO_TRANSCTL ((SiTransCtl) NULL) 171 | #define SI_NO_MASK ((SiTypeMask *) NULL) 172 | #define SI_ANY_DEVICE -1 173 | #define SI_NO_DEVICE -1 174 | #define SI_NO_TYPE -1 175 | #define SI_NO_LIST -1 176 | #define SI_NO_BUTTON -1 177 | #define SI_STRSIZE 128 178 | #define SI_MAXBUF 128 179 | #define SI_KEY_MAXBUF 5120 180 | 181 | typedef int SiDevID; /* Device ID */ 182 | typedef void *SiHdl; /* SpaceWare handle */ 183 | typedef void *SiTransCtl; /* SpaceWare transport control handle */ 184 | 185 | typedef struct /* Open data */ 186 | { 187 | 188 | HWND hWnd; /* Window handle for SpaceWare messages. */ 189 | SiTransCtl transCtl; /* SpaceWare transport control handle. Reserved */ 190 | /* for the s80 transport mechanism. */ 191 | DWORD processID; /* The process ID for this application. */ 192 | char exeFile[MAX_PATH]; /* The executable name of the process. */ 193 | SPWint32 libFlag; /* Library version flag. */ 194 | } SiOpenData; 195 | 196 | typedef struct /* Get event Data */ 197 | { 198 | 199 | UINT msg; 200 | WPARAM wParam; 201 | LPARAM lParam; 202 | } SiGetEventData; 203 | 204 | typedef struct /* Device type mask */ 205 | { 206 | unsigned char mask[8]; 207 | } SiTypeMask; 208 | 209 | typedef struct /* Device port information */ 210 | { 211 | SiDevID devID; /* Device ID */ 212 | int devType; /* Device type */ 213 | int devClass; /* Device class */ 214 | char devName[SI_STRSIZE]; /* Device name */ 215 | char portName[SI_STRSIZE]; /* Port name */ 216 | } SiDevPort; 217 | 218 | typedef struct /* Device information */ 219 | { 220 | char firmware[SI_STRSIZE]; /* Firmware version */ 221 | int devType; /* Device type */ 222 | int numButtons; /* Number of buttons */ 223 | int numDegrees; /* Number of degrees of freedom */ 224 | SPWbool canBeep; /* Device beeps */ 225 | int majorVersion; /* Major version number */ 226 | int minorVersion; /* Minor version number */ 227 | } SiDevInfo; 228 | 229 | typedef struct /* Button information */ 230 | { 231 | char name[SI_STRSIZE]; /* Contains the name of a button for display in an app's GUI */ 232 | } SiButtonName; 233 | 234 | typedef struct /* Button information */ 235 | { 236 | char name[SI_STRSIZE]; /* Contains the name of a device for display in an app's GUI */ 237 | } SiDeviceName; 238 | 239 | typedef struct /* Version information */ 240 | { 241 | int major; /* Major version number */ 242 | int minor; /* Minor version number */ 243 | int build; /* Build number */ 244 | char version[SI_STRSIZE]; /* Version string */ 245 | char date[SI_STRSIZE]; /* Date string */ 246 | } SiVerInfo; 247 | 248 | typedef struct /* Sensitivity parameters */ 249 | { 250 | char dummy; 251 | } SiSensitivity; 252 | 253 | typedef struct /* Tuning parameters */ 254 | { 255 | char dummy; 256 | } SiTuning; 257 | 258 | typedef struct 259 | { 260 | SPWuint8 code; /* Out of band message code */ 261 | union { 262 | SPWuint8 message[SI_MAXBUF-1]; /* The actual message */ 263 | void *pvoid[SI_MAXBUF/8]; /* void ptrs. Enough room for 64bit ptrs */ 264 | }; 265 | } SiSpwOOB; 266 | 267 | typedef struct 268 | { 269 | SPWuint8 string[SI_KEY_MAXBUF]; /* String for keyboard data */ 270 | } SiKeyboardData; 271 | 272 | typedef struct 273 | { 274 | SPWuint32 lpfk; /* LPFK number to send */ 275 | } SiLpfkData; 276 | 277 | typedef enum 278 | { 279 | SI_LEFT = 0, 280 | SI_RIGHT 281 | } SiOrientation; 282 | 283 | typedef struct /* Bitmasks of button states */ 284 | { 285 | SPWuint32 last; /* Buttons pressed as of last event */ 286 | SPWuint32 current; /* Buttons pressed as of this event */ 287 | SPWuint32 pressed; /* Buttons pressed this event */ 288 | SPWuint32 released; /* Buttons released this event */ 289 | } SiButtonData; 290 | 291 | /* 292 | * SI_BUTTON_PRESS_EVENT & SI_BUTTON_RELEASE_EVENT are hardware button 293 | * events. Meaning that they are meant to be sent when a specific hardware 294 | * button is pressed. The correlation between the actual hardware button 295 | * and the resulting button number could be broken by careful editing of 296 | * a config file, but it is intended that the correlation be intact. 297 | * This is basically the same as SI_BUTTON_EVENT, but allows 298 | * more than 29 buttons because it isn't limited to a 32-bit mask. 299 | * Different entries in the config file determine whether SI_BUTTON_PRESS/RELEASE_EVENTs 300 | * or SI_BUTTON_EVENTs will be generated. 301 | * This event was introduced in 3DxWare 5.2. 302 | */ 303 | typedef struct /* Data for SI_BUTTON_PRESS/RELEASE_EVENT */ 304 | { 305 | SPWuint32 buttonNumber; /* The button number that went down/up in a * 306 | * SI_BUTTON_PRESS/RELEASE_EVENT event */ 307 | } SiHWButtonData; 308 | 309 | typedef struct /* Data for SI_APP_EVENT */ 310 | { 311 | SPWuint32 functionNumber; /* The Application-specific function number 312 | * invoked by the user in a SI_APP_EVENT */ 313 | } SiAppEventData; 314 | 315 | typedef struct /* SpaceWare data */ 316 | { 317 | SiButtonData bData; /* Button data */ 318 | long mData[6]; /* Motion data (index via SI_TX, etc) */ 319 | long period; /* Period (milliseconds) */ 320 | } SiSpwData; 321 | 322 | typedef struct /* SpaceWare event */ 323 | { 324 | int type; /* Event type */ 325 | union 326 | { 327 | SiSpwData spwData; /* Button, motion, or combo data */ 328 | SiSpwOOB spwOOB; /* Out of band message */ 329 | SiOrientation spwOrientation;/* Which hand orientation is the device */ 330 | char exData[SI_MAXBUF]; /* Exception data */ 331 | SiKeyboardData spwKeyData; /* String for keyboard data */ 332 | SiLpfkData spwLpfkData; /* LPFK data */ 333 | SiSyncPacket siSyncPacket; /* GUI SyncPacket sent to applications */ 334 | SiHWButtonData hwButtonEvent;/* ButtonNumber that goes with * 335 | * SI_BUTTON_PRESS/RELEASE_EVENT */ 336 | SiAppEventData appEventData; /* Application event function data that * 337 | * goes with an SI_APP_EVENT event */ 338 | } u; 339 | } SiSpwEvent; 340 | 341 | typedef struct /* Event handler (for SiDispatch) */ 342 | { 343 | int (*func) (SiOpenData *, SiGetEventData *, SiSpwEvent *, void *); 344 | void *data; 345 | } SiEventHandler; 346 | 347 | typedef struct /* SpaceWare event handlers */ 348 | { 349 | SiEventHandler button; /* Button event handler */ 350 | SiEventHandler motion; /* Motion event handler */ 351 | SiEventHandler combo; /* Combo event handler */ 352 | SiEventHandler zero; /* Zero event handler */ 353 | SiEventHandler exception; /* Exception event handler */ 354 | } SiSpwHandlers; 355 | 356 | #ifdef __cplusplus 357 | extern "C" { 358 | #endif 359 | 360 | 361 | enum SpwRetVal SiAndTypeMask (SiTypeMask *pTMaskA, SiTypeMask *pTMaskB); 362 | int SiGetPortList (SiDevPort **ppPort); 363 | void SiFreePortList (SiDevPort *pPort); 364 | void SiTune2003 (SiSpwEvent *pEvent); 365 | void SiTuneSC (SiSpwEvent *pEvent); 366 | 367 | 368 | 369 | #ifdef __cplusplus 370 | } 371 | #endif 372 | 373 | #endif /* _SI_H_ */ 374 | -------------------------------------------------------------------------------- /src/exportstep.cpp: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Export a STEP file describing our ratpoly shell. 3 | // 4 | // Copyright 2008-2013 Jonathan Westhues. 5 | //----------------------------------------------------------------------------- 6 | #include "solvespace.h" 7 | 8 | void StepFileWriter::WriteHeader(void) { 9 | fprintf(f, 10 | "ISO-10303-21;\n" 11 | "HEADER;\n" 12 | "\n" 13 | "FILE_DESCRIPTION((''), '2;1');\n" 14 | "\n" 15 | "FILE_NAME(\n" 16 | " 'output_file',\n" 17 | " '2009-06-07T17:44:47-07:00',\n" 18 | " (''),\n" 19 | " (''),\n" 20 | " 'SolveSpace',\n" 21 | " '',\n" 22 | " ''\n" 23 | ");\n" 24 | "\n" 25 | "FILE_SCHEMA (('CONFIG_CONTROL_DESIGN'));\n" 26 | "ENDSEC;\n" 27 | "\n" 28 | "DATA;\n" 29 | "\n" 30 | "/**********************************************************\n" 31 | " * This defines the units and tolerances for the file. It\n" 32 | " * is always the same, independent of the actual data.\n" 33 | " **********************************************************/\n" 34 | "#158=(\n" 35 | "LENGTH_UNIT()\n" 36 | "NAMED_UNIT(*)\n" 37 | "SI_UNIT(.MILLI.,.METRE.)\n" 38 | ");\n" 39 | "#161=(\n" 40 | "NAMED_UNIT(*)\n" 41 | "PLANE_ANGLE_UNIT()\n" 42 | "SI_UNIT($,.RADIAN.)\n" 43 | ");\n" 44 | "#166=(\n" 45 | "NAMED_UNIT(*)\n" 46 | "SI_UNIT($,.STERADIAN.)\n" 47 | "SOLID_ANGLE_UNIT()\n" 48 | ");\n" 49 | "#167=UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(0.001),#158,\n" 50 | "'DISTANCE_ACCURACY_VALUE',\n" 51 | "'string');\n" 52 | "#168=(\n" 53 | "GEOMETRIC_REPRESENTATION_CONTEXT(3)\n" 54 | "GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#167))\n" 55 | "GLOBAL_UNIT_ASSIGNED_CONTEXT((#166,#161,#158))\n" 56 | "REPRESENTATION_CONTEXT('ID1','3D')\n" 57 | ");\n" 58 | "#169=SHAPE_REPRESENTATION('',(#170),#168);\n" 59 | "#170=AXIS2_PLACEMENT_3D('',#173,#171,#172);\n" 60 | "#171=DIRECTION('',(0.,0.,1.));\n" 61 | "#172=DIRECTION('',(1.,0.,0.));\n" 62 | "#173=CARTESIAN_POINT('',(0.,0.,0.));\n" 63 | "\n" 64 | ); 65 | 66 | // Start the ID somewhere beyond the header IDs. 67 | id = 200; 68 | } 69 | void StepFileWriter::WriteProductHeader(void) { 70 | fprintf(f, 71 | "#175 = SHAPE_DEFINITION_REPRESENTATION(#176, #169);\n" 72 | "#176 = PRODUCT_DEFINITION_SHAPE('Version', 'Test Part', #177);\n" 73 | "#177 = PRODUCT_DEFINITION('Version', 'Test Part', #182, #178);\n" 74 | "#178 = DESIGN_CONTEXT('3D Mechanical Parts', #181, 'design');\n" 75 | "#179 = PRODUCT('1', 'Product', 'Test Part', (#180));\n" 76 | "#180 = MECHANICAL_CONTEXT('3D Mechanical Parts', #181, 'mechanical');\n" 77 | "#181 = APPLICATION_CONTEXT(\n" 78 | "'configuration controlled 3d designs of mechanical parts and assemblies');\n" 79 | "#182 = PRODUCT_DEFINITION_FORMATION_WITH_SPECIFIED_SOURCE('Version',\n" 80 | "'Test Part', #179, .MADE.);\n" 81 | "\n" 82 | ); 83 | } 84 | int StepFileWriter::ExportCurve(SBezier *sb) { 85 | int i, ret = id; 86 | 87 | fprintf(f, "#%d=(\n", ret); 88 | fprintf(f, "BOUNDED_CURVE()\n"); 89 | fprintf(f, "B_SPLINE_CURVE(%d,(", sb->deg); 90 | for(i = 0; i <= sb->deg; i++) { 91 | fprintf(f, "#%d", ret + i + 1); 92 | if(i != sb->deg) fprintf(f, ","); 93 | } 94 | fprintf(f, "),.UNSPECIFIED.,.F.,.F.)\n"); 95 | fprintf(f, "B_SPLINE_CURVE_WITH_KNOTS((%d,%d),", 96 | (sb->deg + 1), (sb-> deg + 1)); 97 | fprintf(f, "(0.000,1.000),.UNSPECIFIED.)\n"); 98 | fprintf(f, "CURVE()\n"); 99 | fprintf(f, "GEOMETRIC_REPRESENTATION_ITEM()\n"); 100 | fprintf(f, "RATIONAL_B_SPLINE_CURVE(("); 101 | for(i = 0; i <= sb->deg; i++) { 102 | fprintf(f, "%.10f", sb->weight[i]); 103 | if(i != sb->deg) fprintf(f, ","); 104 | } 105 | fprintf(f, "))\n"); 106 | fprintf(f, "REPRESENTATION_ITEM('')\n);\n"); 107 | 108 | for(i = 0; i <= sb->deg; i++) { 109 | fprintf(f, "#%d=CARTESIAN_POINT('',(%.10f,%.10f,%.10f));\n", 110 | id + 1 + i, 111 | CO(sb->ctrl[i])); 112 | } 113 | fprintf(f, "\n"); 114 | 115 | id = ret + 1 + (sb->deg + 1); 116 | return ret; 117 | } 118 | 119 | int StepFileWriter::ExportCurveLoop(SBezierLoop *loop, bool inner) { 120 | if(loop->l.n < 1) oops(); 121 | 122 | List listOfTrims; 123 | ZERO(&listOfTrims); 124 | 125 | SBezier *sb = &(loop->l.elem[loop->l.n - 1]); 126 | 127 | // Generate "exactly closed" contours, with the same vertex id for the 128 | // finish of a previous edge and the start of the next one. So we need 129 | // the finish of the last Bezier in the loop before we start our process. 130 | fprintf(f, "#%d=CARTESIAN_POINT('',(%.10f,%.10f,%.10f));\n", 131 | id, CO(sb->Finish())); 132 | fprintf(f, "#%d=VERTEX_POINT('',#%d);\n", id+1, id); 133 | int lastFinish = id + 1, prevFinish = lastFinish; 134 | id += 2; 135 | 136 | for(sb = loop->l.First(); sb; sb = loop->l.NextAfter(sb)) { 137 | int curveId = ExportCurve(sb); 138 | 139 | int thisFinish; 140 | if(loop->l.NextAfter(sb) != NULL) { 141 | fprintf(f, "#%d=CARTESIAN_POINT('',(%.10f,%.10f,%.10f));\n", 142 | id, CO(sb->Finish())); 143 | fprintf(f, "#%d=VERTEX_POINT('',#%d);\n", id+1, id); 144 | thisFinish = id + 1; 145 | id += 2; 146 | } else { 147 | thisFinish = lastFinish; 148 | } 149 | 150 | fprintf(f, "#%d=EDGE_CURVE('',#%d,#%d,#%d,%s);\n", 151 | id, prevFinish, thisFinish, curveId, ".T."); 152 | fprintf(f, "#%d=ORIENTED_EDGE('',*,*,#%d,.T.);\n", 153 | id+1, id); 154 | 155 | int oe = id+1; 156 | listOfTrims.Add(&oe); 157 | id += 2; 158 | 159 | prevFinish = thisFinish; 160 | } 161 | 162 | fprintf(f, "#%d=EDGE_LOOP('',(", id); 163 | int *oe; 164 | for(oe = listOfTrims.First(); oe; oe = listOfTrims.NextAfter(oe)) { 165 | fprintf(f, "#%d", *oe); 166 | if(listOfTrims.NextAfter(oe) != NULL) fprintf(f, ","); 167 | } 168 | fprintf(f, "));\n"); 169 | 170 | int fb = id + 1; 171 | fprintf(f, "#%d=%s('',#%d,.T.);\n", 172 | fb, inner ? "FACE_BOUND" : "FACE_OUTER_BOUND", id); 173 | 174 | id += 2; 175 | listOfTrims.Clear(); 176 | 177 | return fb; 178 | } 179 | 180 | void StepFileWriter::ExportSurface(SSurface *ss, SBezierList *sbl) { 181 | int i, j, srfid = id; 182 | 183 | // First, we create the untrimmed surface. We always specify a rational 184 | // B-spline surface (in fact, just a Bezier surface). 185 | fprintf(f, "#%d=(\n", srfid); 186 | fprintf(f, "BOUNDED_SURFACE()\n"); 187 | fprintf(f, "B_SPLINE_SURFACE(%d,%d,(", ss->degm, ss->degn); 188 | for(i = 0; i <= ss->degm; i++) { 189 | fprintf(f, "("); 190 | for(j = 0; j <= ss->degn; j++) { 191 | fprintf(f, "#%d", srfid + 1 + j + i*(ss->degn + 1)); 192 | if(j != ss->degn) fprintf(f, ","); 193 | } 194 | fprintf(f, ")"); 195 | if(i != ss->degm) fprintf(f, ","); 196 | } 197 | fprintf(f, "),.UNSPECIFIED.,.F.,.F.,.F.)\n"); 198 | fprintf(f, "B_SPLINE_SURFACE_WITH_KNOTS((%d,%d),(%d,%d),", 199 | (ss->degm + 1), (ss->degm + 1), 200 | (ss->degn + 1), (ss->degn + 1)); 201 | fprintf(f, "(0.000,1.000),(0.000,1.000),.UNSPECIFIED.)\n"); 202 | fprintf(f, "GEOMETRIC_REPRESENTATION_ITEM()\n"); 203 | fprintf(f, "RATIONAL_B_SPLINE_SURFACE(("); 204 | for(i = 0; i <= ss->degm; i++) { 205 | fprintf(f, "("); 206 | for(j = 0; j <= ss->degn; j++) { 207 | fprintf(f, "%.10f", ss->weight[i][j]); 208 | if(j != ss->degn) fprintf(f, ","); 209 | } 210 | fprintf(f, ")"); 211 | if(i != ss->degm) fprintf(f, ","); 212 | } 213 | fprintf(f, "))\n"); 214 | fprintf(f, "REPRESENTATION_ITEM('')\n"); 215 | fprintf(f, "SURFACE()\n"); 216 | fprintf(f, ");\n"); 217 | 218 | // The control points for the untrimmed surface. 219 | for(i = 0; i <= ss->degm; i++) { 220 | for(j = 0; j <= ss->degn; j++) { 221 | fprintf(f, "#%d=CARTESIAN_POINT('',(%.10f,%.10f,%.10f));\n", 222 | srfid + 1 + j + i*(ss->degn + 1), 223 | CO(ss->ctrl[i][j])); 224 | } 225 | } 226 | fprintf(f, "\n"); 227 | 228 | id = srfid + 1 + (ss->degm + 1)*(ss->degn + 1); 229 | 230 | // Now we do the trim curves. We must group each outer loop separately 231 | // along with its inner faces, so do that now. 232 | SBezierLoopSetSet sblss; 233 | ZERO(&sblss); 234 | SPolygon spxyz; 235 | ZERO(&spxyz); 236 | bool allClosed; 237 | SEdge notClosedAt; 238 | // We specify a surface, so it doesn't check for coplanarity; and we 239 | // don't want it to give us any open contours. The polygon and chord 240 | // tolerance are required, because they are used to calculate the 241 | // contour directions and determine inner vs. outer contours. 242 | sblss.FindOuterFacesFrom(sbl, &spxyz, ss, 243 | SS.ChordTolMm() / SS.exportScale, 244 | &allClosed, ¬ClosedAt, 245 | NULL, NULL, 246 | NULL); 247 | 248 | // So in our list of SBezierLoopSet, each set contains at least one loop 249 | // (the outer boundary), plus any inner loops associated with that outer 250 | // loop. 251 | SBezierLoopSet *sbls; 252 | for(sbls = sblss.l.First(); sbls; sbls = sblss.l.NextAfter(sbls)) { 253 | SBezierLoop *loop = sbls->l.First(); 254 | 255 | List listOfLoops; 256 | ZERO(&listOfLoops); 257 | // Create the face outer boundary from the outer loop. 258 | int fob = ExportCurveLoop(loop, false); 259 | listOfLoops.Add(&fob); 260 | 261 | // And create the face inner boundaries from any inner loops that 262 | // lie within this contour. 263 | loop = sbls->l.NextAfter(loop); 264 | for(; loop; loop = sbls->l.NextAfter(loop)) { 265 | int fib = ExportCurveLoop(loop, true); 266 | listOfLoops.Add(&fib); 267 | } 268 | 269 | // And now create the face that corresponds to this outer loop 270 | // and all of its holes. 271 | int advFaceId = id; 272 | fprintf(f, "#%d=ADVANCED_FACE('',(", advFaceId); 273 | int *fb; 274 | for(fb = listOfLoops.First(); fb; fb = listOfLoops.NextAfter(fb)) { 275 | fprintf(f, "#%d", *fb); 276 | if(listOfLoops.NextAfter(fb) != NULL) fprintf(f, ","); 277 | } 278 | 279 | fprintf(f, "),#%d,.T.);\n", srfid); 280 | fprintf(f, "\n"); 281 | advancedFaces.Add(&advFaceId); 282 | 283 | id++; 284 | listOfLoops.Clear(); 285 | } 286 | sblss.Clear(); 287 | spxyz.Clear(); 288 | } 289 | 290 | void StepFileWriter::WriteFooter(void) { 291 | fprintf(f, 292 | "\n" 293 | "ENDSEC;\n" 294 | "\n" 295 | "END-ISO-10303-21;\n" 296 | ); 297 | } 298 | 299 | void StepFileWriter::ExportSurfacesTo(char *file) { 300 | Group *g = SK.GetGroup(SS.GW.activeGroup); 301 | SShell *shell = &(g->runningShell); 302 | 303 | if(shell->surface.n == 0) { 304 | Error("The model does not contain any surfaces to export.%s", 305 | g->runningMesh.l.n > 0 ? 306 | "\n\nThe model does contain triangles from a mesh, but " 307 | "a triangle mesh cannot be exported as a STEP file. Try " 308 | "File -> Export Mesh... instead." : ""); 309 | return; 310 | } 311 | 312 | f = fopen(file, "wb"); 313 | if(!f) { 314 | Error("Couldn't write to '%s'", file); 315 | return; 316 | } 317 | 318 | WriteHeader(); 319 | WriteProductHeader(); 320 | 321 | ZERO(&advancedFaces); 322 | 323 | SSurface *ss; 324 | for(ss = shell->surface.First(); ss; ss = shell->surface.NextAfter(ss)) { 325 | if(ss->trim.n == 0) continue; 326 | 327 | // Get all of the loops of Beziers that trim our surface (with each 328 | // Bezier split so that we use the section as t goes from 0 to 1), and 329 | // the piecewise linearization of those loops in xyz space. 330 | SBezierList sbl; 331 | ZERO(&sbl); 332 | ss->MakeSectionEdgesInto(shell, NULL, &sbl); 333 | 334 | // Apply the export scale factor. 335 | ss->ScaleSelfBy(1.0/SS.exportScale); 336 | sbl.ScaleSelfBy(1.0/SS.exportScale); 337 | 338 | ExportSurface(ss, &sbl); 339 | 340 | sbl.Clear(); 341 | } 342 | 343 | fprintf(f, "#%d=CLOSED_SHELL('',(", id); 344 | int *af; 345 | for(af = advancedFaces.First(); af; af = advancedFaces.NextAfter(af)) { 346 | fprintf(f, "#%d", *af); 347 | if(advancedFaces.NextAfter(af) != NULL) fprintf(f, ","); 348 | } 349 | fprintf(f, "));\n"); 350 | fprintf(f, "#%d=MANIFOLD_SOLID_BREP('brep',#%d);\n", id+1, id); 351 | fprintf(f, "#%d=ADVANCED_BREP_SHAPE_REPRESENTATION('',(#%d,#170),#168);\n", 352 | id+2, id+1); 353 | fprintf(f, "#%d=SHAPE_REPRESENTATION_RELATIONSHIP($,$,#169,#%d);\n", 354 | id+3, id+2); 355 | 356 | WriteFooter(); 357 | 358 | fclose(f); 359 | advancedFaces.Clear(); 360 | } 361 | 362 | void StepFileWriter::WriteWireframe(void) { 363 | fprintf(f, "#%d=GEOMETRIC_CURVE_SET('curves',(", id); 364 | int *c; 365 | for(c = curves.First(); c; c = curves.NextAfter(c)) { 366 | fprintf(f, "#%d", *c); 367 | if(curves.NextAfter(c) != NULL) fprintf(f, ","); 368 | } 369 | fprintf(f, "));\n"); 370 | fprintf(f, "#%d=GEOMETRICALLY_BOUNDED_WIREFRAME_SHAPE_REPRESENTATION" 371 | "('',(#%d,#170),#168);\n", id+1, id); 372 | fprintf(f, "#%d=SHAPE_REPRESENTATION_RELATIONSHIP($,$,#169,#%d);\n", 373 | id+2, id+1); 374 | 375 | id += 3; 376 | curves.Clear(); 377 | } 378 | 379 | --------------------------------------------------------------------------------