├── .gitignore ├── .gitmodules ├── README.md ├── common └── win32 │ ├── freeze.cpp │ └── freeze.h └── solvespace ├── COPYING.txt ├── Makefile ├── bitmapextra.table ├── bitmapfont.table ├── bsp.cpp ├── clipboard.cpp ├── confscreen.cpp ├── constraint.cpp ├── constrainteq.cpp ├── describescreen.cpp ├── draw.cpp ├── drawconstraint.cpp ├── drawentity.cpp ├── dsc.h ├── entity.cpp ├── export.cpp ├── exportstep.cpp ├── exportvector.cpp ├── exposed ├── CDemo.c ├── DOC.txt ├── Makefile ├── VbDemo.vb ├── lib.cpp ├── slvs.h ├── slvs.i ├── slvs_python.hpp ├── slvs_solid.py ├── solid ├── test.py ├── test2.scad.py └── test3.scad.py ├── expr.cpp ├── expr.h ├── extlib ├── libpng.lib ├── png.h ├── pngconf.h ├── si │ ├── si.h │ ├── siSync.h │ ├── siSyncPriv.h │ ├── siapp.h │ ├── siapp.lib │ ├── spwdata.h │ ├── spwerror.h │ └── spwmacro.h ├── zconf.h ├── zlib.h └── zlib.lib ├── file.cpp ├── font.table ├── generate.cpp ├── glhelper.cpp ├── graphicswin.cpp ├── group.cpp ├── groupmesh.cpp ├── icon.ico ├── icons ├── angle.png ├── arc.png ├── assemble.png ├── bezier.png ├── char-0-check-false.png ├── char-1-check-true.png ├── char-2-radio-false.png ├── char-3-radio-true.png ├── circle.png ├── constraint.png ├── construction.png ├── edges.png ├── equal.png ├── extrude.png ├── faces.png ├── hidden-lines.png ├── horiz.png ├── in3d.png ├── length.png ├── line.png ├── mesh.png ├── normal.png ├── ontoworkplane.png ├── other-supp.png ├── parallel.png ├── perpendicular.png ├── point.png ├── pointonx.png ├── rectangle.png ├── ref.png ├── same-orientation.png ├── shaded.png ├── sketch-in-3d.png ├── sketch-in-plane.png ├── step-rotate.png ├── step-translate.png ├── symmetric.png ├── tangent-arc.png ├── text.png ├── trim.png ├── vert.png └── workplane.png ├── mesh.cpp ├── modify.cpp ├── mouse.cpp ├── obj └── t ├── png2c.pl ├── pngchar2c.pl ├── polygon.cpp ├── polygon.h ├── request.cpp ├── sketch.h ├── solvespace.cpp ├── solvespace.h ├── srf ├── boolean.cpp ├── curve.cpp ├── merge.cpp ├── ratpoly.cpp ├── raycast.cpp ├── surface.cpp ├── surface.h ├── surfinter.cpp └── triangulate.cpp ├── style.cpp ├── system.cpp ├── textscreens.cpp ├── textwin.cpp ├── toolbar.cpp ├── tools ├── Makefile └── ttf2c.cpp ├── ttf.cpp ├── ui.h ├── undoredo.cpp ├── util.cpp ├── view.cpp ├── win32 ├── manifest.xml ├── resource.rc ├── w32main.cpp └── w32util.cpp └── wishlist.txt /.gitignore: -------------------------------------------------------------------------------- 1 | /solvespace/exposed/obj 2 | /solvespace/exposed/CDemo.exe 3 | /solvespace/exposed/libslvs.so 4 | /solvespace/exposed/slvs.dll 5 | /solvespace/exposed/cdemo 6 | 7 | /solvespace/exposed/_slvs.so 8 | /solvespace/exposed/slvs.py 9 | *.pyc 10 | /solvespace/exposed/slvs_wrap.cxx 11 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "solid-python"] 2 | path = solid-python 3 | url = https://github.com/BBBSnowball/SolidPython 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | python-solvespace 2 | ================= 3 | 4 | Geometry constraint solver of SolveSpace as a Python library 5 | 6 | The solver has been written by Jonathan Westhues. You can find more information 7 | [on his page][solvespace-lib]. It is part of [SolveSpace][solvespace-cad], which 8 | is a parametric 3d CAD program. 9 | 10 | My contributions: 11 | 12 | * making it work on Linux (only the library, not the whole program!) 13 | * nice Python interface 14 | * some helpers for use with SolidPython (OpenSCAD) 15 | 16 | I'm going to use the Python library with [SolidPython][solidpython], so I have a 17 | constraint solver for [OpenSCAD][openscad]. 18 | 19 | [solvespace-cad]: http://solvespace.com/index.pl 20 | [solvespace-lib]: http://solvespace.com/library.pl 21 | [solidpython]: https://github.com/SolidCode/SolidPython 22 | [openscad]: http://www.openscad.org/ 23 | 24 | 25 | Build and install 26 | ----------------- 27 | 28 | The repository contains all the code for SolveSpace. This is necessary because the 29 | library referes to files in its parent directory. The library is in `solvespace/exposed`. 30 | You can run `make` to build the library. You should put the files `slvs.py` and `_slvs.so` 31 | into a Python library directory or next to your application, so Python can find them. 32 | 33 | If you are not using Linux, you have to change the Makefile accordingly. You could also 34 | use the build system that the SWIG documentation [suggests][distutils], as this should 35 | work on all platforms. 36 | 37 | [distutils]: http://www.swig.org/Doc1.3/SWIGDocumentation.html#Python_nn6 38 | 39 | Usage 40 | ----- 41 | 42 | Here is a simple example: 43 | 44 | ````python 45 | from slvs import * 46 | 47 | # create a system with up to 20 parameters, entities and constraints 48 | # (If you use System(), you will get the default of 50 parameters, ...) 49 | sys = System(20) 50 | 51 | # A point, initially at (x y z) = (10 10 10) 52 | p1 = Point3d(Param(10.0), Param(10.0), Param(10.0), sys) 53 | # and a second point at (20 20 20) 54 | p2 = Point3d(Param(20.0), Param(20.0), Param(20.0), sys) 55 | # and a line segment connecting them. 56 | LineSegment3d(p1, p2) 57 | 58 | # The distance between the points should be 30.0 units. 59 | Constraint.distance(30.0, p1, p2) 60 | 61 | # Let's tell the solver to keep the second point as close to constant 62 | # as possible, instead moving the first point. 63 | sys.set_dragged(p2) 64 | 65 | # Now that we have written our system, we solve. 66 | sys.solve() 67 | 68 | if (sys.result == SLVS_RESULT_OKAY): 69 | print ("okay; now at (%.3f %.3f %.3f)\n" + 70 | " (%.3f %.3f %.3f)") % ( 71 | sys.get_param(0).val, sys.get_param(1).val, sys.get_param(2).val, 72 | sys.get_param(3).val, sys.get_param(4).val, sys.get_param(5).val) 73 | print "%d DOF" % sys.dof 74 | else: 75 | print "solve failed" 76 | ```` 77 | 78 | Have a look at `CDemo.c` and `test.py`. They contain that example and another one. You can 79 | use the raw C API from Python, but I suggest that you use the wrapper classes. `test.py` 80 | uses both of them because it is meant to test the program. 81 | 82 | TODO 83 | ---- 84 | 85 | * Integrate better with SolidPython. 86 | * Find info about the other constraints and implement them. 87 | * Clean up the code: remove all files that the library doesn't need. 88 | * Make it build on all (or most) platforms. 89 | 90 | License 91 | ------- 92 | 93 | SolveSpace:
94 | "SolveSpace is distributed under the **GPLv3**, which permits most use in free software but 95 | generally forbids linking the library with proprietary software. If you're interested in 96 | the latter, then SolveSpace is also available for licensing under typical commercial terms; 97 | please contact me for details." 98 | (see [here](http://solvespace.com/library.pl)) 99 | 100 | You can use my parts of the code under GPLv3, as well. If the author of SolveSpace permits 101 | use under another license (probably commercial), you may use my parts of the code under the 102 | 3-clause BSD license. In that case, you should add appropriate copyright headers to all files. 103 | -------------------------------------------------------------------------------- /common/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 | /* 11 | * store a window's position in the registry, or fail silently if the registry calls don't work 12 | */ 13 | void FreezeWindowPosF(HWND hwnd, char *subKey, char *name) 14 | { 15 | RECT r; 16 | GetWindowRect(hwnd, &r); 17 | 18 | HKEY software; 19 | if(RegOpenKeyEx(HKEY_CURRENT_USER, "Software", 0, KEY_ALL_ACCESS, &software) != ERROR_SUCCESS) 20 | return; 21 | 22 | char *keyName = (char *)malloc(strlen(name) + 30); 23 | if(!keyName) 24 | return; 25 | 26 | HKEY sub; 27 | if(RegCreateKeyEx(software, subKey, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &sub, NULL) != ERROR_SUCCESS) 28 | return; 29 | 30 | sprintf(keyName, "%s_left", name); 31 | if(RegSetValueEx(sub, keyName, 0, REG_DWORD, (BYTE *)&(r.left), sizeof(DWORD)) != ERROR_SUCCESS) 32 | return; 33 | 34 | sprintf(keyName, "%s_right", name); 35 | if(RegSetValueEx(sub, keyName, 0, REG_DWORD, (BYTE *)&(r.right), sizeof(DWORD)) != ERROR_SUCCESS) 36 | return; 37 | 38 | sprintf(keyName, "%s_top", name); 39 | if(RegSetValueEx(sub, keyName, 0, REG_DWORD, (BYTE *)&(r.top), sizeof(DWORD)) != ERROR_SUCCESS) 40 | return; 41 | 42 | sprintf(keyName, "%s_bottom", name); 43 | if(RegSetValueEx(sub, keyName, 0, REG_DWORD, (BYTE *)&(r.bottom), sizeof(DWORD)) != ERROR_SUCCESS) 44 | return; 45 | 46 | sprintf(keyName, "%s_maximized", name); 47 | DWORD v = IsZoomed(hwnd); 48 | if(RegSetValueEx(sub, keyName, 0, REG_DWORD, (BYTE *)&(v), sizeof(DWORD)) != ERROR_SUCCESS) 49 | return; 50 | 51 | free(keyName); 52 | } 53 | 54 | static void Clamp(LONG *v, LONG min, LONG max) 55 | { 56 | if(*v < min) *v = min; 57 | if(*v > max) *v = max; 58 | } 59 | 60 | /* 61 | * retrieve a window's position from the registry, or do nothing if there is no info saved 62 | */ 63 | void ThawWindowPosF(HWND hwnd, char *subKey, char *name) 64 | { 65 | HKEY software; 66 | if(RegOpenKeyEx(HKEY_CURRENT_USER, "Software", 0, KEY_ALL_ACCESS, &software) != ERROR_SUCCESS) 67 | return; 68 | 69 | HKEY sub; 70 | if(RegOpenKeyEx(software, subKey, 0, KEY_ALL_ACCESS, &sub) != ERROR_SUCCESS) 71 | return; 72 | 73 | char *keyName = (char *)malloc(strlen(name) + 30); 74 | if(!keyName) 75 | return; 76 | 77 | DWORD l; 78 | RECT r; 79 | 80 | sprintf(keyName, "%s_left", name); 81 | l = sizeof(DWORD); 82 | if(RegQueryValueEx(sub, keyName, NULL, NULL, (BYTE *)&(r.left), &l) != ERROR_SUCCESS) 83 | return; 84 | 85 | sprintf(keyName, "%s_right", name); 86 | l = sizeof(DWORD); 87 | if(RegQueryValueEx(sub, keyName, NULL, NULL, (BYTE *)&(r.right), &l) != ERROR_SUCCESS) 88 | return; 89 | 90 | sprintf(keyName, "%s_top", name); 91 | l = sizeof(DWORD); 92 | if(RegQueryValueEx(sub, keyName, NULL, NULL, (BYTE *)&(r.top), &l) != ERROR_SUCCESS) 93 | return; 94 | 95 | sprintf(keyName, "%s_bottom", name); 96 | l = sizeof(DWORD); 97 | if(RegQueryValueEx(sub, keyName, NULL, NULL, (BYTE *)&(r.bottom), &l) != ERROR_SUCCESS) 98 | return; 99 | 100 | sprintf(keyName, "%s_maximized", name); 101 | DWORD v; 102 | l = sizeof(DWORD); 103 | if(RegQueryValueEx(sub, keyName, NULL, NULL, (BYTE *)&v, &l) != ERROR_SUCCESS) 104 | return; 105 | if(v) 106 | ShowWindow(hwnd, SW_MAXIMIZE); 107 | 108 | RECT dr; 109 | GetWindowRect(GetDesktopWindow(), &dr); 110 | 111 | // If it somehow ended up off-screen, then put it back. 112 | Clamp(&(r.left), dr.left, dr.right); 113 | Clamp(&(r.right), dr.left, dr.right); 114 | Clamp(&(r.top), dr.top, dr.bottom); 115 | Clamp(&(r.bottom), dr.top, dr.bottom); 116 | if(r.right - r.left < 100) { 117 | r.left -= 300; r.right += 300; 118 | } 119 | if(r.bottom - r.top < 100) { 120 | r.top -= 300; r.bottom += 300; 121 | } 122 | Clamp(&(r.left), dr.left, dr.right); 123 | Clamp(&(r.right), dr.left, dr.right); 124 | Clamp(&(r.top), dr.top, dr.bottom); 125 | Clamp(&(r.bottom), dr.top, dr.bottom); 126 | 127 | MoveWindow(hwnd, r.left, r.top, r.right - r.left, r.bottom - r.top, TRUE); 128 | 129 | free(keyName); 130 | } 131 | 132 | /* 133 | * store a DWORD setting in the registry 134 | */ 135 | void FreezeDWORDF(DWORD val, char *subKey, char *name) 136 | { 137 | HKEY software; 138 | if(RegOpenKeyEx(HKEY_CURRENT_USER, "Software", 0, KEY_ALL_ACCESS, &software) != ERROR_SUCCESS) 139 | return; 140 | 141 | HKEY sub; 142 | if(RegCreateKeyEx(software, subKey, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &sub, NULL) != ERROR_SUCCESS) 143 | return; 144 | 145 | if(RegSetValueEx(sub, name, 0, REG_DWORD, (BYTE *)&val, sizeof(DWORD)) != ERROR_SUCCESS) 146 | return; 147 | } 148 | 149 | /* 150 | * retrieve a DWORD setting, or return the default if that setting is unavailable 151 | */ 152 | DWORD ThawDWORDF(DWORD val, char *subKey, char *name) 153 | { 154 | HKEY software; 155 | if(RegOpenKeyEx(HKEY_CURRENT_USER, "Software", 0, KEY_ALL_ACCESS, &software) != ERROR_SUCCESS) 156 | return val; 157 | 158 | HKEY sub; 159 | if(RegOpenKeyEx(software, subKey, 0, KEY_ALL_ACCESS, &sub) != ERROR_SUCCESS) 160 | return val; 161 | 162 | DWORD l = sizeof(DWORD); 163 | DWORD v; 164 | if(RegQueryValueEx(sub, name, NULL, NULL, (BYTE *)&v, &l) != ERROR_SUCCESS) 165 | return val; 166 | 167 | return v; 168 | } 169 | 170 | /* 171 | * store a string setting in the registry 172 | */ 173 | void FreezeStringF(char *val, char *subKey, char *name) 174 | { 175 | HKEY software; 176 | if(RegOpenKeyEx(HKEY_CURRENT_USER, "Software", 0, KEY_ALL_ACCESS, &software) != ERROR_SUCCESS) 177 | return; 178 | 179 | HKEY sub; 180 | if(RegCreateKeyEx(software, subKey, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &sub, NULL) != ERROR_SUCCESS) 181 | return; 182 | 183 | if(RegSetValueEx(sub, name, 0, REG_SZ, (BYTE *)val, strlen(val)+1) != ERROR_SUCCESS) 184 | return; 185 | } 186 | 187 | /* 188 | * retrieve a string setting, or return the default if that setting is unavailable 189 | */ 190 | void ThawStringF(char *val, int max, char *subKey, char *name) 191 | { 192 | HKEY software; 193 | if(RegOpenKeyEx(HKEY_CURRENT_USER, "Software", 0, KEY_ALL_ACCESS, &software) != ERROR_SUCCESS) 194 | return; 195 | 196 | HKEY sub; 197 | if(RegOpenKeyEx(software, subKey, 0, KEY_ALL_ACCESS, &sub) != ERROR_SUCCESS) 198 | return; 199 | 200 | DWORD l = max; 201 | if(RegQueryValueEx(sub, name, NULL, NULL, (BYTE *)val, &l) != ERROR_SUCCESS) 202 | return; 203 | if(l >= (DWORD)max) return; 204 | 205 | val[l] = '\0'; 206 | return; 207 | } 208 | 209 | -------------------------------------------------------------------------------- /common/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, char *subKey, char *name); 16 | 17 | #define ThawWindowPos(hwnd) ThawWindowPosF(hwnd, FREEZE_SUBKEY, #hwnd) 18 | void ThawWindowPosF(HWND hWnd, char *subKey, char *name); 19 | 20 | #define FreezeDWORD(val) FreezeDWORDF(val, FREEZE_SUBKEY, #val) 21 | void FreezeDWORDF(DWORD val, char *subKey, char *name); 22 | 23 | #define ThawDWORD(val) val = ThawDWORDF(val, FREEZE_SUBKEY, #val) 24 | DWORD ThawDWORDF(DWORD val, char *subKey, char *name); 25 | 26 | #define FreezeString(val) FreezeStringF(val, FREEZE_SUBKEY, #val) 27 | void FreezeStringF(char *val, char *subKey, char *name); 28 | 29 | #define ThawString(val, max) ThawStringF(val, max, FREEZE_SUBKEY, #val) 30 | void ThawStringF(char *val, int max, char *subKey, char *name); 31 | 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /solvespace/Makefile: -------------------------------------------------------------------------------- 1 | DEFINES = /D_WIN32_WINNT=0x500 /DISOLATION_AWARE_ENABLED /D_WIN32_IE=0x500 /DWIN32_LEAN_AND_MEAN /DWIN32 2 | # Use the multi-threaded static libc because libpng and zlib do; not sure if anything bad 3 | # happens if those mix, but don't want to risk it. 4 | CFLAGS = /W3 /nologo -MT -Iextlib -I..\common\win32 /D_DEBUG /D_CRT_SECURE_NO_WARNINGS /I. /Zi /EHs # /O2 5 | 6 | HEADERS = ..\common\win32\freeze.h ui.h solvespace.h dsc.h sketch.h expr.h polygon.h srf\surface.h 7 | 8 | OBJDIR = obj 9 | 10 | FREEZE = $(OBJDIR)\freeze.obj 11 | 12 | W32OBJS = $(OBJDIR)\w32main.obj \ 13 | $(OBJDIR)\w32util.obj \ 14 | 15 | SSOBJS = $(OBJDIR)\solvespace.obj \ 16 | $(OBJDIR)\textwin.obj \ 17 | $(OBJDIR)\textscreens.obj \ 18 | $(OBJDIR)\confscreen.obj \ 19 | $(OBJDIR)\describescreen.obj \ 20 | $(OBJDIR)\graphicswin.obj \ 21 | $(OBJDIR)\modify.obj \ 22 | $(OBJDIR)\clipboard.obj \ 23 | $(OBJDIR)\view.obj \ 24 | $(OBJDIR)\util.obj \ 25 | $(OBJDIR)\style.obj \ 26 | $(OBJDIR)\entity.obj \ 27 | $(OBJDIR)\drawentity.obj \ 28 | $(OBJDIR)\group.obj \ 29 | $(OBJDIR)\groupmesh.obj \ 30 | $(OBJDIR)\request.obj \ 31 | $(OBJDIR)\glhelper.obj \ 32 | $(OBJDIR)\expr.obj \ 33 | $(OBJDIR)\constraint.obj \ 34 | $(OBJDIR)\constrainteq.obj \ 35 | $(OBJDIR)\mouse.obj \ 36 | $(OBJDIR)\draw.obj \ 37 | $(OBJDIR)\toolbar.obj \ 38 | $(OBJDIR)\drawconstraint.obj \ 39 | $(OBJDIR)\file.obj \ 40 | $(OBJDIR)\undoredo.obj \ 41 | $(OBJDIR)\system.obj \ 42 | $(OBJDIR)\polygon.obj \ 43 | $(OBJDIR)\mesh.obj \ 44 | $(OBJDIR)\bsp.obj \ 45 | $(OBJDIR)\ttf.obj \ 46 | $(OBJDIR)\generate.obj \ 47 | $(OBJDIR)\export.obj \ 48 | $(OBJDIR)\exportvector.obj \ 49 | $(OBJDIR)\exportstep.obj \ 50 | 51 | SRFOBJS = $(OBJDIR)\ratpoly.obj \ 52 | $(OBJDIR)\curve.obj \ 53 | $(OBJDIR)\surface.obj \ 54 | $(OBJDIR)\triangulate.obj \ 55 | $(OBJDIR)\boolean.obj \ 56 | $(OBJDIR)\surfinter.obj \ 57 | $(OBJDIR)\raycast.obj \ 58 | $(OBJDIR)\merge.obj \ 59 | 60 | 61 | RES = $(OBJDIR)\resource.res 62 | 63 | 64 | LIBS = user32.lib gdi32.lib comctl32.lib advapi32.lib shell32.lib opengl32.lib glu32.lib \ 65 | extlib\libpng.lib extlib\zlib.lib extlib\si\siapp.lib 66 | 67 | all: $(OBJDIR)/solvespace.exe 68 | @cp $(OBJDIR)/solvespace.exe . 69 | 70 | clean: 71 | rm -f obj/* 72 | 73 | $(OBJDIR)/solvespace.exe: $(SRFOBJS) $(SSOBJS) $(W32OBJS) $(FREEZE) $(RES) 74 | @$(CC) $(DEFINES) $(CFLAGS) -Fe$(OBJDIR)/solvespace.exe $(SSOBJS) $(SRFOBJS) $(W32OBJS) $(FREEZE) $(RES) $(LIBS) 75 | editbin /nologo /STACK:8388608 $(OBJDIR)/solvespace.exe 76 | @echo solvespace.exe 77 | 78 | $(SSOBJS): $(@B).cpp $(HEADERS) 79 | @$(CC) $(CFLAGS) $(DEFINES) -c -Fo$(OBJDIR)/$(@B).obj $(@B).cpp 80 | 81 | $(SRFOBJS): srf\$(@B).cpp $(HEADERS) 82 | @$(CC) $(CFLAGS) $(DEFINES) -c -Fo$(OBJDIR)/$(@B).obj srf\$(@B).cpp 83 | 84 | $(W32OBJS): win32/$(@B).cpp $(HEADERS) 85 | @$(CC) $(CFLAGS) $(DEFINES) -c -Fo$(OBJDIR)/$(@B).obj win32/$(@B).cpp 86 | 87 | $(FREEZE): ..\common\win32\$(@B).cpp $(HEADERS) 88 | @$(CC) $(CFLAGS) $(DEFINES) -c -Fo$(OBJDIR)/$(@B).obj ..\common\win32\$(@B).cpp 89 | 90 | $(RES): win32/$(@B).rc icon.ico 91 | rc win32/$(@B).rc 92 | mv win32/$(@B).res $(OBJDIR)/$(@B).res 93 | 94 | toolbar.cpp: $(OBJDIR)/icons.h 95 | 96 | textwin.cpp: $(OBJDIR)/icons.h 97 | 98 | glhelper.cpp: bitmapfont.table font.table bitmapextra.table 99 | 100 | $(OBJDIR)/icons.h: icons/* png2c.pl 101 | perl png2c.pl $(OBJDIR)/icons.h $(OBJDIR)/icons-proto.h 102 | 103 | -------------------------------------------------------------------------------- /solvespace/bitmapextra.table: -------------------------------------------------------------------------------- 1 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3 | 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 4 | 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 5 | 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 6 | 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 15 | 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 16 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17 | 18 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20 | 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 21 | 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 22 | 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 23 | 0, 0, 255, 255, 0, 0, 0, 255, 255, 255, 0, 0, 0, 255, 255, 0, 24 | 0, 0, 255, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0, 255, 255, 0, 25 | 0, 0, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 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, 255, 255, 255, 0, 0, 0, 255, 255, 0, 28 | 0, 0, 255, 255, 0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 255, 0, 29 | 0, 0, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 0, 30 | 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 31 | 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 32 | 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 33 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34 | 35 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37 | 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 38 | 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 39 | 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 40 | 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 41 | 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 42 | 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 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, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 46 | 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 47 | 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 48 | 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 49 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51 | 52 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54 | 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 55 | 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 56 | 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 57 | 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 58 | 0, 0, 255, 255, 0, 0, 0, 255, 255, 0, 0, 0, 255, 255, 0, 0, 59 | 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 0, 0, 255, 255, 0, 0, 60 | 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 0, 0, 255, 255, 0, 0, 61 | 0, 0, 255, 255, 0, 0, 0, 255, 255, 0, 0, 0, 255, 255, 0, 0, 62 | 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 63 | 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 64 | 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 65 | 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 66 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68 | 69 | -------------------------------------------------------------------------------- /solvespace/dsc.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Data structures used frequently in the program, various kinds of vectors 3 | // (of real numbers, not symbolic algebra stuff) and our templated lists. 4 | // 5 | // Copyright 2008-2013 Jonathan Westhues. 6 | //----------------------------------------------------------------------------- 7 | #ifndef __DSC_H 8 | #define __DSC_H 9 | 10 | typedef unsigned long DWORD; 11 | typedef unsigned char BYTE; 12 | 13 | class Vector; 14 | class Vector4; 15 | class Point2d; 16 | class hEntity; 17 | class hParam; 18 | 19 | class Quaternion { 20 | public: 21 | // a + (vx)*i + (vy)*j + (vz)*k 22 | double w, vx, vy, vz; 23 | 24 | static const Quaternion IDENTITY; 25 | 26 | static Quaternion From(double w, double vx, double vy, double vz); 27 | static Quaternion From(hParam w, hParam vx, hParam vy, hParam vz); 28 | static Quaternion From(Vector u, Vector v); 29 | static Quaternion From(Vector axis, double dtheta); 30 | 31 | Quaternion Plus(Quaternion b); 32 | Quaternion Minus(Quaternion b); 33 | Quaternion ScaledBy(double s); 34 | double Magnitude(void); 35 | Quaternion WithMagnitude(double s); 36 | 37 | // Call a rotation matrix [ u' v' n' ]'; this returns the first and 38 | // second rows, where that matrix is generated by this quaternion 39 | Vector RotationU(void); 40 | Vector RotationV(void); 41 | Vector RotationN(void); 42 | Vector Rotate(Vector p); 43 | 44 | Quaternion ToThe(double p); 45 | Quaternion Inverse(void); 46 | Quaternion Times(Quaternion b); 47 | Quaternion Mirror(void); 48 | }; 49 | 50 | class Vector { 51 | public: 52 | double x, y, z; 53 | 54 | static Vector From(double x, double y, double z); 55 | static Vector From(hParam x, hParam y, hParam z); 56 | static Vector AtIntersectionOfPlanes(Vector n1, double d1, 57 | Vector n2, double d2); 58 | static Vector AtIntersectionOfLines(Vector a0, Vector a1, 59 | Vector b0, Vector b1, 60 | bool *skew, 61 | double *pa=NULL, double *pb=NULL); 62 | static Vector AtIntersectionOfPlaneAndLine(Vector n, double d, 63 | Vector p0, Vector p1, 64 | bool *parallel); 65 | static Vector AtIntersectionOfPlanes(Vector na, double da, 66 | Vector nb, double db, 67 | Vector nc, double dc, bool *parallel); 68 | static void ClosestPointBetweenLines(Vector pa, Vector da, 69 | Vector pb, Vector db, 70 | double *ta, double *tb); 71 | 72 | double Element(int i); 73 | bool Equals(Vector v, double tol=LENGTH_EPS); 74 | bool EqualsExactly(Vector v); 75 | Vector Plus(Vector b); 76 | Vector Minus(Vector b); 77 | Vector Negated(void); 78 | Vector Cross(Vector b); 79 | double DirectionCosineWith(Vector b); 80 | double Dot(Vector b); 81 | Vector Normal(int which); 82 | Vector RotatedAbout(Vector orig, Vector axis, double theta); 83 | Vector RotatedAbout(Vector axis, double theta); 84 | Vector DotInToCsys(Vector u, Vector v, Vector n); 85 | Vector ScaleOutOfCsys(Vector u, Vector v, Vector n); 86 | double DistanceToLine(Vector p0, Vector dp); 87 | bool OnLineSegment(Vector a, Vector b, double tol=LENGTH_EPS); 88 | Vector ClosestPointOnLine(Vector p0, Vector dp); 89 | double Magnitude(void); 90 | double MagSquared(void); 91 | Vector WithMagnitude(double s); 92 | Vector ScaledBy(double s); 93 | Vector ProjectInto(hEntity wrkpl); 94 | Vector ProjectVectorInto(hEntity wrkpl); 95 | double DivPivoting(Vector delta); 96 | Vector ClosestOrtho(void); 97 | void MakeMaxMin(Vector *maxv, Vector *minv); 98 | Vector ClampWithin(double minv, double maxv); 99 | static bool BoundingBoxesDisjoint(Vector amax, Vector amin, 100 | Vector bmax, Vector bmin); 101 | static bool BoundingBoxIntersectsLine(Vector amax, Vector amin, 102 | Vector p0, Vector p1, bool segment); 103 | bool OutsideAndNotOn(Vector maxv, Vector minv); 104 | Vector InPerspective(Vector u, Vector v, Vector n, 105 | Vector origin, double cameraTan); 106 | Point2d Project2d(Vector u, Vector v); 107 | Point2d ProjectXy(void); 108 | Vector4 Project4d(void); 109 | }; 110 | 111 | class Vector4 { 112 | public: 113 | double w, x, y, z; 114 | 115 | static Vector4 From(double w, double x, double y, double z); 116 | static Vector4 From(double w, Vector v3); 117 | static Vector4 Blend(Vector4 a, Vector4 b, double t); 118 | 119 | Vector4 Plus(Vector4 b); 120 | Vector4 Minus(Vector4 b); 121 | Vector4 ScaledBy(double s); 122 | Vector PerspectiveProject(void); 123 | }; 124 | 125 | class Point2d { 126 | public: 127 | double x, y; 128 | 129 | static Point2d From(double x, double y); 130 | 131 | Point2d Plus(Point2d b); 132 | Point2d Minus(Point2d b); 133 | Point2d ScaledBy(double s); 134 | double DivPivoting(Point2d delta); 135 | double Dot(Point2d p); 136 | double DistanceTo(Point2d p); 137 | double DistanceToLine(Point2d p0, Point2d dp, bool segment); 138 | double Magnitude(void); 139 | double MagSquared(void); 140 | Point2d WithMagnitude(double v); 141 | Point2d Normal(void); 142 | bool Equals(Point2d v, double tol=LENGTH_EPS); 143 | }; 144 | 145 | // A simple list 146 | template 147 | class List { 148 | public: 149 | T *elem; 150 | int n; 151 | int elemsAllocated; 152 | 153 | void AllocForOneMore(void) { 154 | if(n >= elemsAllocated) { 155 | elemsAllocated = (elemsAllocated + 32)*2; 156 | elem = (T *)MemRealloc(elem, elemsAllocated*sizeof(elem[0])); 157 | } 158 | } 159 | 160 | void Add(T *t) { 161 | AllocForOneMore(); 162 | elem[n++] = *t; 163 | } 164 | 165 | void AddToBeginning(T *t) { 166 | AllocForOneMore(); 167 | memmove(elem+1, elem, n*sizeof(elem[0])); 168 | n++; 169 | elem[0] = *t; 170 | } 171 | 172 | T *First(void) { 173 | return (n == 0) ? NULL : &(elem[0]); 174 | } 175 | T *NextAfter(T *prev) { 176 | if(!prev) return NULL; 177 | if(prev - elem == (n - 1)) return NULL; 178 | return prev + 1; 179 | } 180 | 181 | void ClearTags(void) { 182 | int i; 183 | for(i = 0; i < n; i++) { 184 | elem[i].tag = 0; 185 | } 186 | } 187 | 188 | void Clear(void) { 189 | if(elem) MemFree(elem); 190 | elem = NULL; 191 | n = elemsAllocated = 0; 192 | } 193 | 194 | void RemoveTagged(void) { 195 | int src, dest; 196 | dest = 0; 197 | for(src = 0; src < n; src++) { 198 | if(elem[src].tag) { 199 | // this item should be deleted 200 | } else { 201 | if(src != dest) { 202 | elem[dest] = elem[src]; 203 | } 204 | dest++; 205 | } 206 | } 207 | n = dest; 208 | // and elemsAllocated is untouched, because we didn't resize 209 | } 210 | 211 | void RemoveLast(int cnt) { 212 | if(n < cnt) oops(); 213 | n -= cnt; 214 | // and elemsAllocated is untouched, same as in RemoveTagged 215 | } 216 | 217 | void Reverse(void) { 218 | int i; 219 | for(i = 0; i < (n/2); i++) { 220 | SWAP(T, elem[i], elem[(n-1)-i]); 221 | } 222 | } 223 | }; 224 | 225 | // A list, where each element has an integer identifier. The list is kept 226 | // sorted by that identifier, and items can be looked up in log n time by 227 | // id. 228 | template 229 | class IdList { 230 | public: 231 | T *elem; 232 | int n; 233 | int elemsAllocated; 234 | 235 | DWORD MaximumId(void) { 236 | DWORD id = 0; 237 | 238 | int i; 239 | for(i = 0; i < n; i++) { 240 | id = max(id, elem[i].h.v); 241 | } 242 | return id; 243 | } 244 | 245 | H AddAndAssignId(T *t) { 246 | t->h.v = (MaximumId() + 1); 247 | Add(t); 248 | 249 | return t->h; 250 | } 251 | 252 | void Add(T *t) { 253 | if(n >= elemsAllocated) { 254 | elemsAllocated = (elemsAllocated + 32)*2; 255 | elem = (T *)MemRealloc(elem, elemsAllocated*sizeof(elem[0])); 256 | } 257 | 258 | int first = 0, last = n; 259 | // We know that we must insert within the closed interval [first,last] 260 | while(first != last) { 261 | int mid = (first + last)/2; 262 | H hm = elem[mid].h; 263 | if(hm.v > t->h.v) { 264 | last = mid; 265 | } else if(hm.v < t->h.v) { 266 | first = mid + 1; 267 | } else { 268 | dbp("can't insert in list; is handle %d not unique?", t->h.v); 269 | oops(); 270 | } 271 | } 272 | int i = first; 273 | 274 | memmove(elem+i+1, elem+i, (n-i)*sizeof(elem[0])); 275 | elem[i] = *t; 276 | n++; 277 | } 278 | 279 | T *FindById(H h) { 280 | T *t = FindByIdNoOops(h); 281 | if(!t) { 282 | dbp("failed to look up item %08x, searched %d items", h.v, n); 283 | oops(); 284 | } 285 | return t; 286 | } 287 | 288 | T *FindByIdNoOops(H h) { 289 | int first = 0, last = n-1; 290 | while(first <= last) { 291 | int mid = (first + last)/2; 292 | H hm = elem[mid].h; 293 | if(hm.v > h.v) { 294 | last = mid-1; // and first stays the same 295 | } else if(hm.v < h.v) { 296 | first = mid+1; // and last stays the same 297 | } else { 298 | return &(elem[mid]); 299 | } 300 | } 301 | return NULL; 302 | } 303 | 304 | T *First(void) { 305 | return (n == 0) ? NULL : &(elem[0]); 306 | } 307 | T *NextAfter(T *prev) { 308 | if(!prev) return NULL; 309 | if(prev - elem == (n - 1)) return NULL; 310 | return prev + 1; 311 | } 312 | 313 | void ClearTags(void) { 314 | int i; 315 | for(i = 0; i < n; i++) { 316 | elem[i].tag = 0; 317 | } 318 | } 319 | 320 | void Tag(H h, int tag) { 321 | int i; 322 | for(i = 0; i < n; i++) { 323 | if(elem[i].h.v == h.v) { 324 | elem[i].tag = tag; 325 | } 326 | } 327 | } 328 | 329 | void RemoveTagged(void) { 330 | int src, dest; 331 | dest = 0; 332 | for(src = 0; src < n; src++) { 333 | if(elem[src].tag) { 334 | // this item should be deleted 335 | } else { 336 | if(src != dest) { 337 | elem[dest] = elem[src]; 338 | } 339 | dest++; 340 | } 341 | } 342 | n = dest; 343 | // and elemsAllocated is untouched, because we didn't resize 344 | } 345 | void RemoveById(H h) { 346 | ClearTags(); 347 | FindById(h)->tag = 1; 348 | RemoveTagged(); 349 | } 350 | 351 | void MoveSelfInto(IdList *l) { 352 | memcpy(l, this, sizeof(*this)); 353 | elemsAllocated = n = 0; 354 | elem = NULL; 355 | } 356 | 357 | void DeepCopyInto(IdList *l) { 358 | l->elem = (T *)MemAlloc(elemsAllocated * sizeof(elem[0])); 359 | memcpy(l->elem, elem, elemsAllocated * sizeof(elem[0])); 360 | l->elemsAllocated = elemsAllocated; 361 | l->n = n; 362 | } 363 | 364 | void Clear(void) { 365 | elemsAllocated = n = 0; 366 | if(elem) MemFree(elem); 367 | elem = NULL; 368 | } 369 | 370 | }; 371 | 372 | class NameStr { 373 | public: 374 | char str[64]; 375 | 376 | inline void strcpy(char *in) { 377 | memcpy(str, in, min(strlen(in)+1, sizeof(str))); 378 | str[sizeof(str)-1] = '\0'; 379 | } 380 | }; 381 | 382 | class BandedMatrix { 383 | public: 384 | static const int MAX_UNKNOWNS = 16; 385 | static const int RIGHT_OF_DIAG = 1; 386 | static const int LEFT_OF_DIAG = 2; 387 | 388 | double A[MAX_UNKNOWNS][MAX_UNKNOWNS]; 389 | double B[MAX_UNKNOWNS]; 390 | double X[MAX_UNKNOWNS]; 391 | int n; 392 | 393 | void Solve(void); 394 | }; 395 | 396 | #endif 397 | -------------------------------------------------------------------------------- /solvespace/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 | 70 | int StepFileWriter::ExportCurve(SBezier *sb) { 71 | int i, ret = id; 72 | 73 | fprintf(f, "#%d=(\n", ret); 74 | fprintf(f, "BOUNDED_CURVE()\n"); 75 | fprintf(f, "B_SPLINE_CURVE(%d,(", sb->deg); 76 | for(i = 0; i <= sb->deg; i++) { 77 | fprintf(f, "#%d", ret + i + 1); 78 | if(i != sb->deg) fprintf(f, ","); 79 | } 80 | fprintf(f, "),.UNSPECIFIED.,.F.,.F.)\n"); 81 | fprintf(f, "B_SPLINE_CURVE_WITH_KNOTS((%d,%d),", 82 | (sb->deg + 1), (sb-> deg + 1)); 83 | fprintf(f, "(0.000,1.000),.UNSPECIFIED.)\n"); 84 | fprintf(f, "CURVE()\n"); 85 | fprintf(f, "GEOMETRIC_REPRESENTATION_ITEM()\n"); 86 | fprintf(f, "RATIONAL_B_SPLINE_CURVE(("); 87 | for(i = 0; i <= sb->deg; i++) { 88 | fprintf(f, "%.10f", sb->weight[i]); 89 | if(i != sb->deg) fprintf(f, ","); 90 | } 91 | fprintf(f, "))\n"); 92 | fprintf(f, "REPRESENTATION_ITEM('')\n);\n"); 93 | 94 | for(i = 0; i <= sb->deg; i++) { 95 | fprintf(f, "#%d=CARTESIAN_POINT('',(%.10f,%.10f,%.10f));\n", 96 | id + 1 + i, 97 | CO(sb->ctrl[i])); 98 | } 99 | fprintf(f, "\n"); 100 | 101 | id = ret + 1 + (sb->deg + 1); 102 | return ret; 103 | } 104 | 105 | int StepFileWriter::ExportCurveLoop(SBezierLoop *loop, bool inner) { 106 | if(loop->l.n < 1) oops(); 107 | 108 | List listOfTrims; 109 | ZERO(&listOfTrims); 110 | 111 | SBezier *sb = &(loop->l.elem[loop->l.n - 1]); 112 | 113 | // Generate "exactly closed" contours, with the same vertex id for the 114 | // finish of a previous edge and the start of the next one. So we need 115 | // the finish of the last Bezier in the loop before we start our process. 116 | fprintf(f, "#%d=CARTESIAN_POINT('',(%.10f,%.10f,%.10f));\n", 117 | id, CO(sb->Finish())); 118 | fprintf(f, "#%d=VERTEX_POINT('',#%d);\n", id+1, id); 119 | int lastFinish = id + 1, prevFinish = lastFinish; 120 | id += 2; 121 | 122 | for(sb = loop->l.First(); sb; sb = loop->l.NextAfter(sb)) { 123 | int curveId = ExportCurve(sb); 124 | 125 | int thisFinish; 126 | if(loop->l.NextAfter(sb) != NULL) { 127 | fprintf(f, "#%d=CARTESIAN_POINT('',(%.10f,%.10f,%.10f));\n", 128 | id, CO(sb->Finish())); 129 | fprintf(f, "#%d=VERTEX_POINT('',#%d);\n", id+1, id); 130 | thisFinish = id + 1; 131 | id += 2; 132 | } else { 133 | thisFinish = lastFinish; 134 | } 135 | 136 | fprintf(f, "#%d=EDGE_CURVE('',#%d,#%d,#%d,%s);\n", 137 | id, prevFinish, thisFinish, curveId, ".T."); 138 | fprintf(f, "#%d=ORIENTED_EDGE('',*,*,#%d,.T.);\n", 139 | id+1, id); 140 | 141 | int oe = id+1; 142 | listOfTrims.Add(&oe); 143 | id += 2; 144 | 145 | prevFinish = thisFinish; 146 | } 147 | 148 | fprintf(f, "#%d=EDGE_LOOP('',(", id); 149 | int *oe; 150 | for(oe = listOfTrims.First(); oe; oe = listOfTrims.NextAfter(oe)) { 151 | fprintf(f, "#%d", *oe); 152 | if(listOfTrims.NextAfter(oe) != NULL) fprintf(f, ","); 153 | } 154 | fprintf(f, "));\n"); 155 | 156 | int fb = id + 1; 157 | fprintf(f, "#%d=%s('',#%d,.T.);\n", 158 | fb, inner ? "FACE_BOUND" : "FACE_OUTER_BOUND", id); 159 | 160 | id += 2; 161 | listOfTrims.Clear(); 162 | 163 | return fb; 164 | } 165 | 166 | void StepFileWriter::ExportSurface(SSurface *ss, SBezierList *sbl) { 167 | int i, j, srfid = id; 168 | 169 | // First, we create the untrimmed surface. We always specify a rational 170 | // B-spline surface (in fact, just a Bezier surface). 171 | fprintf(f, "#%d=(\n", srfid); 172 | fprintf(f, "BOUNDED_SURFACE()\n"); 173 | fprintf(f, "B_SPLINE_SURFACE(%d,%d,(", ss->degm, ss->degn); 174 | for(i = 0; i <= ss->degm; i++) { 175 | fprintf(f, "("); 176 | for(j = 0; j <= ss->degn; j++) { 177 | fprintf(f, "#%d", srfid + 1 + j + i*(ss->degn + 1)); 178 | if(j != ss->degn) fprintf(f, ","); 179 | } 180 | fprintf(f, ")"); 181 | if(i != ss->degm) fprintf(f, ","); 182 | } 183 | fprintf(f, "),.UNSPECIFIED.,.F.,.F.,.F.)\n"); 184 | fprintf(f, "B_SPLINE_SURFACE_WITH_KNOTS((%d,%d),(%d,%d),", 185 | (ss->degm + 1), (ss->degm + 1), 186 | (ss->degn + 1), (ss->degn + 1)); 187 | fprintf(f, "(0.000,1.000),(0.000,1.000),.UNSPECIFIED.)\n"); 188 | fprintf(f, "GEOMETRIC_REPRESENTATION_ITEM()\n"); 189 | fprintf(f, "RATIONAL_B_SPLINE_SURFACE(("); 190 | for(i = 0; i <= ss->degm; i++) { 191 | fprintf(f, "("); 192 | for(j = 0; j <= ss->degn; j++) { 193 | fprintf(f, "%.10f", ss->weight[i][j]); 194 | if(j != ss->degn) fprintf(f, ","); 195 | } 196 | fprintf(f, ")"); 197 | if(i != ss->degm) fprintf(f, ","); 198 | } 199 | fprintf(f, "))\n"); 200 | fprintf(f, "REPRESENTATION_ITEM('')\n"); 201 | fprintf(f, "SURFACE()\n"); 202 | fprintf(f, ");\n"); 203 | 204 | // The control points for the untrimmed surface. 205 | for(i = 0; i <= ss->degm; i++) { 206 | for(j = 0; j <= ss->degn; j++) { 207 | fprintf(f, "#%d=CARTESIAN_POINT('',(%.10f,%.10f,%.10f));\n", 208 | srfid + 1 + j + i*(ss->degn + 1), 209 | CO(ss->ctrl[i][j])); 210 | } 211 | } 212 | fprintf(f, "\n"); 213 | 214 | id = srfid + 1 + (ss->degm + 1)*(ss->degn + 1); 215 | 216 | // Now we do the trim curves. We must group each outer loop separately 217 | // along with its inner faces, so do that now. 218 | SBezierLoopSetSet sblss; 219 | ZERO(&sblss); 220 | SPolygon spxyz; 221 | ZERO(&spxyz); 222 | bool allClosed; 223 | SEdge notClosedAt; 224 | // We specify a surface, so it doesn't check for coplanarity; and we 225 | // don't want it to give us any open contours. The polygon and chord 226 | // tolerance are required, because they are used to calculate the 227 | // contour directions and determine inner vs. outer contours. 228 | sblss.FindOuterFacesFrom(sbl, &spxyz, ss, 229 | SS.ChordTolMm() / SS.exportScale, 230 | &allClosed, ¬ClosedAt, 231 | NULL, NULL, 232 | NULL); 233 | 234 | // So in our list of SBezierLoopSet, each set contains at least one loop 235 | // (the outer boundary), plus any inner loops associated with that outer 236 | // loop. 237 | SBezierLoopSet *sbls; 238 | for(sbls = sblss.l.First(); sbls; sbls = sblss.l.NextAfter(sbls)) { 239 | SBezierLoop *loop = sbls->l.First(); 240 | 241 | List listOfLoops; 242 | ZERO(&listOfLoops); 243 | // Create the face outer boundary from the outer loop. 244 | int fob = ExportCurveLoop(loop, false); 245 | listOfLoops.Add(&fob); 246 | 247 | // And create the face inner boundaries from any inner loops that 248 | // lie within this contour. 249 | loop = sbls->l.NextAfter(loop); 250 | for(; loop; loop = sbls->l.NextAfter(loop)) { 251 | int fib = ExportCurveLoop(loop, true); 252 | listOfLoops.Add(&fib); 253 | } 254 | 255 | // And now create the face that corresponds to this outer loop 256 | // and all of its holes. 257 | int advFaceId = id; 258 | fprintf(f, "#%d=ADVANCED_FACE('',(", advFaceId); 259 | int *fb; 260 | for(fb = listOfLoops.First(); fb; fb = listOfLoops.NextAfter(fb)) { 261 | fprintf(f, "#%d", *fb); 262 | if(listOfLoops.NextAfter(fb) != NULL) fprintf(f, ","); 263 | } 264 | 265 | fprintf(f, "),#%d,.T.);\n", srfid); 266 | fprintf(f, "\n"); 267 | advancedFaces.Add(&advFaceId); 268 | 269 | id++; 270 | listOfLoops.Clear(); 271 | } 272 | sblss.Clear(); 273 | spxyz.Clear(); 274 | } 275 | 276 | void StepFileWriter::WriteFooter(void) { 277 | fprintf(f, 278 | "\n" 279 | "ENDSEC;\n" 280 | "\n" 281 | "END-ISO-10303-21;\n" 282 | ); 283 | } 284 | 285 | void StepFileWriter::ExportSurfacesTo(char *file) { 286 | Group *g = SK.GetGroup(SS.GW.activeGroup); 287 | SShell *shell = &(g->runningShell); 288 | 289 | if(shell->surface.n == 0) { 290 | Error("The model does not contain any surfaces to export.%s", 291 | g->runningMesh.l.n > 0 ? 292 | "\n\nThe model does contain triangles from a mesh, but " 293 | "a triangle mesh cannot be exported as a STEP file. Try " 294 | "File -> Export Mesh... instead." : ""); 295 | return; 296 | } 297 | 298 | f = fopen(file, "wb"); 299 | if(!f) { 300 | Error("Couldn't write to '%s'", file); 301 | return; 302 | } 303 | 304 | WriteHeader(); 305 | 306 | ZERO(&advancedFaces); 307 | 308 | SSurface *ss; 309 | for(ss = shell->surface.First(); ss; ss = shell->surface.NextAfter(ss)) { 310 | if(ss->trim.n == 0) continue; 311 | 312 | // Get all of the loops of Beziers that trim our surface (with each 313 | // Bezier split so that we use the section as t goes from 0 to 1), and 314 | // the piecewise linearization of those loops in xyz space. 315 | SBezierList sbl; 316 | ZERO(&sbl); 317 | ss->MakeSectionEdgesInto(shell, NULL, &sbl); 318 | 319 | // Apply the export scale factor. 320 | ss->ScaleSelfBy(1.0/SS.exportScale); 321 | sbl.ScaleSelfBy(1.0/SS.exportScale); 322 | 323 | ExportSurface(ss, &sbl); 324 | 325 | sbl.Clear(); 326 | } 327 | 328 | fprintf(f, "#%d=CLOSED_SHELL('',(", id); 329 | int *af; 330 | for(af = advancedFaces.First(); af; af = advancedFaces.NextAfter(af)) { 331 | fprintf(f, "#%d", *af); 332 | if(advancedFaces.NextAfter(af) != NULL) fprintf(f, ","); 333 | } 334 | fprintf(f, "));\n"); 335 | fprintf(f, "#%d=MANIFOLD_SOLID_BREP('brep',#%d);\n", id+1, id); 336 | fprintf(f, "#%d=ADVANCED_BREP_SHAPE_REPRESENTATION('',(#%d,#170),#168);\n", 337 | id+2, id+1); 338 | fprintf(f, "#%d=SHAPE_REPRESENTATION_RELATIONSHIP($,$,#169,#%d);\n", 339 | id+3, id+2); 340 | 341 | WriteFooter(); 342 | 343 | fclose(f); 344 | advancedFaces.Clear(); 345 | } 346 | 347 | void StepFileWriter::WriteWireframe(void) { 348 | fprintf(f, "#%d=GEOMETRIC_CURVE_SET('curves',(", id); 349 | int *c; 350 | for(c = curves.First(); c; c = curves.NextAfter(c)) { 351 | fprintf(f, "#%d", *c); 352 | if(curves.NextAfter(c) != NULL) fprintf(f, ","); 353 | } 354 | fprintf(f, "));\n"); 355 | fprintf(f, "#%d=GEOMETRICALLY_BOUNDED_WIREFRAME_SHAPE_REPRESENTATION" 356 | "('',(#%d,#170),#168);\n", id+1, id); 357 | fprintf(f, "#%d=SHAPE_REPRESENTATION_RELATIONSHIP($,$,#169,#%d);\n", 358 | id+2, id+1); 359 | 360 | id += 3; 361 | curves.Clear(); 362 | } 363 | 364 | -------------------------------------------------------------------------------- /solvespace/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 WIN32 9 | # include 10 | #else 11 | # include 12 | # include 13 | #endif 14 | #include 15 | 16 | #include "slvs.h" 17 | 18 | Slvs_System sys; 19 | 20 | void *CheckMalloc(size_t n) 21 | { 22 | void *r = malloc(n); 23 | if(!r) { 24 | printf("out of memory!\n"); 25 | exit(-1); 26 | } 27 | return r; 28 | } 29 | 30 | //----------------------------------------------------------------------------- 31 | // An example of a constraint in 3d. We create a single group, with some 32 | // entities and constraints. 33 | //----------------------------------------------------------------------------- 34 | void Example3d(void) 35 | { 36 | // This will contain a single group, which will arbitrarily number 1. 37 | int g = 1; 38 | 39 | // A point, initially at (x y z) = (10 10 10) 40 | sys.param[sys.params++] = Slvs_MakeParam(1, g, 10.0); 41 | sys.param[sys.params++] = Slvs_MakeParam(2, g, 10.0); 42 | sys.param[sys.params++] = Slvs_MakeParam(3, g, 10.0); 43 | sys.entity[sys.entities++] = Slvs_MakePoint3d(101, g, 1, 2, 3); 44 | // and a second point at (20 20 20) 45 | sys.param[sys.params++] = Slvs_MakeParam(4, g, 20.0); 46 | sys.param[sys.params++] = Slvs_MakeParam(5, g, 20.0); 47 | sys.param[sys.params++] = Slvs_MakeParam(6, g, 20.0); 48 | sys.entity[sys.entities++] = Slvs_MakePoint3d(102, g, 4, 5, 6); 49 | // and a line segment connecting them. 50 | sys.entity[sys.entities++] = Slvs_MakeLineSegment(200, g, 51 | SLVS_FREE_IN_3D, 101, 102); 52 | 53 | // The distance between the points should be 30.0 units. 54 | sys.constraint[sys.constraints++] = Slvs_MakeConstraint( 55 | 1, g, 56 | SLVS_C_PT_PT_DISTANCE, 57 | SLVS_FREE_IN_3D, 58 | 30.0, 59 | 101, 102, 0, 0); 60 | 61 | // Let's tell the solver to keep the second point as close to constant 62 | // as possible, instead moving the first point. 63 | sys.dragged[0] = 4; 64 | sys.dragged[1] = 5; 65 | sys.dragged[2] = 6; 66 | 67 | // Now that we have written our system, we solve. 68 | Slvs_Solve(&sys, g); 69 | 70 | if(sys.result == SLVS_RESULT_OKAY) { 71 | printf("okay; now at (%.3f %.3f %.3f)\n" 72 | " (%.3f %.3f %.3f)\n", 73 | sys.param[0].val, sys.param[1].val, sys.param[2].val, 74 | sys.param[3].val, sys.param[4].val, sys.param[5].val); 75 | printf("%d DOF\n", sys.dof); 76 | } else { 77 | printf("solve failed"); 78 | } 79 | } 80 | 81 | //----------------------------------------------------------------------------- 82 | // An example of a constraint in 2d. In our first group, we create a workplane 83 | // along the reference frame's xy plane. In a second group, we create some 84 | // entities in that group and dimension them. 85 | //----------------------------------------------------------------------------- 86 | void Example2d(void) 87 | { 88 | int g; 89 | double qw, qx, qy, qz; 90 | 91 | g = 1; 92 | // First, we create our workplane. Its origin corresponds to the origin 93 | // of our base frame (x y z) = (0 0 0) 94 | sys.param[sys.params++] = Slvs_MakeParam(1, g, 0.0); 95 | sys.param[sys.params++] = Slvs_MakeParam(2, g, 0.0); 96 | sys.param[sys.params++] = Slvs_MakeParam(3, g, 0.0); 97 | sys.entity[sys.entities++] = Slvs_MakePoint3d(101, g, 1, 2, 3); 98 | // and it is parallel to the xy plane, so it has basis vectors (1 0 0) 99 | // and (0 1 0). 100 | Slvs_MakeQuaternion(1, 0, 0, 101 | 0, 1, 0, &qw, &qx, &qy, &qz); 102 | sys.param[sys.params++] = Slvs_MakeParam(4, g, qw); 103 | sys.param[sys.params++] = Slvs_MakeParam(5, g, qx); 104 | sys.param[sys.params++] = Slvs_MakeParam(6, g, qy); 105 | sys.param[sys.params++] = Slvs_MakeParam(7, g, qz); 106 | sys.entity[sys.entities++] = Slvs_MakeNormal3d(102, g, 4, 5, 6, 7); 107 | 108 | sys.entity[sys.entities++] = Slvs_MakeWorkplane(200, g, 101, 102); 109 | 110 | // Now create a second group. We'll solve group 2, while leaving group 1 111 | // constant; so the workplane that we've created will be locked down, 112 | // and the solver can't move it. 113 | g = 2; 114 | // These points are represented by their coordinates (u v) within the 115 | // workplane, so they need only two parameters each. 116 | sys.param[sys.params++] = Slvs_MakeParam(11, g, 10.0); 117 | sys.param[sys.params++] = Slvs_MakeParam(12, g, 20.0); 118 | sys.entity[sys.entities++] = Slvs_MakePoint2d(301, g, 200, 11, 12); 119 | 120 | sys.param[sys.params++] = Slvs_MakeParam(13, g, 20.0); 121 | sys.param[sys.params++] = Slvs_MakeParam(14, g, 10.0); 122 | sys.entity[sys.entities++] = Slvs_MakePoint2d(302, g, 200, 13, 14); 123 | 124 | // And we create a line segment with those endpoints. 125 | sys.entity[sys.entities++] = Slvs_MakeLineSegment(400, g, 126 | 200, 301, 302); 127 | 128 | // Now three more points. 129 | sys.param[sys.params++] = Slvs_MakeParam(15, g, 100.0); 130 | sys.param[sys.params++] = Slvs_MakeParam(16, g, 120.0); 131 | sys.entity[sys.entities++] = Slvs_MakePoint2d(303, g, 200, 15, 16); 132 | 133 | sys.param[sys.params++] = Slvs_MakeParam(17, g, 120.0); 134 | sys.param[sys.params++] = Slvs_MakeParam(18, g, 110.0); 135 | sys.entity[sys.entities++] = Slvs_MakePoint2d(304, g, 200, 17, 18); 136 | 137 | sys.param[sys.params++] = Slvs_MakeParam(19, g, 115.0); 138 | sys.param[sys.params++] = Slvs_MakeParam(20, g, 115.0); 139 | sys.entity[sys.entities++] = Slvs_MakePoint2d(305, g, 200, 19, 20); 140 | 141 | // And arc, centered at point 303, starting at point 304, ending at 142 | // point 305. 143 | sys.entity[sys.entities++] = Slvs_MakeArcOfCircle(401, g, 200, 102, 144 | 303, 304, 305); 145 | 146 | // Now one more point, and a distance 147 | sys.param[sys.params++] = Slvs_MakeParam(21, g, 200.0); 148 | sys.param[sys.params++] = Slvs_MakeParam(22, g, 200.0); 149 | sys.entity[sys.entities++] = Slvs_MakePoint2d(306, g, 200, 21, 22); 150 | 151 | sys.param[sys.params++] = Slvs_MakeParam(23, g, 30.0); 152 | sys.entity[sys.entities++] = Slvs_MakeDistance(307, g, 200, 23); 153 | 154 | // And a complete circle, centered at point 306 with radius equal to 155 | // distance 307. The normal is 102, the same as our workplane. 156 | sys.entity[sys.entities++] = Slvs_MakeCircle(402, g, 200, 157 | 306, 102, 307); 158 | 159 | 160 | // The length of our line segment is 30.0 units. 161 | sys.constraint[sys.constraints++] = Slvs_MakeConstraint( 162 | 1, g, 163 | SLVS_C_PT_PT_DISTANCE, 164 | 200, 165 | 30.0, 166 | 301, 302, 0, 0); 167 | 168 | // And the distance from our line segment to the origin is 10.0 units. 169 | sys.constraint[sys.constraints++] = Slvs_MakeConstraint( 170 | 2, g, 171 | SLVS_C_PT_LINE_DISTANCE, 172 | 200, 173 | 10.0, 174 | 101, 0, 400, 0); 175 | // And the line segment is vertical. 176 | sys.constraint[sys.constraints++] = Slvs_MakeConstraint( 177 | 3, g, 178 | SLVS_C_VERTICAL, 179 | 200, 180 | 0.0, 181 | 0, 0, 400, 0); 182 | // And the distance from one endpoint to the origin is 15.0 units. 183 | sys.constraint[sys.constraints++] = Slvs_MakeConstraint( 184 | 4, g, 185 | SLVS_C_PT_PT_DISTANCE, 186 | 200, 187 | 15.0, 188 | 301, 101, 0, 0); 189 | /* 190 | // And same for the other endpoint; so if you add this constraint then 191 | // the sketch is overconstrained and will signal an error. 192 | sys.constraint[sys.constraints++] = Slvs_MakeConstraint( 193 | 5, g, 194 | SLVS_C_PT_PT_DISTANCE, 195 | 200, 196 | 18.0, 197 | 302, 101, 0, 0); */ 198 | 199 | // The arc and the circle have equal radius. 200 | sys.constraint[sys.constraints++] = Slvs_MakeConstraint( 201 | 6, g, 202 | SLVS_C_EQUAL_RADIUS, 203 | 200, 204 | 0.0, 205 | 0, 0, 401, 402); 206 | // The arc has radius 17.0 units. 207 | sys.constraint[sys.constraints++] = Slvs_MakeConstraint( 208 | 7, g, 209 | SLVS_C_DIAMETER, 210 | 200, 211 | 17.0*2, 212 | 0, 0, 401, 0); 213 | 214 | // If the solver fails, then ask it to report which constraints caused 215 | // the problem. 216 | sys.calculateFaileds = 1; 217 | 218 | // And solve. 219 | Slvs_Solve(&sys, g); 220 | 221 | if(sys.result == SLVS_RESULT_OKAY) { 222 | printf("solved okay\n"); 223 | printf("line from (%.3f %.3f) to (%.3f %.3f)\n", 224 | sys.param[7].val, sys.param[8].val, 225 | sys.param[9].val, sys.param[10].val); 226 | 227 | printf("arc center (%.3f %.3f) start (%.3f %.3f) finish (%.3f %.3f)\n", 228 | sys.param[11].val, sys.param[12].val, 229 | sys.param[13].val, sys.param[14].val, 230 | sys.param[15].val, sys.param[16].val); 231 | 232 | printf("circle center (%.3f %.3f) radius %.3f\n", 233 | sys.param[17].val, sys.param[18].val, 234 | sys.param[19].val); 235 | printf("%d DOF\n", sys.dof); 236 | } else { 237 | int i; 238 | printf("solve failed: problematic constraints are:"); 239 | for(i = 0; i < sys.faileds; i++) { 240 | printf(" %lu", sys.failed[i]); 241 | } 242 | printf("\n"); 243 | if(sys.result == SLVS_RESULT_INCONSISTENT) { 244 | printf("system inconsistent\n"); 245 | } else { 246 | printf("system nonconvergent\n"); 247 | } 248 | } 249 | } 250 | 251 | int main(void) 252 | { 253 | memset(&sys, 0, sizeof(sys)); 254 | sys.param = (Slvs_Param *) CheckMalloc(50*sizeof(sys.param[0])); 255 | sys.entity = (Slvs_Entity *) CheckMalloc(50*sizeof(sys.entity[0])); 256 | sys.constraint = (Slvs_Constraint *) CheckMalloc(50*sizeof(sys.constraint[0])); 257 | 258 | sys.failed = (Slvs_hConstraint *) CheckMalloc(50*sizeof(sys.failed[0])); 259 | sys.faileds = 50; 260 | 261 | for(;;) { 262 | Example2d(); 263 | sys.params = sys.constraints = sys.entities = 0; 264 | break; 265 | } 266 | 267 | 268 | 269 | memset(&sys, 0, sizeof(sys)); 270 | sys.param = (Slvs_Param *) CheckMalloc(50*sizeof(sys.param[0])); 271 | sys.entity = (Slvs_Entity *) CheckMalloc(50*sizeof(sys.entity[0])); 272 | sys.constraint = (Slvs_Constraint *) CheckMalloc(50*sizeof(sys.constraint[0])); 273 | 274 | sys.failed = (Slvs_hConstraint *) CheckMalloc(50*sizeof(sys.failed[0])); 275 | sys.faileds = 50; 276 | 277 | Example3d(); 278 | 279 | return 0; 280 | } 281 | 282 | -------------------------------------------------------------------------------- /solvespace/exposed/Makefile: -------------------------------------------------------------------------------- 1 | WIN_DEFINES = -D_WIN32_WINNT=0x500 -D_WIN32_IE=0x500 -DWIN32_LEAN_AND_MEAN 2 | DEFINES = -DISOLATION_AWARE_ENABLED -DLIBRARY 3 | # Use the multi-threaded static libc because libpng and zlib do; not sure if anything bad 4 | # happens if those mix, but don't want to risk it. 5 | #TODO -MT - multithread? 6 | #TODO /Zi /EHs /O2 /GS- 7 | CFLAGS = -Iextlib -I../../common/win32 -D_DEBUG -D_CRT_SECURE_NO_WARNINGS -I. -I.. -O2 -g -Wno-write-strings -fpermissive 8 | CFLAGS_SHARED = -fPIC -shared $(CFLAGS) 9 | 10 | HEADERS = ../solvespace.h ../dsc.h ../sketch.h ../expr.h slvs.h 11 | 12 | OBJDIR = obj 13 | 14 | SSOBJS = $(OBJDIR)/util.obj \ 15 | $(OBJDIR)/entity.obj \ 16 | $(OBJDIR)/expr.obj \ 17 | $(OBJDIR)/constrainteq.obj \ 18 | $(OBJDIR)/system.obj \ 19 | 20 | 21 | W32OBJS = $(OBJDIR)/w32util.obj \ 22 | 23 | 24 | LIBOBJS = $(OBJDIR)/lib.obj \ 25 | 26 | 27 | #LIBS = user32.lib gdi32.lib comctl32.lib advapi32.lib shell32.lib 28 | LIBS = 29 | 30 | CC = gcc 31 | CXX = g++ 32 | 33 | all: cdemo _slvs.so slvs.py 34 | LD_LIBRARY_PATH=. ./cdemo 35 | 36 | test-python: _slvs.so slvs.py 37 | python test.py 38 | 39 | clean: 40 | rm -f obj/* cdemo libslvs.so _slvs.so slvs.py slvs_wrap.cxx 41 | 42 | .SECONDEXPANSION: 43 | 44 | libslvs.so: $(SSOBJS) $(LIBOBJS) $(W32OBJS) 45 | $(CXX) -shared -fPIC -o$@ $(SSOBJS) $(LIBOBJS) $(W32OBJS) $(LIBS) 46 | 47 | cdemo: CDemo.c libslvs.so 48 | $(CXX) $(CFLAGS) -o$@ CDemo.c -L. -lslvs $(LIBS) 49 | 50 | $(SSOBJS): ../$$(basename $$(notdir $$@)).cpp $(HEADERS) 51 | $(CXX) $(CFLAGS_SHARED) $(DEFINES) -c -o$@ $< 52 | 53 | $(W32OBJS): ../win32/$$(basename $$(notdir $$@)).cpp $(HEADERS) 54 | $(CXX) $(CFLAGS_SHARED) $(DEFINES) -c -o$@ $< 55 | 56 | $(LIBOBJS): $$(basename $$(notdir $$@)).cpp $(HEADERS) 57 | $(CXX) $(CFLAGS_SHARED) $(DEFINES) -c -o$@ $< 58 | 59 | slvs.py slvs_wrap.cxx: slvs.i slvs_python.hpp 60 | swig -c++ -python slvs.i 61 | 62 | $(OBJDIR)/slvs_wrap.o: slvs_wrap.cxx slvs_python.hpp 63 | $(CXX) $(CFLAGS_SHARED) -Wno-unused-but-set-variable -c -o$@ $< `python2-config --cflags` 64 | 65 | _slvs.so: $(SSOBJS) $(LIBOBJS) $(W32OBJS) $(OBJDIR)/slvs_wrap.o 66 | $(CXX) -shared -fPIC -o$@ $(SSOBJS) $(LIBOBJS) $(W32OBJS) $(OBJDIR)/slvs_wrap.o $(LIBS) `python2-config --ldflags` 67 | -------------------------------------------------------------------------------- /solvespace/exposed/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 "slvs.h" 10 | 11 | Sketch SK; 12 | System SYS; 13 | 14 | int IsInit = 0; 15 | 16 | void Group::GenerateEquations(IdList *l) { 17 | // Nothing to do for now. 18 | } 19 | 20 | void DoMessageBox(char *str, int rows, int cols, BOOL error) 21 | { 22 | } 23 | 24 | extern "C" { 25 | 26 | void Slvs_QuaternionU(double qw, double qx, double qy, double qz, 27 | double *x, double *y, double *z) 28 | { 29 | Quaternion q = Quaternion::From(qw, qx, qy, qz); 30 | Vector v = q.RotationU(); 31 | *x = v.x; 32 | *y = v.y; 33 | *z = v.z; 34 | } 35 | 36 | void Slvs_QuaternionV(double qw, double qx, double qy, double qz, 37 | double *x, double *y, double *z) 38 | { 39 | Quaternion q = Quaternion::From(qw, qx, qy, qz); 40 | Vector v = q.RotationV(); 41 | *x = v.x; 42 | *y = v.y; 43 | *z = v.z; 44 | } 45 | 46 | void Slvs_QuaternionN(double qw, double qx, double qy, double qz, 47 | double *x, double *y, double *z) 48 | { 49 | Quaternion q = Quaternion::From(qw, qx, qy, qz); 50 | Vector v = q.RotationN(); 51 | *x = v.x; 52 | *y = v.y; 53 | *z = v.z; 54 | } 55 | 56 | void Slvs_MakeQuaternion(double ux, double uy, double uz, 57 | double vx, double vy, double vz, 58 | double *qw, double *qx, double *qy, double *qz) 59 | { 60 | Vector u = Vector::From(ux, uy, uz), 61 | v = Vector::From(vx, vy, vz); 62 | Quaternion q = Quaternion::From(u, v); 63 | *qw = q.w; 64 | *qx = q.vx; 65 | *qy = q.vy; 66 | *qz = q.vz; 67 | } 68 | 69 | void Slvs_Solve(Slvs_System *ssys, Slvs_hGroup shg) 70 | { 71 | if(!IsInit) { 72 | InitHeaps(); 73 | IsInit = 1; 74 | } 75 | 76 | int i; 77 | for(i = 0; i < ssys->params; i++) { 78 | Slvs_Param *sp = &(ssys->param[i]); 79 | Param p; 80 | ZERO(&p); 81 | 82 | p.h.v = sp->h; 83 | p.val = sp->val; 84 | SK.param.Add(&p); 85 | if(sp->group == shg) { 86 | SYS.param.Add(&p); 87 | } 88 | } 89 | 90 | for(i = 0; i < ssys->entities; i++) { 91 | Slvs_Entity *se = &(ssys->entity[i]); 92 | EntityBase e; 93 | ZERO(&e); 94 | 95 | switch(se->type) { 96 | case SLVS_E_POINT_IN_3D: e.type = Entity::POINT_IN_3D; break; 97 | case SLVS_E_POINT_IN_2D: e.type = Entity::POINT_IN_2D; break; 98 | case SLVS_E_NORMAL_IN_3D: e.type = Entity::NORMAL_IN_3D; break; 99 | case SLVS_E_NORMAL_IN_2D: e.type = Entity::NORMAL_IN_2D; break; 100 | case SLVS_E_DISTANCE: e.type = Entity::DISTANCE; break; 101 | case SLVS_E_WORKPLANE: e.type = Entity::WORKPLANE; break; 102 | case SLVS_E_LINE_SEGMENT: e.type = Entity::LINE_SEGMENT; break; 103 | case SLVS_E_CUBIC: e.type = Entity::CUBIC; break; 104 | case SLVS_E_CIRCLE: e.type = Entity::CIRCLE; break; 105 | case SLVS_E_ARC_OF_CIRCLE: e.type = Entity::ARC_OF_CIRCLE; break; 106 | 107 | default: dbp("bad entity type %d", se->type); return; 108 | } 109 | e.h.v = se->h; 110 | e.group.v = se->group; 111 | e.workplane.v = se->wrkpl; 112 | e.point[0].v = se->point[0]; 113 | e.point[1].v = se->point[1]; 114 | e.point[2].v = se->point[2]; 115 | e.point[3].v = se->point[3]; 116 | e.normal.v = se->normal; 117 | e.distance.v = se->distance; 118 | e.param[0].v = se->param[0]; 119 | e.param[1].v = se->param[1]; 120 | e.param[2].v = se->param[2]; 121 | e.param[3].v = se->param[3]; 122 | 123 | SK.entity.Add(&e); 124 | } 125 | 126 | for(i = 0; i < ssys->constraints; i++) { 127 | Slvs_Constraint *sc = &(ssys->constraint[i]); 128 | ConstraintBase c; 129 | ZERO(&c); 130 | 131 | int t; 132 | switch(sc->type) { 133 | case SLVS_C_POINTS_COINCIDENT: t = Constraint::POINTS_COINCIDENT; break; 134 | case SLVS_C_PT_PT_DISTANCE: t = Constraint::PT_PT_DISTANCE; break; 135 | case SLVS_C_PT_PLANE_DISTANCE: t = Constraint::PT_PLANE_DISTANCE; break; 136 | case SLVS_C_PT_LINE_DISTANCE: t = Constraint::PT_LINE_DISTANCE; break; 137 | case SLVS_C_PT_FACE_DISTANCE: t = Constraint::PT_FACE_DISTANCE; break; 138 | case SLVS_C_PT_IN_PLANE: t = Constraint::PT_IN_PLANE; break; 139 | case SLVS_C_PT_ON_LINE: t = Constraint::PT_ON_LINE; break; 140 | case SLVS_C_PT_ON_FACE: t = Constraint::PT_ON_FACE; break; 141 | case SLVS_C_EQUAL_LENGTH_LINES: t = Constraint::EQUAL_LENGTH_LINES; break; 142 | case SLVS_C_LENGTH_RATIO: t = Constraint::LENGTH_RATIO; break; 143 | case SLVS_C_EQ_LEN_PT_LINE_D: t = Constraint::EQ_LEN_PT_LINE_D; break; 144 | case SLVS_C_EQ_PT_LN_DISTANCES: t = Constraint::EQ_PT_LN_DISTANCES; break; 145 | case SLVS_C_EQUAL_ANGLE: t = Constraint::EQUAL_ANGLE; break; 146 | case SLVS_C_EQUAL_LINE_ARC_LEN: t = Constraint::EQUAL_LINE_ARC_LEN; break; 147 | case SLVS_C_SYMMETRIC: t = Constraint::SYMMETRIC; break; 148 | case SLVS_C_SYMMETRIC_HORIZ: t = Constraint::SYMMETRIC_HORIZ; break; 149 | case SLVS_C_SYMMETRIC_VERT: t = Constraint::SYMMETRIC_VERT; break; 150 | case SLVS_C_SYMMETRIC_LINE: t = Constraint::SYMMETRIC_LINE; break; 151 | case SLVS_C_AT_MIDPOINT: t = Constraint::AT_MIDPOINT; break; 152 | case SLVS_C_HORIZONTAL: t = Constraint::HORIZONTAL; break; 153 | case SLVS_C_VERTICAL: t = Constraint::VERTICAL; break; 154 | case SLVS_C_DIAMETER: t = Constraint::DIAMETER; break; 155 | case SLVS_C_PT_ON_CIRCLE: t = Constraint::PT_ON_CIRCLE; break; 156 | case SLVS_C_SAME_ORIENTATION: t = Constraint::SAME_ORIENTATION; break; 157 | case SLVS_C_ANGLE: t = Constraint::ANGLE; break; 158 | case SLVS_C_PARALLEL: t = Constraint::PARALLEL; break; 159 | case SLVS_C_PERPENDICULAR: t = Constraint::PERPENDICULAR; break; 160 | case SLVS_C_ARC_LINE_TANGENT: t = Constraint::ARC_LINE_TANGENT; break; 161 | case SLVS_C_CUBIC_LINE_TANGENT: t = Constraint::CUBIC_LINE_TANGENT; break; 162 | case SLVS_C_EQUAL_RADIUS: t = Constraint::EQUAL_RADIUS; break; 163 | case SLVS_C_PROJ_PT_DISTANCE: t = Constraint::PROJ_PT_DISTANCE; break; 164 | case SLVS_C_WHERE_DRAGGED: t = Constraint::WHERE_DRAGGED; break; 165 | case SLVS_C_CURVE_CURVE_TANGENT:t = Constraint::CURVE_CURVE_TANGENT; break; 166 | 167 | default: dbp("bad constraint type %d", sc->type); return; 168 | } 169 | 170 | c.type = t; 171 | 172 | c.h.v = sc->h; 173 | c.group.v = sc->group; 174 | c.workplane.v = sc->wrkpl; 175 | c.valA = sc->valA; 176 | c.ptA.v = sc->ptA; 177 | c.ptB.v = sc->ptB; 178 | c.entityA.v = sc->entityA; 179 | c.entityB.v = sc->entityB; 180 | c.entityC.v = sc->entityC; 181 | c.entityD.v = sc->entityD; 182 | c.other = (sc->other) ? true : false; 183 | c.other2 = (sc->other2) ? true : false; 184 | 185 | SK.constraint.Add(&c); 186 | } 187 | 188 | for(i = 0; i < arraylen(ssys->dragged); i++) { 189 | if(ssys->dragged[i]) { 190 | hParam hp = { ssys->dragged[i] }; 191 | SYS.dragged.Add(&hp); 192 | } 193 | } 194 | 195 | Group g; 196 | ZERO(&g); 197 | g.h.v = shg; 198 | 199 | List bad; 200 | ZERO(&bad); 201 | 202 | // Now we're finally ready to solve! 203 | bool andFindBad = ssys->calculateFaileds ? true : false; 204 | int how = SYS.Solve(&g, &(ssys->dof), &bad, andFindBad, false); 205 | 206 | switch(how) { 207 | case System::SOLVED_OKAY: 208 | ssys->result = SLVS_RESULT_OKAY; 209 | break; 210 | 211 | case System::DIDNT_CONVERGE: 212 | ssys->result = SLVS_RESULT_DIDNT_CONVERGE; 213 | break; 214 | 215 | case System::SINGULAR_JACOBIAN: 216 | ssys->result = SLVS_RESULT_INCONSISTENT; 217 | break; 218 | 219 | case System::TOO_MANY_UNKNOWNS: 220 | ssys->result = SLVS_RESULT_TOO_MANY_UNKNOWNS; 221 | break; 222 | 223 | default: oops(); 224 | } 225 | 226 | // Write the new parameter values back to our caller. 227 | for(i = 0; i < ssys->params; i++) { 228 | Slvs_Param *sp = &(ssys->param[i]); 229 | hParam hp = { sp->h }; 230 | sp->val = SK.GetParam(hp)->val; 231 | } 232 | 233 | if(ssys->failed) { 234 | // Copy over any the list of problematic constraints. 235 | for(i = 0; i < ssys->faileds && i < bad.n; i++) { 236 | ssys->failed[i] = bad.elem[i].v; 237 | } 238 | ssys->faileds = bad.n; 239 | } 240 | 241 | bad.Clear(); 242 | SYS.param.Clear(); 243 | SYS.entity.Clear(); 244 | SYS.eq.Clear(); 245 | SYS.dragged.Clear(); 246 | 247 | SK.param.Clear(); 248 | SK.entity.Clear(); 249 | SK.constraint.Clear(); 250 | 251 | FreeAllTemporary(); 252 | } 253 | 254 | } 255 | -------------------------------------------------------------------------------- /solvespace/exposed/slvs.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Data structures and prototypes for slvs.lib, a geometric constraint solver. 3 | // 4 | // See the comments in this file, the accompanying sample code that uses 5 | // this library, and the accompanying documentation (DOC.txt). 6 | // 7 | // Copyright 2009-2013 Jonathan Westhues. 8 | //----------------------------------------------------------------------------- 9 | 10 | #ifndef __SLVS_H 11 | #define __SLVS_H 12 | 13 | #ifndef __DSC_H 14 | typedef unsigned long DWORD; 15 | typedef unsigned char BYTE; 16 | #endif 17 | 18 | 19 | #ifdef WIN32 20 | #ifdef EXPORT_DLL 21 | #define DLL __declspec( dllexport ) 22 | #else 23 | #define DLL __declspec( dllimport ) 24 | #endif 25 | #else 26 | // I think on Windows that would be __declspec(dll{ex,im}port), but 27 | // in Linux we don't need it. 28 | #define DLL 29 | #endif 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | typedef DWORD Slvs_hParam; 36 | typedef DWORD Slvs_hEntity; 37 | typedef DWORD Slvs_hConstraint; 38 | typedef DWORD Slvs_hGroup; 39 | 40 | // To obtain the 3d (not projected into a workplane) of a constraint or 41 | // an entity, specify this instead of the workplane. 42 | #define SLVS_FREE_IN_3D 0 43 | 44 | 45 | typedef struct { 46 | Slvs_hParam h; 47 | Slvs_hGroup group; 48 | double val; 49 | } Slvs_Param; 50 | 51 | 52 | #define SLVS_E_POINT_IN_3D 50000 53 | #define SLVS_E_POINT_IN_2D 50001 54 | 55 | #define SLVS_E_NORMAL_IN_3D 60000 56 | #define SLVS_E_NORMAL_IN_2D 60001 57 | 58 | #define SLVS_E_DISTANCE 70000 59 | 60 | // The special point, normal, and distance types used for parametric step 61 | // and repeat, extrude, and assembly are currently not exposed. Please 62 | // contact us if you are interested in using these. 63 | 64 | #define SLVS_E_WORKPLANE 80000 65 | #define SLVS_E_LINE_SEGMENT 80001 66 | #define SLVS_E_CUBIC 80002 67 | #define SLVS_E_CIRCLE 80003 68 | #define SLVS_E_ARC_OF_CIRCLE 80004 69 | 70 | typedef struct { 71 | Slvs_hEntity h; 72 | Slvs_hGroup group; 73 | 74 | int type; 75 | 76 | Slvs_hEntity wrkpl; 77 | Slvs_hEntity point[4]; 78 | Slvs_hEntity normal; 79 | Slvs_hEntity distance; 80 | 81 | Slvs_hParam param[4]; 82 | } Slvs_Entity; 83 | 84 | #define SLVS_C_POINTS_COINCIDENT 100000 85 | #define SLVS_C_PT_PT_DISTANCE 100001 86 | #define SLVS_C_PT_PLANE_DISTANCE 100002 87 | #define SLVS_C_PT_LINE_DISTANCE 100003 88 | #define SLVS_C_PT_FACE_DISTANCE 100004 89 | #define SLVS_C_PT_IN_PLANE 100005 90 | #define SLVS_C_PT_ON_LINE 100006 91 | #define SLVS_C_PT_ON_FACE 100007 92 | #define SLVS_C_EQUAL_LENGTH_LINES 100008 93 | #define SLVS_C_LENGTH_RATIO 100009 94 | #define SLVS_C_EQ_LEN_PT_LINE_D 100010 95 | #define SLVS_C_EQ_PT_LN_DISTANCES 100011 96 | #define SLVS_C_EQUAL_ANGLE 100012 97 | #define SLVS_C_EQUAL_LINE_ARC_LEN 100013 98 | #define SLVS_C_SYMMETRIC 100014 99 | #define SLVS_C_SYMMETRIC_HORIZ 100015 100 | #define SLVS_C_SYMMETRIC_VERT 100016 101 | #define SLVS_C_SYMMETRIC_LINE 100017 102 | #define SLVS_C_AT_MIDPOINT 100018 103 | #define SLVS_C_HORIZONTAL 100019 104 | #define SLVS_C_VERTICAL 100020 105 | #define SLVS_C_DIAMETER 100021 106 | #define SLVS_C_PT_ON_CIRCLE 100022 107 | #define SLVS_C_SAME_ORIENTATION 100023 108 | #define SLVS_C_ANGLE 100024 109 | #define SLVS_C_PARALLEL 100025 110 | #define SLVS_C_PERPENDICULAR 100026 111 | #define SLVS_C_ARC_LINE_TANGENT 100027 112 | #define SLVS_C_CUBIC_LINE_TANGENT 100028 113 | #define SLVS_C_EQUAL_RADIUS 100029 114 | #define SLVS_C_PROJ_PT_DISTANCE 100030 115 | #define SLVS_C_WHERE_DRAGGED 100031 116 | #define SLVS_C_CURVE_CURVE_TANGENT 100032 117 | 118 | typedef struct { 119 | Slvs_hConstraint h; 120 | Slvs_hGroup group; 121 | 122 | int type; 123 | 124 | Slvs_hEntity wrkpl; 125 | 126 | double valA; 127 | Slvs_hEntity ptA; 128 | Slvs_hEntity ptB; 129 | Slvs_hEntity entityA; 130 | Slvs_hEntity entityB; 131 | Slvs_hEntity entityC; 132 | Slvs_hEntity entityD; 133 | 134 | int other; 135 | int other2; 136 | } Slvs_Constraint; 137 | 138 | 139 | typedef struct { 140 | //// INPUT VARIABLES 141 | // 142 | // Here, we specify the parameters and their initial values, the entities, 143 | // and the constraints. For example, param[] points to the array of 144 | // parameters, which has length params, so that the last valid element 145 | // is param[params-1]. 146 | // 147 | // param[] is actually an in/out variable; if the solver is successful, 148 | // then the new values (that satisfy the constraints) are written to it. 149 | // 150 | Slvs_Param *param; 151 | int params; 152 | Slvs_Entity *entity; 153 | int entities; 154 | Slvs_Constraint *constraint; 155 | int constraints; 156 | 157 | // If a parameter corresponds to a point (distance, normal, etc.) being 158 | // dragged, then specify it here. This will cause the solver to favor 159 | // that parameter, and attempt to change it as little as possible even 160 | // if that requires it to change other parameters more. 161 | // 162 | // Unused members of this array should be set to zero. 163 | Slvs_hParam dragged[4]; 164 | 165 | // If the solver fails, then it can determine which constraints are 166 | // causing the problem. But this is a relatively slow process (for 167 | // a system with n constraints, about n times as long as just solving). 168 | // If calculateFaileds is true, then the solver will do so, otherwise 169 | // not. 170 | int calculateFaileds; 171 | 172 | //// OUTPUT VARIABLES 173 | // 174 | // If the solver fails, then it can report which constraints are causing 175 | // the problem. The caller should allocate the array failed[], and pass 176 | // its size in faileds. 177 | // 178 | // The solver will set faileds equal to the number of problematic 179 | // constraints, and write their Slvs_hConstraints into failed[]. To 180 | // ensure that there is sufficient space for any possible set of 181 | // failing constraints, faileds should be greater than or equal to 182 | // constraints. 183 | Slvs_hConstraint *failed; 184 | int faileds; 185 | 186 | // The solver indicates the number of unconstrained degrees of freedom. 187 | int dof; 188 | 189 | // The solver indicates whether the solution succeeded. 190 | #define SLVS_RESULT_OKAY 0 191 | #define SLVS_RESULT_INCONSISTENT 1 192 | #define SLVS_RESULT_DIDNT_CONVERGE 2 193 | #define SLVS_RESULT_TOO_MANY_UNKNOWNS 3 194 | int result; 195 | } Slvs_System; 196 | 197 | DLL void Slvs_Solve(Slvs_System *sys, Slvs_hGroup hg); 198 | 199 | 200 | // Our base coordinate system has basis vectors 201 | // (1, 0, 0) (0, 1, 0) (0, 0, 1) 202 | // A unit quaternion defines a rotation to a new coordinate system with 203 | // basis vectors 204 | // U V N 205 | // which these functions compute from the quaternion. 206 | DLL void Slvs_QuaternionU(double qw, double qx, double qy, double qz, 207 | double *x, double *y, double *z); 208 | DLL void Slvs_QuaternionV(double qw, double qx, double qy, double qz, 209 | double *x, double *y, double *z); 210 | DLL void Slvs_QuaternionN(double qw, double qx, double qy, double qz, 211 | double *x, double *y, double *z); 212 | 213 | // Similarly, compute a unit quaternion in terms of two basis vectors. 214 | DLL void Slvs_MakeQuaternion(double ux, double uy, double uz, 215 | double vx, double vy, double vz, 216 | double *qw, double *qx, double *qy, double *qz); 217 | 218 | 219 | //------------------------------------- 220 | // These are just convenience functions, to save you the trouble of filling 221 | // out the structures by hand. The code is included in the header file to 222 | // let the compiler inline them if possible. 223 | 224 | static Slvs_Param Slvs_MakeParam(Slvs_hParam h, Slvs_hGroup group, double val) 225 | { 226 | Slvs_Param r; 227 | r.h = h; 228 | r.group = group; 229 | r.val = val; 230 | return r; 231 | } 232 | static Slvs_Entity Slvs_MakePoint2d(Slvs_hEntity h, Slvs_hGroup group, 233 | Slvs_hEntity wrkpl, 234 | Slvs_hParam u, Slvs_hParam v) 235 | { 236 | Slvs_Entity r; 237 | memset(&r, 0, sizeof(r)); 238 | r.h = h; 239 | r.group = group; 240 | r.type = SLVS_E_POINT_IN_2D; 241 | r.wrkpl = wrkpl; 242 | r.param[0] = u; 243 | r.param[1] = v; 244 | return r; 245 | } 246 | static Slvs_Entity Slvs_MakePoint3d(Slvs_hEntity h, Slvs_hGroup group, 247 | Slvs_hParam x, Slvs_hParam y, Slvs_hParam z) 248 | { 249 | Slvs_Entity r; 250 | memset(&r, 0, sizeof(r)); 251 | r.h = h; 252 | r.group = group; 253 | r.type = SLVS_E_POINT_IN_3D; 254 | r.wrkpl = SLVS_FREE_IN_3D; 255 | r.param[0] = x; 256 | r.param[1] = y; 257 | r.param[2] = z; 258 | return r; 259 | } 260 | static Slvs_Entity Slvs_MakeNormal3d(Slvs_hEntity h, Slvs_hGroup group, 261 | Slvs_hParam qw, Slvs_hParam qx, Slvs_hParam qy, Slvs_hParam qz) 262 | { 263 | Slvs_Entity r; 264 | memset(&r, 0, sizeof(r)); 265 | r.h = h; 266 | r.group = group; 267 | r.type = SLVS_E_NORMAL_IN_3D; 268 | r.wrkpl = SLVS_FREE_IN_3D; 269 | r.param[0] = qw; 270 | r.param[1] = qx; 271 | r.param[2] = qy; 272 | r.param[3] = qz; 273 | return r; 274 | } 275 | static Slvs_Entity Slvs_MakeNormal2d(Slvs_hEntity h, Slvs_hGroup group, 276 | Slvs_hEntity wrkpl) 277 | { 278 | Slvs_Entity r; 279 | memset(&r, 0, sizeof(r)); 280 | r.h = h; 281 | r.group = group; 282 | r.type = SLVS_E_NORMAL_IN_2D; 283 | r.wrkpl = wrkpl; 284 | return r; 285 | } 286 | static Slvs_Entity Slvs_MakeDistance(Slvs_hEntity h, Slvs_hGroup group, 287 | Slvs_hEntity wrkpl, Slvs_hParam d) 288 | { 289 | Slvs_Entity r; 290 | memset(&r, 0, sizeof(r)); 291 | r.h = h; 292 | r.group = group; 293 | r.type = SLVS_E_DISTANCE; 294 | r.wrkpl = wrkpl; 295 | r.param[0] = d; 296 | return r; 297 | } 298 | static Slvs_Entity Slvs_MakeLineSegment(Slvs_hEntity h, Slvs_hGroup group, 299 | Slvs_hEntity wrkpl, 300 | Slvs_hEntity ptA, Slvs_hEntity ptB) 301 | { 302 | Slvs_Entity r; 303 | memset(&r, 0, sizeof(r)); 304 | r.h = h; 305 | r.group = group; 306 | r.type = SLVS_E_LINE_SEGMENT; 307 | r.wrkpl = wrkpl; 308 | r.point[0] = ptA; 309 | r.point[1] = ptB; 310 | return r; 311 | } 312 | static Slvs_Entity Slvs_MakeCubic(Slvs_hEntity h, Slvs_hGroup group, 313 | Slvs_hEntity wrkpl, 314 | Slvs_hEntity pt0, Slvs_hEntity pt1, 315 | Slvs_hEntity pt2, Slvs_hEntity pt3) 316 | { 317 | Slvs_Entity r; 318 | memset(&r, 0, sizeof(r)); 319 | r.h = h; 320 | r.group = group; 321 | r.type = SLVS_E_CUBIC; 322 | r.wrkpl = wrkpl; 323 | r.point[0] = pt0; 324 | r.point[1] = pt1; 325 | r.point[2] = pt2; 326 | r.point[3] = pt3; 327 | return r; 328 | } 329 | static Slvs_Entity Slvs_MakeArcOfCircle(Slvs_hEntity h, Slvs_hGroup group, 330 | Slvs_hEntity wrkpl, 331 | Slvs_hEntity normal, 332 | Slvs_hEntity center, 333 | Slvs_hEntity start, Slvs_hEntity end) 334 | { 335 | Slvs_Entity r; 336 | memset(&r, 0, sizeof(r)); 337 | r.h = h; 338 | r.group = group; 339 | r.type = SLVS_E_ARC_OF_CIRCLE; 340 | r.wrkpl = wrkpl; 341 | r.normal = normal; 342 | r.point[0] = center; 343 | r.point[1] = start; 344 | r.point[2] = end; 345 | return r; 346 | } 347 | static Slvs_Entity Slvs_MakeCircle(Slvs_hEntity h, Slvs_hGroup group, 348 | Slvs_hEntity wrkpl, 349 | Slvs_hEntity center, 350 | Slvs_hEntity normal, Slvs_hEntity radius) 351 | { 352 | Slvs_Entity r; 353 | memset(&r, 0, sizeof(r)); 354 | r.h = h; 355 | r.group = group; 356 | r.type = SLVS_E_CIRCLE; 357 | r.wrkpl = wrkpl; 358 | r.point[0] = center; 359 | r.normal = normal; 360 | r.distance = radius; 361 | return r; 362 | } 363 | static Slvs_Entity Slvs_MakeWorkplane(Slvs_hEntity h, Slvs_hGroup group, 364 | Slvs_hEntity origin, Slvs_hEntity normal) 365 | { 366 | Slvs_Entity r; 367 | memset(&r, 0, sizeof(r)); 368 | r.h = h; 369 | r.group = group; 370 | r.type = SLVS_E_WORKPLANE; 371 | r.wrkpl = SLVS_FREE_IN_3D; 372 | r.point[0] = origin; 373 | r.normal = normal; 374 | return r; 375 | } 376 | 377 | static Slvs_Constraint Slvs_MakeConstraint(Slvs_hConstraint h, 378 | Slvs_hGroup group, 379 | int type, 380 | Slvs_hEntity wrkpl, 381 | double valA, 382 | Slvs_hEntity ptA, 383 | Slvs_hEntity ptB, 384 | Slvs_hEntity entityA, 385 | Slvs_hEntity entityB) 386 | { 387 | Slvs_Constraint r; 388 | memset(&r, 0, sizeof(r)); 389 | r.h = h; 390 | r.group = group; 391 | r.type = type; 392 | r.wrkpl = wrkpl; 393 | r.valA = valA; 394 | r.ptA = ptA; 395 | r.ptB = ptB; 396 | r.entityA = entityA; 397 | r.entityB = entityB; 398 | return r; 399 | } 400 | 401 | #ifdef __cplusplus 402 | } 403 | #endif 404 | 405 | #endif 406 | -------------------------------------------------------------------------------- /solvespace/exposed/slvs_solid.py: -------------------------------------------------------------------------------- 1 | from slvs import * 2 | from solid import * 3 | 4 | 5 | # call to_openscad(), if it exists 6 | def _to_openscad(x): 7 | if hasattr(x, 'to_openscad'): 8 | return x.to_openscad() 9 | elif isinstance(x, list) or isinstance(x, tuple): 10 | return map(_to_openscad, x) 11 | else: 12 | return x 13 | 14 | def mat_transpose(m): 15 | for i in range(4): 16 | for j in range(4): 17 | if i < j: 18 | a = m[i][j] 19 | b = m[j][i] 20 | m[i][j] = b 21 | m[j][i] = a 22 | 23 | 24 | class RenderSystem(object): 25 | __slots__ = "itemscale" 26 | 27 | def __init__(self): 28 | self.itemscale = 1 29 | 30 | def point3d(self, pt, size = 0.1): 31 | pt = Vector(pt) 32 | size *= self.itemscale 33 | # We want equilateral triangles. I built that in 34 | # in SolveSpace and copied the dimensions. 35 | side = size 36 | hs = side/2 37 | height = size*0.8660 38 | center_to_baseline = size*0.2887 39 | center_to_top = size*0.5773 40 | cb = center_to_baseline 41 | ct = center_to_top 42 | triangle = [ [-hs, -cb], [hs, -cb], [0, ct] ] 43 | pts = [ pt ] 44 | for z in [-height, +height]: 45 | for p in triangle: 46 | pts.append(pt + (p + [z])) 47 | ts = [] 48 | for ps in [[0,1,2,3], [0,4,5,6]]: 49 | for a in range(0, 4): 50 | for b in range(a+1, 4): 51 | for c in range(b+1, 4): 52 | ts.append([ps[a], ps[b], ps[c]]) 53 | return polyhedron(points = pts, 54 | #triangles = [[1,2,3],[4,6,5]]) 55 | triangles = ts) 56 | 57 | def line3d(self, a, b, size = 0.01): 58 | a = Vector(a) 59 | b = Vector(b) 60 | length = (b-a).length() 61 | width = size*self.itemscale 62 | wh = width/2 63 | obj = linear_extrude(height = width)( 64 | polygon([ [0,-wh], [0, wh], [length, wh], [length, -wh] ])) 65 | return multmatrix(move_and_rotate(a, b, a+[0,0,1]))(obj) 66 | 67 | def system(self, system): 68 | obj = union() 69 | 70 | for i in range(system.entities): 71 | t = system.entity_type(i) 72 | if t == SLVS_E_POINT_IN_3D: 73 | obj.add(self.point3d(system.get_Point3d(i))) 74 | elif t == SLVS_E_LINE_SEGMENT: 75 | line = system.get_LineSegment3d(i) 76 | obj.add(self.line3d(line.a(), line.b())) 77 | 78 | return obj 79 | -------------------------------------------------------------------------------- /solvespace/exposed/solid: -------------------------------------------------------------------------------- 1 | ../../solid-python/solid/ -------------------------------------------------------------------------------- /solvespace/exposed/test2.scad.py: -------------------------------------------------------------------------------- 1 | import math 2 | from slvs import * 3 | from solid import * 4 | 5 | sys = System() 6 | 7 | # We want to find the plane for three points. The points 8 | # shouldn't change, so we put them into another group. 9 | 10 | p1 = Point3d(Param(1), Param(1), Param(9), sys) 11 | p2 = Point3d(Param(5), Param(2), Param(2), sys) 12 | p3 = Point3d(Param(0), Param(7), Param(5), sys) 13 | 14 | #p1 = Point3d(Param(0), Param(0), Param(1), sys) 15 | #p2 = Point3d(Param(5), Param(0), Param(1), sys) 16 | #p3 = Point3d(Param(0), Param(7), Param(2), sys) 17 | 18 | # Other entities go into another group 19 | sys.default_group = 2 20 | 21 | wrkpl = Workplane(p1, Normal3d(Param(1), Param(0), Param(0), Param(0), sys)) 22 | 23 | # Some constraints: all points are in the plane 24 | # (p1 is its origin, so we don't need a constraint) 25 | Constraint.on(wrkpl, p2) 26 | Constraint.on(wrkpl, p3) 27 | 28 | # Solve it (group 2 is still active) 29 | sys.solve() 30 | 31 | if(sys.result == SLVS_RESULT_OKAY): 32 | print "solved okay" 33 | for p in [p1, p2, p3]: 34 | print "point at (%.3f, %.3f, %.3f)" % tuple(p.to_openscad()) 35 | print "normal at (%.3f, %.3f, %.3f, %.3f)" % tuple(wrkpl.normal().vector()) 36 | print wrkpl.to_openscad() 37 | print "%d DOF" % sys.dof 38 | else: 39 | print("solve failed") 40 | 41 | 42 | # draw some geometry, so we see the result 43 | 44 | geom = union() 45 | 46 | # a small triangle for each point 47 | for p in [p1, p2, p3]: 48 | x = p.x().value 49 | y = p.y().value 50 | z = p.z().value 51 | 52 | w = 0.3 53 | 54 | geom.add( 55 | linear_extrude(height = z)( 56 | polygon([[x,y], [x-w,y], [x,y-w]]))) 57 | 58 | # draw plane: create flat surface in xy-plane and rotate+translate 59 | 60 | plane = linear_extrude(height = 0.3)( 61 | square(size = [8, 8])) 62 | 63 | # We call to_openscad to make sure it is called now, as 64 | # we will change the points soon. 65 | plane1 = multmatrix(wrkpl.to_openscad())(plane) 66 | 67 | geom += plane1 68 | 69 | 70 | 71 | # This time we do it without the solver. 72 | 73 | # Move points, so the second plane won't overlap the first 74 | p1.z().value += 2 75 | p2.z().value += 2 76 | p3.z().value += 2 77 | 78 | plane2 = multmatrix(move_and_rotate(p1, p2, p3))(plane) 79 | geom += plane2 80 | 81 | scad_render_to_file(geom, "/tmp/out.scad") 82 | -------------------------------------------------------------------------------- /solvespace/exposed/test3.scad.py: -------------------------------------------------------------------------------- 1 | from slvs_solid import * 2 | 3 | r = RenderSystem() 4 | r.itemscale = 4 5 | 6 | p1 = [ 2, 0, 0] 7 | p2 = [ 0, 0, 0] 8 | p3 = [ 2, 4, 2] 9 | p4 = [-3, 2, -2] 10 | 11 | pts = [ p1, p2, p3, p4 ] 12 | 13 | #obj = r.point3d([2, 0, 0]) + r.point3d([0, 0, 0]) + linear_extrude(height = 0.5)(polygon([[0,0,0], [2,0,0], [0,2,0]])) 14 | #obj = union()(map(r.point3d, pts)) + r.line3d(p3, p4) 15 | 16 | sys = System() 17 | p1s = Point3d(*(p1 + [sys])) 18 | p2s = Point3d(*(p2 + [sys])) 19 | p3s = Point3d(*(p3 + [sys])) 20 | p4s = Point3d(*(p4 + [sys])) 21 | line = LineSegment3d(p3s, p4s) 22 | 23 | obj = r.system(sys) 24 | 25 | print repr(scad_render(obj)) 26 | scad_render_to_file(obj, "/tmp/out.scad") 27 | -------------------------------------------------------------------------------- /solvespace/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 | DWORD marker; 16 | 17 | // A parameter, by the hParam handle 18 | static const int PARAM = 0; 19 | // A parameter, by a pointer straight in to the param table (faster, 20 | // if we know that the param table won't move around) 21 | static const int PARAM_PTR = 1; 22 | 23 | // These are used only for user-entered expressions. 24 | static const int POINT = 10; 25 | static const int ENTITY = 11; 26 | 27 | static const int CONSTANT = 20; 28 | 29 | static const int PLUS = 100; 30 | static const int MINUS = 101; 31 | static const int TIMES = 102; 32 | static const int DIV = 103; 33 | static const int NEGATE = 104; 34 | static const int SQRT = 105; 35 | static const int SQUARE = 106; 36 | static const int SIN = 107; 37 | static const int COS = 108; 38 | static const int ASIN = 109; 39 | static const int ACOS = 110; 40 | 41 | // Special helpers for when we're parsing an expression from text. 42 | // Initially, literals (like a constant number) appear in the same 43 | // format as they will in the finished expression, but the operators 44 | // are different until the parser fixes things up (and builds the 45 | // tree from the flat list that the lexer outputs). 46 | static const int ALL_RESOLVED = 1000; 47 | static const int PAREN = 1001; 48 | static const int BINARY_OP = 1002; 49 | static const int UNARY_OP = 1003; 50 | 51 | int op; 52 | Expr *a; 53 | Expr *b; 54 | union { 55 | double v; 56 | hParam parh; 57 | Param *parp; 58 | hEntity entity; 59 | 60 | // For use while parsing 61 | char c; 62 | } x; 63 | 64 | static inline Expr *AllocExpr(void) 65 | { return (Expr *)AllocTemporary(sizeof(Expr)); } 66 | 67 | static Expr *From(hParam p); 68 | static Expr *From(double v); 69 | 70 | Expr *AnyOp(int op, Expr *b); 71 | inline Expr *Plus (Expr *b) { return AnyOp(PLUS, b); } 72 | inline Expr *Minus(Expr *b) { return AnyOp(MINUS, b); } 73 | inline Expr *Times(Expr *b) { return AnyOp(TIMES, b); } 74 | inline Expr *Div (Expr *b) { return AnyOp(DIV, b); } 75 | 76 | inline Expr *Negate(void) { return AnyOp(NEGATE, NULL); } 77 | inline Expr *Sqrt (void) { return AnyOp(SQRT, NULL); } 78 | inline Expr *Square(void) { return AnyOp(SQUARE, NULL); } 79 | inline Expr *Sin (void) { return AnyOp(SIN, NULL); } 80 | inline Expr *Cos (void) { return AnyOp(COS, NULL); } 81 | inline Expr *ASin (void) { return AnyOp(ASIN, NULL); } 82 | inline Expr *ACos (void) { return AnyOp(ACOS, NULL); } 83 | 84 | Expr *PartialWrt(hParam p); 85 | double Eval(void); 86 | QWORD ParamsUsed(void); 87 | bool DependsOn(hParam p); 88 | static bool Tol(double a, double b); 89 | Expr *FoldConstants(void); 90 | void Substitute(hParam oldh, hParam newh); 91 | 92 | static const hParam NO_PARAMS, MULTIPLE_PARAMS; 93 | hParam ReferencedParams(ParamList *pl); 94 | 95 | void ParamsToPointers(void); 96 | 97 | void App(char *str, ...); 98 | char *Print(void); 99 | void PrintW(void); // worker 100 | 101 | // number of child nodes: 0 (e.g. constant), 1 (sqrt), or 2 (+) 102 | int Children(void); 103 | // total number of nodes in the tree 104 | int Nodes(void); 105 | 106 | // Make a simple copy 107 | Expr *DeepCopy(void); 108 | // Make a copy, with the parameters (usually referenced by hParam) 109 | // resolved to pointers to the actual value. This speeds things up 110 | // considerably. 111 | Expr *DeepCopyWithParamsAsPointers(IdList *firstTry, 112 | IdList *thenTry); 113 | 114 | static Expr *From(char *in, bool popUpError); 115 | static void Lex(char *in); 116 | static Expr *Next(void); 117 | static void Consume(void); 118 | 119 | static void PushOperator(Expr *e); 120 | static Expr *PopOperator(void); 121 | static Expr *TopOperator(void); 122 | static void PushOperand(Expr *e); 123 | static Expr *PopOperand(void); 124 | 125 | static void Reduce(void); 126 | static void ReduceAndPush(Expr *e); 127 | static int Precedence(Expr *e); 128 | 129 | static int Precedence(int op); 130 | static void Parse(void); 131 | }; 132 | 133 | class ExprVector { 134 | public: 135 | Expr *x, *y, *z; 136 | 137 | static ExprVector From(Expr *x, Expr *y, Expr *z); 138 | static ExprVector From(Vector vn); 139 | static ExprVector From(hParam x, hParam y, hParam z); 140 | static ExprVector From(double x, double y, double z); 141 | 142 | ExprVector Plus(ExprVector b); 143 | ExprVector Minus(ExprVector b); 144 | Expr *Dot(ExprVector b); 145 | ExprVector Cross(ExprVector b); 146 | ExprVector ScaledBy(Expr *s); 147 | ExprVector WithMagnitude(Expr *s); 148 | Expr *Magnitude(void); 149 | 150 | Vector Eval(void); 151 | }; 152 | 153 | class ExprQuaternion { 154 | public: 155 | Expr *w, *vx, *vy, *vz; 156 | 157 | static ExprQuaternion From(Expr *w, Expr *vx, Expr *vy, Expr *vz); 158 | static ExprQuaternion From(Quaternion qn); 159 | static ExprQuaternion From(hParam w, hParam vx, hParam vy, hParam vz); 160 | 161 | ExprVector RotationU(void); 162 | ExprVector RotationV(void); 163 | ExprVector RotationN(void); 164 | 165 | ExprVector Rotate(ExprVector p); 166 | ExprQuaternion Times(ExprQuaternion b); 167 | 168 | Expr *Magnitude(void); 169 | }; 170 | 171 | #endif 172 | 173 | -------------------------------------------------------------------------------- /solvespace/extlib/libpng.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/extlib/libpng.lib -------------------------------------------------------------------------------- /solvespace/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 | -------------------------------------------------------------------------------- /solvespace/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 | -------------------------------------------------------------------------------- /solvespace/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 | -------------------------------------------------------------------------------- /solvespace/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 | -------------------------------------------------------------------------------- /solvespace/extlib/si/siapp.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/extlib/si/siapp.lib -------------------------------------------------------------------------------- /solvespace/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 | -------------------------------------------------------------------------------- /solvespace/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 | -------------------------------------------------------------------------------- /solvespace/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 | -------------------------------------------------------------------------------- /solvespace/extlib/zconf.h: -------------------------------------------------------------------------------- 1 | /* zconf.h -- configuration of the zlib compression library 2 | * Copyright (C) 1995-2005 Jean-loup Gailly. 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | /* @(#) $Id$ */ 7 | 8 | #ifndef ZCONF_H 9 | #define ZCONF_H 10 | 11 | /* 12 | * If you *really* need a unique prefix for all types and library functions, 13 | * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. 14 | */ 15 | #ifdef Z_PREFIX 16 | # define deflateInit_ z_deflateInit_ 17 | # define deflate z_deflate 18 | # define deflateEnd z_deflateEnd 19 | # define inflateInit_ z_inflateInit_ 20 | # define inflate z_inflate 21 | # define inflateEnd z_inflateEnd 22 | # define deflateInit2_ z_deflateInit2_ 23 | # define deflateSetDictionary z_deflateSetDictionary 24 | # define deflateCopy z_deflateCopy 25 | # define deflateReset z_deflateReset 26 | # define deflateParams z_deflateParams 27 | # define deflateBound z_deflateBound 28 | # define deflatePrime z_deflatePrime 29 | # define inflateInit2_ z_inflateInit2_ 30 | # define inflateSetDictionary z_inflateSetDictionary 31 | # define inflateSync z_inflateSync 32 | # define inflateSyncPoint z_inflateSyncPoint 33 | # define inflateCopy z_inflateCopy 34 | # define inflateReset z_inflateReset 35 | # define inflateBack z_inflateBack 36 | # define inflateBackEnd z_inflateBackEnd 37 | # define compress z_compress 38 | # define compress2 z_compress2 39 | # define compressBound z_compressBound 40 | # define uncompress z_uncompress 41 | # define adler32 z_adler32 42 | # define crc32 z_crc32 43 | # define get_crc_table z_get_crc_table 44 | # define zError z_zError 45 | 46 | # define alloc_func z_alloc_func 47 | # define free_func z_free_func 48 | # define in_func z_in_func 49 | # define out_func z_out_func 50 | # define Byte z_Byte 51 | # define uInt z_uInt 52 | # define uLong z_uLong 53 | # define Bytef z_Bytef 54 | # define charf z_charf 55 | # define intf z_intf 56 | # define uIntf z_uIntf 57 | # define uLongf z_uLongf 58 | # define voidpf z_voidpf 59 | # define voidp z_voidp 60 | #endif 61 | 62 | #if defined(__MSDOS__) && !defined(MSDOS) 63 | # define MSDOS 64 | #endif 65 | #if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) 66 | # define OS2 67 | #endif 68 | #if defined(_WINDOWS) && !defined(WINDOWS) 69 | # define WINDOWS 70 | #endif 71 | #if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) 72 | # ifndef WIN32 73 | # define WIN32 74 | # endif 75 | #endif 76 | #if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) 77 | # if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) 78 | # ifndef SYS16BIT 79 | # define SYS16BIT 80 | # endif 81 | # endif 82 | #endif 83 | 84 | /* 85 | * Compile with -DMAXSEG_64K if the alloc function cannot allocate more 86 | * than 64k bytes at a time (needed on systems with 16-bit int). 87 | */ 88 | #ifdef SYS16BIT 89 | # define MAXSEG_64K 90 | #endif 91 | #ifdef MSDOS 92 | # define UNALIGNED_OK 93 | #endif 94 | 95 | #ifdef __STDC_VERSION__ 96 | # ifndef STDC 97 | # define STDC 98 | # endif 99 | # if __STDC_VERSION__ >= 199901L 100 | # ifndef STDC99 101 | # define STDC99 102 | # endif 103 | # endif 104 | #endif 105 | #if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) 106 | # define STDC 107 | #endif 108 | #if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) 109 | # define STDC 110 | #endif 111 | #if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) 112 | # define STDC 113 | #endif 114 | #if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) 115 | # define STDC 116 | #endif 117 | 118 | #if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ 119 | # define STDC 120 | #endif 121 | 122 | #ifndef STDC 123 | # ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ 124 | # define const /* note: need a more gentle solution here */ 125 | # endif 126 | #endif 127 | 128 | /* Some Mac compilers merge all .h files incorrectly: */ 129 | #if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) 130 | # define NO_DUMMY_DECL 131 | #endif 132 | 133 | /* Maximum value for memLevel in deflateInit2 */ 134 | #ifndef MAX_MEM_LEVEL 135 | # ifdef MAXSEG_64K 136 | # define MAX_MEM_LEVEL 8 137 | # else 138 | # define MAX_MEM_LEVEL 9 139 | # endif 140 | #endif 141 | 142 | /* Maximum value for windowBits in deflateInit2 and inflateInit2. 143 | * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files 144 | * created by gzip. (Files created by minigzip can still be extracted by 145 | * gzip.) 146 | */ 147 | #ifndef MAX_WBITS 148 | # define MAX_WBITS 15 /* 32K LZ77 window */ 149 | #endif 150 | 151 | /* The memory requirements for deflate are (in bytes): 152 | (1 << (windowBits+2)) + (1 << (memLevel+9)) 153 | that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) 154 | plus a few kilobytes for small objects. For example, if you want to reduce 155 | the default memory requirements from 256K to 128K, compile with 156 | make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" 157 | Of course this will generally degrade compression (there's no free lunch). 158 | 159 | The memory requirements for inflate are (in bytes) 1 << windowBits 160 | that is, 32K for windowBits=15 (default value) plus a few kilobytes 161 | for small objects. 162 | */ 163 | 164 | /* Type declarations */ 165 | 166 | #ifndef OF /* function prototypes */ 167 | # ifdef STDC 168 | # define OF(args) args 169 | # else 170 | # define OF(args) () 171 | # endif 172 | #endif 173 | 174 | /* The following definitions for FAR are needed only for MSDOS mixed 175 | * model programming (small or medium model with some far allocations). 176 | * This was tested only with MSC; for other MSDOS compilers you may have 177 | * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, 178 | * just define FAR to be empty. 179 | */ 180 | #ifdef SYS16BIT 181 | # if defined(M_I86SM) || defined(M_I86MM) 182 | /* MSC small or medium model */ 183 | # define SMALL_MEDIUM 184 | # ifdef _MSC_VER 185 | # define FAR _far 186 | # else 187 | # define FAR far 188 | # endif 189 | # endif 190 | # if (defined(__SMALL__) || defined(__MEDIUM__)) 191 | /* Turbo C small or medium model */ 192 | # define SMALL_MEDIUM 193 | # ifdef __BORLANDC__ 194 | # define FAR _far 195 | # else 196 | # define FAR far 197 | # endif 198 | # endif 199 | #endif 200 | 201 | #if defined(WINDOWS) || defined(WIN32) 202 | /* If building or using zlib as a DLL, define ZLIB_DLL. 203 | * This is not mandatory, but it offers a little performance increase. 204 | */ 205 | # ifdef ZLIB_DLL 206 | # if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) 207 | # ifdef ZLIB_INTERNAL 208 | # define ZEXTERN extern __declspec(dllexport) 209 | # else 210 | # define ZEXTERN extern __declspec(dllimport) 211 | # endif 212 | # endif 213 | # endif /* ZLIB_DLL */ 214 | /* If building or using zlib with the WINAPI/WINAPIV calling convention, 215 | * define ZLIB_WINAPI. 216 | * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. 217 | */ 218 | # ifdef ZLIB_WINAPI 219 | # ifdef FAR 220 | # undef FAR 221 | # endif 222 | # include 223 | /* No need for _export, use ZLIB.DEF instead. */ 224 | /* For complete Windows compatibility, use WINAPI, not __stdcall. */ 225 | # define ZEXPORT WINAPI 226 | # ifdef WIN32 227 | # define ZEXPORTVA WINAPIV 228 | # else 229 | # define ZEXPORTVA FAR CDECL 230 | # endif 231 | # endif 232 | #endif 233 | 234 | #if defined (__BEOS__) 235 | # ifdef ZLIB_DLL 236 | # ifdef ZLIB_INTERNAL 237 | # define ZEXPORT __declspec(dllexport) 238 | # define ZEXPORTVA __declspec(dllexport) 239 | # else 240 | # define ZEXPORT __declspec(dllimport) 241 | # define ZEXPORTVA __declspec(dllimport) 242 | # endif 243 | # endif 244 | #endif 245 | 246 | #ifndef ZEXTERN 247 | # define ZEXTERN extern 248 | #endif 249 | #ifndef ZEXPORT 250 | # define ZEXPORT 251 | #endif 252 | #ifndef ZEXPORTVA 253 | # define ZEXPORTVA 254 | #endif 255 | 256 | #ifndef FAR 257 | # define FAR 258 | #endif 259 | 260 | #if !defined(__MACTYPES__) 261 | typedef unsigned char Byte; /* 8 bits */ 262 | #endif 263 | typedef unsigned int uInt; /* 16 bits or more */ 264 | typedef unsigned long uLong; /* 32 bits or more */ 265 | 266 | #ifdef SMALL_MEDIUM 267 | /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ 268 | # define Bytef Byte FAR 269 | #else 270 | typedef Byte FAR Bytef; 271 | #endif 272 | typedef char FAR charf; 273 | typedef int FAR intf; 274 | typedef uInt FAR uIntf; 275 | typedef uLong FAR uLongf; 276 | 277 | #ifdef STDC 278 | typedef void const *voidpc; 279 | typedef void FAR *voidpf; 280 | typedef void *voidp; 281 | #else 282 | typedef Byte const *voidpc; 283 | typedef Byte FAR *voidpf; 284 | typedef Byte *voidp; 285 | #endif 286 | 287 | #if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ 288 | # include /* for off_t */ 289 | # include /* for SEEK_* and off_t */ 290 | # ifdef VMS 291 | # include /* for off_t */ 292 | # endif 293 | # define z_off_t off_t 294 | #endif 295 | #ifndef SEEK_SET 296 | # define SEEK_SET 0 /* Seek from beginning of file. */ 297 | # define SEEK_CUR 1 /* Seek from current position. */ 298 | # define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ 299 | #endif 300 | #ifndef z_off_t 301 | # define z_off_t long 302 | #endif 303 | 304 | #if defined(__OS400__) 305 | # define NO_vsnprintf 306 | #endif 307 | 308 | #if defined(__MVS__) 309 | # define NO_vsnprintf 310 | # ifdef FAR 311 | # undef FAR 312 | # endif 313 | #endif 314 | 315 | /* MVS linker does not support external names larger than 8 bytes */ 316 | #if defined(__MVS__) 317 | # pragma map(deflateInit_,"DEIN") 318 | # pragma map(deflateInit2_,"DEIN2") 319 | # pragma map(deflateEnd,"DEEND") 320 | # pragma map(deflateBound,"DEBND") 321 | # pragma map(inflateInit_,"ININ") 322 | # pragma map(inflateInit2_,"ININ2") 323 | # pragma map(inflateEnd,"INEND") 324 | # pragma map(inflateSync,"INSY") 325 | # pragma map(inflateSetDictionary,"INSEDI") 326 | # pragma map(compressBound,"CMBND") 327 | # pragma map(inflate_table,"INTABL") 328 | # pragma map(inflate_fast,"INFA") 329 | # pragma map(inflate_copyright,"INCOPY") 330 | #endif 331 | 332 | #endif /* ZCONF_H */ 333 | -------------------------------------------------------------------------------- /solvespace/extlib/zlib.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/extlib/zlib.lib -------------------------------------------------------------------------------- /solvespace/file.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/file.cpp -------------------------------------------------------------------------------- /solvespace/graphicswin.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/graphicswin.cpp -------------------------------------------------------------------------------- /solvespace/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icon.ico -------------------------------------------------------------------------------- /solvespace/icons/angle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/angle.png -------------------------------------------------------------------------------- /solvespace/icons/arc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/arc.png -------------------------------------------------------------------------------- /solvespace/icons/assemble.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/assemble.png -------------------------------------------------------------------------------- /solvespace/icons/bezier.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/bezier.png -------------------------------------------------------------------------------- /solvespace/icons/char-0-check-false.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/char-0-check-false.png -------------------------------------------------------------------------------- /solvespace/icons/char-1-check-true.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/char-1-check-true.png -------------------------------------------------------------------------------- /solvespace/icons/char-2-radio-false.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/char-2-radio-false.png -------------------------------------------------------------------------------- /solvespace/icons/char-3-radio-true.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/char-3-radio-true.png -------------------------------------------------------------------------------- /solvespace/icons/circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/circle.png -------------------------------------------------------------------------------- /solvespace/icons/constraint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/constraint.png -------------------------------------------------------------------------------- /solvespace/icons/construction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/construction.png -------------------------------------------------------------------------------- /solvespace/icons/edges.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/edges.png -------------------------------------------------------------------------------- /solvespace/icons/equal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/equal.png -------------------------------------------------------------------------------- /solvespace/icons/extrude.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/extrude.png -------------------------------------------------------------------------------- /solvespace/icons/faces.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/faces.png -------------------------------------------------------------------------------- /solvespace/icons/hidden-lines.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/hidden-lines.png -------------------------------------------------------------------------------- /solvespace/icons/horiz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/horiz.png -------------------------------------------------------------------------------- /solvespace/icons/in3d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/in3d.png -------------------------------------------------------------------------------- /solvespace/icons/length.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/length.png -------------------------------------------------------------------------------- /solvespace/icons/line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/line.png -------------------------------------------------------------------------------- /solvespace/icons/mesh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/mesh.png -------------------------------------------------------------------------------- /solvespace/icons/normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/normal.png -------------------------------------------------------------------------------- /solvespace/icons/ontoworkplane.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/ontoworkplane.png -------------------------------------------------------------------------------- /solvespace/icons/other-supp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/other-supp.png -------------------------------------------------------------------------------- /solvespace/icons/parallel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/parallel.png -------------------------------------------------------------------------------- /solvespace/icons/perpendicular.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/perpendicular.png -------------------------------------------------------------------------------- /solvespace/icons/point.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/point.png -------------------------------------------------------------------------------- /solvespace/icons/pointonx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/pointonx.png -------------------------------------------------------------------------------- /solvespace/icons/rectangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/rectangle.png -------------------------------------------------------------------------------- /solvespace/icons/ref.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/ref.png -------------------------------------------------------------------------------- /solvespace/icons/same-orientation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/same-orientation.png -------------------------------------------------------------------------------- /solvespace/icons/shaded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/shaded.png -------------------------------------------------------------------------------- /solvespace/icons/sketch-in-3d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/sketch-in-3d.png -------------------------------------------------------------------------------- /solvespace/icons/sketch-in-plane.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/sketch-in-plane.png -------------------------------------------------------------------------------- /solvespace/icons/step-rotate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/step-rotate.png -------------------------------------------------------------------------------- /solvespace/icons/step-translate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/step-translate.png -------------------------------------------------------------------------------- /solvespace/icons/symmetric.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/symmetric.png -------------------------------------------------------------------------------- /solvespace/icons/tangent-arc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/tangent-arc.png -------------------------------------------------------------------------------- /solvespace/icons/text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/text.png -------------------------------------------------------------------------------- /solvespace/icons/trim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/trim.png -------------------------------------------------------------------------------- /solvespace/icons/vert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/vert.png -------------------------------------------------------------------------------- /solvespace/icons/workplane.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/icons/workplane.png -------------------------------------------------------------------------------- /solvespace/obj/t: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BBBSnowball/python-solvespace/2ade9f596580fdd7d5661206baa4722366b345ac/solvespace/obj/t -------------------------------------------------------------------------------- /solvespace/png2c.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use GD; 4 | 5 | my ($out, $proto) = @ARGV; 6 | open(OUT, ">$out") or die "$out: $!"; 7 | open(PROTO, ">$proto") or die "$proto: $!"; 8 | 9 | for $file () { 10 | next if $file =~ /char-/; 11 | 12 | $file =~ m#.*/(.*)\.png#; 13 | $base = "Icon_$1"; 14 | $base =~ y/-/_/; 15 | 16 | open(PNG, $file) or die "$file: $!\n"; 17 | $img = newFromPng GD::Image(\*PNG) or die; 18 | $img->trueColor(1); 19 | 20 | close PNG; 21 | 22 | ($width, $height) = $img->getBounds(); 23 | die "$file: $width, $height" if ($width != 24) or ($height != 24); 24 | 25 | print PROTO "extern unsigned char $base\[24*24*3\];"; 26 | print OUT "unsigned char $base\[24*24*3] = {\n"; 27 | 28 | for($y = 0; $y < 24; $y++) { 29 | for($x = 0; $x < 24; $x++) { 30 | $index = $img->getPixel($x, 23-$y); 31 | ($r, $g, $b) = $img->rgb($index); 32 | if($r + $g + $b < 11) { 33 | ($r, $g, $b) = (30, 30, 30); 34 | } 35 | printf OUT " 0x%02x, 0x%02x, 0x%02x,\n", $r, $g, $b; 36 | } 37 | } 38 | 39 | print OUT "};\n\n"; 40 | 41 | } 42 | -------------------------------------------------------------------------------- /solvespace/pngchar2c.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use GD; 4 | 5 | for $file (sort ) { 6 | open(PNG, $file) or die "$file: $!\n"; 7 | $img = newFromPng GD::Image(\*PNG) or die; 8 | $img->trueColor(1); 9 | close PNG; 10 | 11 | ($width, $height) = $img->getBounds(); 12 | die "$file: $width, $height" if ($width != 16) or ($height != 16); 13 | 14 | for($x = 0; $x < 16; $x++) { 15 | for($y = 0; $y < 16; $y++) { 16 | $index = $img->getPixel($x, $y); 17 | ($r, $g, $b) = $img->rgb($index); 18 | if($r + $g + $b < 11) { 19 | print " 0, "; 20 | } else { 21 | print "255, "; 22 | } 23 | } 24 | print "\n"; 25 | } 26 | print "\n"; 27 | } 28 | 29 | -------------------------------------------------------------------------------- /solvespace/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 | static const int UNKNOWN = 0; 78 | static const int NOT_EAR = 1; 79 | static const int EAR = 2; 80 | int ear; 81 | 82 | Vector p; 83 | Vector auxv; 84 | }; 85 | 86 | class SPointList { 87 | public: 88 | List l; 89 | 90 | void Clear(void); 91 | bool ContainsPoint(Vector pt); 92 | int IndexForPoint(Vector pt); 93 | void IncrementTagFor(Vector pt); 94 | void Add(Vector pt); 95 | }; 96 | 97 | class SContour { 98 | public: 99 | int tag; 100 | int timesEnclosed; 101 | Vector xminPt; 102 | List l; 103 | 104 | void AddPoint(Vector p); 105 | void MakeEdgesInto(SEdgeList *el); 106 | void Reverse(void); 107 | Vector ComputeNormal(void); 108 | double SignedAreaProjdToNormal(Vector n); 109 | bool IsClockwiseProjdToNormal(Vector n); 110 | bool ContainsPointProjdToNormal(Vector n, Vector p); 111 | void OffsetInto(SContour *dest, double r); 112 | void CopyInto(SContour *dest); 113 | void FindPointWithMinX(void); 114 | Vector AnyEdgeMidpoint(void); 115 | 116 | bool IsEar(int bp, double scaledEps); 117 | bool BridgeToContour(SContour *sc, SEdgeList *el, List *vl); 118 | void ClipEarInto(SMesh *m, int bp, double scaledEps); 119 | void UvTriangulateInto(SMesh *m, SSurface *srf); 120 | }; 121 | 122 | typedef struct { 123 | DWORD face; 124 | int color; 125 | } STriMeta; 126 | 127 | class SPolygon { 128 | public: 129 | List l; 130 | Vector normal; 131 | 132 | Vector ComputeNormal(void); 133 | void AddEmptyContour(void); 134 | int WindingNumberForPoint(Vector p); 135 | double SignedArea(void); 136 | bool ContainsPoint(Vector p); 137 | void MakeEdgesInto(SEdgeList *el); 138 | void FixContourDirections(void); 139 | void Clear(void); 140 | bool SelfIntersecting(Vector *intersectsAt); 141 | bool IsEmpty(void); 142 | Vector AnyPoint(void); 143 | void OffsetInto(SPolygon *dest, double r); 144 | void UvTriangulateInto(SMesh *m, SSurface *srf); 145 | void UvGridTriangulateInto(SMesh *m, SSurface *srf); 146 | }; 147 | 148 | class STriangle { 149 | public: 150 | int tag; 151 | STriMeta meta; 152 | Vector a, b, c; 153 | Vector an, bn, cn; 154 | 155 | static STriangle From(STriMeta meta, Vector a, Vector b, Vector c); 156 | Vector Normal(void); 157 | void FlipNormal(void); 158 | double MinAltitude(void); 159 | int WindingNumberForPoint(Vector p); 160 | bool ContainsPoint(Vector p); 161 | bool ContainsPointProjd(Vector n, Vector p); 162 | }; 163 | 164 | class SBsp2 { 165 | public: 166 | Vector np; // normal to the plane 167 | 168 | Vector no; // outer normal to the edge 169 | double d; 170 | SEdge edge; 171 | 172 | SBsp2 *pos; 173 | SBsp2 *neg; 174 | 175 | SBsp2 *more; 176 | 177 | static const int POS = 100, NEG = 101, COPLANAR = 200; 178 | void InsertTriangleHow(int how, STriangle *tr, SMesh *m, SBsp3 *bsp3); 179 | void InsertTriangle(STriangle *tr, SMesh *m, SBsp3 *bsp3); 180 | Vector IntersectionWith(Vector a, Vector b); 181 | SBsp2 *InsertEdge(SEdge *nedge, Vector nnp, Vector out); 182 | static SBsp2 *Alloc(void); 183 | 184 | void DebugDraw(Vector n, double d); 185 | }; 186 | 187 | class SBsp3 { 188 | public: 189 | Vector n; 190 | double d; 191 | 192 | STriangle tri; 193 | SBsp3 *pos; 194 | SBsp3 *neg; 195 | 196 | SBsp3 *more; 197 | 198 | SBsp2 *edges; 199 | 200 | static SBsp3 *Alloc(void); 201 | static SBsp3 *FromMesh(SMesh *m); 202 | 203 | Vector IntersectionWith(Vector a, Vector b); 204 | 205 | static const int POS = 100, NEG = 101, COPLANAR = 200; 206 | void InsertHow(int how, STriangle *str, SMesh *instead); 207 | SBsp3 *Insert(STriangle *str, SMesh *instead); 208 | 209 | void InsertConvexHow(int how, STriMeta meta, Vector *vertex, int n, 210 | SMesh *instead); 211 | SBsp3 *InsertConvex(STriMeta meta, Vector *vertex, int n, SMesh *instead); 212 | 213 | void InsertInPlane(bool pos2, STriangle *tr, SMesh *m); 214 | 215 | void GenerateInPaintOrder(SMesh *m); 216 | 217 | void DebugDraw(void); 218 | }; 219 | 220 | class SMesh { 221 | public: 222 | List l; 223 | 224 | bool flipNormal; 225 | bool keepCoplanar; 226 | bool atLeastOneDiscarded; 227 | 228 | void Clear(void); 229 | void AddTriangle(STriangle *st); 230 | void AddTriangle(STriMeta meta, Vector a, Vector b, Vector c); 231 | void AddTriangle(STriMeta meta, Vector n, Vector a, Vector b, Vector c); 232 | void DoBounding(Vector v, Vector *vmax, Vector *vmin); 233 | void GetBounding(Vector *vmax, Vector *vmin); 234 | 235 | void Simplify(int start); 236 | 237 | void AddAgainstBsp(SMesh *srcm, SBsp3 *bsp3); 238 | void MakeFromUnionOf(SMesh *a, SMesh *b); 239 | void MakeFromDifferenceOf(SMesh *a, SMesh *b); 240 | 241 | void MakeFromCopyOf(SMesh *a); 242 | void MakeFromTransformationOf(SMesh *a, 243 | Vector trans, Quaternion q, double scale); 244 | void MakeFromAssemblyOf(SMesh *a, SMesh *b); 245 | 246 | void MakeEdgesInPlaneInto(SEdgeList *sel, Vector n, double d); 247 | void MakeEmphasizedEdgesInto(SEdgeList *sel); 248 | 249 | bool IsEmpty(void); 250 | void RemapFaces(Group *g, int remap); 251 | 252 | DWORD FirstIntersectionWith(Point2d mp); 253 | }; 254 | 255 | // A linked list of triangles 256 | class STriangleLl { 257 | public: 258 | STriangle *tri; 259 | 260 | STriangleLl *next; 261 | 262 | static STriangleLl *Alloc(void); 263 | }; 264 | 265 | class SKdNode { 266 | public: 267 | int which; // whether c is x, y, or z 268 | double c; 269 | 270 | SKdNode *gt; 271 | SKdNode *lt; 272 | 273 | STriangleLl *tris; 274 | 275 | static SKdNode *Alloc(void); 276 | static SKdNode *From(SMesh *m); 277 | static SKdNode *From(STriangleLl *tll); 278 | 279 | void AddTriangle(STriangle *tr); 280 | void MakeMeshInto(SMesh *m); 281 | void ClearTags(void); 282 | 283 | void FindEdgeOn(Vector a, Vector b, int *n, int cnt, bool coplanarIsInter, 284 | bool *inter, bool *fwd, 285 | DWORD *face); 286 | static const int NAKED_OR_SELF_INTER_EDGES = 100; 287 | static const int SELF_INTER_EDGES = 200; 288 | static const int TURNING_EDGES = 300; 289 | static const int EMPHASIZED_EDGES = 400; 290 | void MakeCertainEdgesInto(SEdgeList *sel, int how, bool coplanarIsInter, 291 | bool *inter, bool *leaky); 292 | 293 | void OcclusionTestLine(SEdge orig, SEdgeList *sel, int cnt); 294 | void SplitLinesAgainstTriangle(SEdgeList *sel, STriangle *tr); 295 | 296 | void SnapToMesh(SMesh *m); 297 | void SnapToVertex(Vector v, SMesh *extras); 298 | }; 299 | 300 | #endif 301 | 302 | -------------------------------------------------------------------------------- /solvespace/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 }, 26 | }; 27 | 28 | 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; 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 | 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 | -------------------------------------------------------------------------------- /solvespace/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 != 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 | -------------------------------------------------------------------------------- /solvespace/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 "obj/icons.h" 10 | 11 | BYTE SPACER[1]; 12 | static const struct { 13 | BYTE *image; 14 | int menu; 15 | char *tip; 16 | } Toolbar[] = { 17 | { Icon_line, GraphicsWindow::MNU_LINE_SEGMENT, "Sketch line segment" }, 18 | { Icon_rectangle, GraphicsWindow::MNU_RECTANGLE, "Sketch rectangle" }, 19 | { Icon_circle, GraphicsWindow::MNU_CIRCLE, "Sketch circle" }, 20 | { Icon_arc, GraphicsWindow::MNU_ARC, "Sketch arc of a circle" }, 21 | { Icon_text, GraphicsWindow::MNU_TTF_TEXT, "Sketch curves from text in a TrueType font" }, 22 | { Icon_tangent_arc, GraphicsWindow::MNU_TANGENT_ARC, "Create tangent arc at selected point" }, 23 | { Icon_bezier, GraphicsWindow::MNU_CUBIC, "Sketch cubic Bezier spline" }, 24 | { Icon_point, GraphicsWindow::MNU_DATUM_POINT, "Sketch datum point" }, 25 | { Icon_construction, GraphicsWindow::MNU_CONSTRUCTION, "Toggle construction" }, 26 | { Icon_trim, GraphicsWindow::MNU_SPLIT_CURVES, "Split lines / curves where they intersect" }, 27 | { SPACER }, 28 | 29 | { Icon_length, GraphicsWindow::MNU_DISTANCE_DIA, "Constrain distance / diameter / length" }, 30 | { Icon_angle, GraphicsWindow::MNU_ANGLE, "Constrain angle" }, 31 | { Icon_horiz, GraphicsWindow::MNU_HORIZONTAL, "Constrain to be horizontal" }, 32 | { Icon_vert, GraphicsWindow::MNU_VERTICAL, "Constrain to be vertical" }, 33 | { Icon_parallel, GraphicsWindow::MNU_PARALLEL, "Constrain to be parallel or tangent" }, 34 | { Icon_perpendicular, GraphicsWindow::MNU_PERPENDICULAR, "Constrain to be perpendicular" }, 35 | { Icon_pointonx, GraphicsWindow::MNU_ON_ENTITY, "Constrain point on line / curve / plane / point" }, 36 | { Icon_symmetric, GraphicsWindow::MNU_SYMMETRIC, "Constrain symmetric" }, 37 | { Icon_equal, GraphicsWindow::MNU_EQUAL, "Constrain equal length / radius / angle" }, 38 | { Icon_same_orientation,GraphicsWindow::MNU_ORIENTED_SAME, "Constrain normals in same orientation" }, 39 | { Icon_other_supp, GraphicsWindow::MNU_OTHER_ANGLE, "Other supplementary angle" }, 40 | { Icon_ref, GraphicsWindow::MNU_REFERENCE, "Toggle reference dimension" }, 41 | { SPACER }, 42 | 43 | { Icon_extrude, GraphicsWindow::MNU_GROUP_EXTRUDE, "New group extruding active sketch" }, 44 | { Icon_sketch_in_plane, GraphicsWindow::MNU_GROUP_WRKPL, "New group in new workplane (thru given entities)" }, 45 | { Icon_step_rotate, GraphicsWindow::MNU_GROUP_ROT, "New group step and repeat rotating" }, 46 | { Icon_step_translate, GraphicsWindow::MNU_GROUP_TRANS, "New group step and repeat translating" }, 47 | { Icon_sketch_in_3d, GraphicsWindow::MNU_GROUP_3D, "New group in 3d" }, 48 | { Icon_assemble, GraphicsWindow::MNU_GROUP_IMPORT, "New group importing / assembling file" }, 49 | { SPACER }, 50 | 51 | { Icon_in3d, GraphicsWindow::MNU_NEAREST_ISO, "Nearest isometric view" }, 52 | { Icon_ontoworkplane, GraphicsWindow::MNU_ONTO_WORKPLANE, "Align view to active workplane" }, 53 | { NULL }, 54 | }; 55 | 56 | void GraphicsWindow::ToolbarDraw(void) { 57 | ToolbarDrawOrHitTest(0, 0, true, NULL); 58 | } 59 | 60 | bool GraphicsWindow::ToolbarMouseMoved(int x, int y) { 61 | x += ((int)width/2); 62 | y += ((int)height/2); 63 | 64 | int nh; 65 | bool withinToolbar = ToolbarDrawOrHitTest(x, y, false, &nh); 66 | if(!withinToolbar) nh = 0; 67 | 68 | if(nh != toolbarTooltipped) { 69 | // Don't let the tool tip move around if the mouse moves within the 70 | // same item. 71 | toolbarMouseX = x; 72 | toolbarMouseY = y; 73 | toolbarTooltipped = 0; 74 | } 75 | 76 | if(nh != toolbarHovered) { 77 | toolbarHovered = nh; 78 | SetTimerFor(1000); 79 | PaintGraphics(); 80 | } 81 | // So if we moved off the toolbar, then toolbarHovered is now equal to 82 | // zero, so it doesn't matter if the tool tip timer expires. And if 83 | // we moved from one item to another, we reset the timer, so also okay. 84 | return withinToolbar; 85 | } 86 | 87 | bool GraphicsWindow::ToolbarMouseDown(int x, int y) { 88 | x += ((int)width/2); 89 | y += ((int)height/2); 90 | 91 | int nh = -1; 92 | bool withinToolbar = ToolbarDrawOrHitTest(x, y, false, &nh); 93 | // They might have clicked within the toolbar, but not on a button. 94 | if(withinToolbar && nh >= 0) { 95 | for(int i = 0; SS.GW.menu[i].level >= 0; i++) { 96 | if(nh == SS.GW.menu[i].id) { 97 | (SS.GW.menu[i].fn)((GraphicsWindow::MenuId)SS.GW.menu[i].id); 98 | break; 99 | } 100 | } 101 | } 102 | return withinToolbar; 103 | } 104 | 105 | bool GraphicsWindow::ToolbarDrawOrHitTest(int mx, int my, 106 | bool paint, int *menu) 107 | { 108 | int i; 109 | int x = 17, y = (int)(height - 52); 110 | 111 | int fudge = 8; 112 | int h = 32*15 + 3*16 + fudge; 113 | int aleft = 0, aright = 66, atop = y+16+fudge/2, abot = y+16-h; 114 | 115 | bool withinToolbar = 116 | (mx >= aleft && mx <= aright && my <= atop && my >= abot); 117 | 118 | if(!paint && !withinToolbar) { 119 | // This gets called every MouseMove event, so return quickly. 120 | return false; 121 | } 122 | 123 | if(paint) { 124 | glMatrixMode(GL_MODELVIEW); 125 | glLoadIdentity(); 126 | glMatrixMode(GL_PROJECTION); 127 | glLoadIdentity(); 128 | glTranslated(-1, -1, 0); 129 | glScaled(2.0/width, 2.0/height, 0); 130 | glDisable(GL_LIGHTING); 131 | 132 | double c = 30.0/255; 133 | glColor4d(c, c, c, 1.0); 134 | glxAxisAlignedQuad(aleft, aright, atop, abot); 135 | } 136 | 137 | struct { 138 | bool show; 139 | char *str; 140 | } toolTip = { false, NULL }; 141 | 142 | bool leftpos = true; 143 | for(i = 0; Toolbar[i].image; i++) { 144 | if(Toolbar[i].image == SPACER) { 145 | if(!leftpos) { 146 | leftpos = true; 147 | y -= 32; 148 | x -= 32; 149 | } 150 | y -= 16; 151 | 152 | if(paint) { 153 | // Draw a separator bar in a slightly different color. 154 | int divw = 30, divh = 2; 155 | glColor4d(0.17, 0.17, 0.17, 1); 156 | x += 16; 157 | y += 24; 158 | glxAxisAlignedQuad(x+divw, x-divw, y+divh, y-divh); 159 | x -= 16; 160 | y -= 24; 161 | } 162 | 163 | continue; 164 | } 165 | 166 | if(paint) { 167 | glRasterPos2i(x - 12, y - 12); 168 | glDrawPixels(24, 24, GL_RGB, GL_UNSIGNED_BYTE, Toolbar[i].image); 169 | 170 | if(toolbarHovered == Toolbar[i].menu) { 171 | // Highlight the hovered or pending item. 172 | glColor4d(1, 1, 0, 0.3); 173 | int boxhw = 15; 174 | glxAxisAlignedQuad(x+boxhw, x-boxhw, y+boxhw, y-boxhw); 175 | } 176 | 177 | if(toolbarTooltipped == Toolbar[i].menu) { 178 | // Display the tool tip for this item; postpone till later 179 | // so that no one draws over us. Don't need position since 180 | // that's just wherever the mouse is. 181 | toolTip.show = true; 182 | toolTip.str = Toolbar[i].tip; 183 | } 184 | } else { 185 | int boxhw = 16; 186 | if(mx < (x+boxhw) && mx > (x - boxhw) && 187 | my < (y+boxhw) && my > (y - boxhw)) 188 | { 189 | if(menu) *menu = Toolbar[i].menu; 190 | } 191 | } 192 | 193 | if(leftpos) { 194 | x += 32; 195 | leftpos = false; 196 | } else { 197 | x -= 32; 198 | y -= 32; 199 | leftpos = true; 200 | } 201 | } 202 | 203 | if(paint) { 204 | // Do this last so that nothing can draw over it. 205 | if(toolTip.show) { 206 | glxCreateBitmapFont(); 207 | char str[1024]; 208 | if(strlen(toolTip.str) >= 200) oops(); 209 | strcpy(str, toolTip.str); 210 | 211 | for(i = 0; SS.GW.menu[i].level >= 0; i++) { 212 | if(toolbarTooltipped == SS.GW.menu[i].id) { 213 | int accel = SS.GW.menu[i].accel; 214 | int ac = accel & 0xff; 215 | 216 | char *s = str+strlen(str); 217 | if(isalnum(ac) || ac == '[') { 218 | if(accel & 0x100) { 219 | sprintf(s, " (Shift+%c)", ac); 220 | } else if((accel & ~0xff) == 0) { 221 | sprintf(s, " (%c)", ac); 222 | } 223 | } else if(ac == 0xf3) { 224 | sprintf(s, " (F3)"); 225 | } 226 | break; 227 | } 228 | } 229 | 230 | int tw = strlen(str)*SS.TW.CHAR_WIDTH + 10, 231 | th = SS.TW.LINE_HEIGHT + 2; 232 | 233 | double ox = toolbarMouseX + 3, oy = toolbarMouseY + 3; 234 | glLineWidth(1); 235 | glColor4d(1.0, 1.0, 0.6, 1.0); 236 | glxAxisAlignedQuad(ox, ox+tw, oy, oy+th); 237 | glColor4d(0.0, 0.0, 0.0, 1.0); 238 | glxAxisAlignedLineLoop(ox, ox+tw, oy, oy+th); 239 | 240 | glColor4d(0, 0, 0, 1); 241 | glPushMatrix(); 242 | glTranslated(ox+5, oy+3, 0); 243 | glScaled(1, -1, 1); 244 | glxBitmapText(str, Vector::From(0, 0, 0)); 245 | glPopMatrix(); 246 | } 247 | glxDepthRangeLockToFront(false); 248 | } 249 | 250 | return withinToolbar; 251 | } 252 | 253 | void GraphicsWindow::TimerCallback(void) { 254 | SS.GW.toolbarTooltipped = SS.GW.toolbarHovered; 255 | PaintGraphics(); 256 | } 257 | 258 | -------------------------------------------------------------------------------- /solvespace/tools/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | cl ttf2c.cpp user32.lib gdi32.lib comctl32.lib 3 | ttf2c.exe > ..\bitmapfont.table 4 | 5 | -------------------------------------------------------------------------------- /solvespace/tools/ttf2c.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | //----------------------------------------------------------------------------- 6 | // Entry point into the program. 7 | //----------------------------------------------------------------------------- 8 | int main(void) 9 | { 10 | InitCommonControls(); 11 | 12 | // A monospaced font 13 | HFONT font = CreateFont(16, 9, 0, 0, FW_REGULAR, FALSE, 14 | FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, 15 | DEFAULT_QUALITY, FF_DONTCARE, "Lucida Console"); 16 | 17 | HDC hdc = CreateDC("DISPLAY", NULL, NULL, NULL); 18 | HBITMAP bitmap = CreateCompatibleBitmap(hdc, 30, 30); 19 | 20 | SelectObject(hdc, bitmap); 21 | SelectObject(hdc, font); 22 | 23 | printf("static const BYTE FontTexture[256*16*16] = {\n"); 24 | 25 | int c; 26 | for(c = 0; c < 128; c++) { 27 | 28 | RECT r; 29 | r.left = 0; r.top = 0; 30 | r.right = 30; r.bottom = 30; 31 | FillRect(hdc, &r, (HBRUSH)GetStockObject(BLACK_BRUSH)); 32 | 33 | SetBkColor(hdc, RGB(0, 0, 0)); 34 | SetTextColor(hdc, RGB(255, 255, 255)); 35 | char str[2] = { c, 0 }; 36 | TextOut(hdc, 0, 0, str, 1); 37 | 38 | int i, j; 39 | for(i = 0; i < 16; i++) { 40 | for(j = 0; j < 16; j++) { 41 | COLORREF c = GetPixel(hdc, i, j); 42 | printf("%3d, ", c ? 255 : 0); 43 | } 44 | printf("\n"); 45 | } 46 | printf("\n"); 47 | } 48 | printf("#include \"bitmapextra.table\"\n"); 49 | printf("};\n"); 50 | 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /solvespace/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 SolveSpace::UndoRemember(void) { 11 | unsaved = true; 12 | PushFromCurrentOnto(&undo); 13 | UndoClearStack(&redo); 14 | UndoEnableMenus(); 15 | } 16 | 17 | void SolveSpace::UndoUndo(void) { 18 | if(undo.cnt <= 0) return; 19 | 20 | PushFromCurrentOnto(&redo); 21 | PopOntoCurrentFrom(&undo); 22 | UndoEnableMenus(); 23 | } 24 | 25 | void SolveSpace::UndoRedo(void) { 26 | if(redo.cnt <= 0) return; 27 | 28 | PushFromCurrentOnto(&undo); 29 | PopOntoCurrentFrom(&redo); 30 | UndoEnableMenus(); 31 | } 32 | 33 | void SolveSpace::UndoEnableMenus(void) { 34 | EnableMenuById(GraphicsWindow::MNU_UNDO, undo.cnt > 0); 35 | EnableMenuById(GraphicsWindow::MNU_REDO, redo.cnt > 0); 36 | } 37 | 38 | void SolveSpace::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 SolveSpace::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 | later.showTW = true; 132 | } 133 | 134 | void SolveSpace::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 SolveSpace::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 | -------------------------------------------------------------------------------- /solvespace/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, DWORD 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, DWORD 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, DWORD 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(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 | -------------------------------------------------------------------------------- /solvespace/win32/manifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | Parametric 3d CAD tool. 10 | 11 | 12 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /solvespace/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 | -------------------------------------------------------------------------------- /solvespace/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 | #ifdef WIN32 10 | # include 11 | #endif 12 | #include 13 | #include 14 | #include 15 | 16 | #include "solvespace.h" 17 | 18 | #ifdef WIN32 19 | 20 | static HANDLE PermHeap, TempHeap; 21 | 22 | void dbp(char *str, ...) 23 | { 24 | va_list f; 25 | static char buf[1024*50]; 26 | va_start(f, str); 27 | _vsnprintf(buf, sizeof(buf), str, f); 28 | va_end(f); 29 | 30 | OutputDebugString(buf); 31 | } 32 | 33 | void GetAbsoluteFilename(char *file) 34 | { 35 | char absoluteFile[MAX_PATH]; 36 | GetFullPathName(file, sizeof(absoluteFile), absoluteFile, NULL); 37 | strcpy(file, absoluteFile); 38 | } 39 | 40 | //----------------------------------------------------------------------------- 41 | // A separate heap, on which we allocate expressions. Maybe a bit faster, 42 | // since no fragmentation issues whatsoever, and it also makes it possible 43 | // to be sloppy with our memory management, and just free everything at once 44 | // at the end. 45 | //----------------------------------------------------------------------------- 46 | void *AllocTemporary(int n) 47 | { 48 | void *v = HeapAlloc(TempHeap, HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY, n); 49 | if(!v) oops(); 50 | return v; 51 | } 52 | void FreeTemporary(void *p) { 53 | HeapFree(TempHeap, HEAP_NO_SERIALIZE, p); 54 | } 55 | void FreeAllTemporary(void) 56 | { 57 | if(TempHeap) HeapDestroy(TempHeap); 58 | TempHeap = HeapCreate(HEAP_NO_SERIALIZE, 1024*1024*20, 0); 59 | // This is a good place to validate, because it gets called fairly 60 | // often. 61 | vl(); 62 | } 63 | 64 | void *MemRealloc(void *p, int n) { 65 | if(!p) { 66 | return MemAlloc(n); 67 | } 68 | 69 | p = HeapReAlloc(PermHeap, HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY, p, n); 70 | if(!p) oops(); 71 | return p; 72 | } 73 | void *MemAlloc(int n) { 74 | void *p = HeapAlloc(PermHeap, HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY, n); 75 | if(!p) oops(); 76 | return p; 77 | } 78 | void MemFree(void *p) { 79 | HeapFree(PermHeap, HEAP_NO_SERIALIZE, p); 80 | } 81 | 82 | void vl(void) { 83 | if(!HeapValidate(TempHeap, HEAP_NO_SERIALIZE, NULL)) oops(); 84 | if(!HeapValidate(PermHeap, HEAP_NO_SERIALIZE, NULL)) oops(); 85 | } 86 | 87 | void InitHeaps(void) { 88 | // Create the heap used for long-lived stuff (that gets freed piecewise). 89 | PermHeap = HeapCreate(HEAP_NO_SERIALIZE, 1024*1024*20, 0); 90 | // Create the heap that we use to store Exprs and other temp stuff. 91 | FreeAllTemporary(); 92 | } 93 | 94 | #else // not WIN32 95 | 96 | #include 97 | // not available without support for C++0x 98 | // I could enable that, but I rather use the old, portable way. 99 | //#include 100 | #include 101 | 102 | void dbp(char *str, ...) 103 | { 104 | va_list f; 105 | static char buf[1024*50]; 106 | va_start(f, str); 107 | vsnprintf(buf, sizeof(buf), str, f); 108 | va_end(f); 109 | 110 | fprintf(stderr, "%s", buf); 111 | } 112 | 113 | void GetAbsoluteFilename(char *file) 114 | { 115 | char* absoluteFile = realpath(file, NULL); 116 | if (strlen(absoluteFile) > MAX_PATH-1) { 117 | printf("This absolute path is too long: %s\nI will quit now. Sorry.\n", absoluteFile); 118 | exit(2); 119 | } 120 | strcpy(file, absoluteFile); 121 | } 122 | 123 | // We're using the default heap here, so the 'free' trick (see above) 124 | // doesn't work. This means that we might leak a lot of memory. 125 | // Therefore, we keep track of temporary stuff and free it in 126 | // FreeAllTemporary. Of course, we must 'forget' any pointer that 127 | // has been deleted with FreeTemporary, so we don't free it again. 128 | 129 | typedef std::set tmem; 130 | tmem temporary_memory; 131 | 132 | void *AllocTemporary(int n) { 133 | void *p = MemAlloc(n); 134 | temporary_memory.insert(p); 135 | return p; 136 | } 137 | void FreeTemporary(void *p) { 138 | temporary_memory.erase(p); 139 | MemFree(p); 140 | } 141 | void FreeAllTemporary(void) { 142 | for (typename tmem::iterator i = temporary_memory.begin(); 143 | i != temporary_memory.end(); 144 | i++) { 145 | MemFree(*i); 146 | } 147 | temporary_memory.clear(); 148 | 149 | vl(); 150 | } 151 | 152 | void *MemRealloc(void *p, int n) { 153 | if(!p) { 154 | return MemAlloc(n); 155 | } 156 | 157 | void *p2 = realloc(p, n); 158 | if(!p2) oops(); 159 | //TODO initialize additional memory with zeros 160 | 161 | if (p != p2) { 162 | temporary_memory.erase(p); 163 | temporary_memory.insert(p2); 164 | } 165 | 166 | return p2; 167 | } 168 | void *MemAlloc(int n) { 169 | void* x = malloc(n); 170 | memset(x, 0, n); 171 | return x; 172 | } 173 | void MemFree(void *p) { 174 | free(p); 175 | } 176 | 177 | void vl(void) { 178 | // we cannot validate resp. stdlib does it automatically at 179 | // appropriate times, if we have compiled it for debug 180 | } 181 | 182 | void InitHeaps(void) { 183 | } 184 | 185 | #endif 186 | -------------------------------------------------------------------------------- /solvespace/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 | --------------------------------------------------------------------------------