Skip to content

Commit

Permalink
Calculate area of selected faces, if any.
Browse files Browse the repository at this point in the history
  • Loading branch information
Evil-Spirit authored and whitequark committed Sep 11, 2019
1 parent 915f55a commit 7f9117b
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -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.

Expand Down
11 changes: 11 additions & 0 deletions src/mesh.cpp
Expand Up @@ -1181,3 +1181,14 @@ double SMesh::CalculateVolume() const {
}
return vol;
}

double SMesh::CalculateSurfaceArea(const std::vector<uint32_t> &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;
}
6 changes: 6 additions & 0 deletions src/polygon.cpp
Expand Up @@ -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) ||
Expand Down
2 changes: 2 additions & 0 deletions src/polygon.h
Expand Up @@ -191,6 +191,7 @@ class STriangle {
bool Raytrace(const Vector &rayPoint, const Vector &rayDir,
double *t, Vector *inters) const;
double SignedVolume() const;
double Area() const;
bool IsDegenerate() const;
};

Expand Down Expand Up @@ -281,6 +282,7 @@ class SMesh {
void PrecomputeTransparency();
void RemoveDegenerateTriangles();
double CalculateVolume() const;
double CalculateSurfaceArea(const std::vector<uint32_t> &faces) const;

bool IsEmpty() const;
void RemapFaces(Group *g, int remap);
Expand Down
17 changes: 17 additions & 0 deletions src/solvespace.cpp
Expand Up @@ -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<uint32_t> 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%%."),

This comment has been minimized.

Copy link
@Evil-Spirit

Evil-Spirit Sep 11, 2019

Author Collaborator

1%%

This comment has been minimized.

Copy link
@whitequark

whitequark Sep 11, 2019

Contributor

This is correct, no? That's because % needs to be escaped for printf.

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-"
Expand Down

0 comments on commit 7f9117b

Please sign in to comment.