diff --git a/constraint.cpp b/constraint.cpp index ef55576..1ed47d7 100644 --- a/constraint.cpp +++ b/constraint.cpp @@ -19,7 +19,7 @@ void Constraint::Constrain(int type, hEntity ptA, hEntity ptB, hEntity entityA) Constraint c; memset(&c, 0, sizeof(c)); c.group = SS.GW.activeGroup; - c.workplane = SS.GW.activeWorkplane; + c.workplane = SS.GW.ActiveWorkplane(); c.type = type; c.ptA = ptA; c.ptB = ptB; @@ -35,7 +35,7 @@ void Constraint::MenuConstrain(int id) { Constraint c; memset(&c, 0, sizeof(c)); c.group = SS.GW.activeGroup; - c.workplane = SS.GW.activeWorkplane; + c.workplane = SS.GW.ActiveWorkplane(); SS.GW.GroupSelection(); #define gs (SS.GW.gs) diff --git a/entity.cpp b/entity.cpp index 6547d6a..449aeec 100644 --- a/entity.cpp +++ b/entity.cpp @@ -695,32 +695,42 @@ void Entity::DrawOrGetDistance(int order) { Vector u = Normal()->NormalU(); Vector v = Normal()->NormalV(); - double s = (min(SS.GW.width, SS.GW.height))*0.4/SS.GW.scale; + double s = (min(SS.GW.width, SS.GW.height))*0.45/SS.GW.scale; Vector us = u.ScaledBy(s); Vector vs = v.ScaledBy(s); Vector pp = p.Plus (us).Plus (vs); Vector pm = p.Plus (us).Minus(vs); - Vector mm = p.Minus(us).Minus(vs); + Vector mm = p.Minus(us).Minus(vs), mm2 = mm; Vector mp = p.Minus(us).Plus (vs); glxColor3d(0, 0.3, 0.3); glEnable(GL_LINE_STIPPLE); glLineStipple(3, 0x1111); + if(!h.isFromRequest()) { + mm = mm.Plus(v.ScaledBy(60/SS.GW.scale)); + mm2 = mm2.Plus(u.ScaledBy(60/SS.GW.scale)); + LineDrawOrGetDistance(mm2, mm); + } LineDrawOrGetDistance(pp, pm); - LineDrawOrGetDistance(pm, mm); + LineDrawOrGetDistance(pm, mm2); LineDrawOrGetDistance(mm, mp); LineDrawOrGetDistance(mp, pp); glDisable(GL_LINE_STIPPLE); + char *str = DescriptionString()+5; if(dogd.drawing) { glPushMatrix(); - glxTranslatev(mm); + glxTranslatev(mm2); glxOntoWorkplane(u, v); - glxWriteText(DescriptionString()); + glxWriteText(str); glPopMatrix(); } else { + Vector pos = mm2.Plus(u.ScaledBy(glxStrWidth(str)/2)).Plus( + v.ScaledBy(glxStrHeight()/2)); + Point2d pp = SS.GW.ProjectPoint(pos); + dogd.dmin = min(dogd.dmin, pp.DistanceTo(dogd.mp) - 10); // If a line lies in a plane, then select the line, not // the plane. dogd.dmin += 3; diff --git a/file.cpp b/file.cpp index 866ae7f..1828a1a 100644 --- a/file.cpp +++ b/file.cpp @@ -17,11 +17,6 @@ void SolveSpace::NewFile(void) { g.h = Group::HGROUP_REFERENCES; group.Add(&g); - // And an empty group, for the first stuff the user draws. - g.name.strcpy("drawing"); - 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; @@ -41,84 +36,94 @@ void SolveSpace::NewFile(void) { r.name.strcpy("#ZX"); r.h = Request::HREQUEST_REFERENCE_ZX; request.Add(&r); + + // And an empty group, for the first stuff the user draws. + g.type = Group::DRAWING_WORKPLANE; + g.subtype = Group::WORKPLANE_BY_POINT_ORTHO; + g.wrkpl.q = Quaternion::MakeFrom(1, 0, 0, 0); + hRequest hr = Request::HREQUEST_REFERENCE_XY; + g.wrkpl.origin = hr.entity(1); + g.name.strcpy("draw-in-plane"); + group.AddAndAssignId(&g); + SS.GetGroup(g.h)->activeWorkplane = g.h.entity(0); } - const SolveSpace::SaveTable SolveSpace::SAVED[] = { - { 'g', "Group.h.v", 'x', &(SS.sv.g.h.v) }, - { 'g', "Group.type", 'd', &(SS.sv.g.type) }, - { 'g', "Group.name", 'N', &(SS.sv.g.name) }, - { 'g', "Group.opA.v", 'x', &(SS.sv.g.opA.v) }, - { 'g', "Group.opB.v", 'x', &(SS.sv.g.opB.v) }, - { 'g', "Group.subtype", 'd', &(SS.sv.g.subtype) }, - { 'g', "Group.meshCombine", 'd', &(SS.sv.g.meshCombine) }, - { 'g', "Group.wrkpl.q.w", 'f', &(SS.sv.g.wrkpl.q.w) }, - { 'g', "Group.wrkpl.q.vx", 'f', &(SS.sv.g.wrkpl.q.vx) }, - { 'g', "Group.wrkpl.q.vy", 'f', &(SS.sv.g.wrkpl.q.vy) }, - { 'g', "Group.wrkpl.q.vz", 'f', &(SS.sv.g.wrkpl.q.vz) }, - { 'g', "Group.wrkpl.origin.v", 'x', &(SS.sv.g.wrkpl.origin.v) }, - { 'g', "Group.wrkpl.entityB.v", 'x', &(SS.sv.g.wrkpl.entityB.v)}, - { 'g', "Group.wrkpl.entityC.v", 'x', &(SS.sv.g.wrkpl.entityC.v)}, - { 'g', "Group.wrkpl.swapUV", 'b', &(SS.sv.g.wrkpl.swapUV) }, - { 'g', "Group.wrkpl.negateU", 'b', &(SS.sv.g.wrkpl.negateU) }, - { 'g', "Group.wrkpl.negateV", 'b', &(SS.sv.g.wrkpl.negateV) }, - { 'g', "Group.visible", 'b', &(SS.sv.g.visible) }, - { 'g', "Group.remap", 'M', &(SS.sv.g.remap) }, + { 'g', "Group.h.v", 'x', &(SS.sv.g.h.v) }, + { 'g', "Group.type", 'd', &(SS.sv.g.type) }, + { 'g', "Group.name", 'N', &(SS.sv.g.name) }, + { 'g', "Group.activeWorkplane.v", 'x', &(SS.sv.g.activeWorkplane.v) }, + { 'g', "Group.opA.v", 'x', &(SS.sv.g.opA.v) }, + { 'g', "Group.opB.v", 'x', &(SS.sv.g.opB.v) }, + { 'g', "Group.subtype", 'd', &(SS.sv.g.subtype) }, + { 'g', "Group.meshCombine", 'd', &(SS.sv.g.meshCombine) }, + { 'g', "Group.wrkpl.q.w", 'f', &(SS.sv.g.wrkpl.q.w) }, + { 'g', "Group.wrkpl.q.vx", 'f', &(SS.sv.g.wrkpl.q.vx) }, + { 'g', "Group.wrkpl.q.vy", 'f', &(SS.sv.g.wrkpl.q.vy) }, + { 'g', "Group.wrkpl.q.vz", 'f', &(SS.sv.g.wrkpl.q.vz) }, + { 'g', "Group.wrkpl.origin.v", 'x', &(SS.sv.g.wrkpl.origin.v) }, + { 'g', "Group.wrkpl.entityB.v", 'x', &(SS.sv.g.wrkpl.entityB.v) }, + { 'g', "Group.wrkpl.entityC.v", 'x', &(SS.sv.g.wrkpl.entityC.v) }, + { 'g', "Group.wrkpl.swapUV", 'b', &(SS.sv.g.wrkpl.swapUV) }, + { 'g', "Group.wrkpl.negateU", 'b', &(SS.sv.g.wrkpl.negateU) }, + { 'g', "Group.wrkpl.negateV", 'b', &(SS.sv.g.wrkpl.negateV) }, + { 'g', "Group.visible", 'b', &(SS.sv.g.visible) }, + { 'g', "Group.remap", 'M', &(SS.sv.g.remap) }, - { 'p', "Param.h.v.", 'x', &(SS.sv.p.h.v) }, - { 'p', "Param.val", 'f', &(SS.sv.p.val) }, + { 'p', "Param.h.v.", 'x', &(SS.sv.p.h.v) }, + { 'p', "Param.val", 'f', &(SS.sv.p.val) }, - { 'r', "Request.h.v", 'x', &(SS.sv.r.h.v) }, - { 'r', "Request.type", 'd', &(SS.sv.r.type) }, - { 'r', "Request.workplane.v", 'x', &(SS.sv.r.workplane.v) }, - { 'r', "Request.group.v", 'x', &(SS.sv.r.group.v) }, - { 'r', "Request.name", 'N', &(SS.sv.r.name) }, - { 'r', "Request.construction", 'b', &(SS.sv.r.construction) }, + { 'r', "Request.h.v", 'x', &(SS.sv.r.h.v) }, + { 'r', "Request.type", 'd', &(SS.sv.r.type) }, + { 'r', "Request.workplane.v", 'x', &(SS.sv.r.workplane.v) }, + { 'r', "Request.group.v", 'x', &(SS.sv.r.group.v) }, + { 'r', "Request.name", 'N', &(SS.sv.r.name) }, + { 'r', "Request.construction", 'b', &(SS.sv.r.construction) }, - { 'e', "Entity.h.v", 'x', &(SS.sv.e.h.v) }, - { 'e', "Entity.type", 'd', &(SS.sv.e.type) }, - { 'e', "Entity.group.v", 'x', &(SS.sv.e.group.v) }, - { 'e', "Entity.construction", 'b', &(SS.sv.e.construction) }, - { 'e', "Entity.param[0].v", 'x', &(SS.sv.e.param[0].v) }, - { 'e', "Entity.param[1].v", 'x', &(SS.sv.e.param[1].v) }, - { 'e', "Entity.param[2].v", 'x', &(SS.sv.e.param[2].v) }, - { 'e', "Entity.param[3].v", 'x', &(SS.sv.e.param[3].v) }, - { 'e', "Entity.param[4].v", 'x', &(SS.sv.e.param[4].v) }, - { 'e', "Entity.param[5].v", 'x', &(SS.sv.e.param[5].v) }, - { 'e', "Entity.param[6].v", 'x', &(SS.sv.e.param[6].v) }, - { 'e', "Entity.point[0].v", 'x', &(SS.sv.e.point[0].v) }, - { 'e', "Entity.point[1].v", 'x', &(SS.sv.e.point[1].v) }, - { 'e', "Entity.point[2].v", 'x', &(SS.sv.e.point[2].v) }, - { 'e', "Entity.point[3].v", 'x', &(SS.sv.e.point[3].v) }, - { 'e', "Entity.normal.v", 'x', &(SS.sv.e.normal.v) }, - { 'e', "Entity.distance.v", 'x', &(SS.sv.e.distance.v) }, - { 'e', "Entity.workplane.v", 'x', &(SS.sv.e.workplane.v) }, - { 'e', "Entity.numPoint.x", 'f', &(SS.sv.e.numPoint.x) }, - { 'e', "Entity.numPoint.y", 'f', &(SS.sv.e.numPoint.y) }, - { 'e', "Entity.numPoint.z", 'f', &(SS.sv.e.numPoint.z) }, - { 'e', "Entity.numNormal.w", 'f', &(SS.sv.e.numNormal.w) }, - { 'e', "Entity.numNormal.vx", 'f', &(SS.sv.e.numNormal.vx) }, - { 'e', "Entity.numNormal.vy", 'f', &(SS.sv.e.numNormal.vy) }, - { 'e', "Entity.numNormal.vz", 'f', &(SS.sv.e.numNormal.vz) }, - { 'e', "Entity.numDistance", 'f', &(SS.sv.e.numDistance) }, + { 'e', "Entity.h.v", 'x', &(SS.sv.e.h.v) }, + { 'e', "Entity.type", 'd', &(SS.sv.e.type) }, + { 'e', "Entity.group.v", 'x', &(SS.sv.e.group.v) }, + { 'e', "Entity.construction", 'b', &(SS.sv.e.construction) }, + { 'e', "Entity.param[0].v", 'x', &(SS.sv.e.param[0].v) }, + { 'e', "Entity.param[1].v", 'x', &(SS.sv.e.param[1].v) }, + { 'e', "Entity.param[2].v", 'x', &(SS.sv.e.param[2].v) }, + { 'e', "Entity.param[3].v", 'x', &(SS.sv.e.param[3].v) }, + { 'e', "Entity.param[4].v", 'x', &(SS.sv.e.param[4].v) }, + { 'e', "Entity.param[5].v", 'x', &(SS.sv.e.param[5].v) }, + { 'e', "Entity.param[6].v", 'x', &(SS.sv.e.param[6].v) }, + { 'e', "Entity.point[0].v", 'x', &(SS.sv.e.point[0].v) }, + { 'e', "Entity.point[1].v", 'x', &(SS.sv.e.point[1].v) }, + { 'e', "Entity.point[2].v", 'x', &(SS.sv.e.point[2].v) }, + { 'e', "Entity.point[3].v", 'x', &(SS.sv.e.point[3].v) }, + { 'e', "Entity.normal.v", 'x', &(SS.sv.e.normal.v) }, + { 'e', "Entity.distance.v", 'x', &(SS.sv.e.distance.v) }, + { 'e', "Entity.workplane.v", 'x', &(SS.sv.e.workplane.v) }, + { 'e', "Entity.numPoint.x", 'f', &(SS.sv.e.numPoint.x) }, + { 'e', "Entity.numPoint.y", 'f', &(SS.sv.e.numPoint.y) }, + { 'e', "Entity.numPoint.z", 'f', &(SS.sv.e.numPoint.z) }, + { 'e', "Entity.numNormal.w", 'f', &(SS.sv.e.numNormal.w) }, + { 'e', "Entity.numNormal.vx", 'f', &(SS.sv.e.numNormal.vx) }, + { 'e', "Entity.numNormal.vy", 'f', &(SS.sv.e.numNormal.vy) }, + { 'e', "Entity.numNormal.vz", 'f', &(SS.sv.e.numNormal.vz) }, + { 'e', "Entity.numDistance", 'f', &(SS.sv.e.numDistance) }, - { 'c', "Constraint.h.v", 'x', &(SS.sv.c.h.v) }, - { 'c', "Constraint.type", 'd', &(SS.sv.c.type) }, - { 'c', "Constraint.group.v", 'x', &(SS.sv.c.group.v) }, - { 'c', "Constraint.workplane.v", 'x', &(SS.sv.c.workplane.v) }, - { 'c', "Constraint.exprA", 'E', &(SS.sv.c.exprA) }, - { 'c', "Constraint.exprB", 'E', &(SS.sv.c.exprB) }, - { 'c', "Constraint.ptA.v", 'x', &(SS.sv.c.ptA.v) }, - { 'c', "Constraint.ptB.v", 'x', &(SS.sv.c.ptB.v) }, - { 'c', "Constraint.ptC.v", 'x', &(SS.sv.c.ptC.v) }, - { 'c', "Constraint.entityA.v", 'x', &(SS.sv.c.entityA.v) }, - { 'c', "Constraint.entityB.v", 'x', &(SS.sv.c.entityB.v) }, - { 'c', "Constraint.otherAngle", 'b', &(SS.sv.c.otherAngle) }, - { 'c', "Constraint.disp.offset.x", 'f', &(SS.sv.c.disp.offset.x) }, - { 'c', "Constraint.disp.offset.y", 'f', &(SS.sv.c.disp.offset.y) }, - { 'c', "Constraint.disp.offset.z", 'f', &(SS.sv.c.disp.offset.z) }, + { 'c', "Constraint.h.v", 'x', &(SS.sv.c.h.v) }, + { 'c', "Constraint.type", 'd', &(SS.sv.c.type) }, + { 'c', "Constraint.group.v", 'x', &(SS.sv.c.group.v) }, + { 'c', "Constraint.workplane.v", 'x', &(SS.sv.c.workplane.v) }, + { 'c', "Constraint.exprA", 'E', &(SS.sv.c.exprA) }, + { 'c', "Constraint.exprB", 'E', &(SS.sv.c.exprB) }, + { 'c', "Constraint.ptA.v", 'x', &(SS.sv.c.ptA.v) }, + { 'c', "Constraint.ptB.v", 'x', &(SS.sv.c.ptB.v) }, + { 'c', "Constraint.ptC.v", 'x', &(SS.sv.c.ptC.v) }, + { 'c', "Constraint.entityA.v", 'x', &(SS.sv.c.entityA.v) }, + { 'c', "Constraint.entityB.v", 'x', &(SS.sv.c.entityB.v) }, + { 'c', "Constraint.otherAngle", 'b', &(SS.sv.c.otherAngle) }, + { 'c', "Constraint.disp.offset.x", 'f', &(SS.sv.c.disp.offset.x) }, + { 'c', "Constraint.disp.offset.y", 'f', &(SS.sv.c.disp.offset.y) }, + { 'c', "Constraint.disp.offset.z", 'f', &(SS.sv.c.disp.offset.z) }, - { 0, NULL, NULL, NULL }, + { 0, NULL, NULL, NULL }, }; void SolveSpace::SaveUsingTable(int type) { diff --git a/graphicswin.cpp b/graphicswin.cpp index 02de59c..8e803f8 100644 --- a/graphicswin.cpp +++ b/graphicswin.cpp @@ -31,7 +31,6 @@ const GraphicsWindow::MenuEntry GraphicsWindow::menu[] = { { 1, "Zoom &In\t+", MNU_ZOOM_IN, '+', mView }, { 1, "Zoom &Out\t-", MNU_ZOOM_OUT, '-', mView }, { 1, "Zoom To &Fit\tF", MNU_ZOOM_TO_FIT, 'F', mView }, -{ 1, "Onto Othe&r Side\tCtrl+O", MNU_OTHER_SIDE, 'R'|C, mView }, { 1, NULL, 0, NULL }, { 1, "Show Text &Window\tTab", MNU_SHOW_TEXT_WND, '\t', mView }, { 1, NULL, 0, NULL }, @@ -102,15 +101,11 @@ void GraphicsWindow::Init(void) { projRight.x = 1; projRight.y = projRight.z = 0; projUp.y = 1; projUp.z = projUp.x = 0; - // Start locked on to the XY plane. - hRequest r = Request::HREQUEST_REFERENCE_XY; - activeWorkplane = r.entity(0); - // And with the latest visible group active int i; for(i = 0; i < SS.group.n; i++) { Group *g = &(SS.group.elem[i]); - if(g->visible) activeGroup = g->h; + if(i == 0 || g->visible) activeGroup = g->h; } EnsureValidActives(); @@ -145,7 +140,13 @@ Point2d GraphicsWindow::ProjectPoint(Vector p) { return r; } -void GraphicsWindow::AnimateOnto(Quaternion quatf, Vector offsetf) { +void GraphicsWindow::AnimateOntoWorkplane(void) { + if(!LockedInWorkplane()) return; + + Entity *w = SS.GetEntity(ActiveWorkplane()); + Quaternion quatf = w->Normal()->NormalGetNum(); + Vector offsetf = (SS.GetEntity(w->point[0])->PointGetNum()).ScaledBy(-1); + // Get our initial orientation and translation. Quaternion quat0 = Quaternion::MakeFrom(projRight, projUp); Vector offset0 = offset; @@ -197,15 +198,6 @@ void GraphicsWindow::MenuView(int id) { case MNU_ZOOM_TO_FIT: break; - case MNU_OTHER_SIDE: { - Quaternion quatf = Quaternion::MakeFrom( - SS.GW.projRight.ScaledBy(-1), SS.GW.projUp.ScaledBy(1)); - Vector ru = quatf.RotationU(); - Vector rv = quatf.RotationV(); - SS.GW.AnimateOnto(quatf, SS.GW.offset); - break; - } - case MNU_SHOW_TEXT_WND: SS.GW.showTextWindow = !SS.GW.showTextWindow; SS.GW.EnsureValidActives(); @@ -243,25 +235,25 @@ void GraphicsWindow::EnsureValidActives(void) { } // The active coordinate system must also exist. - if(activeWorkplane.v != Entity::FREE_IN_3D.v) { - Entity *e = SS.entity.FindByIdNoOops(activeWorkplane); + if(LockedInWorkplane()) { + Entity *e = SS.entity.FindByIdNoOops(ActiveWorkplane()); if(e) { hGroup hgw = e->group; if(hgw.v != activeGroup.v && SS.GroupsInOrder(activeGroup, hgw)) { // The active workplane is in a group that comes after the // active group; so any request or constraint will fail. - activeWorkplane = Entity::FREE_IN_3D; + SetWorkplaneFreeIn3d(); change = true; } } else { - activeWorkplane = Entity::FREE_IN_3D; + SetWorkplaneFreeIn3d(); change = true; } } - bool in3d = (activeWorkplane.v == Entity::FREE_IN_3D.v); - CheckMenuById(MNU_FREE_IN_3D, in3d); - CheckMenuById(MNU_SEL_WORKPLANE, !in3d); + bool locked = LockedInWorkplane(); + CheckMenuById(MNU_FREE_IN_3D, !locked); + CheckMenuById(MNU_SEL_WORKPLANE, locked); // And update the checked state for various menus switch(viewUnits) { @@ -282,6 +274,16 @@ void GraphicsWindow::EnsureValidActives(void) { if(change) SS.TW.Show(); } +void GraphicsWindow::SetWorkplaneFreeIn3d(void) { + SS.GetGroup(activeGroup)->activeWorkplane = Entity::FREE_IN_3D; +} +hEntity GraphicsWindow::ActiveWorkplane(void) { + return SS.GetGroup(activeGroup)->activeWorkplane; +} +bool GraphicsWindow::LockedInWorkplane(void) { + return (SS.GW.ActiveWorkplane().v != Entity::FREE_IN_3D.v); +} + void GraphicsWindow::GeneratePerSolving(void) { SS.GenerateAll(solving == SOLVE_ALWAYS); } @@ -336,25 +338,23 @@ void GraphicsWindow::MenuRequest(int id) { case MNU_SEL_WORKPLANE: { SS.GW.GroupSelection(); if(SS.GW.gs.n == 1 && SS.GW.gs.workplanes == 1) { - SS.GW.activeWorkplane = SS.GW.gs.entity[0]; + SS.GetGroup(SS.GW.activeGroup)->activeWorkplane = + SS.GW.gs.entity[0]; } - if(SS.GW.activeWorkplane.v == Entity::FREE_IN_3D.v) { + if(!SS.GW.LockedInWorkplane()) { Error("Select workplane (e.g., the XY plane) " "before locking on."); break; } // Align the view with the selected workplane - Entity *e = SS.GetEntity(SS.GW.activeWorkplane); - Quaternion quatf = e->Normal()->NormalGetNum(); - Vector offsetf = (e->WorkplaneGetOffset()).ScaledBy(-1); - SS.GW.AnimateOnto(quatf, offsetf); + SS.GW.AnimateOntoWorkplane(); SS.GW.ClearSuper(); SS.TW.Show(); break; } case MNU_FREE_IN_3D: - SS.GW.activeWorkplane = Entity::FREE_IN_3D; + SS.GW.SetWorkplaneFreeIn3d(); SS.GW.EnsureValidActives(); SS.TW.Show(); break; @@ -800,7 +800,7 @@ hRequest GraphicsWindow::AddRequest(int type) { Request r; memset(&r, 0, sizeof(r)); r.group = activeGroup; - r.workplane = activeWorkplane; + r.workplane = ActiveWorkplane(); r.type = type; SS.request.AddAndAssignId(&r); @@ -878,7 +878,7 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) { break; case MNU_RECTANGLE: { - if(SS.GW.activeWorkplane.v == Entity::FREE_IN_3D.v) { + if(!SS.GW.LockedInWorkplane()) { Error("Can't draw rectangle in 3d; select a workplane first."); break; } @@ -922,7 +922,7 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) { break; case MNU_ARC: - if(SS.GW.activeWorkplane.v == Entity::FREE_IN_3D.v) { + if(!SS.GW.LockedInWorkplane()) { Error("Can't draw arc in 3d; select a workplane first."); ClearPending(); break; diff --git a/sketch.cpp b/sketch.cpp index f95598a..aee8e0c 100644 --- a/sketch.cpp +++ b/sketch.cpp @@ -74,7 +74,7 @@ void Group::MenuGroup(int id) { case GraphicsWindow::MNU_GROUP_EXTRUDE: g.type = EXTRUDE; g.opA = SS.GW.activeGroup; - g.wrkpl.entityB = SS.GW.activeWorkplane; + g.wrkpl.entityB = SS.GW.ActiveWorkplane(); g.subtype = EXTRUDE_ONE_SIDED; g.name.strcpy("extrude"); break; @@ -92,12 +92,9 @@ void Group::MenuGroup(int id) { SS.GenerateAll(SS.GW.solving == GraphicsWindow::SOLVE_ALWAYS); SS.GW.activeGroup = g.h; if(g.type == DRAWING_WORKPLANE) { - SS.GW.activeWorkplane = g.h.entity(0); - Entity *e = SS.GetEntity(SS.GW.activeWorkplane); - Quaternion quatf = e->Normal()->NormalGetNum(); - Vector offsetf = (e->WorkplaneGetOffset()).ScaledBy(-1); - SS.GW.AnimateOnto(quatf, offsetf); + SS.GetGroup(g.h)->activeWorkplane = g.h.entity(0); } + SS.GW.AnimateOntoWorkplane(); TextWindow::ScreenSelectGroup(0, g.h.v); SS.TW.Show(); } diff --git a/sketch.h b/sketch.h index 867f452..507fdd1 100644 --- a/sketch.h +++ b/sketch.h @@ -88,6 +88,7 @@ public: hGroup opA; hGroup opB; bool visible; + hEntity activeWorkplane; static const int SOLVED_OKAY = 0; static const int DIDNT_CONVERGE = 10; diff --git a/textwin.cpp b/textwin.cpp index f160f8c..0040991 100644 --- a/textwin.cpp +++ b/textwin.cpp @@ -223,15 +223,15 @@ void TextWindow::ScreenNavigation(int link, DWORD v) { void TextWindow::ShowHeader(void) { ClearScreen(); - char *cd = (SS.GW.activeWorkplane.v == Entity::FREE_IN_3D.v) ? - "free in 3d" : - SS.GetEntity(SS.GW.activeWorkplane)->DescriptionString(); + char *cd = SS.GW.LockedInWorkplane() ? + SS.GetEntity(SS.GW.ActiveWorkplane())->DescriptionString() : + "free in 3d"; // Navigation buttons if(SS.GW.pending.description) { - Printf(false, " %Bt%Ft workplane:%Fd %s", cd); + Printf(false, " %Bt%Ft wrkpl:%Fd %s", cd); } else { - Printf(false, " %Lb%f<<%E %Lh%fhome%E %Bt%Ft workplane:%Fd %s", + Printf(false, " %Lb%f<<%E %Lh%fhome%E %Bt%Ft wrkpl:%Fd %s", (&TextWindow::ScreenNavigation), (&TextWindow::ScreenNavigation), cd); @@ -299,11 +299,6 @@ void TextWindow::ScreenActivateGroup(int link, DWORD v) { Group *g = SS.GetGroup(hg); g->visible = true; SS.GW.activeGroup.v = v; - if(g->type == Group::DRAWING_WORKPLANE) { - // If we're activating an in-workplane drawing, then activate that - // workplane too. - SS.GW.activeWorkplane = g->h.entity(0); - } SS.GW.ClearSuper(); } void TextWindow::ReportHowGroupSolved(hGroup hg) { diff --git a/ui.h b/ui.h index b3da56e..1293c16 100644 --- a/ui.h +++ b/ui.h @@ -101,7 +101,6 @@ public: MNU_ZOOM_IN, MNU_ZOOM_OUT, MNU_ZOOM_TO_FIT, - MNU_OTHER_SIDE, MNU_SHOW_TEXT_WND, MNU_UNITS_INCHES, MNU_UNITS_MM, @@ -177,7 +176,7 @@ public: void NormalizeProjectionVectors(void); Point2d ProjectPoint(Vector p); - void AnimateOnto(Quaternion quatf, Vector offsetf); + void AnimateOntoWorkplane(void); Vector VectorFromProjs(double right, double up, double forward); typedef enum { @@ -187,8 +186,10 @@ public: Unit viewUnits; hGroup activeGroup; - hEntity activeWorkplane; - void EnsureValidActives(); + void EnsureValidActives(void); + bool LockedInWorkplane(void); + void SetWorkplaneFreeIn3d(void); + hEntity ActiveWorkplane(void); // Operations that must be completed by doing something with the mouse // are noted here. These occupy the same space as the menu ids.