home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Linux / Divers / freedraft.tar.gz / freedraft.tar / FREEdraft-050298 / CORE / selectstack.cpp < prev    next >
C/C++ Source or Header  |  1998-04-19  |  6KB  |  195 lines

  1. // selectstack.cpp
  2.  
  3. // Copyright (C) 1997  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.LIB); if not, write to the        //
  17. // Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. //
  18.  
  19. #include <selectstack.h>
  20. #include <data_enum.h>
  21. #include <engineutility.h>
  22. #include <geom_enum.h>
  23. #include <selectionfilter.h>
  24. #include <coreexception.h>
  25.  
  26. // SelectStack types are used to a list of screen selected entities from 
  27. // the VDGLCanvas back to the vdCmdWindow
  28.  
  29.  
  30. SelectStack::SelectStack(int b, const Point& p) : pickedPoint(p), button(b) { } 
  31.  
  32. SelectStack::SelectStack(const SelectStack& ss)
  33. {
  34.         selectedEntities = ss.selectedEntities;
  35.     pickedPoint = ss.pickedPoint;
  36.     button = ss.button;
  37. }
  38.  
  39. SelectStack& SelectStack::operator=(const SelectStack& ss)
  40. {
  41.         selectedEntities = ss.selectedEntities;
  42.     pickedPoint = ss.pickedPoint;
  43.     button = ss.button;
  44.     return *this;
  45. }
  46.  
  47. Point SelectStack::GetPoint() const
  48. {
  49.     return pickedPoint;
  50. }
  51.  
  52. void SelectStack::Push(const Handle& h)
  53. {
  54.     selectedEntities.push_back(h);
  55. }
  56.  
  57. int SelectStack::Size() const
  58. {
  59.     return selectedEntities.size();
  60. }
  61.  
  62. Handle SelectStack::operator[](unsigned int idx) const throw (CoreException)
  63. {
  64.     if(idx > selectedEntities.size() )
  65.         throw CoreException("SelectStack::operator[]() : mindex exceeds size");
  66.     return selectedEntities[idx];
  67. }
  68.  
  69.  
  70. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++==
  71.  
  72. SelectStack SelectStack::Filter(const SelectionFilter& sf) const
  73.  
  74. {
  75.  
  76.  
  77.     if(sf.Size()==0)return SelectStack(*this);
  78.  
  79.  
  80. // create empty new selectstack 
  81.     vector<Handle> handleStack;
  82.  
  83.  
  84. // process each item in this SelectStack.
  85.  
  86. // read the entries
  87. //    int deep =0;
  88.     vector<Handle>::const_iterator hi = selectedEntities.begin();
  89.     while(hi != selectedEntities.end()){
  90.  
  91. // filter for type
  92.         if(Handle(*hi).Type() == sf)
  93.         {
  94.             handleStack.push_back(Handle(*hi));
  95.         }
  96.         hi++;
  97.     }
  98.  
  99.     if(sf.Criteria() == CLOSEST)    // currently returns only the closest solution
  100.     {                // should be return the $depth closest solutions... oh well.
  101.         Handle answer[NUM_BUTTONS];    
  102.             int valueArray[NUM_BUTTONS];
  103. #include <valuearray.cpp_>
  104.         double d;
  105.         double distance[NUM_BUTTONS];
  106.         for(unsigned int i=0; i < NUM_BUTTONS; i++){ distance[i]=10000.; }
  107.  
  108.         for(unsigned int n = 0; n <  handleStack.size(); n++)
  109.         {
  110.             d = DistanceHandleToPoint(handleStack[n],pickedPoint); 
  111.         
  112.             for(unsigned int j=0;j<NUM_BUTTONS;j++)
  113.             {
  114.                 if(valueArray[j] == handleStack[n].Type() && d < distance[j])
  115.                 {
  116.                     distance[j] = d;
  117.                     answer[j] = handleStack[n];
  118.                 }
  119.             }
  120.         }
  121.     // assemble a SelectStack containing closest entity of each type.
  122.         SelectStack tmp(button,pickedPoint); // only changed distances
  123.         for(int i=0; i<NUM_BUTTONS; i++){ if(distance[i] < 9999.)tmp.Push(answer[i]); }
  124.         return tmp;
  125.     }
  126.  
  127.     else                // No Criteria
  128.     {
  129.         SelectStack tmp(button,pickedPoint);
  130.  
  131.         vector<Handle>::iterator j = handleStack.begin();
  132.         while(j != handleStack.end())
  133.         {
  134.             tmp.Push(Handle(*j));
  135.             j++;
  136.         }
  137.         return tmp;
  138.     }
  139. }
  140. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++==
  141. // returns the handle at the top of the
  142. // selected entities
  143.  
  144. Handle SelectStack::Top() const throw (CoreException)
  145. {
  146.     if(selectedEntities.size()==0)
  147.         throw CoreException("SelectStack::Top() :  zero selected entities");
  148.     return Handle(*selectedEntities.rbegin());
  149. }
  150. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++==
  151.  
  152. // returns the Selection - handle,
  153. //pick point, and button, at the top of the selected entities
  154.  
  155. Selection SelectStack::SelectTop() const throw (CoreException) 
  156. {
  157.     if(selectedEntities.size()==0)
  158.         throw CoreException("SelectStack::SelectTop() :  zero selected entities");
  159.     return Selection(Handle(*selectedEntities.begin()), pickedPoint,button);
  160. }
  161. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++==
  162.     
  163. Handle SelectStack::Pop() throw (CoreException)
  164. {
  165.     if(selectedEntities.size()==0)
  166.         throw CoreException("SelectStack::Pop() : zero selected entities");
  167.     Handle tmp(*selectedEntities.rbegin());
  168.     selectedEntities.pop_back();
  169.     return tmp;
  170. }
  171. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++==
  172.  
  173. Handle SelectStack::TopofType(int type) throw (CoreException)
  174. {
  175.     
  176.     if(selectedEntities.size()==0)
  177.         throw CoreException("SelectStack::TopofType() : zero selected entities");
  178.  
  179.     vector<Handle>::reverse_iterator i = selectedEntities.rbegin();
  180.  
  181.     while(i != selectedEntities.rend()){
  182.         if( Handle(*i).Type() == type)return Handle(*i);
  183.         i++;
  184.     }
  185.     throw CoreException("SelectStack::TopOfType() : requested type not found in selection");
  186. }
  187. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++==
  188.  
  189.  
  190. ostream& operator<<(ostream& os, const SelectStack& ss)
  191. {
  192.     return os << "SelectStack: button = " << ss.button << " pickedPoint = " << ss.pickedPoint << 
  193.     " size = " << ss.selectedEntities.size() << '\n';
  194. }
  195.