home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dream 52
/
Amiga_Dream_52.iso
/
Linux
/
Divers
/
freedraft.tar.gz
/
freedraft.tar
/
FREEdraft-050298
/
COMMAND
/
MEASUREMENTMENU
/
measurementmenuhandler.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1998-05-01
|
17KB
|
612 lines
// measurementmenuhandler.cpp
// Copyright (C) 1998 Cliff Johnson //
// //
// This program is free software; you can redistribute it and/or //
// modify it under the terms of the GNU General Public //
// License as published by the Free Software Foundation; either //
// version 2 of the License, or (at your option) any later version. //
// //
// This software is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU //
// General Public License for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this software (see COPYING); if not, write to the //
// Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. //
#include <iostream.h>
#include <strstream.h>
#include <math.h>
#include <v/vnotice.h>
#include <vdapp_enum.h>
#include <geom_enum.h>
#include <comexception.h>
#include <geomexception.h>
#include <point.h>
#include <line.h>
#include <arc.h>
#include <circle.h>
#include <segment.h>
#include <pick.h>
#include <pickgeom.h>
#include "measurement_enum.h"
#include "measurementmenuhandler.h"
//**********constructor ***********************************************************
MeasurementMenuHandler::MeasurementMenuHandler(vdCmdWindow* cmdwin,int r)
: MenuHandler(cmdwin,r)
{
note = new vNoticeDialog(commandWindow);
// set the menu and button labels.
commandWindow->SetString(MENULABEL0,"Query ");
commandWindow->SetString(MENUBUTTON00,"what is?");
commandWindow->SetString(MENUBUTTON01,"button01");
commandWindow->SetString(MENULABEL1,"Measure");
commandWindow->SetString(MENUBUTTON10,"distance");
commandWindow->SetString(MENUBUTTON11,"angle ");
commandWindow->SetString(MENULABEL2,"Label2");
commandWindow->SetString(MENUBUTTON20,"button20");
commandWindow->SetString(MENUBUTTON21,"button21");
commandWindow->SetString(MENULABEL3,"Label3");
commandWindow->SetString(MENUBUTTON30,"button30");
commandWindow->SetString(MENUBUTTON31,"button31");
commandWindow->SetString(MENULABEL4,"Label4");
commandWindow->SetString(MENUBUTTON40,"button40");
commandWindow->SetString(MENUBUTTON41,"button41");
commandWindow->SetString(MENULABEL5,"Label5");
commandWindow->SetString(MENUBUTTON50,"button50");
commandWindow->SetString(MENUBUTTON51,"button51");
commandWindow->SetString(MENULABEL6,"Label6");
commandWindow->SetString(MENUBUTTON60,"button60");
commandWindow->SetString(MENUBUTTON61,"button61");
commandWindow->SetString(MENULABEL7,"Label7");
commandWindow->SetString(MENUBUTTON70,"button70");
commandWindow->SetString(MENUBUTTON71,"button71");
commandWindow->SetString(MENULABEL8,"Label8");
commandWindow->SetString(MENUBUTTON80,"button80");
commandWindow->SetString(MENUBUTTON81,"button81");
commandWindow->SetString(MENULABEL9,"Label9");
commandWindow->SetString(MENUBUTTON90,"button90");
commandWindow->SetString(MENUBUTTON91,"button91");
commandWindow->SetString(MENULABEL10,"Label10");
commandWindow->SetString(MENUBUTTON100,"button100");
commandWindow->SetString(MENUBUTTON101,"button101");
commandWindow->SetValue(MENUBUTTON00,isSens,Sensitive);
commandWindow->SetValue(MENUBUTTON01,notSens,Sensitive);
commandWindow->SetValue(MENUBUTTON10,isSens,Sensitive);
commandWindow->SetValue(MENUBUTTON11,isSens,Sensitive);
commandWindow->SetValue(MENUBUTTON20,notSens,Sensitive);
commandWindow->SetValue(MENUBUTTON21,notSens,Sensitive);
commandWindow->SetValue(MENUBUTTON30,notSens,Sensitive);
commandWindow->SetValue(MENUBUTTON31,notSens,Sensitive);
commandWindow->SetValue(MENUBUTTON40,notSens,Sensitive);
commandWindow->SetValue(MENUBUTTON41,notSens,Sensitive);
commandWindow->SetValue(MENUBUTTON50,notSens,Sensitive);
commandWindow->SetValue(MENUBUTTON51,notSens,Sensitive);
commandWindow->SetValue(MENUBUTTON60,notSens,Sensitive);
commandWindow->SetValue(MENUBUTTON61,notSens,Sensitive);
commandWindow->SetValue(MENUBUTTON70,notSens,Sensitive);
commandWindow->SetValue(MENUBUTTON71,notSens,Sensitive);
commandWindow->SetValue(MENUBUTTON80,notSens,Sensitive);
commandWindow->SetValue(MENUBUTTON81,notSens,Sensitive);
commandWindow->SetValue(MENUBUTTON90,notSens,Sensitive);
commandWindow->SetValue(MENUBUTTON91,notSens,Sensitive);
commandWindow->SetValue(MENUBUTTON100,notSens,Sensitive);
commandWindow->SetValue(MENUBUTTON101,notSens,Sensitive);
}
//**********destructor ***********************************************************
MeasurementMenuHandler::~MeasurementMenuHandler()
{
delete note;
}
//***********************************************************************************
// virtual function MenuCommand
//***********************************************************************************
void MeasurementMenuHandler::MenuCommand(int id)
{
switch(id)
{
case MENUBUTTON00:
{
WhatIs0();
break;
}
case MENUBUTTON10:
{
Distance0();
break;
}
case MENUBUTTON11:
{
Angle0();
break;
}
}
MenuHandler::MenuCommand(id);
}
//***********************************************************************************
// virtual function CommandActions
//***********************************************************************************
void MeasurementMenuHandler::CommandActions()
{
while(parm == 0)
{
switch(commandStack.back())
{
case MEASUREMENT_WHATIS:
{
WhatIs1();
break;
}
case MEASUREMENT_DISTANCE1:
{
Distance1();
break;
}
case MEASUREMENT_DISTANCE2:
{
Distance2();
break;
}
case MEASUREMENT_ANGLE1:
{
Angle1();
break;
}
case MEASUREMENT_ANGLE2:
{
Angle2();
break;
}
default:
MenuHandler::CommandActions();
}
}
}
//===========================================================================
void MeasurementMenuHandler::WhatIs0()
{
Initialize();
commandStack.push_back(MEASUREMENT_WHATIS);
SelectionFilter sf;
sf.Add(POINT);
sf.Add(LINE);
sf.Add(CIRCLE);
sf.Add(SEGMENT);
sf.Add(ARC);
SetTypeMask(sf);
parm = 1;
Say(NULL);
Say("> Entity analysis: Select an entity :");
}
//===========================================================================
void MeasurementMenuHandler::WhatIs1()
{
Pick pk;
int button;
ostrstream out;
try
{
button = MenuHandler::Get1Pick(pk);
}
catch(ComException & ce)
{
cerr << "Comexception raised in MeasurementMenuHandler::Whatis1()" << endl;
cerr << " " << ce.what() << endl;
Say(" > ERROR: invalid selection >>> Select an entity: ");
goto cleanup;
}
switch(pk.Type())
{
case POINT:
{
Point p = GetPointFromPick(pk);
out << "Type = Point\n";
out << "Coords = " << p << ends ;
break;
}
case LINE:
{
Line l = GetLineFromPick(pk);
out << "Type = Line\n";
out << "Origin = " << l.Origin() << '\n';
out << "Direction = " << l.Direction() << ends;
break;
}
case CIRCLE:
{
Circle c = GetCircleFromPick(pk);
out << "Type = Circle\n";
out << "Center = " << c.Center() << '\n';
out << "Radius = " << c.Radius() << ends;
break;
}
case ARC:
{
Arc a = GetArcFromPick(pk);
out << "Type = Arc\n";
out << "Center = " << a.Center() << '\n';
out << "Origin = " << a.Origin() << '\n';
out << "Endpoint = " << a.Endpoint() << '\n';
out << "Radius = " << a.Radius() << '\n';
out << "Angle = " << a.ArcAngle()*180/M_PI << " degrees" << ends;
break;
}
case SEGMENT:
{
Segment s = GetSegmentFromPick(pk);
out << "Type = Segment\n";
out << "Origin = " << s.Origin() << '\n';
out << "Endpoint = " << s.Endpoint() << '\n';
out << "Length = " << s.Length() << ends;
break;
}
default:
goto cleanup;
}
note->Notice(out.str());
cleanup:
pk.CleanUp();
parm = 1;
}
//===========================================================================
void MeasurementMenuHandler::Distance0()
{
Initialize();
commandStack.push_back(MEASUREMENT_DISTANCE1);
SelectionFilter sf;
sf.Add(POINT);
sf.Add(LINE);
sf.Add(CIRCLE);
sf.Add(SEGMENT);
sf.Add(ARC);
SetTypeMask(sf);
parm = 1;
Say(NULL);
Say("> Distance measurment: Select an entity: ");
}
//===========================================================================
void MeasurementMenuHandler::Distance1()
{
Pick pk;
int button;
try
{
button = MenuHandler::Get1Pick(pk);
}
catch(ComException & ce)
{
cerr << "Comexception raised in MeasurementMenuHandler::Distance1()" << endl;
cerr << " " << ce.what() << endl;
Say(" > ERROR: invalid selection >>> Distance measurement: Select an entity:");
pk.CleanUp();
parm = 1;
return;
}
// if a circle or arc was selected, only a point is valid for second pick
// if a line or segment was selected, a point, line, or segment may be selected second
// if a point was selected, anything can be selected on the second pick
SelectionFilter sf;
if(pk.Type() == CIRCLE || pk.Type() == ARC)
{
sf.Add(POINT);
SetTypeMask(sf);
Say(" Select a point:");
}
else if(pk.Type() == LINE || pk.Type() == SEGMENT)
{
sf.Add(POINT);
sf.Add(LINE);
sf.Add(SEGMENT);
SetTypeMask(sf);
Say(" Select a point, line, or segment");
}
else
{
Say(" Select another entity:");
}
// set the new command
commandStack.pop_back();
commandStack.push_back(MEASUREMENT_DISTANCE2);
// highlight
SetHighlight(pk,true);
Redraw();
// save the pick
pk.Lock();
PushPick(pk,button);
// set the parm count
parm = 1;
}
//===========================================================================
void MeasurementMenuHandler::Distance2()
{
Pick pk1,pk2;
int button1,button2;
double d;
// get the second pick
try
{
button2 = MenuHandler::Get1Pick(pk2);
}
catch(ComException& ce)
{ // pick 2 is bad - ignore it.
cerr << "ComException raised in MeasurementMenuHandler::Distance2()" << endl;
cerr << " " << ce.what() << endl;
Say(" > Selection invalid. Reselect second entity.");
pk2.CleanUp();
parm = 1;
return;
}
// get the first pick again
try
{
button1 = MenuHandler::Get1Pick(pk1);
}
catch(ComException& ce)
{
// pick 1 has gone bad - reset the function
cerr << "ComException raised in MeasurementMenuHandler::Distance2()" << endl;
cerr << " " << ce.what() << endl;
Say("ERROR: first selection lost! -> resetting...");
goto reinit;
}
// process different combinations
// point vs. point
if(pk1.Type() == POINT && pk2.Type() == POINT)
{
Point p1 = GetPointFromPick(pk1);
Point p2 = GetPointFromPick(pk2);
d = p1.Distance(p2);
}
// point vs. line/segment
// point vs. circle
// point vs. arc
else if( pk1.Type() == POINT || pk2.Type() == POINT)
{
Point p;
if(pk1.Type() == LINE || pk1.Type() == SEGMENT || pk2.Type() == LINE || pk2.Type() == SEGMENT)
{
Line l;
if(pk1.Type() == POINT)
{
p = GetPointFromPick(pk1);
l = GetLineFromPick(pk2);
}
else
{
p = GetPointFromPick(pk2);
l = GetLineFromPick(pk1);
}
d = l.Distance(p);
}
else if(pk1.Type() == CIRCLE || pk2.Type() == CIRCLE)
{
Circle c;
if(pk1.Type() == POINT)
{
p = GetPointFromPick(pk1);
c = GetCircleFromPick(pk2);
}
else
{
p = GetPointFromPick(pk2);
c = GetCircleFromPick(pk1);
}
d = c.Distance(p);
}
else if(pk1.Type() == ARC || pk2.Type() == ARC)
{
Arc a;
if(pk1.Type() == POINT)
{
p = GetPointFromPick(pk1);
a = GetArcFromPick(pk2);
}
else
{
p = GetPointFromPick(pk2);
a = GetArcFromPick(pk1);
}
d = a.Distance(p);
}
}
else if((pk1.Type() == LINE || pk1.Type() == SEGMENT) && (pk2.Type() == LINE || pk2.Type() == SEGMENT))
{
Line l1 = GetLineFromPick(pk1);
Line l2 = GetLineFromPick(pk2);
Vector v1 = l1.Direction();
Vector v2 = l2.Direction();
if(Angle(v1,v2) > Point::NullAngle)
{
note->Notice("Lines/Segments are not parallel");
goto reinit;
}
d = l1.Distance(l2.Origin());
}
else
{
note->Notice("Error: unexpected combination... distance computation not implemented");
goto reinit;
}
{
ostrstream out;
out << "Distance = " << d << ends;
note->Notice(out.str());
}
reinit:
// highlight
SetHighlight(pk1,false);
Redraw();
pk1.Unlock();
pk2.Unlock();
pk1.CleanUp();
pk2.CleanUp();
commandStack.pop_back();
commandStack.push_back(MEASUREMENT_DISTANCE1);
parm = 1;
Say(NULL);
Say("> Distance measurment: Select an entity: ");
// line/segment vs. line/segment
}
//===========================================================================
void MeasurementMenuHandler::Angle0()
{
Initialize();
commandStack.push_back(MEASUREMENT_ANGLE1);
SelectionFilter sf;
sf.Add(LINE);
sf.Add(SEGMENT);
SetTypeMask(sf);
parm = 1;
Say(NULL);
Say("> Angle measurment: Select a line or segment: ");
}
//===========================================================================
void MeasurementMenuHandler::Angle1()
{
// check the pick out
Pick pk;
int button;
try
{
button = MenuHandler::Get1Pick(pk);
}
catch(ComException & ce)
{
cerr << "Comexception raised in MeasurementMenuHandler::Angle1()" << endl;
cerr << " " << ce.what() << endl;
Say(" > ERROR: invalid selection >>> Angle measurement: Select a line or segment:");
pk.CleanUp();
parm = 1;
return;
}
if(pk.Type() != LINE && pk.Type() != SEGMENT)
{
Say(" > ERROR: invalid selection >>> Angle measurement: Select a line or segment:");
pk.CleanUp();
parm = 1;
return;
}
// set the new command
commandStack.pop_back();
commandStack.push_back(MEASUREMENT_ANGLE2);
// highlight the first pick
SetHighlight(pk,true);
Redraw();
// save the pick
pk.Lock();
PushPick(pk,button);
// set the parm count
parm = 1;
}
//===========================================================================
void MeasurementMenuHandler::Angle2()
{
Pick pk1,pk2;
int button1,button2;
// get the second pick
try
{
button2 = MenuHandler::Get1Pick(pk2);
}
catch(ComException& ce)
{ // pick 2 is bad - ignore it.
cerr << "ComException raised in MeasurementMenuHandler::Angle2()" << endl;
cerr << " " << ce.what() << endl;
Say(" > Selection invalid. Reselect second line or segment.");
pk2.CleanUp();
parm = 1;
return;
}
// get the first pick again
try
{
button1 = MenuHandler::Get1Pick(pk1);
}
catch(ComException& ce)
{
// pick 1 has gone bad - reset the function
cerr << "ComException raised in MeasurementMenuHandler::Angle2()" << endl;
cerr << " " << ce.what() << endl;
Say("ERROR: first selection lost! -> resetting...");
goto reinit;
}
// check the pick types
if((pk1.Type() != LINE && pk1.Type() != SEGMENT) || (pk2.Type() != LINE && pk2.Type() != SEGMENT))
{
Say("ERROR: a selection is not a line or segment -> resetting...");
goto reinit;
}
{
// get two lines
Line l1 = GetLineFromPick(pk1);
Line l2 = GetLineFromPick(pk2);
// get the angle
Vector v1 = l1.Direction();
Vector v2 = l2.Direction();
double a1 = Angle(v1,v2)*180/M_PI;
double a2 = 180. - a1;
// display the dialog
ostrstream out;
out << "Angle = " << a1 << " degrees \nComplement = " << a2 << " degrees" << ends;
note->Notice(out.str());
// reset prompt string
Say(NULL);
}
// reinitialize
reinit:
SetHighlight(pk1,false);
Redraw();
pk1.Unlock();
pk2.Unlock();
pk1.CleanUp();
pk2.CleanUp();
commandStack.pop_back();
commandStack.push_back(MEASUREMENT_ANGLE1);
parm = 1;
Say("> Angle measurment: Select a line or segment: ");
}