Add parallel and same orientation constraints, that work on line
segments and normals. [git-p4: depot-paths = "//depot/solvespace/": change = 1713]
This commit is contained in:
parent
018e8a0444
commit
10240cc1df
|
@ -181,6 +181,30 @@ void Constraint::MenuConstrain(int id) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case GraphicsWindow::MNU_ORIENTED_SAME:
|
||||||
|
if(gs.anyNormals == 2 && gs.n == 2) {
|
||||||
|
c.type = SAME_ORIENTATION;
|
||||||
|
c.entityA = gs.anyNormal[0];
|
||||||
|
c.entityB = gs.anyNormal[1];
|
||||||
|
} else {
|
||||||
|
Error("Bad selection for same orientation constraint.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
AddConstraint(&c);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GraphicsWindow::MNU_PARALLEL:
|
||||||
|
if(gs.vectors == 2 && gs.n == 2) {
|
||||||
|
c.type = PARALLEL;
|
||||||
|
c.entityA = gs.vector[0];
|
||||||
|
c.entityB = gs.vector[1];
|
||||||
|
} else {
|
||||||
|
Error("Bad selection for parallel constraint.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
AddConstraint(&c);
|
||||||
|
break;
|
||||||
|
|
||||||
case GraphicsWindow::MNU_SOLVE_NOW:
|
case GraphicsWindow::MNU_SOLVE_NOW:
|
||||||
SS.GenerateAll(true);
|
SS.GenerateAll(true);
|
||||||
return;
|
return;
|
||||||
|
@ -528,6 +552,37 @@ void Constraint::Generate(IdList<Equation,hEquation> *l) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SAME_ORIENTATION: {
|
||||||
|
Entity *a = SS.GetEntity(entityA);
|
||||||
|
Entity *b = SS.GetEntity(entityB);
|
||||||
|
ExprVector au = a->NormalExprsU(),
|
||||||
|
av = a->NormalExprsV(),
|
||||||
|
an = a->NormalExprsN();
|
||||||
|
ExprVector bu = b->NormalExprsU(),
|
||||||
|
bv = b->NormalExprsV(),
|
||||||
|
bn = b->NormalExprsN();
|
||||||
|
|
||||||
|
AddEq(l, VectorsParallel(0, an, bn), 0);
|
||||||
|
AddEq(l, VectorsParallel(1, an, bn), 1);
|
||||||
|
AddEq(l, au.Dot(bv), 2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PARALLEL: {
|
||||||
|
ExprVector a = SS.GetEntity(entityA)->VectorGetExprs();
|
||||||
|
ExprVector b = SS.GetEntity(entityB)->VectorGetExprs();
|
||||||
|
|
||||||
|
if(workplane.v == Entity::FREE_IN_3D.v) {
|
||||||
|
AddEq(l, VectorsParallel(0, a, b), 0);
|
||||||
|
AddEq(l, VectorsParallel(1, a, b), 1);
|
||||||
|
} else {
|
||||||
|
Entity *w = SS.GetEntity(workplane);
|
||||||
|
ExprVector wn = w->Normal()->NormalExprsN();
|
||||||
|
AddEq(l, (a.Cross(b)).Dot(wn), 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default: oops();
|
default: oops();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -231,6 +231,35 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SAME_ORIENTATION: {
|
||||||
|
for(int i = 0; i < 2; i++) {
|
||||||
|
Entity *e = SS.GetEntity(i == 0 ? entityA : entityB);
|
||||||
|
Quaternion q = e->NormalGetNum();
|
||||||
|
Vector n = q.RotationN().WithMagnitude(25/SS.GW.scale);
|
||||||
|
Vector u = q.RotationU().WithMagnitude(6/SS.GW.scale);
|
||||||
|
Vector p = SS.GetEntity(e->point[0])->PointGetNum();
|
||||||
|
p = p.Plus(n.WithMagnitude(10/SS.GW.scale));
|
||||||
|
|
||||||
|
LineDrawOrGetDistance(p.Plus(u), p.Minus(u).Plus(n));
|
||||||
|
LineDrawOrGetDistance(p.Minus(u), p.Plus(u).Plus(n));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PARALLEL: {
|
||||||
|
for(int i = 0; i < 2; i++) {
|
||||||
|
Entity *e = SS.GetEntity(i == 0 ? entityA : entityB);
|
||||||
|
Vector n = e->VectorGetExprs().Eval();
|
||||||
|
n = n.WithMagnitude(25/SS.GW.scale);
|
||||||
|
Vector u = (gn.Cross(n)).WithMagnitude(4/SS.GW.scale);
|
||||||
|
Vector p = e->VectorGetRefPoint();
|
||||||
|
|
||||||
|
LineDrawOrGetDistance(p.Plus(u), p.Plus(u).Plus(n));
|
||||||
|
LineDrawOrGetDistance(p.Minus(u), p.Minus(u).Plus(n));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case EQUAL_LENGTH_LINES: {
|
case EQUAL_LENGTH_LINES: {
|
||||||
for(int i = 0; i < 2; i++) {
|
for(int i = 0; i < 2; i++) {
|
||||||
Entity *e = SS.GetEntity(i == 0 ? entityA : entityB);
|
Entity *e = SS.GetEntity(i == 0 ? entityA : entityB);
|
||||||
|
|
46
entity.cpp
46
entity.cpp
|
@ -5,6 +5,49 @@ char *Entity::DescriptionString(void) {
|
||||||
return r->DescriptionString();
|
return r->DescriptionString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Entity::HasVector(void) {
|
||||||
|
switch(type) {
|
||||||
|
case LINE_SEGMENT:
|
||||||
|
case NORMAL_IN_3D:
|
||||||
|
case NORMAL_IN_2D:
|
||||||
|
case NORMAL_XFRMD:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ExprVector Entity::VectorGetExprs(void) {
|
||||||
|
switch(type) {
|
||||||
|
case LINE_SEGMENT:
|
||||||
|
return (SS.GetEntity(point[0])->PointGetExprs()).Minus(
|
||||||
|
SS.GetEntity(point[1])->PointGetExprs());
|
||||||
|
|
||||||
|
case NORMAL_IN_3D:
|
||||||
|
case NORMAL_IN_2D:
|
||||||
|
case NORMAL_XFRMD:
|
||||||
|
return NormalExprsN();
|
||||||
|
|
||||||
|
default: oops();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector Entity::VectorGetRefPoint(void) {
|
||||||
|
switch(type) {
|
||||||
|
case LINE_SEGMENT:
|
||||||
|
return ((SS.GetEntity(point[0])->PointGetNum()).Plus(
|
||||||
|
SS.GetEntity(point[1])->PointGetNum())).ScaledBy(0.5);
|
||||||
|
|
||||||
|
case NORMAL_IN_3D:
|
||||||
|
case NORMAL_IN_2D:
|
||||||
|
case NORMAL_XFRMD:
|
||||||
|
return SS.GetEntity(point[0])->PointGetNum();
|
||||||
|
|
||||||
|
default: oops();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool Entity::IsCircle(void) {
|
bool Entity::IsCircle(void) {
|
||||||
return (type == CIRCLE);
|
return (type == CIRCLE);
|
||||||
}
|
}
|
||||||
|
@ -456,10 +499,13 @@ void Entity::DrawOrGetDistance(int order) {
|
||||||
Vector mp = p.Minus(us).Plus (vs);
|
Vector mp = p.Minus(us).Plus (vs);
|
||||||
|
|
||||||
glxColor3d(0, 0.3, 0.3);
|
glxColor3d(0, 0.3, 0.3);
|
||||||
|
glEnable(GL_LINE_STIPPLE);
|
||||||
|
glLineStipple(3, 0x1111);
|
||||||
LineDrawOrGetDistance(pp, pm);
|
LineDrawOrGetDistance(pp, pm);
|
||||||
LineDrawOrGetDistance(pm, mm);
|
LineDrawOrGetDistance(pm, mm);
|
||||||
LineDrawOrGetDistance(mm, mp);
|
LineDrawOrGetDistance(mm, mp);
|
||||||
LineDrawOrGetDistance(mp, pp);
|
LineDrawOrGetDistance(mp, pp);
|
||||||
|
glDisable(GL_LINE_STIPPLE);
|
||||||
|
|
||||||
if(dogd.drawing) {
|
if(dogd.drawing) {
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
|
|
8
expr.cpp
8
expr.cpp
|
@ -53,6 +53,14 @@ Expr *ExprVector::Magnitude(void) {
|
||||||
return r->Sqrt();
|
return r->Sqrt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vector ExprVector::Eval(void) {
|
||||||
|
Vector r;
|
||||||
|
r.x = x->Eval();
|
||||||
|
r.y = y->Eval();
|
||||||
|
r.z = z->Eval();
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
ExprQuaternion ExprQuaternion::FromExprs(Expr *w, Expr *vx, Expr *vy, Expr *vz)
|
ExprQuaternion ExprQuaternion::FromExprs(Expr *w, Expr *vx, Expr *vy, Expr *vz)
|
||||||
{
|
{
|
||||||
ExprQuaternion q;
|
ExprQuaternion q;
|
||||||
|
|
2
expr.h
2
expr.h
|
@ -130,6 +130,8 @@ public:
|
||||||
ExprVector Cross(ExprVector b);
|
ExprVector Cross(ExprVector b);
|
||||||
ExprVector ScaledBy(Expr *s);
|
ExprVector ScaledBy(Expr *s);
|
||||||
Expr *Magnitude(void);
|
Expr *Magnitude(void);
|
||||||
|
|
||||||
|
Vector Eval(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ExprQuaternion {
|
class ExprQuaternion {
|
||||||
|
|
|
@ -79,6 +79,8 @@ const GraphicsWindow::MenuEntry GraphicsWindow::menu[] = {
|
||||||
{ 1, "E&qual Length / Radius\tShift+Q", MNU_EQUAL, 'Q'|S, mCon },
|
{ 1, "E&qual Length / Radius\tShift+Q", MNU_EQUAL, 'Q'|S, mCon },
|
||||||
{ 1, "At &Midpoint\tShift+M", MNU_AT_MIDPOINT, 'M'|S, mCon },
|
{ 1, "At &Midpoint\tShift+M", MNU_AT_MIDPOINT, 'M'|S, mCon },
|
||||||
{ 1, "S&ymmetric\tShift+Y", MNU_SYMMETRIC, 'Y'|S, mCon },
|
{ 1, "S&ymmetric\tShift+Y", MNU_SYMMETRIC, 'Y'|S, mCon },
|
||||||
|
{ 1, "Para&llel\tShift+L", MNU_PARALLEL, 'L'|S, mCon },
|
||||||
|
{ 1, "Same O&rientation\tShift+R", MNU_ORIENTED_SAME, 'R'|S, mCon },
|
||||||
{ 1, NULL, 0, NULL },
|
{ 1, NULL, 0, NULL },
|
||||||
{ 1, "Sym&bolic Equation\tShift+B", 0, 'B'|S, NULL },
|
{ 1, "Sym&bolic Equation\tShift+B", 0, 'B'|S, NULL },
|
||||||
{ 1, NULL, 0, NULL },
|
{ 1, NULL, 0, NULL },
|
||||||
|
@ -627,11 +629,27 @@ void GraphicsWindow::GroupSelection(void) {
|
||||||
(gs.n)++;
|
(gs.n)++;
|
||||||
|
|
||||||
Entity *e = SS.entity.FindById(s->entity);
|
Entity *e = SS.entity.FindById(s->entity);
|
||||||
|
// A list of points, and a list of all entities that aren't points.
|
||||||
if(e->IsPoint()) {
|
if(e->IsPoint()) {
|
||||||
gs.point[(gs.points)++] = s->entity;
|
gs.point[(gs.points)++] = s->entity;
|
||||||
} else {
|
} else {
|
||||||
gs.entity[(gs.entities)++] = s->entity;
|
gs.entity[(gs.entities)++] = s->entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// And an auxiliary list of normals, including normals from
|
||||||
|
// workplanes.
|
||||||
|
if(e->IsNormal()) {
|
||||||
|
gs.anyNormal[(gs.anyNormals)++] = s->entity;
|
||||||
|
} else if(e->IsWorkplane()) {
|
||||||
|
gs.anyNormal[(gs.anyNormals)++] = e->Normal()->h;
|
||||||
|
}
|
||||||
|
|
||||||
|
// And of vectors (i.e., stuff with a direction to constrain)
|
||||||
|
if(e->HasVector()) {
|
||||||
|
gs.vector[(gs.vectors)++] = s->entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
// And some aux counts too
|
||||||
switch(e->type) {
|
switch(e->type) {
|
||||||
case Entity::WORKPLANE: (gs.workplanes)++; break;
|
case Entity::WORKPLANE: (gs.workplanes)++; break;
|
||||||
case Entity::LINE_SEGMENT: (gs.lineSegments)++; break;
|
case Entity::LINE_SEGMENT: (gs.lineSegments)++; break;
|
||||||
|
|
7
sketch.h
7
sketch.h
|
@ -205,8 +205,9 @@ public:
|
||||||
|
|
||||||
bool IsCircle(void);
|
bool IsCircle(void);
|
||||||
|
|
||||||
bool HasDirection(void);
|
bool HasVector(void);
|
||||||
ExprVector GetDirection(void);
|
ExprVector VectorGetExprs(void);
|
||||||
|
Vector VectorGetRefPoint(void);
|
||||||
|
|
||||||
// For distances
|
// For distances
|
||||||
double DistanceGetNum(void);
|
double DistanceGetNum(void);
|
||||||
|
@ -300,6 +301,8 @@ public:
|
||||||
static const int VERTICAL = 81;
|
static const int VERTICAL = 81;
|
||||||
static const int DIAMETER = 90;
|
static const int DIAMETER = 90;
|
||||||
static const int PT_ON_CIRCLE = 100;
|
static const int PT_ON_CIRCLE = 100;
|
||||||
|
static const int SAME_ORIENTATION = 110;
|
||||||
|
static const int PARALLEL = 120;
|
||||||
|
|
||||||
int tag;
|
int tag;
|
||||||
hConstraint h;
|
hConstraint h;
|
||||||
|
|
14
system.cpp
14
system.cpp
|
@ -81,6 +81,20 @@ bool System::IsDragged(hParam p) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(SS.GW.pending.normal.v) {
|
||||||
|
Entity *norm = SS.entity.FindByIdNoOops(SS.GW.pending.normal);
|
||||||
|
if(norm) {
|
||||||
|
switch(norm->type) {
|
||||||
|
case Entity::NORMAL_IN_3D:
|
||||||
|
if(p.v == (norm->param[0].v)) return true;
|
||||||
|
if(p.v == (norm->param[1].v)) return true;
|
||||||
|
if(p.v == (norm->param[2].v)) return true;
|
||||||
|
if(p.v == (norm->param[3].v)) return true;
|
||||||
|
break;
|
||||||
|
// other types are locked, so not draggable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
6
ui.h
6
ui.h
|
@ -119,6 +119,8 @@ public:
|
||||||
MNU_AT_MIDPOINT,
|
MNU_AT_MIDPOINT,
|
||||||
MNU_HORIZONTAL,
|
MNU_HORIZONTAL,
|
||||||
MNU_VERTICAL,
|
MNU_VERTICAL,
|
||||||
|
MNU_PARALLEL,
|
||||||
|
MNU_ORIENTED_SAME,
|
||||||
MNU_SOLVE_AUTO,
|
MNU_SOLVE_AUTO,
|
||||||
MNU_SOLVE_NOW,
|
MNU_SOLVE_NOW,
|
||||||
} MenuId;
|
} MenuId;
|
||||||
|
@ -219,11 +221,15 @@ public:
|
||||||
struct {
|
struct {
|
||||||
hEntity point[MAX_SELECTED];
|
hEntity point[MAX_SELECTED];
|
||||||
hEntity entity[MAX_SELECTED];
|
hEntity entity[MAX_SELECTED];
|
||||||
|
hEntity anyNormal[MAX_SELECTED];
|
||||||
|
hEntity vector[MAX_SELECTED];
|
||||||
int points;
|
int points;
|
||||||
int entities;
|
int entities;
|
||||||
int workplanes;
|
int workplanes;
|
||||||
int lineSegments;
|
int lineSegments;
|
||||||
int circlesOrArcs;
|
int circlesOrArcs;
|
||||||
|
int anyNormals;
|
||||||
|
int vectors;
|
||||||
int n;
|
int n;
|
||||||
} gs;
|
} gs;
|
||||||
void GroupSelection(void);
|
void GroupSelection(void);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user