Add ability to measure the area of a plane sketch, since that's

easy and useful. Also make the volume measurement use Message(),
and not a separate text window screen.

And make Edit -> Unselect All (Esc) clear the marks drawn to
indicate free parameters, since it clears all the other temporary
stuff drawn in the graphics window.

[git-p4: depot-paths = "//depot/solvespace/": change = 2121]
solver
Jonathan Westhues 2010-03-01 09:23:57 -08:00
parent a11010c593
commit c81cbd9ee9
8 changed files with 73 additions and 31 deletions

View File

@ -120,6 +120,7 @@ const GraphicsWindow::MenuEntry GraphicsWindow::menu[] = {
{ 0, "&Analyze", 0, NULL },
{ 1, "Measure &Volume\tCtrl+Shift+V", MNU_VOLUME, 'V'|S|C,mAna },
{ 1, "Measure &Area\tCtrl+Shift+A", MNU_AREA, 'A'|S|C,mAna },
{ 1, "Show &Interfering Parts\tCtrl+Shift+I", MNU_INTERFERENCE, 'I'|S|C,mAna },
{ 1, "Show &Naked Edges\tCtrl+Shift+N", MNU_NAKED_EDGES, 'N'|S|C,mAna },
{ 1, NULL, 0, NULL },
@ -631,6 +632,12 @@ void GraphicsWindow::MenuEdit(int id) {
HideTextEditControl();
SS.nakedEdges.Clear();
SS.justExportedInfo.draw = false;
// This clears the marks drawn to indicate which points are
// still free to drag.
Param *p;
for(p = SK.param.First(); p; p = SK.param.NextAfter(p)) {
p->free = false;
}
break;
case MNU_SELECT_ALL: {

View File

@ -548,6 +548,10 @@ bool SContour::IsClockwiseProjdToNormal(Vector n) {
// what we do then.
if(n.Magnitude() < 0.01) return true;
return (SignedAreaProjdToNormal(n) < 0);
}
double SContour::SignedAreaProjdToNormal(Vector n) {
// An arbitrary 2d coordinate system that has n as its normal
Vector u = n.Normal(0);
Vector v = n.Normal(1);
@ -561,7 +565,7 @@ bool SContour::IsClockwiseProjdToNormal(Vector n) {
area += ((v0 + v1)/2)*(u1 - u0);
}
return (area < 0);
return area;
}
bool SContour::ContainsPointProjdToNormal(Vector n, Vector p) {
@ -621,6 +625,17 @@ Vector SPolygon::ComputeNormal(void) {
return (l.elem[0]).ComputeNormal();
}
double SPolygon::SignedArea(void) {
SContour *sc;
double area = 0;
// This returns the true area only if the contours are all oriented
// correctly, with the holes backwards from the outer contours.
for(sc = l.First(); sc; sc = l.NextAfter(sc)) {
area += sc->SignedAreaProjdToNormal(normal);
}
return area;
}
bool SPolygon::ContainsPoint(Vector p) {
return (WindingNumberForPoint(p) % 2) == 1;
}

View File

@ -99,6 +99,7 @@ public:
void MakeEdgesInto(SEdgeList *el);
void Reverse(void);
Vector ComputeNormal(void);
double SignedAreaProjdToNormal(Vector n);
bool IsClockwiseProjdToNormal(Vector n);
bool ContainsPointProjdToNormal(Vector n, Vector p);
void OffsetInto(SContour *dest, double r);
@ -125,6 +126,7 @@ public:
Vector ComputeNormal(void);
void AddEmptyContour(void);
int WindingNumberForPoint(Vector p);
double SignedArea(void);
bool ContainsPoint(Vector p);
void MakeEdgesInto(SEdgeList *el);
void FixContourDirections(void);

View File

@ -630,9 +630,49 @@ void SolveSpace::MenuAnalyze(int id) {
vol += integral;
}
SS.TW.shown.volume = vol;
SS.TW.GoToScreen(TextWindow::SCREEN_MESH_VOLUME);
SS.later.showTW = true;
char msg[1024];
sprintf(msg, "The volume of the solid model is:\n\n"
" %.3f %s^3",
vol / pow(SS.MmPerUnit(), 3),
SS.UnitName());
if(SS.viewUnits == SolveSpace::UNIT_MM) {
sprintf(msg+strlen(msg), "\n %.2f mL", vol/(10*10*10));
}
strcpy(msg+strlen(msg),
"\n\nCurved surfaces have been approximated as triangles.\n"
"This introduces error, typically of around 1%.");
Message("%s", msg);
break;
}
case GraphicsWindow::MNU_AREA: {
Group *g = SK.GetGroup(SS.GW.activeGroup);
if(g->polyError.how != Group::POLY_GOOD) {
Error("This group does not contain a correctly-formed "
"2d closed area. It is open, not coplanar, or self-"
"intersecting.");
break;
}
SEdgeList sel;
ZERO(&sel);
g->polyLoops.MakeEdgesInto(&sel);
SPolygon sp;
ZERO(&sp);
sel.AssemblePolygon(&sp, NULL, true);
sp.normal = sp.ComputeNormal();
sp.FixContourDirections();
double area = sp.SignedArea();
double scale = SS.MmPerUnit();
Message("The area of the region sketched in this group is:\n\n"
" %.3f %s^2\n\n"
"Curves have been approximated as piecewise linear.\n"
"This introduces error, typically of around 1%%.",
area / (scale*scale),
SS.UnitName());
sel.Clear();
sp.Clear();
break;
}

View File

@ -674,23 +674,6 @@ void TextWindow::ShowStepDimension(void) {
Printf(true, "(or %Fl%Ll%fcancel operation%E)", &ScreenHome);
}
//-----------------------------------------------------------------------------
// A report of the volume of the mesh. No interaction, output-only.
//-----------------------------------------------------------------------------
void TextWindow::ShowMeshVolume(void) {
Printf(true, "%FtMESH VOLUME");
Printf(true, " %3 %s^3",
shown.volume / pow(SS.MmPerUnit(), 3),
SS.UnitName());
if(SS.viewUnits == SolveSpace::UNIT_MM) {
Printf(false, " %2 mL", shown.volume/(10*10*10));
}
Printf(true, "%Fl%Ll%f(back)%E", &ScreenHome);
}
//-----------------------------------------------------------------------------
// The edit control is visible, and the user just pressed enter.
//-----------------------------------------------------------------------------

View File

@ -234,7 +234,6 @@ void TextWindow::Show(void) {
case SCREEN_GROUP_SOLVE_INFO: ShowGroupSolveInfo(); break;
case SCREEN_CONFIGURATION: ShowConfiguration(); break;
case SCREEN_STEP_DIMENSION: ShowStepDimension(); break;
case SCREEN_MESH_VOLUME: ShowMeshVolume(); break;
case SCREEN_LIST_OF_STYLES: ShowListOfStyles(); break;
case SCREEN_STYLE_INFO: ShowStyleInfo(); break;
case SCREEN_PASTE_TRANSFORMED: ShowPasteTransformed(); break;

13
ui.h
View File

@ -51,11 +51,10 @@ public:
static const int SCREEN_GROUP_SOLVE_INFO = 2;
static const int SCREEN_CONFIGURATION = 3;
static const int SCREEN_STEP_DIMENSION = 4;
static const int SCREEN_MESH_VOLUME = 5;
static const int SCREEN_LIST_OF_STYLES = 6;
static const int SCREEN_STYLE_INFO = 7;
static const int SCREEN_PASTE_TRANSFORMED = 8;
static const int SCREEN_EDIT_VIEW = 9;
static const int SCREEN_LIST_OF_STYLES = 5;
static const int SCREEN_STYLE_INFO = 6;
static const int SCREEN_PASTE_TRANSFORMED = 7;
static const int SCREEN_EDIT_VIEW = 8;
typedef struct {
int screen;
@ -74,8 +73,6 @@ public:
Vector origin;
double scale;
} paste;
double volume;
} ShownState;
ShownState shown;
@ -149,7 +146,6 @@ public:
void ShowListOfStyles(void);
void ShowStyleInfo(void);
void ShowStepDimension(void);
void ShowMeshVolume(void);
void ShowPasteTransformed(void);
void ShowEditView(void);
// Special screen, based on selection
@ -330,6 +326,7 @@ public:
MNU_COMMENT,
// Analyze
MNU_VOLUME,
MNU_AREA,
MNU_INTERFERENCE,
MNU_NAKED_EDGES,
MNU_SHOW_DOF,

View File

@ -1,7 +1,6 @@
replace show/hide links with icons
add checked/unchecked checkbox and radio button
fix bug with rotation in plane where green line stays displayed
area of sketch in a given workplane (easy, useful)
lock point where dragged constraint
remove toolbar icons for sketch in 3d, add View -> Align to Workplane