Add horizontal and vertical constraints. Those have their own 2d/3d
issues, when the points are not all in the same coordinate system. All painful, of course. Also add continuous line drawing, and auto-constraining of line segments as I draw. [git-p4: depot-paths = "//depot/solvespace/": change = 1683]
This commit is contained in:
parent
1bf7e3deaf
commit
a8001adf33
114
constraint.cpp
114
constraint.cpp
|
@ -5,6 +5,16 @@ hConstraint Constraint::AddConstraint(Constraint *c) {
|
|||
return c->h;
|
||||
}
|
||||
|
||||
void Constraint::ConstrainCoincident(hEntity ptA, hEntity ptB) {
|
||||
Constraint c;
|
||||
memset(&c, 0, sizeof(c));
|
||||
c.group = SS.GW.activeGroup;
|
||||
c.type = Constraint::POINTS_COINCIDENT;
|
||||
c.ptA = ptA;
|
||||
c.ptB = ptB;
|
||||
SS.constraint.AddAndAssignId(&c);
|
||||
}
|
||||
|
||||
void Constraint::MenuConstrain(int id) {
|
||||
Constraint c;
|
||||
memset(&c, 0, sizeof(c));
|
||||
|
@ -62,6 +72,48 @@ void Constraint::MenuConstrain(int id) {
|
|||
AddConstraint(&c);
|
||||
break;
|
||||
|
||||
case GraphicsWindow::MNU_VERTICAL:
|
||||
case GraphicsWindow::MNU_HORIZONTAL: {
|
||||
hEntity ha, hb;
|
||||
if(gs.lineSegments == 1 && gs.n == 1) {
|
||||
c.entityA = gs.entity[0];
|
||||
Entity *e = SS.GetEntity(c.entityA);
|
||||
ha = e->assoc[0];
|
||||
hb = e->assoc[1];
|
||||
} else if(gs.points == 2 && gs.n == 2) {
|
||||
ha = c.ptA = gs.point[0];
|
||||
hb = c.ptB = gs.point[1];
|
||||
} else {
|
||||
Error("Bad selection for horizontal / vertical constraint.");
|
||||
return;
|
||||
}
|
||||
Entity *ea = SS.GetEntity(ha);
|
||||
Entity *eb = SS.GetEntity(hb);
|
||||
if(ea->csys.v == Entity::NO_CSYS.v &&
|
||||
eb->csys.v == Entity::NO_CSYS.v)
|
||||
{
|
||||
Error("Horizontal/vertical constraint applies only to "
|
||||
"entities drawn in a 2d coordinate system.");
|
||||
return;
|
||||
}
|
||||
if(eb->csys.v == SS.GW.activeCsys.v) {
|
||||
// We are constraining two points in two different csyss; so
|
||||
// we have two choices for the definitons of the coordinate
|
||||
// directions. ptA's gets chosen, so make sure that's the
|
||||
// active csys.
|
||||
hEntity t = c.ptA;
|
||||
c.ptA = c.ptB;
|
||||
c.ptB = t;
|
||||
}
|
||||
if(id == GraphicsWindow::MNU_HORIZONTAL) {
|
||||
c.type = HORIZONTAL;
|
||||
} else {
|
||||
c.type = VERTICAL;
|
||||
}
|
||||
AddConstraint(&c);
|
||||
break;
|
||||
}
|
||||
|
||||
case GraphicsWindow::MNU_SOLVE_NOW:
|
||||
SS.Solve();
|
||||
return;
|
||||
|
@ -157,24 +209,27 @@ void Constraint::Generate(IdList<Equation,hEquation> *l) {
|
|||
AddEq(l, eab.x, 0);
|
||||
AddEq(l, eab.y, 1);
|
||||
AddEq(l, eab.z, 2);
|
||||
} else if(a->IsPointIn3d() && !b->IsPointIn3d()) {
|
||||
// One point has 2 DOF, one has 3; write two eqs, on the
|
||||
// projection of the 3 DOF point into the 2 DOF point plane.
|
||||
ExprVector p3;
|
||||
p3 = a->PointGetExprs();
|
||||
Entity *csy = SS.GetEntity(b->csys);
|
||||
ExprVector u, v;
|
||||
csy->Csys2dGetBasisExprs(&u, &v);
|
||||
AddEq(l, Expr::FromParam(b->param.h[0])->Minus(p3.Dot(u)), 0);
|
||||
AddEq(l, Expr::FromParam(b->param.h[1])->Minus(p3.Dot(v)), 1);
|
||||
} else if(a->csys.v == b->csys.v) {
|
||||
} else if(!(a->IsPointIn3d() || b->IsPointIn3d()) &&
|
||||
(a->csys.v == b->csys.v))
|
||||
{
|
||||
// Both in same csys, nice.
|
||||
AddEq(l, Expr::FromParam(a->param.h[0])->Minus(
|
||||
Expr::FromParam(b->param.h[0])), 0);
|
||||
AddEq(l, Expr::FromParam(a->param.h[1])->Minus(
|
||||
Expr::FromParam(b->param.h[1])), 1);
|
||||
} else {
|
||||
oops();
|
||||
// Either two 2 DOF points in different planes, or one
|
||||
// 3 DOF point and one 2 DOF point. Either way, write two
|
||||
// equations on the projection of a into b's plane.
|
||||
ExprVector p3;
|
||||
p3 = a->PointGetExprs();
|
||||
Entity *csy = SS.GetEntity(b->csys);
|
||||
ExprVector offset = csy->Csys2dGetOffsetExprs();
|
||||
p3 = p3.Minus(offset);
|
||||
ExprVector u, v;
|
||||
csy->Csys2dGetBasisExprs(&u, &v);
|
||||
AddEq(l, Expr::FromParam(b->param.h[0])->Minus(p3.Dot(u)), 0);
|
||||
AddEq(l, Expr::FromParam(b->param.h[1])->Minus(p3.Dot(v)), 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -188,6 +243,41 @@ void Constraint::Generate(IdList<Equation,hEquation> *l) {
|
|||
break;
|
||||
}
|
||||
|
||||
case HORIZONTAL:
|
||||
case VERTICAL: {
|
||||
hEntity ha, hb;
|
||||
if(entityA.v) {
|
||||
Entity *e = SS.GetEntity(entityA);
|
||||
ha = e->assoc[0];
|
||||
hb = e->assoc[1];
|
||||
} else {
|
||||
ha = ptA;
|
||||
hb = ptB;
|
||||
}
|
||||
Entity *a = SS.GetEntity(ha);
|
||||
Entity *b = SS.GetEntity(hb);
|
||||
if(a->csys.v == Entity::NO_CSYS.v) {
|
||||
Entity *t = a;
|
||||
a = b;
|
||||
b = t;
|
||||
}
|
||||
|
||||
if(a->csys.v == b->csys.v) {
|
||||
int i = (type == HORIZONTAL) ? 1 : 0;
|
||||
AddEq(l, Expr::FromParam(a->param.h[i])->Minus(
|
||||
Expr::FromParam(b->param.h[i])), 0);
|
||||
} else {
|
||||
Entity *csy = SS.GetEntity(a->csys);
|
||||
ExprVector u, v;
|
||||
csy->Csys2dGetBasisExprs(&u, &v);
|
||||
ExprVector norm = (type == HORIZONTAL) ? v : u;
|
||||
ExprVector pa = a->PointGetExprs();
|
||||
ExprVector pb = b->PointGetExprs();
|
||||
AddEq(l, (pa.Minus(pb)).Dot(norm), 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: oops();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
|
|||
Vector gu = SS.GW.projUp;
|
||||
Vector gn = gr.Cross(gu);
|
||||
|
||||
glxColor(1, 0.3, 1);
|
||||
glxColor(1, 0.2, 1);
|
||||
switch(type) {
|
||||
case PT_PT_DISTANCE: {
|
||||
Vector ap = SS.GetEntity(ptA)->PointGetCoords();
|
||||
|
@ -125,6 +125,55 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
|
|||
break;
|
||||
}
|
||||
|
||||
case HORIZONTAL:
|
||||
case VERTICAL:
|
||||
if(entityA.v) {
|
||||
Entity *e = SS.GetEntity(entityA);
|
||||
Vector a = SS.GetEntity(e->assoc[0])->PointGetCoords();
|
||||
Vector b = SS.GetEntity(e->assoc[1])->PointGetCoords();
|
||||
Vector m = (a.ScaledBy(0.5)).Plus(b.ScaledBy(0.5));
|
||||
|
||||
if(dogd.drawing) {
|
||||
glPushMatrix();
|
||||
glxTranslatev(m);
|
||||
glxOntoCsys(gr, gu);
|
||||
glxWriteText(type == HORIZONTAL ? "H" : "V");
|
||||
glPopMatrix();
|
||||
} else {
|
||||
Point2d ref = SS.GW.ProjectPoint(m);
|
||||
dogd.dmin = min(dogd.dmin, ref.DistanceTo(dogd.mp)-10);
|
||||
}
|
||||
} else {
|
||||
Vector a = SS.GetEntity(ptA)->PointGetCoords();
|
||||
Vector b = SS.GetEntity(ptB)->PointGetCoords();
|
||||
Entity *csy = SS.GetEntity(SS.GetEntity(ptA)->csys);
|
||||
Vector cn = csy->Csys2dGetNormalVector();
|
||||
|
||||
int i;
|
||||
for(i = 0; i < 2; i++) {
|
||||
Vector o = (i == 0) ? a : b;
|
||||
Vector d = (i == 0) ? a.Minus(b) : b.Minus(a);
|
||||
Vector dp = cn.Cross(d);
|
||||
d = d.WithMagnitude(14/SS.GW.scale);
|
||||
Vector c = o.Minus(d);
|
||||
LineDrawOrGetDistance(o, c);
|
||||
d = d.WithMagnitude(3/SS.GW.scale);
|
||||
dp = dp.WithMagnitude(2/SS.GW.scale);
|
||||
if(dogd.drawing) {
|
||||
glBegin(GL_QUADS);
|
||||
glxVertex3v((c.Plus(d)).Plus(dp));
|
||||
glxVertex3v((c.Minus(d)).Plus(dp));
|
||||
glxVertex3v((c.Minus(d)).Minus(dp));
|
||||
glxVertex3v((c.Plus(d)).Minus(dp));
|
||||
glEnd();
|
||||
} else {
|
||||
Point2d ref = SS.GW.ProjectPoint(c);
|
||||
dogd.dmin = min(dogd.dmin, ref.DistanceTo(dogd.mp)-6);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default: oops();
|
||||
}
|
||||
}
|
||||
|
|
10
entity.cpp
10
entity.cpp
|
@ -16,6 +16,12 @@ void Entity::Csys2dGetBasisVectors(Vector *u, Vector *v) {
|
|||
*v = quat.RotationV();
|
||||
}
|
||||
|
||||
Vector Entity::Csys2dGetNormalVector(void) {
|
||||
Vector u, v;
|
||||
Csys2dGetBasisVectors(&u, &v);
|
||||
return u.Cross(v);
|
||||
}
|
||||
|
||||
void Entity::Csys2dGetBasisExprs(ExprVector *u, ExprVector *v) {
|
||||
Expr *a = Expr::FromParam(param.h[0]);
|
||||
Expr *b = Expr::FromParam(param.h[1]);
|
||||
|
@ -47,6 +53,10 @@ void Entity::Csys2dGetBasisExprs(ExprVector *u, ExprVector *v) {
|
|||
v->z = (v->z)->Plus(two->Times(c->Times(d)));
|
||||
}
|
||||
|
||||
ExprVector Entity::Csys2dGetOffsetExprs(void) {
|
||||
return SS.GetEntity(assoc[0])->PointGetExprs();
|
||||
}
|
||||
|
||||
bool Entity::HasPlane(void) {
|
||||
switch(type) {
|
||||
case CSYS_2D:
|
||||
|
|
|
@ -73,8 +73,8 @@ const GraphicsWindow::MenuEntry GraphicsWindow::menu[] = {
|
|||
{ 1, "A&ngle\tShift+N", 0, 'N'|S, NULL },
|
||||
{ 1, "Other S&upplementary Angle\tShift+U", 0, 'U'|S, NULL },
|
||||
{ 1, NULL, 0, NULL },
|
||||
{ 1, "&Horizontal\tShift+H", 0, 'H'|S, NULL },
|
||||
{ 1, "&Vertical\tShift+V", 0, 'V'|S, NULL },
|
||||
{ 1, "&Horizontal\tShift+H", MNU_HORIZONTAL, 'H'|S, mCon },
|
||||
{ 1, "&Vertical\tShift+V", MNU_VERTICAL, 'V'|S, mCon },
|
||||
{ 1, NULL, 0, NULL },
|
||||
{ 1, "&On Point / Curve / Plane\tShift+O", MNU_ON_ENTITY, 'O'|S, mCon },
|
||||
{ 1, "E&qual Length / Radius\tShift+Q", MNU_EQUAL, 'Q'|S, mCon },
|
||||
|
@ -264,6 +264,8 @@ void GraphicsWindow::MenuEdit(int id) {
|
|||
SS.GW.ClearSelection();
|
||||
SS.GW.pendingOperation = 0;
|
||||
SS.GW.pendingDescription = NULL;
|
||||
SS.GW.pendingPoint.v = 0;
|
||||
SS.GW.pendingConstraint.v = 0;
|
||||
SS.TW.ScreenNavigation('h', 0);
|
||||
SS.TW.Show();
|
||||
break;
|
||||
|
@ -360,7 +362,7 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
|
|||
double dy = (y - orig.mouse.y) / scale;
|
||||
|
||||
// When the view is locked, permit only translation (pan).
|
||||
if(shiftDown || viewLocked) {
|
||||
if(!(shiftDown || ctrlDown) || viewLocked) {
|
||||
offset.x = orig.offset.x + dx*projRight.x + dy*projUp.x;
|
||||
offset.y = orig.offset.y + dx*projRight.y + dy*projUp.y;
|
||||
offset.z = orig.offset.z + dx*projRight.z + dy*projUp.z;
|
||||
|
@ -404,7 +406,7 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
|
|||
// Start dragging this point.
|
||||
ClearSelection();
|
||||
pendingPoint = hover.entity;
|
||||
pendingOperation = PENDING_OPERATION_DRAGGING_POINT;
|
||||
pendingOperation = DRAGGING_POINT;
|
||||
}
|
||||
} else if(hover.constraint.v &&
|
||||
SS.GetConstraint(hover.constraint)->HasLabel())
|
||||
|
@ -412,29 +414,28 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
|
|||
if(dm > dmt) {
|
||||
ClearSelection();
|
||||
pendingConstraint = hover.constraint;
|
||||
pendingOperation = PENDING_OPERATION_DRAGGING_CONSTRAINT;
|
||||
pendingOperation = DRAGGING_CONSTRAINT;
|
||||
}
|
||||
}
|
||||
} else if(pendingOperation == PENDING_OPERATION_DRAGGING_POINT ||
|
||||
pendingOperation == PENDING_OPERATION_DRAGGING_NEW_POINT)
|
||||
} else if(pendingOperation == DRAGGING_POINT ||
|
||||
pendingOperation == DRAGGING_NEW_POINT ||
|
||||
pendingOperation == DRAGGING_NEW_LINE_POINT)
|
||||
{
|
||||
UpdateDraggedEntity(pendingPoint, x, y);
|
||||
} else if(pendingOperation == PENDING_OPERATION_DRAGGING_CONSTRAINT) {
|
||||
} else if(pendingOperation == DRAGGING_CONSTRAINT) {
|
||||
Constraint *c = SS.constraint.FindById(pendingConstraint);
|
||||
UpdateDraggedPoint(&(c->disp.offset), x, y);
|
||||
}
|
||||
} else {
|
||||
// No buttons pressed.
|
||||
if(pendingOperation == PENDING_OPERATION_DRAGGING_NEW_POINT) {
|
||||
if(pendingOperation == DRAGGING_NEW_POINT ||
|
||||
pendingOperation == DRAGGING_NEW_LINE_POINT)
|
||||
{
|
||||
UpdateDraggedEntity(pendingPoint, x, y);
|
||||
HitTestMakeSelection(mp);
|
||||
} else {
|
||||
// Do our usual hit testing, for the selection.
|
||||
Selection s;
|
||||
HitTestMakeSelection(mp, &s);
|
||||
if(!s.Equals(&hover)) {
|
||||
hover = s;
|
||||
InvalidateGraphics();
|
||||
}
|
||||
HitTestMakeSelection(mp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -457,18 +458,22 @@ void GraphicsWindow::Selection::Draw(void) {
|
|||
if(constraint.v) SS.GetConstraint(constraint)->Draw();
|
||||
}
|
||||
|
||||
void GraphicsWindow::HitTestMakeSelection(Point2d mp, Selection *dest) {
|
||||
void GraphicsWindow::HitTestMakeSelection(Point2d mp) {
|
||||
int i;
|
||||
double d, dmin = 1e12;
|
||||
|
||||
memset(dest, 0, sizeof(*dest));
|
||||
Selection s;
|
||||
memset(&s, 0, sizeof(s));
|
||||
|
||||
// Do the entities
|
||||
for(i = 0; i < SS.entity.n; i++) {
|
||||
d = SS.entity.elem[i].GetDistance(mp);
|
||||
Entity *e = &(SS.entity.elem[i]);
|
||||
// Don't hover whatever's being dragged.
|
||||
if(e->h.request().v == pendingPoint.request().v) continue;
|
||||
|
||||
d = e->GetDistance(mp);
|
||||
if(d < 10 && d < dmin) {
|
||||
memset(dest, 0, sizeof(*dest));
|
||||
dest->entity = SS.entity.elem[i].h;
|
||||
memset(&s, 0, sizeof(s));
|
||||
s.entity = e->h;
|
||||
dmin = d;
|
||||
}
|
||||
}
|
||||
|
@ -477,11 +482,16 @@ void GraphicsWindow::HitTestMakeSelection(Point2d mp, Selection *dest) {
|
|||
for(i = 0; i < SS.constraint.n; i++) {
|
||||
d = SS.constraint.elem[i].GetDistance(mp);
|
||||
if(d < 10 && d < dmin) {
|
||||
memset(dest, 0, sizeof(*dest));
|
||||
dest->constraint = SS.constraint.elem[i].h;
|
||||
memset(&s, 0, sizeof(s));
|
||||
s.constraint = SS.constraint.elem[i].h;
|
||||
dmin = d;
|
||||
}
|
||||
}
|
||||
|
||||
if(!s.Equals(&hover)) {
|
||||
hover = s;
|
||||
InvalidateGraphics();
|
||||
}
|
||||
}
|
||||
|
||||
void GraphicsWindow::ClearSelection(void) {
|
||||
|
@ -565,17 +575,41 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
|
|||
hr = AddRequest(Request::LINE_SEGMENT);
|
||||
SS.GetEntity(hr.entity(1))->PointForceTo(v);
|
||||
|
||||
pendingOperation = PENDING_OPERATION_DRAGGING_NEW_POINT;
|
||||
pendingOperation = DRAGGING_NEW_LINE_POINT;
|
||||
pendingPoint = hr.entity(2);
|
||||
pendingDescription = "click to place next point of line";
|
||||
SS.GetEntity(pendingPoint)->PointForceTo(v);
|
||||
break;
|
||||
|
||||
case PENDING_OPERATION_DRAGGING_NEW_POINT:
|
||||
case DRAGGING_NEW_POINT:
|
||||
// The MouseMoved event has already dragged it under the cursor.
|
||||
pendingOperation = 0;
|
||||
pendingPoint.v = 0;
|
||||
break;
|
||||
|
||||
case DRAGGING_NEW_LINE_POINT: {
|
||||
if(hover.entity.v && SS.GetEntity(hover.entity)->IsPoint()) {
|
||||
Constraint::ConstrainCoincident(pendingPoint, hover.entity);
|
||||
pendingOperation = 0;
|
||||
pendingPoint.v = 0;
|
||||
break;
|
||||
}
|
||||
// Create a new line segment, so that we continue drawing.
|
||||
hRequest hr = AddRequest(Request::LINE_SEGMENT);
|
||||
SS.GetEntity(hr.entity(1))->PointForceTo(v);
|
||||
|
||||
// Constrain the line segments to share an endpoint
|
||||
Constraint::ConstrainCoincident(pendingPoint, hr.entity(1));
|
||||
|
||||
// And drag an endpoint of the new line segment
|
||||
pendingOperation = DRAGGING_NEW_LINE_POINT;
|
||||
pendingPoint = hr.entity(2);
|
||||
pendingDescription = "click to place next point of next line";
|
||||
SS.GetEntity(pendingPoint)->PointForceTo(v);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 0:
|
||||
default: {
|
||||
pendingOperation = 0;
|
||||
|
@ -609,8 +643,8 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
|
|||
|
||||
void GraphicsWindow::MouseLeftUp(double mx, double my) {
|
||||
switch(pendingOperation) {
|
||||
case PENDING_OPERATION_DRAGGING_POINT:
|
||||
case PENDING_OPERATION_DRAGGING_CONSTRAINT:
|
||||
case DRAGGING_POINT:
|
||||
case DRAGGING_CONSTRAINT:
|
||||
pendingOperation = 0;
|
||||
pendingPoint.v = 0;
|
||||
pendingConstraint.v = 0;
|
||||
|
|
21
polygon.h
Normal file
21
polygon.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
|
||||
#ifndef __POLYGON_H
|
||||
#define __POLYGON_H
|
||||
|
||||
class SPolyhedron {
|
||||
public:
|
||||
};
|
||||
|
||||
class SPolygon {
|
||||
public:
|
||||
};
|
||||
|
||||
class SContour {
|
||||
public:
|
||||
};
|
||||
|
||||
class SEdgeList {
|
||||
public:
|
||||
};
|
||||
|
||||
#endif
|
8
sketch.h
8
sketch.h
|
@ -58,9 +58,13 @@ public:
|
|||
int solveOrder;
|
||||
bool solved;
|
||||
|
||||
bool visible;
|
||||
|
||||
NameStr name;
|
||||
|
||||
char *DescriptionString(void);
|
||||
|
||||
SPolygon GetPolygon(void);
|
||||
};
|
||||
|
||||
|
||||
|
@ -140,7 +144,9 @@ public:
|
|||
|
||||
// Applies only for a CSYS_2D type
|
||||
void Csys2dGetBasisVectors(Vector *u, Vector *v);
|
||||
Vector Csys2dGetNormalVector(void);
|
||||
void Csys2dGetBasisExprs(ExprVector *u, ExprVector *v);
|
||||
ExprVector Csys2dGetOffsetExprs(void);
|
||||
|
||||
bool IsPoint(void);
|
||||
bool IsPointIn3d(void);
|
||||
|
@ -260,6 +266,8 @@ public:
|
|||
void ModifyToSatisfy(void);
|
||||
void AddEq(IdList<Equation,hEquation> *l, Expr *expr, int index);
|
||||
static Expr *Distance(hEntity pa, hEntity pb);
|
||||
|
||||
static void ConstrainCoincident(hEntity ptA, hEntity ptB);
|
||||
};
|
||||
|
||||
class hEquation {
|
||||
|
|
|
@ -56,6 +56,7 @@ void MemFree(void *p);
|
|||
|
||||
|
||||
#include "dsc.h"
|
||||
#include "polygon.h"
|
||||
#include "sketch.h"
|
||||
#include "ui.h"
|
||||
#include "expr.h"
|
||||
|
|
11
ui.h
11
ui.h
|
@ -101,6 +101,8 @@ public:
|
|||
MNU_DISTANCE_DIA,
|
||||
MNU_EQUAL,
|
||||
MNU_ON_ENTITY,
|
||||
MNU_HORIZONTAL,
|
||||
MNU_VERTICAL,
|
||||
MNU_SOLVE_NOW,
|
||||
} MenuId;
|
||||
typedef void MenuHandler(int id);
|
||||
|
@ -148,9 +150,10 @@ public:
|
|||
|
||||
// Operations that must be completed by doing something with the mouse
|
||||
// are noted here.
|
||||
static const int PENDING_OPERATION_DRAGGING_POINT = 0x0f000000;
|
||||
static const int PENDING_OPERATION_DRAGGING_NEW_POINT = 0x0f000001;
|
||||
static const int PENDING_OPERATION_DRAGGING_CONSTRAINT = 0x0f000002;
|
||||
static const int DRAGGING_POINT = 0x0f000000;
|
||||
static const int DRAGGING_NEW_POINT = 0x0f000001;
|
||||
static const int DRAGGING_NEW_LINE_POINT = 0x0f000002;
|
||||
static const int DRAGGING_CONSTRAINT = 0x0f000003;
|
||||
hEntity pendingPoint;
|
||||
hConstraint pendingConstraint;
|
||||
int pendingOperation;
|
||||
|
@ -175,7 +178,7 @@ public:
|
|||
Selection hover;
|
||||
static const int MAX_SELECTED = 32;
|
||||
Selection selection[MAX_SELECTED];
|
||||
void HitTestMakeSelection(Point2d mp, Selection *dest);
|
||||
void HitTestMakeSelection(Point2d mp);
|
||||
void ClearSelection(void);
|
||||
struct {
|
||||
hEntity point[MAX_SELECTED];
|
||||
|
|
Loading…
Reference in New Issue
Block a user