From 99f6ea34f1bbd239cbb2e9cc6d129b6acc3782ed Mon Sep 17 00:00:00 2001 From: EvilSpirit Date: Thu, 30 Mar 2017 21:39:42 +0700 Subject: [PATCH] Add an option to display areas of closed contours. This is useful e.g. for architectural work. --- CHANGELOG.md | 1 + src/confscreen.cpp | 8 + src/draw.cpp | 10 + src/groupmesh.cpp | 35 ++ src/sketch.h | 1 + src/solvespace.cpp | 4 + src/solvespace.h | 1 + src/srf/curve.cpp | 11 + src/srf/surface.h | 2 + src/ui.h | 1 + test/CMakeLists.txt | 1 + test/analysis/contour_area/normal.png | Bin 0 -> 4872 bytes test/analysis/contour_area/normal.slvs | 512 +++++++++++++++++++++++++ test/analysis/contour_area/test.cpp | 7 + 14 files changed, 594 insertions(+) create mode 100644 test/analysis/contour_area/normal.png create mode 100644 test/analysis/contour_area/normal.slvs create mode 100644 test/analysis/contour_area/test.cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index adab5ef1..a44126bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,7 @@ New measurement/analysis features: "Analyze → Measure Perimeter". * New command for measuring center of mass, with live updates as the sketch changes, "Analyze → Center of Mass". + * New option for displaying areas of closed contours. * When selecting a point and a line, projected distance to to current workplane is displayed. diff --git a/src/confscreen.cpp b/src/confscreen.cpp index 60f53578..698aa857 100644 --- a/src/confscreen.cpp +++ b/src/confscreen.cpp @@ -84,6 +84,11 @@ void TextWindow::ScreenChangeBackFaces(int link, uint32_t v) { InvalidateGraphics(); } +void TextWindow::ScreenChangeShowContourAreas(int link, uint32_t v) { + SS.showContourAreas = !SS.showContourAreas; + InvalidateGraphics(); +} + void TextWindow::ScreenChangeCheckClosedContour(int link, uint32_t v) { SS.checkClosedContour = !SS.checkClosedContour; InvalidateGraphics(); @@ -297,6 +302,9 @@ void TextWindow::ShowConfiguration() { Printf(false, " %Fd%f%Ll%s check sketch for closed contour%E", &ScreenChangeCheckClosedContour, SS.checkClosedContour ? CHECK_TRUE : CHECK_FALSE); + Printf(false, " %Fd%f%Ll%s show areas of closed contours%E", + &ScreenChangeShowContourAreas, + SS.showContourAreas ? CHECK_TRUE : CHECK_FALSE); Printf(false, ""); Printf(false, "%Ft autosave interval (in minutes)%E"); diff --git a/src/draw.cpp b/src/draw.cpp index bbe0b2c9..d79c9bfd 100644 --- a/src/draw.cpp +++ b/src/draw.cpp @@ -693,6 +693,16 @@ void GraphicsWindow::Draw(Canvas *canvas) { c.Draw(Constraint::DrawAs::DEFAULT, canvas); } + // Draw areas + if(SS.showContourAreas) { + for(hGroup hg : SK.groupOrder) { + Group *g = SK.GetGroup(hg); + if(g->h.v != activeGroup.v) continue; + if(!(g->IsVisible())) continue; + g->DrawContourAreaLabels(canvas); + } + } + // Draw the "pending" constraint, i.e. a constraint that would be // placed on a line that is almost horizontal or vertical. if(SS.GW.pending.operation == Pending::DRAGGING_NEW_LINE_POINT && diff --git a/src/groupmesh.cpp b/src/groupmesh.cpp index f33dd0be..0f4bf31d 100644 --- a/src/groupmesh.cpp +++ b/src/groupmesh.cpp @@ -677,3 +677,38 @@ void Group::DrawFilledPaths(Canvas *canvas) { } } +void Group::DrawContourAreaLabels(Canvas *canvas) { + const Camera &camera = canvas->GetCamera(); + Vector gr = camera.projRight.ScaledBy(1 / camera.scale); + Vector gu = camera.projUp.ScaledBy(1 / camera.scale); + + for(SBezierLoopSet &sbls : bezierLoops.l) { + if(sbls.l.n == 0 || sbls.l.elem[0].l.n == 0) continue; + + Vector min = sbls.l.elem[0].l.elem[0].ctrl[0]; + Vector max = min; + Vector zero = Vector::From(0.0, 0.0, 0.0); + sbls.GetBoundingProjd(Vector::From(1.0, 0.0, 0.0), zero, &min.x, &max.x); + sbls.GetBoundingProjd(Vector::From(0.0, 1.0, 0.0), zero, &min.y, &max.y); + sbls.GetBoundingProjd(Vector::From(0.0, 0.0, 1.0), zero, &min.z, &max.z); + + Vector mid = min.Plus(max).ScaledBy(0.5); + + hStyle hs = { Style::CONSTRAINT }; + Canvas::Stroke stroke = Style::Stroke(hs); + stroke.layer = Canvas::Layer::FRONT; + + double scale = SS.MmPerUnit(); + std::string label = ssprintf("%.3f %s²", + fabs(sbls.SignedArea() / (scale * scale)), + SS.UnitName()); + + double fontHeight = Style::TextHeight(hs); + double textWidth = VectorFont::Builtin()->GetWidth(fontHeight, label), + textHeight = VectorFont::Builtin()->GetCapHeight(fontHeight); + Vector pos = mid.Minus(gr.ScaledBy(textWidth / 2.0)) + .Minus(gu.ScaledBy(textHeight / 2.0)); + canvas->DrawVectorText(label, fontHeight, pos, gr, gu, canvas->GetStroke(stroke)); + } +} + diff --git a/src/sketch.h b/src/sketch.h index c677dfe7..694af658 100644 --- a/src/sketch.h +++ b/src/sketch.h @@ -287,6 +287,7 @@ public: void Draw(Canvas *canvas); void DrawPolyError(Canvas *canvas); void DrawFilledPaths(Canvas *canvas); + void DrawContourAreaLabels(Canvas *canvas); SPolygon GetPolygon(); diff --git a/src/solvespace.cpp b/src/solvespace.cpp index 9021a1e5..6b1b38fc 100644 --- a/src/solvespace.cpp +++ b/src/solvespace.cpp @@ -70,6 +70,8 @@ void SolveSpaceUI::Init() { drawBackFaces = CnfThawBool(true, "DrawBackFaces"); // Check that contours are closed and not self-intersecting checkClosedContour = CnfThawBool(true, "CheckClosedContour"); + // Draw closed polygons areas + showContourAreas = CnfThawBool(false, "ShowContourAreas"); // Export shaded triangles in a 2d view exportShadedTriangles = CnfThawBool(true, "ExportShadedTriangles"); // Export pwl curves (instead of exact) always @@ -191,6 +193,8 @@ void SolveSpaceUI::Exit() { CnfFreezeBool(fixExportColors, "FixExportColors"); // Draw back faces of triangles (when mesh is leaky/self-intersecting) CnfFreezeBool(drawBackFaces, "DrawBackFaces"); + // Draw closed polygons areas + CnfFreezeBool(showContourAreas, "ShowContourAreas"); // Check that contours are closed and not self-intersecting CnfFreezeBool(checkClosedContour, "CheckClosedContour"); // Export shaded triangles in a 2d view diff --git a/src/solvespace.h b/src/solvespace.h index 3330095b..7e0c68f4 100644 --- a/src/solvespace.h +++ b/src/solvespace.h @@ -651,6 +651,7 @@ public: float exportOffset; bool fixExportColors; bool drawBackFaces; + bool showContourAreas; bool checkClosedContour; bool showToolbar; Platform::Path screenshotFile; diff --git a/src/srf/curve.cpp b/src/srf/curve.cpp index 5a8f1a26..b2186da2 100644 --- a/src/srf/curve.cpp +++ b/src/srf/curve.cpp @@ -536,6 +536,17 @@ void SBezierLoopSet::GetBoundingProjd(Vector u, Vector orig, } } +double SBezierLoopSet::SignedArea() { + if(EXACT(area == 0.0)) { + SPolygon sp = {}; + MakePwlInto(&sp); + sp.normal = sp.ComputeNormal(); + area = sp.SignedArea(); + sp.Clear(); + } + return area; +} + //----------------------------------------------------------------------------- // Convert all the Beziers into piecewise linear form, and assemble that into // a polygon, one contour per loop. diff --git a/src/srf/surface.h b/src/srf/surface.h index 2eae2a3c..98ad8208 100644 --- a/src/srf/surface.h +++ b/src/srf/surface.h @@ -151,6 +151,7 @@ public: List l; Vector normal; Vector point; + double area; static SBezierLoopSet From(SBezierList *spcl, SPolygon *poly, double chordTol, @@ -158,6 +159,7 @@ public: SBezierList *openContours); void GetBoundingProjd(Vector u, Vector orig, double *umin, double *umax) const; + double SignedArea(); void MakePwlInto(SPolygon *sp) const; void Clear(); }; diff --git a/src/ui.h b/src/ui.h index b9e47e62..38e85390 100644 --- a/src/ui.h +++ b/src/ui.h @@ -517,6 +517,7 @@ public: static void ScreenChangeFixExportColors(int link, uint32_t v); static void ScreenChangeBackFaces(int link, uint32_t v); + static void ScreenChangeShowContourAreas(int link, uint32_t v); static void ScreenChangeCheckClosedContour(int link, uint32_t v); static void ScreenChangePwlCurves(int link, uint32_t v); static void ScreenChangeCanvasSizeAuto(int link, uint32_t v); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index bb70d978..ba348a24 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -11,6 +11,7 @@ endforeach() set(testsuite_SOURCES harness.cpp + analysis/contour_area/test.cpp core/expr/test.cpp core/locale/test.cpp core/path/test.cpp diff --git a/test/analysis/contour_area/normal.png b/test/analysis/contour_area/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..9daf8eebb6a11cd10651ddfb29e9bfb8865aa9a3 GIT binary patch literal 4872 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 U3Gz+w2^U!J;=cCw8tB;n0Wh5!f&c&j literal 0 HcmV?d00001 diff --git a/test/analysis/contour_area/normal.slvs b/test/analysis/contour_area/normal.slvs new file mode 100644 index 00000000..15dc34af --- /dev/null +++ b/test/analysis/contour_area/normal.slvs @@ -0,0 +1,512 @@ +±²³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.scale=1.00000000000000000000 +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.scale=1.00000000000000000000 +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=10.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050013 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00060010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00060011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00060013 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00060014 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00070010 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00070011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00070013 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00070014 +Param.val=10.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=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000006 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000007 +Request.type=200 +Request.workplane.v=80020000 +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=1 +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=1 +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=1 +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=10.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=10.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=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=-10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=-10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00060001 +Entity.point[1].v=00060002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=-10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00070000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00070001 +Entity.point[1].v=00070002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00070001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00070002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=10.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=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00040001 +Constraint.ptB.v=00050002 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00050001 +Constraint.ptB.v=00060002 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000003 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00060001 +Constraint.ptB.v=00070002 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000004 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00070001 +Constraint.ptB.v=00040002 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000005 +Constraint.type=81 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000006 +Constraint.type=80 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00050000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000007 +Constraint.type=81 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00060000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000008 +Constraint.type=80 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00070000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/analysis/contour_area/test.cpp b/test/analysis/contour_area/test.cpp new file mode 100644 index 00000000..748f0eb0 --- /dev/null +++ b/test/analysis/contour_area/test.cpp @@ -0,0 +1,7 @@ +#include "harness.h" + +TEST_CASE(normal_roundtrip) { + SS.showContourAreas = true; + CHECK_LOAD("normal.slvs"); + CHECK_RENDER("normal.png"); +}