From 4c30c097925949dccbf8db11159480e6b42123a9 Mon Sep 17 00:00:00 2001 From: whitequark <whitequark@whitequark.org> Date: Sat, 13 Aug 2016 10:48:48 +0000 Subject: [PATCH] Correctly draw vector text for constraints free in 3d. --- src/drawconstraint.cpp | 8 +- test/constraint/angle/skew.png | Bin 0 -> 4851 bytes test/constraint/angle/skew.slvs | 340 ++++++++++++++++++ test/constraint/angle/test.cpp | 5 + .../at_midpoint/line_plane_free_in_3d.png | Bin 4350 -> 4395 bytes .../at_midpoint/line_pt_free_in_3d.png | Bin 4338 -> 4372 bytes .../cubic_line_tangent/free_in_3d.png | Bin 5145 -> 5142 bytes 7 files changed, 350 insertions(+), 3 deletions(-) create mode 100644 test/constraint/angle/skew.png create mode 100644 test/constraint/angle/skew.slvs diff --git a/src/drawconstraint.cpp b/src/drawconstraint.cpp index 6442989..b744805 100644 --- a/src/drawconstraint.cpp +++ b/src/drawconstraint.cpp @@ -437,7 +437,7 @@ void Constraint::DoArcForAngle(Canvas *canvas, Canvas::hStroke hcs, Vector trans = (*ref).Plus(gu.ScaledBy(-1.5*VectorFont::Builtin()->GetCapHeight(textHeight))); canvas->DrawVectorText("angle between skew lines", textHeight, - trans, gr.WithMagnitude(pixels), gu.WithMagnitude(pixels), + trans, gr.WithMagnitude(1), gu.WithMagnitude(1), hcs); } } @@ -925,7 +925,8 @@ void Constraint::DoLayout(DrawAs how, Canvas *canvas, } Vector ex = VectorFont::Builtin()->GetExtents(textHeight, "T"); - canvas->DrawVectorText("T", textHeight, textAt.Minus(ex.ScaledBy(0.5)), u, v, hcs); + canvas->DrawVectorText("T", textHeight, textAt.Minus(ex.ScaledBy(0.5)), + u.WithMagnitude(1), v.WithMagnitude(1), hcs); if(refs) refs->push_back(textAt); return; } @@ -1122,7 +1123,8 @@ s: } Vector o = m.Plus(offset).Plus(u.WithMagnitude(textHeight/5)), ex = VectorFont::Builtin()->GetExtents(textHeight, s); - canvas->DrawVectorText(s, textHeight, o.Minus(ex.ScaledBy(0.5)), r, u, hcs); + canvas->DrawVectorText(s, textHeight, o.Minus(ex.ScaledBy(0.5)), + r.WithMagnitude(1), u.WithMagnitude(1), hcs); if(refs) refs->push_back(o); } else { Vector a = SK.GetEntity(ptA)->PointGetNum(); diff --git a/test/constraint/angle/skew.png b/test/constraint/angle/skew.png new file mode 100644 index 0000000000000000000000000000000000000000..76191f56d4e65e419526099e3defe3238f4d5cc0 GIT binary patch literal 4851 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 literal 0 HcmV?d00001 diff --git a/test/constraint/angle/skew.slvs b/test/constraint/angle/skew.slvs new file mode 100644 index 0000000..e793f93 --- /dev/null +++ b/test/constraint/angle/skew.slvs @@ -0,0 +1,340 @@ +���SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050013 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.workplane.v=00020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.workplane.v=00020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=00020000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actPoint.z=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=00020000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actPoint.z=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=120 +Constraint.group.v=00000002 +Constraint.valA=90.00000000000000000000 +Constraint.entityA.v=00050000 +Constraint.entityB.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +Constraint.disp.offset.x=2.50000000000000044409 +Constraint.disp.offset.y=-2.50000000000000000000 +Constraint.disp.offset.z=-2.50000000000000000000 +AddConstraint + diff --git a/test/constraint/angle/test.cpp b/test/constraint/angle/test.cpp index 57d7820..a117b23 100644 --- a/test/constraint/angle/test.cpp +++ b/test/constraint/angle/test.cpp @@ -47,3 +47,8 @@ TEST_CASE(reference_free_in_3d_migrate_from_v20) { CHECK_RENDER("reference_free_in_3d.png"); CHECK_SAVE("reference_free_in_3d.slvs"); } + +TEST_CASE(skew_render) { + CHECK_LOAD("skew.slvs"); + CHECK_RENDER("skew.png"); +} diff --git a/test/constraint/at_midpoint/line_plane_free_in_3d.png b/test/constraint/at_midpoint/line_plane_free_in_3d.png index 81d1acbbf9bca6ef6ead0dc0871b14b079663516..510aa890e9ec35c5d975bff4608d853e2a0645b6 100644 GIT binary patch literal 4395 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 M?Dp7}Y{w-02fC-|Bme*a literal 4350 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 diff --git a/test/constraint/at_midpoint/line_pt_free_in_3d.png b/test/constraint/at_midpoint/line_pt_free_in_3d.png index 314734ea249391454937c1e95d08291c3814364d..fe283089e4a2e716c8d6cb2cf55a2f91d2bd300b 100644 GIT binary patch literal 4372 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 literal 4338 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 diff --git a/test/constraint/cubic_line_tangent/free_in_3d.png b/test/constraint/cubic_line_tangent/free_in_3d.png index 1583d9351f38be916b0e3172d660bb6f014eb8b3..5784a678f75016af3b50405c0b77478924b564b4 100644 GIT binary patch literal 5142 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 literal 5145 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 Q@Fzd8L*H~;@)n%?U(_4NR{#J2