diff --git a/CHANGELOG.md b/CHANGELOG.md index 5dbdf355..b7f6d7a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -72,6 +72,8 @@ New measurement/analysis features: * New option for displaying areas of closed contours. * When calculating volume of the mesh, volume of the solid from the current group is now shown alongside total volume of all solids. + * When calculating area, and faces are selected, calculate area of those faces + instead of the closed contour in the sketch. * When selecting a point and a line, projected distance to current workplane is displayed. diff --git a/src/mesh.cpp b/src/mesh.cpp index 28484204..57aa87b4 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -1181,3 +1181,14 @@ double SMesh::CalculateVolume() const { } return vol; } + +double SMesh::CalculateSurfaceArea(const std::vector &faces) const { + double area = 0.0; + for(uint32_t f : faces) { + for(const STriangle &t : l) { + if(f != t.meta.face) continue; + area += t.Area(); + } + } + return area; +} diff --git a/src/polygon.cpp b/src/polygon.cpp index e28bc424..736a1626 100644 --- a/src/polygon.cpp +++ b/src/polygon.cpp @@ -87,6 +87,12 @@ double STriangle::SignedVolume() const { return a.Dot(b.Cross(c)) / 6.0; } +double STriangle::Area() const { + Vector ab = a.Minus(b); + Vector cb = c.Minus(b); + return ab.Cross(cb).Magnitude() / 2.0; +} + bool STriangle::IsDegenerate() const { return a.OnLineSegment(b, c) || b.OnLineSegment(a, c) || diff --git a/src/polygon.h b/src/polygon.h index eed7b155..b7c5a71e 100644 --- a/src/polygon.h +++ b/src/polygon.h @@ -191,6 +191,7 @@ public: bool Raytrace(const Vector &rayPoint, const Vector &rayDir, double *t, Vector *inters) const; double SignedVolume() const; + double Area() const; bool IsDegenerate() const; }; @@ -281,6 +282,7 @@ public: void PrecomputeTransparency(); void RemoveDegenerateTriangles(); double CalculateVolume() const; + double CalculateSurfaceArea(const std::vector &faces) const; bool IsEmpty() const; void RemapFaces(Group *g, int remap); diff --git a/src/solvespace.cpp b/src/solvespace.cpp index 0407a941..2c0157d0 100644 --- a/src/solvespace.cpp +++ b/src/solvespace.cpp @@ -797,6 +797,23 @@ void SolveSpaceUI::MenuAnalyze(Command id) { case Command::AREA: { Group *g = SK.GetGroup(SS.GW.activeGroup); + SS.GW.GroupSelection(); + auto const &gs = SS.GW.gs; + double scale = SS.MmPerUnit(); + + if(gs.faces > 0) { + std::vector faces; + faces.push_back(gs.face[0].v); + if(gs.faces > 1) faces.push_back(gs.face[1].v); + double area = g->displayMesh.CalculateSurfaceArea(faces); + Message(_("The surface area of the selected faces is:\n\n" + " %s\n\n" + "Curves have been approximated as piecewise linear.\n" + "This introduces error, typically of around 1%%."), + SS.MmToStringSI(area, /*dim=*/2).c_str()); + break; + } + if(g->polyError.how != PolyError::GOOD) { Error(_("This group does not contain a correctly-formed " "2d closed area. It is open, not coplanar, or self-"