Make the points locked in 2d csys (expressed as two parameters, for
the plane basis vectors) work, easy. Tweak the text window a bit, for cosmetics, and start to add the symbolic expression code. [git-p4: depot-paths = "//depot/solvespace/": change = 1667]solver
parent
b6bf07ac2c
commit
094e10204d
1
Makefile
1
Makefile
|
@ -16,6 +16,7 @@ SSOBJS = $(OBJDIR)\solvespace.obj \
|
|||
$(OBJDIR)\entity.obj \
|
||||
$(OBJDIR)\sketch.obj \
|
||||
$(OBJDIR)\glhelper.obj \
|
||||
$(OBJDIR)\expr.obj \
|
||||
|
||||
|
||||
LIBS = user32.lib gdi32.lib comctl32.lib advapi32.lib opengl32.lib glu32.lib
|
||||
|
|
19
entity.cpp
19
entity.cpp
|
@ -1,5 +1,15 @@
|
|||
#include "solvespace.h"
|
||||
|
||||
void Entity::Get2dCsysBasisVectors(Vector *u, Vector *v) {
|
||||
double q[4];
|
||||
for(int i = 0; i < 4; i++) {
|
||||
q[i] = SS.param.FindById(param(i))->val;
|
||||
}
|
||||
|
||||
*u = Vector::RotationU(q[0], q[1], q[2], q[3]);
|
||||
*v = Vector::RotationV(q[0], q[1], q[2], q[3]);
|
||||
}
|
||||
|
||||
void Entity::LineDrawOrGetDistance(Vector a, Vector b) {
|
||||
if(dogd.drawing) {
|
||||
glBegin(GL_LINE_STRIP);
|
||||
|
@ -36,13 +46,8 @@ void Entity::DrawOrGetDistance(void) {
|
|||
Vector p;
|
||||
p = SS.point.FindById(point(16))->GetCoords();
|
||||
|
||||
double q[4];
|
||||
for(int i = 0; i < 4; i++) {
|
||||
q[i] = SS.param.FindById(param(i))->val;
|
||||
}
|
||||
|
||||
Vector u = Vector::RotationU(q[0], q[1], q[2], q[3]);
|
||||
Vector v = Vector::RotationV(q[0], q[1], q[2], q[3]);
|
||||
Vector u, v;
|
||||
Get2dCsysBasisVectors(&u, &v);
|
||||
|
||||
double s = (min(SS.GW.width, SS.GW.height))*0.4/SS.GW.scale;
|
||||
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
#include "solvespace.h"
|
||||
|
||||
Expr *Expr::FromParam(hParam p) {
|
||||
Expr *r = AllocExpr();
|
||||
r->op = PARAM;
|
||||
r->x.parh = p;
|
||||
return r;
|
||||
}
|
||||
|
||||
Expr *Expr::FromConstant(double v) {
|
||||
Expr *r = AllocExpr();
|
||||
r->op = CONSTANT;
|
||||
r->x.v = v;
|
||||
return r;
|
||||
}
|
||||
|
||||
Expr *Expr::AnyOp(int newOp, Expr *b) {
|
||||
Expr *r = AllocExpr();
|
||||
r->op = newOp;
|
||||
r->a = this;
|
||||
r->b = b;
|
||||
return r;
|
||||
}
|
||||
|
||||
double Expr::Eval(void) {
|
||||
switch(op) {
|
||||
case PARAM: return SS.GetParam(x.parh)->val;
|
||||
case PARAM_PTR: return (x.parp)->val;
|
||||
|
||||
case CONSTANT: return x.v;
|
||||
|
||||
case PLUS: return a->Eval() + b->Eval();
|
||||
case MINUS: return a->Eval() - b->Eval();
|
||||
case TIMES: return a->Eval() * b->Eval();
|
||||
case DIV: return a->Eval() / b->Eval();
|
||||
|
||||
case NEGATE: return -(a->Eval());
|
||||
case SQRT: return sqrt(a->Eval());
|
||||
case SQUARE: { double r = a->Eval(); return r*r; }
|
||||
case SIN: return sin(a->Eval());
|
||||
case COS: return cos(a->Eval());
|
||||
|
||||
default: oops();
|
||||
}
|
||||
}
|
||||
|
25
expr.h
25
expr.h
|
@ -32,12 +32,33 @@ public:
|
|||
Expr *a;
|
||||
Expr *b;
|
||||
union {
|
||||
double v;
|
||||
hParam parh;
|
||||
double *parp;
|
||||
Param *parp;
|
||||
hPoint point;
|
||||
hEntity entity;
|
||||
double v;
|
||||
} x;
|
||||
|
||||
static Expr *FromParam(hParam p);
|
||||
static Expr *FromConstant(double v);
|
||||
|
||||
Expr *AnyOp(int op, Expr *b);
|
||||
inline Expr *Plus (Expr *b) { return AnyOp(PLUS, b); }
|
||||
inline Expr *Minus(Expr *b) { return AnyOp(MINUS, b); }
|
||||
inline Expr *Times(Expr *b) { return AnyOp(TIMES, b); }
|
||||
inline Expr *Div (Expr *b) { return AnyOp(DIV, b); }
|
||||
|
||||
inline Expr *Negate(void) { return AnyOp(NEGATE, NULL); }
|
||||
inline Expr *Sqrt (void) { return AnyOp(SQRT, NULL); }
|
||||
inline Expr *Square(void) { return AnyOp(SQUARE, NULL); }
|
||||
inline Expr *Sin (void) { return AnyOp(SIN, NULL); }
|
||||
inline Expr *Cos (void) { return AnyOp(COS, NULL); }
|
||||
|
||||
Expr *PartialWrt(hParam p);
|
||||
double Eval(void);
|
||||
|
||||
void ParamsToPointers(void);
|
||||
void Print(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -125,12 +125,7 @@ void GraphicsWindow::MenuView(MenuId id) {
|
|||
SS.GW.GroupSelection();
|
||||
if(SS.GW.gs.n == 1 && SS.GW.gs.csyss == 1) {
|
||||
Entity *e = SS.entity.FindById(SS.GW.gs.entity[0]);
|
||||
double q[4];
|
||||
for(int i = 0; i < 4; i++) {
|
||||
q[i] = SS.param.FindById(e->param(i))->val;
|
||||
}
|
||||
SS.GW.projRight = Vector::RotationU(q[0], q[1], q[2], q[3]);
|
||||
SS.GW.projUp = Vector::RotationV(q[0], q[1], q[2], q[3]);
|
||||
e->Get2dCsysBasisVectors( &(SS.GW.projRight), &(SS.GW.projUp));
|
||||
SS.GW.offset = SS.point.FindById(e->point(16))->GetCoords();
|
||||
SS.GW.ClearSelection();
|
||||
InvalidateGraphics();
|
||||
|
@ -376,6 +371,7 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
|
|||
SS.point.FindById(hr.entity(0).point(16))->ForceTo(v);
|
||||
pendingOperation = PENDING_OPERATION_DRAGGING_POINT;
|
||||
pendingPoint = hr.entity(0).point(16+3);
|
||||
pendingDescription = "click to place next point of line";
|
||||
SS.point.FindById(pendingPoint)->ForceTo(v);
|
||||
break;
|
||||
|
||||
|
|
36
sketch.cpp
36
sketch.cpp
|
@ -100,33 +100,51 @@ void Param::ForceTo(double v) {
|
|||
known = true;
|
||||
}
|
||||
|
||||
void Point::ForceTo(Vector v) {
|
||||
void Point::ForceTo(Vector p) {
|
||||
switch(type) {
|
||||
case IN_FREE_SPACE:
|
||||
SS.param.FindById(param(0))->ForceTo(v.x);
|
||||
SS.param.FindById(param(1))->ForceTo(v.y);
|
||||
SS.param.FindById(param(2))->ForceTo(v.z);
|
||||
SS.GetParam(param(0))->ForceTo(p.x);
|
||||
SS.GetParam(param(1))->ForceTo(p.y);
|
||||
SS.GetParam(param(2))->ForceTo(p.z);
|
||||
break;
|
||||
|
||||
case IN_2D_CSYS: {
|
||||
Entity *c = SS.GetEntity(csys);
|
||||
Vector u, v;
|
||||
c->Get2dCsysBasisVectors(&u, &v);
|
||||
SS.GetParam(param(0))->ForceTo(p.Dot(u));
|
||||
SS.GetParam(param(1))->ForceTo(p.Dot(v));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
oops();
|
||||
}
|
||||
}
|
||||
|
||||
Vector Point::GetCoords(void) {
|
||||
Vector v;
|
||||
Vector p;
|
||||
switch(type) {
|
||||
case IN_FREE_SPACE:
|
||||
v.x = SS.param.FindById(param(0))->val;
|
||||
v.y = SS.param.FindById(param(1))->val;
|
||||
v.z = SS.param.FindById(param(2))->val;
|
||||
p.x = SS.GetParam(param(0))->val;
|
||||
p.y = SS.GetParam(param(1))->val;
|
||||
p.z = SS.GetParam(param(2))->val;
|
||||
break;
|
||||
|
||||
case IN_2D_CSYS: {
|
||||
Entity *c = SS.GetEntity(csys);
|
||||
Vector u, v;
|
||||
c->Get2dCsysBasisVectors(&u, &v);
|
||||
p = u.ScaledBy(SS.GetParam(param(0))->val);
|
||||
p = p.Plus(v.ScaledBy(SS.GetParam(param(1))->val));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
oops();
|
||||
}
|
||||
|
||||
return v;
|
||||
return p;
|
||||
}
|
||||
|
||||
void Point::Draw(void) {
|
||||
|
|
2
sketch.h
2
sketch.h
|
@ -122,6 +122,8 @@ public:
|
|||
inline hPoint point(int i)
|
||||
{ hPoint r; r.v = ((this->h.v) << 7) | i; return r; }
|
||||
|
||||
void Get2dCsysBasisVectors(Vector *u, Vector *v);
|
||||
|
||||
struct {
|
||||
bool drawing;
|
||||
Point2d mp;
|
||||
|
|
|
@ -21,7 +21,7 @@ void SolveSpace::Init(void) {
|
|||
g.h = Group::HGROUP_REFERENCES;
|
||||
group.Add(&g);
|
||||
|
||||
g.csys = Entity::NO_CSYS;
|
||||
g.csys.v = Request::HREQUEST_REFERENCE_XY.v << 10;
|
||||
g.name.strcpy("");
|
||||
group.AddAndAssignId(&g);
|
||||
|
||||
|
|
|
@ -12,8 +12,13 @@
|
|||
#define max(x, y) ((x) > (y) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
class Expr;
|
||||
|
||||
void dbp(char *str, ...);
|
||||
void Error(char *str, ...);
|
||||
Expr *AllocExpr(void);
|
||||
void FreeAllExprs(void);
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
@ -22,7 +27,6 @@ void Error(char *str, ...);
|
|||
#include <gl/gl.h>
|
||||
#include <gl/glu.h>
|
||||
|
||||
class Expr;
|
||||
#include "dsc.h"
|
||||
#include "sketch.h"
|
||||
#include "ui.h"
|
||||
|
@ -58,6 +62,9 @@ public:
|
|||
IdList<Point,hPoint> point;
|
||||
IdList<Param,hParam> param;
|
||||
|
||||
inline Entity *GetEntity(hEntity h) { return entity.FindById(h); }
|
||||
inline Param *GetParam (hParam h) { return param. FindById(h); }
|
||||
|
||||
hGroup activeGroup;
|
||||
|
||||
void GenerateAll(void);
|
||||
|
|
15
textwin.cpp
15
textwin.cpp
|
@ -208,7 +208,7 @@ void TextWindow::ShowHeader(void) {
|
|||
Printf("");
|
||||
} else {
|
||||
// Navigation buttons
|
||||
Printf(" %Lb%f<<%E %Lh%fhome%E group:%s",
|
||||
Printf(" %Lb%f<<%E %Lh%fhome%E %C4 group:%s",
|
||||
(DWORD)(&TextWindow::ScreenNavigaton),
|
||||
(DWORD)(&TextWindow::ScreenNavigaton),
|
||||
SS.group.FindById(SS.GW.activeGroup)->DescriptionString());
|
||||
|
@ -245,7 +245,7 @@ void TextWindow::ShowHeader(void) {
|
|||
}
|
||||
|
||||
void TextWindow::ShowGroupList(void) {
|
||||
Printf("%C8[[click group to view requests]]%E");
|
||||
Printf("%C8[[all groups in sketch follow]]%E");
|
||||
int i;
|
||||
for(i = 0; i <= SS.group.elems; i++) {
|
||||
DWORD v;
|
||||
|
@ -275,6 +275,17 @@ void TextWindow::ShowRequestList(void) {
|
|||
Printf("%C8[[requests in all groups]]%E");
|
||||
} else {
|
||||
Group *g = SS.group.FindById(shown->group);
|
||||
if(SS.GW.activeGroup.v == shown->group.v) {
|
||||
Printf("%C8[[this is the active group]]");
|
||||
} else {
|
||||
Printf("%C8[[not active; %Llactivate this group%E%C8]]");
|
||||
}
|
||||
if(g->csys.v == Entity::NO_CSYS.v) {
|
||||
Printf("[[points may go anywhere in 3d]]");
|
||||
} else {
|
||||
Printf("[[locked into plane %s]]",
|
||||
SS.request.FindById(g->csys.request())->DescriptionString());
|
||||
}
|
||||
Printf("%C8[[requests in group %s]]%E", g->DescriptionString());
|
||||
}
|
||||
|
||||
|
|
|
@ -53,6 +53,27 @@ void Error(char *str, ...)
|
|||
MessageBox(h, buf, "SolveSpace Error", MB_OK | MB_ICONERROR);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// A separate heap, on which we allocate expressions. Maybe a bit faster,
|
||||
// since no fragmentation issues whatsoever, and it also makes it possible
|
||||
// to be sloppy with our memory management, and just free everything at once
|
||||
// at the end.
|
||||
//-----------------------------------------------------------------------------
|
||||
static HANDLE Heap;
|
||||
Expr *AllocExpr(void)
|
||||
{
|
||||
Expr *v = (Expr *)HeapAlloc(Heap, HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY,
|
||||
sizeof(Expr));
|
||||
if(!v) oops();
|
||||
memset(v, 0, sizeof(*v));
|
||||
return v;
|
||||
}
|
||||
void FreeAllExprs(void)
|
||||
{
|
||||
if(Heap) HeapDestroy(Heap);
|
||||
Heap = HeapCreate(HEAP_NO_SERIALIZE, 1024*1024*20, 0);
|
||||
}
|
||||
|
||||
static void PaintTextWnd(HDC hdc)
|
||||
{
|
||||
RECT rect;
|
||||
|
@ -104,9 +125,18 @@ static void PaintTextWnd(HDC hdc)
|
|||
} else {
|
||||
SelectObject(backDc, FixedFont);
|
||||
}
|
||||
TextOut(backDc, 4 + c*TEXT_WIDTH,
|
||||
(r-TextWndScrollPos)*TEXT_HEIGHT + 1,
|
||||
(char *)&(SS.TW.text[r][c]), 1);
|
||||
|
||||
int x = 4 + c*TEXT_WIDTH;
|
||||
int y = (r-TextWndScrollPos)*TEXT_HEIGHT + 1 + (r >= 3 ? 9 : 0);
|
||||
|
||||
HBRUSH b = CreateSolidBrush(SS.TW.colors[color].bg);
|
||||
RECT a;
|
||||
a.left = x; a.right = x+TEXT_WIDTH;
|
||||
a.top = y; a.bottom = y+TEXT_HEIGHT;
|
||||
FillRect(backDc, &a, b);
|
||||
DeleteObject(b);
|
||||
|
||||
TextOut(backDc, x, y, (char *)&(SS.TW.text[r][c]), 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -166,6 +196,7 @@ LRESULT CALLBACK TextWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
case WM_SIZING: {
|
||||
RECT *r = (RECT *)lParam;
|
||||
int hc = (r->bottom - r->top) - ClientIsSmallerBy;
|
||||
hc += TEXT_HEIGHT/2;
|
||||
int extra = hc % TEXT_HEIGHT;
|
||||
switch(wParam) {
|
||||
case WMSZ_BOTTOM:
|
||||
|
@ -526,6 +557,9 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||
if(!LinkFont)
|
||||
LinkFont = (HFONT)GetStockObject(SYSTEM_FONT);
|
||||
|
||||
// Create the heap that we use to store Exprs.
|
||||
FreeAllExprs();
|
||||
|
||||
// Call in to the platform-independent code, and let them do their init
|
||||
SS.Init();
|
||||
|
||||
|
|
Loading…
Reference in New Issue