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 >
C/C++ Source or Header  |  1998-05-01  |  17KB  |  612 lines

  1. // measurementmenuhandler.cpp
  2.  
  3. // Copyright (C) 1998  Cliff Johnson                                       //
  4. //                                                                         //
  5. // This program is free software; you can redistribute it and/or           //
  6. // modify it under the terms of the GNU  General Public                    //
  7. // License as published by the Free Software Foundation; either            //
  8. // version 2 of the License, or (at your option) any later version.        //
  9. //                                                                         //
  10. // This software is distributed in the hope that it will be useful,        //
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of          //
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU       //
  13. // General Public License for more details.                                //
  14. //                                                                         //
  15. // You should have received a copy of the GNU General Public License       //
  16. // along with this software (see COPYING); if not, write to the        //
  17. // Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. //
  18.  
  19. #include <iostream.h>
  20. #include <strstream.h>
  21. #include <math.h>
  22.  
  23. #include <v/vnotice.h>
  24.  
  25.  
  26. #include <vdapp_enum.h>
  27. #include <geom_enum.h>
  28.  
  29. #include <comexception.h>
  30. #include <geomexception.h>
  31.  
  32. #include <point.h>
  33. #include <line.h>
  34. #include <arc.h>
  35. #include <circle.h>
  36. #include <segment.h>
  37. #include <pick.h>
  38. #include <pickgeom.h>
  39.  
  40. #include "measurement_enum.h"
  41. #include "measurementmenuhandler.h"
  42.  
  43.  
  44. //**********constructor ***********************************************************
  45. MeasurementMenuHandler::MeasurementMenuHandler(vdCmdWindow* cmdwin,int r) 
  46. : MenuHandler(cmdwin,r)
  47. {
  48.     note = new vNoticeDialog(commandWindow);
  49.  
  50. // set the menu and button labels.
  51.  
  52.     commandWindow->SetString(MENULABEL0,"Query ");
  53.     commandWindow->SetString(MENUBUTTON00,"what is?");
  54.     commandWindow->SetString(MENUBUTTON01,"button01");
  55.  
  56.     commandWindow->SetString(MENULABEL1,"Measure");
  57.     commandWindow->SetString(MENUBUTTON10,"distance");
  58.     commandWindow->SetString(MENUBUTTON11,"angle   ");
  59.  
  60.     commandWindow->SetString(MENULABEL2,"Label2");
  61.     commandWindow->SetString(MENUBUTTON20,"button20");
  62.     commandWindow->SetString(MENUBUTTON21,"button21");
  63.  
  64.     commandWindow->SetString(MENULABEL3,"Label3");
  65.     commandWindow->SetString(MENUBUTTON30,"button30");
  66.     commandWindow->SetString(MENUBUTTON31,"button31");
  67.  
  68.     commandWindow->SetString(MENULABEL4,"Label4");
  69.     commandWindow->SetString(MENUBUTTON40,"button40");
  70.     commandWindow->SetString(MENUBUTTON41,"button41");
  71.  
  72.     commandWindow->SetString(MENULABEL5,"Label5");
  73.     commandWindow->SetString(MENUBUTTON50,"button50");
  74.     commandWindow->SetString(MENUBUTTON51,"button51");
  75.  
  76.     commandWindow->SetString(MENULABEL6,"Label6");
  77.     commandWindow->SetString(MENUBUTTON60,"button60");
  78.     commandWindow->SetString(MENUBUTTON61,"button61");
  79.  
  80.     commandWindow->SetString(MENULABEL7,"Label7");
  81.     commandWindow->SetString(MENUBUTTON70,"button70");
  82.     commandWindow->SetString(MENUBUTTON71,"button71");
  83.  
  84.     commandWindow->SetString(MENULABEL8,"Label8");
  85.     commandWindow->SetString(MENUBUTTON80,"button80");
  86.     commandWindow->SetString(MENUBUTTON81,"button81");
  87.  
  88.     commandWindow->SetString(MENULABEL9,"Label9");
  89.     commandWindow->SetString(MENUBUTTON90,"button90");
  90.     commandWindow->SetString(MENUBUTTON91,"button91");
  91.  
  92.     commandWindow->SetString(MENULABEL10,"Label10");
  93.     commandWindow->SetString(MENUBUTTON100,"button100");
  94.     commandWindow->SetString(MENUBUTTON101,"button101");
  95.  
  96.     commandWindow->SetValue(MENUBUTTON00,isSens,Sensitive);
  97.     commandWindow->SetValue(MENUBUTTON01,notSens,Sensitive);
  98.     commandWindow->SetValue(MENUBUTTON10,isSens,Sensitive);
  99.     commandWindow->SetValue(MENUBUTTON11,isSens,Sensitive);
  100.     commandWindow->SetValue(MENUBUTTON20,notSens,Sensitive);
  101.     commandWindow->SetValue(MENUBUTTON21,notSens,Sensitive);
  102.     commandWindow->SetValue(MENUBUTTON30,notSens,Sensitive);
  103.     commandWindow->SetValue(MENUBUTTON31,notSens,Sensitive);
  104.     commandWindow->SetValue(MENUBUTTON40,notSens,Sensitive);
  105.     commandWindow->SetValue(MENUBUTTON41,notSens,Sensitive);
  106.     commandWindow->SetValue(MENUBUTTON50,notSens,Sensitive);
  107.     commandWindow->SetValue(MENUBUTTON51,notSens,Sensitive);
  108.     commandWindow->SetValue(MENUBUTTON60,notSens,Sensitive);
  109.     commandWindow->SetValue(MENUBUTTON61,notSens,Sensitive);
  110.     commandWindow->SetValue(MENUBUTTON70,notSens,Sensitive);
  111.     commandWindow->SetValue(MENUBUTTON71,notSens,Sensitive);
  112.     commandWindow->SetValue(MENUBUTTON80,notSens,Sensitive);
  113.     commandWindow->SetValue(MENUBUTTON81,notSens,Sensitive);
  114.     commandWindow->SetValue(MENUBUTTON90,notSens,Sensitive);
  115.     commandWindow->SetValue(MENUBUTTON91,notSens,Sensitive);
  116.     commandWindow->SetValue(MENUBUTTON100,notSens,Sensitive);
  117.     commandWindow->SetValue(MENUBUTTON101,notSens,Sensitive);
  118. }
  119.  
  120. //**********destructor ***********************************************************
  121.  
  122. MeasurementMenuHandler::~MeasurementMenuHandler()
  123. {
  124.     delete note;
  125. }
  126.  
  127. //***********************************************************************************
  128. // virtual function MenuCommand
  129. //***********************************************************************************
  130. void MeasurementMenuHandler::MenuCommand(int id)
  131. {
  132.     switch(id)
  133.     {
  134.     case MENUBUTTON00:
  135.         {
  136.             WhatIs0();
  137.             break;
  138.         }
  139.     case MENUBUTTON10:
  140.         {
  141.             Distance0();
  142.             break;
  143.         }
  144.     case MENUBUTTON11:
  145.         {
  146.             Angle0();
  147.             break;
  148.         }
  149.     }
  150.     MenuHandler::MenuCommand(id);
  151. }
  152.  
  153. //***********************************************************************************
  154. // virtual function CommandActions
  155. //***********************************************************************************
  156.  
  157. void MeasurementMenuHandler::CommandActions()
  158. {
  159.     while(parm == 0)
  160.     {
  161.         switch(commandStack.back())
  162.         {
  163.         case MEASUREMENT_WHATIS:
  164.             {
  165.                 WhatIs1();
  166.                 break;
  167.             }
  168.         case MEASUREMENT_DISTANCE1:
  169.             {
  170.                 Distance1();
  171.                 break;
  172.             }
  173.         case MEASUREMENT_DISTANCE2:
  174.             {
  175.                 Distance2();
  176.                 break;
  177.             }
  178.         case MEASUREMENT_ANGLE1:
  179.             {
  180.                 Angle1();
  181.                 break;
  182.             }
  183.         case MEASUREMENT_ANGLE2:
  184.             {
  185.                 Angle2();
  186.                 break;
  187.             }
  188.         default:
  189.             MenuHandler::CommandActions();
  190.         }
  191.     }
  192. }
  193. //===========================================================================
  194. void MeasurementMenuHandler::WhatIs0()
  195. {
  196.     Initialize();
  197.     commandStack.push_back(MEASUREMENT_WHATIS);
  198.     SelectionFilter sf;
  199.     sf.Add(POINT);
  200.     sf.Add(LINE);
  201.     sf.Add(CIRCLE);
  202.     sf.Add(SEGMENT);
  203.     sf.Add(ARC);
  204.     SetTypeMask(sf);
  205.     parm = 1;
  206.     Say(NULL);
  207.     Say("> Entity analysis: Select an entity :");
  208. }
  209. //===========================================================================
  210. void MeasurementMenuHandler::WhatIs1()
  211. {
  212.         Pick pk;
  213.         int button;
  214.     ostrstream out;
  215.         try
  216.         {
  217.                 button = MenuHandler::Get1Pick(pk);
  218.         }
  219.         catch(ComException & ce)
  220.         {
  221.                 cerr << "Comexception raised in MeasurementMenuHandler::Whatis1()" << endl;
  222.                 cerr << "       " << ce.what() << endl;
  223.                 Say(" > ERROR: invalid selection >>> Select an entity: ");
  224.         goto cleanup;
  225.         }
  226.     switch(pk.Type())
  227.     {
  228.     case POINT:
  229.         {
  230.             Point p = GetPointFromPick(pk);
  231.             out << "Type   = Point\n";
  232.             out << "Coords = " << p << ends ;
  233.             break;
  234.         }
  235.     case LINE:
  236.         {
  237.             Line l = GetLineFromPick(pk);
  238.             out << "Type      = Line\n";
  239.             out << "Origin    = " << l.Origin() << '\n';
  240.             out << "Direction = " << l.Direction() << ends;
  241.             break;
  242.         }
  243.     case CIRCLE:
  244.         {
  245.             Circle c = GetCircleFromPick(pk);
  246.             out << "Type   = Circle\n";
  247.             out << "Center = " << c.Center() << '\n';
  248.             out << "Radius = " << c.Radius() << ends;
  249.             break;
  250.         }
  251.     case ARC:
  252.         {
  253.             Arc a = GetArcFromPick(pk);
  254.             out << "Type     = Arc\n";
  255.             out << "Center   = " << a.Center() << '\n';
  256.             out << "Origin   = " << a.Origin() << '\n';
  257.             out << "Endpoint = " << a.Endpoint() << '\n';
  258.             out << "Radius   = " << a.Radius() << '\n';
  259.             out << "Angle    = " << a.ArcAngle()*180/M_PI << " degrees" << ends;
  260.             break;
  261.         }
  262.             
  263.     case SEGMENT:
  264.         {
  265.             Segment s = GetSegmentFromPick(pk);
  266.             out << "Type     = Segment\n";
  267.             out << "Origin   = " << s.Origin() << '\n';
  268.             out << "Endpoint = " << s.Endpoint() << '\n';
  269.             out << "Length   = " << s.Length() << ends;
  270.             break;
  271.         }
  272.     default:
  273.         goto cleanup;
  274.     }
  275.     note->Notice(out.str());
  276. cleanup:
  277.     pk.CleanUp();
  278.     parm = 1;
  279. }
  280. //===========================================================================
  281. void MeasurementMenuHandler::Distance0()
  282. {
  283.     Initialize();
  284.     commandStack.push_back(MEASUREMENT_DISTANCE1);
  285.     SelectionFilter sf;
  286.     sf.Add(POINT);
  287.     sf.Add(LINE);
  288.     sf.Add(CIRCLE);
  289.     sf.Add(SEGMENT);
  290.     sf.Add(ARC);
  291.     SetTypeMask(sf);
  292.     parm = 1;
  293.     Say(NULL);
  294.     Say("> Distance measurment: Select an entity: ");
  295. }
  296. //===========================================================================
  297. void MeasurementMenuHandler::Distance1()
  298. {
  299.         Pick pk;
  300.         int button;
  301.         try
  302.         {
  303.                 button = MenuHandler::Get1Pick(pk);
  304.         }
  305.         catch(ComException & ce)
  306.         {
  307.                 cerr << "Comexception raised in MeasurementMenuHandler::Distance1()" << endl;
  308.                 cerr << "       " << ce.what() << endl;
  309.                 Say(" > ERROR: invalid selection >>> Distance measurement: Select an entity:");
  310.                 pk.CleanUp();
  311.                 parm = 1;
  312.                 return;
  313.         }
  314.     // if a circle or arc was selected, only a point is valid for second pick
  315.     // if a line or segment was selected, a point, line, or segment may be selected second
  316.     // if a point was selected, anything can be selected on the second pick
  317.     SelectionFilter sf;
  318.     if(pk.Type() == CIRCLE || pk.Type() == ARC)
  319.     {
  320.         sf.Add(POINT);
  321.         SetTypeMask(sf);
  322.         Say(" Select a point:");
  323.     }
  324.     else if(pk.Type() == LINE || pk.Type() == SEGMENT)
  325.     {
  326.         sf.Add(POINT);
  327.         sf.Add(LINE);
  328.         sf.Add(SEGMENT);
  329.         SetTypeMask(sf);
  330.         Say(" Select a point, line, or segment");
  331.     }
  332.     else 
  333.     {
  334.         Say(" Select another entity:");
  335.     }
  336.     
  337. // set the new command
  338.     commandStack.pop_back();
  339.     commandStack.push_back(MEASUREMENT_DISTANCE2);
  340.  
  341. // highlight
  342.     SetHighlight(pk,true);
  343.     Redraw();
  344.  
  345. // save the pick
  346.     pk.Lock();
  347.     PushPick(pk,button);
  348.  
  349. // set the parm count
  350.     parm = 1;
  351.  
  352. }
  353. //===========================================================================
  354. void MeasurementMenuHandler::Distance2()
  355. {
  356.         Pick pk1,pk2;
  357.         int button1,button2;
  358.     double d;
  359.  
  360. // get the second pick
  361.         try
  362.         {
  363.                 button2 = MenuHandler::Get1Pick(pk2);
  364.         }
  365.         catch(ComException& ce)
  366.         {       // pick 2 is bad - ignore it.
  367.                 cerr << "ComException raised in MeasurementMenuHandler::Distance2()" << endl;
  368.                 cerr << "        " << ce.what() << endl;
  369.                 Say(" > Selection invalid. Reselect second entity.");
  370.                 pk2.CleanUp();
  371.                 parm = 1;
  372.                 return;
  373.         }
  374.     // get the first pick again
  375.         try
  376.         {
  377.                 button1 = MenuHandler::Get1Pick(pk1);
  378.         }
  379.         catch(ComException& ce)
  380.         {
  381.         // pick 1 has gone bad  - reset the function
  382.                 cerr << "ComException raised in MeasurementMenuHandler::Distance2()" << endl;
  383.                 cerr << "        " << ce.what() << endl;
  384.                 Say("ERROR: first selection lost! -> resetting...");
  385.                 goto reinit;
  386.         }
  387. // process different combinations
  388. // point vs. point
  389.     if(pk1.Type() == POINT && pk2.Type() == POINT)
  390.     {
  391.         Point p1 = GetPointFromPick(pk1);
  392.         Point p2 = GetPointFromPick(pk2);
  393.         d = p1.Distance(p2);
  394.     }
  395. // point vs. line/segment
  396. // point vs. circle
  397. // point vs. arc
  398.     else if( pk1.Type() == POINT || pk2.Type() == POINT)
  399.     {
  400.         Point p;
  401.         if(pk1.Type() == LINE || pk1.Type() == SEGMENT || pk2.Type() == LINE || pk2.Type() == SEGMENT)
  402.         {
  403.             Line l;
  404.             if(pk1.Type() == POINT)
  405.             {
  406.                 p = GetPointFromPick(pk1);
  407.                 l = GetLineFromPick(pk2);
  408.             }
  409.             else
  410.             {
  411.                 p = GetPointFromPick(pk2);
  412.                 l = GetLineFromPick(pk1);
  413.             }
  414.             d = l.Distance(p);
  415.         }
  416.         else if(pk1.Type() == CIRCLE || pk2.Type() == CIRCLE)
  417.         {
  418.             Circle c;
  419.             if(pk1.Type() == POINT)
  420.             {
  421.                 p = GetPointFromPick(pk1);
  422.                 c = GetCircleFromPick(pk2);
  423.             }
  424.             else
  425.             {
  426.                 p = GetPointFromPick(pk2);
  427.                 c = GetCircleFromPick(pk1);
  428.             }
  429.             d = c.Distance(p);
  430.         }
  431.         else if(pk1.Type() == ARC || pk2.Type() == ARC)
  432.         {
  433.             Arc a;
  434.             if(pk1.Type() == POINT)
  435.             {
  436.                 p = GetPointFromPick(pk1);
  437.                 a = GetArcFromPick(pk2);
  438.             }
  439.             else
  440.             {
  441.                 p = GetPointFromPick(pk2);
  442.                 a = GetArcFromPick(pk1);
  443.             }
  444.             d = a.Distance(p);
  445.         }
  446.     }
  447.     else if((pk1.Type() == LINE || pk1.Type() == SEGMENT) && (pk2.Type() == LINE || pk2.Type() == SEGMENT))
  448.     {
  449.         Line l1 = GetLineFromPick(pk1);
  450.         Line l2 = GetLineFromPick(pk2);
  451.         Vector v1 = l1.Direction();
  452.         Vector v2 = l2.Direction();
  453.         if(Angle(v1,v2) > Point::NullAngle)
  454.         {
  455.             note->Notice("Lines/Segments are not parallel");
  456.             goto reinit;
  457.         }
  458.         d = l1.Distance(l2.Origin());
  459.     }
  460.     else 
  461.     {
  462.         note->Notice("Error: unexpected combination... distance computation not implemented");
  463.         goto reinit;
  464.     }
  465.     {
  466.         ostrstream out;
  467.         out << "Distance = " << d << ends;
  468.         note->Notice(out.str());
  469.     }
  470. reinit:
  471. // highlight
  472.     SetHighlight(pk1,false);
  473.     Redraw();
  474.     pk1.Unlock();
  475.     pk2.Unlock();
  476.     pk1.CleanUp();
  477.     pk2.CleanUp();
  478.     commandStack.pop_back();
  479.     commandStack.push_back(MEASUREMENT_DISTANCE1);    
  480.     parm = 1;
  481.     Say(NULL);
  482.     Say("> Distance measurment: Select an entity: ");
  483.     
  484. // line/segment vs. line/segment
  485.  
  486. }
  487. //===========================================================================
  488. void MeasurementMenuHandler::Angle0()
  489. {
  490.     Initialize();
  491.     commandStack.push_back(MEASUREMENT_ANGLE1);
  492.     SelectionFilter sf;
  493.     sf.Add(LINE);
  494.     sf.Add(SEGMENT);
  495.     SetTypeMask(sf);
  496.     parm = 1;
  497.     Say(NULL);
  498.     Say("> Angle measurment: Select a line or segment: ");
  499. }
  500. //===========================================================================
  501. void MeasurementMenuHandler::Angle1()
  502. {
  503. // check the pick out
  504.         Pick pk;
  505.         int button;
  506.         try
  507.         {
  508.                 button = MenuHandler::Get1Pick(pk);
  509.         }
  510.         catch(ComException & ce)
  511.         {
  512.                 cerr << "Comexception raised in MeasurementMenuHandler::Angle1()" << endl;
  513.                 cerr << "       " << ce.what() << endl;
  514.                 Say(" > ERROR: invalid selection >>> Angle measurement: Select a line or segment:");
  515.                 pk.CleanUp();
  516.                 parm = 1;
  517.                 return;
  518.         }
  519.     if(pk.Type() != LINE && pk.Type() != SEGMENT)
  520.     {
  521.                 Say(" > ERROR: invalid selection >>> Angle measurement: Select a line or segment:");
  522.                 pk.CleanUp();
  523.                 parm = 1;
  524.                 return;
  525.     }
  526. // set the new command
  527.     commandStack.pop_back();
  528.     commandStack.push_back(MEASUREMENT_ANGLE2);
  529.  
  530. // highlight the first pick
  531.     SetHighlight(pk,true);
  532.     Redraw();
  533.  
  534. // save the pick
  535.     pk.Lock();
  536.     PushPick(pk,button);
  537.  
  538. // set the parm count
  539.     parm = 1;
  540.  
  541. }
  542. //===========================================================================
  543. void MeasurementMenuHandler::Angle2()
  544. {
  545.         Pick pk1,pk2;
  546.         int button1,button2;
  547.  
  548. // get the second pick
  549.         try
  550.         {
  551.                 button2 = MenuHandler::Get1Pick(pk2);
  552.         }
  553.         catch(ComException& ce)
  554.         {       // pick 2 is bad - ignore it.
  555.                 cerr << "ComException raised in MeasurementMenuHandler::Angle2()" << endl;
  556.                 cerr << "        " << ce.what() << endl;
  557.                 Say(" > Selection invalid. Reselect second line or segment.");
  558.                 pk2.CleanUp();
  559.                 parm = 1;
  560.                 return;
  561.         }
  562.     // get the first pick again
  563.         try
  564.         {
  565.                 button1 = MenuHandler::Get1Pick(pk1);
  566.         }
  567.         catch(ComException& ce)
  568.         {
  569.         // pick 1 has gone bad  - reset the function
  570.                 cerr << "ComException raised in MeasurementMenuHandler::Angle2()" << endl;
  571.                 cerr << "        " << ce.what() << endl;
  572.                 Say("ERROR: first selection lost! -> resetting...");
  573.                 goto reinit;
  574.         }
  575.     // check the pick types
  576.     if((pk1.Type() != LINE && pk1.Type() != SEGMENT) || (pk2.Type() != LINE && pk2.Type() != SEGMENT))
  577.     {
  578.                 Say("ERROR: a selection is not a line or segment -> resetting...");
  579.                 goto reinit;
  580.     }
  581.     {
  582.     // get two lines
  583.         Line l1 = GetLineFromPick(pk1);
  584.         Line l2 = GetLineFromPick(pk2);
  585.     // get the angle
  586.         Vector v1 = l1.Direction();
  587.         Vector v2 = l2.Direction();
  588.         double a1 = Angle(v1,v2)*180/M_PI;
  589.         double a2 = 180. - a1;
  590.     // display the dialog
  591.         ostrstream out;
  592.         out << "Angle = " << a1 << " degrees \nComplement = " << a2 << " degrees" << ends;
  593.         note->Notice(out.str());
  594.     // reset prompt string
  595.         Say(NULL);
  596.     }
  597.     // reinitialize
  598. reinit:
  599.     SetHighlight(pk1,false);
  600.     Redraw();
  601.     pk1.Unlock();
  602.     pk2.Unlock();
  603.     pk1.CleanUp();
  604.     pk2.CleanUp();
  605.     commandStack.pop_back();
  606.     commandStack.push_back(MEASUREMENT_ANGLE1);    
  607.     parm = 1;
  608.     Say("> Angle measurment: Select a line or segment: ");
  609. }
  610.         
  611.  
  612.