From a7fa89c2cc4ea4d8849bd76766ada2fab31456a8 Mon Sep 17 00:00:00 2001 From: Jonathan Westhues Date: Tue, 8 Apr 2008 04:54:53 -0800 Subject: [PATCH] Check in some SolveSpace stuff, even though I didn't make much progress. I want to change the sketch.h stuff fairly significantly, I think, before proceeding. [git-p4: depot-paths = "//depot/solvespace/": change = 1657] --- Makefile | 2 +- cmdline.cpp | 33 +++++++++ dsc.h | 47 +++++++++++-- expr.h | 36 ++++++++++ sketch.cpp | 73 +++++++++++++++++++- sketch.h | 169 ++++++++++++++++++++++++++++++++++------------ solvespace.cpp | 66 +++++++++++++++--- solvespace.h | 7 +- ui.h | 5 ++ win32/w32main.cpp | 2 - 10 files changed, 372 insertions(+), 68 deletions(-) create mode 100644 expr.h diff --git a/Makefile b/Makefile index 5d5c1fa..87f43d2 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ DEFINES = /D_WIN32_WINNT=0x500 /DISOLATION_AWARE_ENABLED /D_WIN32_IE=0x500 /DWIN32_LEAN_AND_MEAN /DWIN32 CFLAGS = /W3 /nologo -I..\common\win32 /O2 /D_DEBUG /D_CRT_SECURE_NO_WARNINGS /Zi /I. -HEADERS = ..\common\win32\freeze.h ui.h solvespace.h dsc.h sketch.h +HEADERS = ..\common\win32\freeze.h ui.h solvespace.h dsc.h sketch.h expr.h OBJDIR = obj diff --git a/cmdline.cpp b/cmdline.cpp index e432258..4df9a81 100644 --- a/cmdline.cpp +++ b/cmdline.cpp @@ -169,3 +169,36 @@ void TextWindow::KeyPressed(int c) { } } +void TextWindow::ShowGroupList(void) { + ClearScreen(); + Printf("*** ALL GROUPS IN SKETCH"); + Printf(""); + + int i; + for(i = 0; i < SS.group.elems; i++) { + Group *g = &(SS.group.elem[i].v); + if(g->name.str[0]) { + Printf(" %s", g->name.str); + } else { + Printf(" unnamed"); + } + } +} + +void TextWindow::ShowRequestList(void) { + ClearScreen(); + Printf("*** REQUESTS"); + Printf(""); + + int i; + for(i = 0; i < SS.request.elems; i++) { + Request *r = &(SS.request.elem[i].v); + + if(r->name.str[0]) { + Printf(" %s", r->name.str); + } else { + Printf(" unnamed"); + } + } +} + diff --git a/dsc.h b/dsc.h index b2eacec..24e9be8 100644 --- a/dsc.h +++ b/dsc.h @@ -2,6 +2,7 @@ #ifndef __DSC_H #define __DSC_H +typedef unsigned __int64 QWORD; typedef unsigned long DWORD; typedef unsigned char BYTE; @@ -41,17 +42,25 @@ public: int elems; int elemsAllocated; - void AddAndAssignId(T *v) { + H AddAndAssignId(T *v) { + H ht; + ht.v = 0; + return AddAndAssignId(v, ht); + } + + H AddAndAssignId(T *v, H ht) { int i; - int id = 0; + QWORD id = 0; for(i = 0; i < elems; i++) { - id = max(id, elem[i].h.v); + id = max(id, (elem[i].h.v & 0xfff)); } H h; - h.v = id + 1; + h.v = (id + 1) | ht.v; AddById(v, h); + + return h; } void AddById(T *v, H h) { @@ -66,6 +75,24 @@ public: elem[elems].tag = 0; elems++; } + + T *FindById(H h) { + int i; + for(i = 0; i < elems; i++) { + if(elem[i].h.v == h.v) { + return &(elem[i].v); + } + } + dbp("failed to look up item %16lx, searched %d items", h.v); + oops(); + } + + void ClearTags(void) { + int i; + for(i = 0; i < elems; i++) { + elem[i].tag = 0; + } + } void RemoveTagged(void) { int src, dest; @@ -81,7 +108,7 @@ public: } } elems = dest; - // and elemsAllocated is untouched + // and elemsAllocated is untouched, because we didn't resize } void Clear(void) { @@ -91,4 +118,14 @@ public: }; +class NameStr { +public: + char str[20]; + + inline void strcpy(char *in) { + memcpy(str, in, min(strlen(in)+1, sizeof(str))); + str[sizeof(str)-1] = '\0'; + } +}; + #endif diff --git a/expr.h b/expr.h new file mode 100644 index 0000000..dc6ba8a --- /dev/null +++ b/expr.h @@ -0,0 +1,36 @@ + +#ifndef __EXPR_H +#define __EXPR_H + +class Expr; + +class Expr { +public: + // A parameter, by the hParam handle + static const int PARAM = 0; + // A parameter, by a pointer straight in to the param table (faster, + // if we know that the param table won't move around) + static const int PARAM_PTR = 1; + + static const int CONSTANT = 10; + static const int PLUS = 21; + static const int MINUS = 22; + static const int TIMES = 23; + static const int DIV = 24; + static const int NEGATE = 25; + static const int SQRT = 26; + static const int SQUARE = 27; + static const int SIN = 28; + static const int COS = 29; + + int op; + Expr *a; + Expr *b; + union { + hParam parh; + double *parp; + double v; + } x; +}; + +#endif diff --git a/sketch.cpp b/sketch.cpp index 43ae6c5..ae142fc 100644 --- a/sketch.cpp +++ b/sketch.cpp @@ -1,6 +1,73 @@ #include "solvespace.h" -const hRequest Request::HREQUEST_DATUM_PLANE_XY = { 0x00000001 }; -const hRequest Request::HREQUEST_DATUM_PLANE_YZ = { 0x00000002 }; -const hRequest Request::HREQUEST_DATUM_PLANE_ZX = { 0x00000003 }; +const hEntity Entity::NONE = { 0 }; +const hGroup Group::HGROUP_REFERENCES = { 1 }; +const hRequest Request::HREQUEST_REFERENCE_XY = { 1 }; +const hRequest Request::HREQUEST_REFERENCE_YZ = { 2 }; +const hRequest Request::HREQUEST_REFERENCE_ZX = { 3 }; + +void Request::GenerateEntities(IdList *l, + IdList *gl) +{ + Entity e; + memset(&e, 0, sizeof(e)); + + Group *g = gl->FindById(group); + e.csys = csys = g->csys; + + switch(type) { + case TWO_D_CSYS: + e.type = Entity::TWO_D_CSYS; + l->AddById(&e, h.entity(group, 0)); + break; + + default: + oops(); + } +} + +void Entity::GeneratePointsAndParams(IdList *lpt, + IdList *lpa) +{ + int ptc, pac; + + switch(type) { + case TWO_D_CSYS: ptc = 1; pac = 4; break; + + default: + oops(); + } + + Point pt; + memset(&pt, 0, sizeof(pt)); + + pt.csys = csys; + + Param pa; + memset(&pa, 0, sizeof(pa)); + int i; + for(i = 0; i < ptc; i++) { + lpt->AddById(&pt, h.point3(i)); + } + for(i = 0; i < pac; i++) { + lpa->AddById(&pa, h.param(i)); + } +} + +void Point::GenerateParams(IdList *l) { + Param pa; + memset(&pa, 0, sizeof(pa)); + + switch(h.v & 7) { + case 0: + // A point in 3-space; three parameters x, y, z. + l->AddById(&pa, h.param(0)); + l->AddById(&pa, h.param(1)); + l->AddById(&pa, h.param(2)); + break; + + default: + oops(); + } +} diff --git a/sketch.h b/sketch.h index 7f19d47..569915c 100644 --- a/sketch.h +++ b/sketch.h @@ -3,62 +3,109 @@ #define __SKETCH_H class hEntity; +class Entity; class hPoint; class hRequest; class hParam; class hGroup; +class hGroup { +public: + // bits 11: 0 -- group index + QWORD v; +}; + class hRequest { public: - int v; + // bits 11: 0 -- request index + QWORD v; - hEntity entity(int i); -}; - -class Request { -public: - static const hRequest HREQUEST_DATUM_PLANE_XY, - HREQUEST_DATUM_PLANE_YZ, - HREQUEST_DATUM_PLANE_ZX; - - static const int FOR_PLANE = 0; - int type; - - hRequest h; -}; - -class hEntity { -public: - int v; - - hRequest request(int i); - hPoint point(int i); -}; - -class Entity { -public: - static const int ENTITY_PLANE = 0; - int type; - - hEntity h; - - void Draw(void); -}; - -class hPoint { -public: - int v; -}; - -class Point { -public: - - hPoint h; + hEntity entity(hGroup g, int i); }; class hParam { public: - int v; + // bits 7: 0 -- param index + // 10: 8 -- type (0 for 3d point, 7 for from entity) + // 15:11 -- point index, or zero if from entity + // 31:16 -- entity index + // 43:32 -- request index + // 55:44 -- group index + QWORD v; + + inline hGroup group(void) { hGroup r; r.v = (v >> 44); return r; } +}; + +class hPoint { +public: + // bits 2: 0 -- type (0 for 3d point) + // 7: 3 -- point index + // 23: 8 -- entity index + // 35:24 -- request index + // 47:36 -- group index + QWORD v; + + inline hParam param(int i) { + hParam r; + r.v = (v << 8) | i; + return r; + } +}; + +class hEntity { +public: + // bits 15: 0 -- entity index + // 27:16 -- request index + // 39:17 -- group index + QWORD v; + + inline hGroup group(void) + { hGroup r; r.v = (v >> 28); return r; } + inline hRequest request(void) + { hRequest r; r.v = (v >> 16) & 0xfff; return r; } + inline hPoint point3(int i) + { hPoint r; r.v = (v << 8) | (i << 3) | 0; return r; } + + inline hParam param(int i) { + hParam r; + r.v = (((v << 8) | 7) << 8) | i; + return r; + } +}; + +// A set of requests. Every request must have an associated group. A group +// may have an associated 2-d coordinate system, in which cases lines or +// curves that belong to the group are automatically constrained into that +// plane; otherwise they are free in 3-space. +class Group { +public: + static const hGroup HGROUP_REFERENCES; + + hEntity csys; + NameStr name; +}; + +// A user request for some primitive or derived operation; for example a +// line, or a +class Request { +public: + static const hRequest HREQUEST_REFERENCE_XY; + static const hRequest HREQUEST_REFERENCE_YZ; + static const hRequest HREQUEST_REFERENCE_ZX; + + static const int TWO_D_CSYS = 0; + static const int LINE_SEGMENT = 1; + + int type; + + hRequest h; + + hGroup group; + hEntity csys; + + NameStr name; + + void GenerateEntities(IdList *l, IdList *gl); }; class Param { @@ -68,5 +115,37 @@ public: hParam h; }; -#endif +class Point { +public: + hPoint h; + hEntity csys; + + void GenerateParams(IdList *l); +}; + +class Entity { +public: + static const hEntity NONE; + + static const int TWO_D_CSYS = 100; + static const int LINE_SEGMENT = 101; + int type; + + hEntity h; + hEntity csys; + + void Draw(void); + void GeneratePointsAndParams(IdList *pt, + IdList *pa); +}; + +// Must be defined later, once hEntity has been defined. +inline hEntity hRequest::entity(hGroup g, int i) { + hEntity r; + r.v = (g.v << 28) | (v << 16) | i; + return r; +} + + +#endif diff --git a/solvespace.cpp b/solvespace.cpp index a324573..c8cc5b7 100644 --- a/solvespace.cpp +++ b/solvespace.cpp @@ -10,21 +10,65 @@ void SolveSpace::Init(void) { TW.Init(); GW.Init(); - req.Clear(); + request.Clear(); entity.Clear(); point.Clear(); param.Clear(); + group.Clear(); - // The sketch starts with three requests, for three datum planes. - Request n; - n.type = Request::FOR_PLANE; - req.AddById(&n, Request::HREQUEST_DATUM_PLANE_XY); - req.AddById(&n, Request::HREQUEST_DATUM_PLANE_YZ); - req.AddById(&n, Request::HREQUEST_DATUM_PLANE_ZX); + // Our initial group, that contains the references. + Group g; + memset(&g, 0, sizeof(g)); + g.csys = Entity::NONE; + g.name.strcpy("__references"); + group.AddById(&g, Group::HGROUP_REFERENCES); + + g.csys = Entity::NONE; + g.name.strcpy(""); + group.AddAndAssignId(&g); + + + // Let's create three two-d coordinate systems, for the coordinate + // planes; these are our references, present in every sketch. + Request r; + memset(&r, 0, sizeof(r)); + r.type = Request::TWO_D_CSYS; + r.group = Group::HGROUP_REFERENCES; + + r.name.strcpy("__xy_plane"); + request.AddById(&r, Request::HREQUEST_REFERENCE_XY); + r.name.strcpy("__yz_plane"); + request.AddById(&r, Request::HREQUEST_REFERENCE_YZ); + r.name.strcpy("__zx_plane"); + request.AddById(&r, Request::HREQUEST_REFERENCE_ZX); + + TW.ShowGroupList(); + TW.ShowRequestList(); + + TW.ClearScreen(); + Solve(); +} + +void SolveSpace::Solve(void) { + int i; + + entity.Clear(); + for(i = 0; i < request.elems; i++) { + request.elem[i].v.GenerateEntities(&entity, &group); + } + + point.Clear(); + param.Clear(); + for(i = 0; i < entity.elems; i++) { + entity.elem[i].v.GeneratePointsAndParams(&point, ¶m); + } + for(i = 0; i < point.elems; i++) { + point.elem[i].v.GenerateParams(¶m); + } + + TW.Printf("entities=%d", entity.elems); + TW.Printf("points=%d", point.elems); + TW.Printf("params=%d", param.elems); - int i; - for(i = 0; i < 10; i++) { - TW.Printf("this is line number %d", i); - } } diff --git a/solvespace.h b/solvespace.h index d4fb093..d75d079 100644 --- a/solvespace.h +++ b/solvespace.h @@ -24,6 +24,7 @@ void dbp(char *str, ...); #include "dsc.h" #include "ui.h" #include "sketch.h" +#include "expr.h" void Invalidate(void); @@ -42,12 +43,16 @@ public: TextWindow TW; GraphicsWindow GW; - IdList req; + IdList group; + IdList request; IdList entity; IdList point; IdList param; + hGroup activeGroup; + void Init(void); + void Solve(void); }; extern SolveSpace SS; diff --git a/ui.h b/ui.h index a2ddf5a..34e0490 100644 --- a/ui.h +++ b/ui.h @@ -55,6 +55,11 @@ public: // These are called by the platform-specific code. void KeyPressed(int c); bool IsHyperlink(int width, int height); + + // These are self-contained screens, that show some information about + // the sketch. + void ShowGroupList(void); + void ShowRequestList(void); }; class GraphicsWindow { diff --git a/win32/w32main.cpp b/win32/w32main.cpp index 9cdcb18..627bd13 100644 --- a/win32/w32main.cpp +++ b/win32/w32main.cpp @@ -210,7 +210,6 @@ LRESULT CALLBACK TextWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) case WM_CHAR: SS.TW.KeyPressed(wParam); - HandleTextWindowScrollBar(SB_BOTTOM, 0); InvalidateRect(TextWnd, NULL, FALSE); break; @@ -276,7 +275,6 @@ LRESULT CALLBACK GraphicsWndProc(HWND hwnd, UINT msg, WPARAM wParam, case WM_CHAR: SS.TW.KeyPressed(wParam); SetForegroundWindow(TextWnd); - HandleTextWindowScrollBar(SB_BOTTOM, 0); InvalidateRect(TextWnd, NULL, FALSE); break;