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 }, { 0, "&Analyze", 0, NULL },
{ 1, "Measure &Volume\tCtrl+Shift+V", MNU_VOLUME, 'V'|S|C,mAna }, { 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 &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, "Show &Naked Edges\tCtrl+Shift+N", MNU_NAKED_EDGES, 'N'|S|C,mAna },
{ 1, NULL, 0, NULL }, { 1, NULL, 0, NULL },
@ -631,6 +632,12 @@ void GraphicsWindow::MenuEdit(int id) {
HideTextEditControl(); HideTextEditControl();
SS.nakedEdges.Clear(); SS.nakedEdges.Clear();
SS.justExportedInfo.draw = false; 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; break;
case MNU_SELECT_ALL: { case MNU_SELECT_ALL: {

View File

@ -548,6 +548,10 @@ bool SContour::IsClockwiseProjdToNormal(Vector n) {
// what we do then. // what we do then.
if(n.Magnitude() < 0.01) return true; 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 // An arbitrary 2d coordinate system that has n as its normal
Vector u = n.Normal(0); Vector u = n.Normal(0);
Vector v = n.Normal(1); Vector v = n.Normal(1);
@ -561,7 +565,7 @@ bool SContour::IsClockwiseProjdToNormal(Vector n) {
area += ((v0 + v1)/2)*(u1 - u0); area += ((v0 + v1)/2)*(u1 - u0);
} }
return (area < 0); return area;
} }
bool SContour::ContainsPointProjdToNormal(Vector n, Vector p) { bool SContour::ContainsPointProjdToNormal(Vector n, Vector p) {
@ -621,6 +625,17 @@ Vector SPolygon::ComputeNormal(void) {
return (l.elem[0]).ComputeNormal(); 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) { bool SPolygon::ContainsPoint(Vector p) {
return (WindingNumberForPoint(p) % 2) == 1; return (WindingNumberForPoint(p) % 2) == 1;
} }

View File

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

View File

@ -630,9 +630,49 @@ void SolveSpace::MenuAnalyze(int id) {
vol += integral; vol += integral;
} }
SS.TW.shown.volume = vol;
SS.TW.GoToScreen(TextWindow::SCREEN_MESH_VOLUME); char msg[1024];
SS.later.showTW = true; 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; break;
} }

View File

@ -674,23 +674,6 @@ void TextWindow::ShowStepDimension(void) {
Printf(true, "(or %Fl%Ll%fcancel operation%E)", &ScreenHome); 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. // 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_GROUP_SOLVE_INFO: ShowGroupSolveInfo(); break;
case SCREEN_CONFIGURATION: ShowConfiguration(); break; case SCREEN_CONFIGURATION: ShowConfiguration(); break;
case SCREEN_STEP_DIMENSION: ShowStepDimension(); break; case SCREEN_STEP_DIMENSION: ShowStepDimension(); break;
case SCREEN_MESH_VOLUME: ShowMeshVolume(); break;
case SCREEN_LIST_OF_STYLES: ShowListOfStyles(); break; case SCREEN_LIST_OF_STYLES: ShowListOfStyles(); break;
case SCREEN_STYLE_INFO: ShowStyleInfo(); break; case SCREEN_STYLE_INFO: ShowStyleInfo(); break;
case SCREEN_PASTE_TRANSFORMED: ShowPasteTransformed(); 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_GROUP_SOLVE_INFO = 2;
static const int SCREEN_CONFIGURATION = 3; static const int SCREEN_CONFIGURATION = 3;
static const int SCREEN_STEP_DIMENSION = 4; static const int SCREEN_STEP_DIMENSION = 4;
static const int SCREEN_MESH_VOLUME = 5; static const int SCREEN_LIST_OF_STYLES = 5;
static const int SCREEN_LIST_OF_STYLES = 6; static const int SCREEN_STYLE_INFO = 6;
static const int SCREEN_STYLE_INFO = 7; static const int SCREEN_PASTE_TRANSFORMED = 7;
static const int SCREEN_PASTE_TRANSFORMED = 8; static const int SCREEN_EDIT_VIEW = 8;
static const int SCREEN_EDIT_VIEW = 9;
typedef struct { typedef struct {
int screen; int screen;
@ -74,8 +73,6 @@ public:
Vector origin; Vector origin;
double scale; double scale;
} paste; } paste;
double volume;
} ShownState; } ShownState;
ShownState shown; ShownState shown;
@ -149,7 +146,6 @@ public:
void ShowListOfStyles(void); void ShowListOfStyles(void);
void ShowStyleInfo(void); void ShowStyleInfo(void);
void ShowStepDimension(void); void ShowStepDimension(void);
void ShowMeshVolume(void);
void ShowPasteTransformed(void); void ShowPasteTransformed(void);
void ShowEditView(void); void ShowEditView(void);
// Special screen, based on selection // Special screen, based on selection
@ -330,6 +326,7 @@ public:
MNU_COMMENT, MNU_COMMENT,
// Analyze // Analyze
MNU_VOLUME, MNU_VOLUME,
MNU_AREA,
MNU_INTERFERENCE, MNU_INTERFERENCE,
MNU_NAKED_EDGES, MNU_NAKED_EDGES,
MNU_SHOW_DOF, MNU_SHOW_DOF,

View File

@ -1,7 +1,6 @@
replace show/hide links with icons replace show/hide links with icons
add checked/unchecked checkbox and radio button add checked/unchecked checkbox and radio button
fix bug with rotation in plane where green line stays displayed 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 lock point where dragged constraint
remove toolbar icons for sketch in 3d, add View -> Align to Workplane remove toolbar icons for sketch in 3d, add View -> Align to Workplane