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 >
Wrap
C/C++ Source or Header
|
1998-04-19
|
6KB
|
195 lines
// selectstack.cpp
// Copyright (C) 1997 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.LIB); if not, write to the //
// Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. //
#include <selectstack.h>
#include <data_enum.h>
#include <engineutility.h>
#include <geom_enum.h>
#include <selectionfilter.h>
#include <coreexception.h>
// SelectStack types are used to a list of screen selected entities from
// the VDGLCanvas back to the vdCmdWindow
SelectStack::SelectStack(int b, const Point& p) : pickedPoint(p), button(b) { }
SelectStack::SelectStack(const SelectStack& ss)
{
selectedEntities = ss.selectedEntities;
pickedPoint = ss.pickedPoint;
button = ss.button;
}
SelectStack& SelectStack::operator=(const SelectStack& ss)
{
selectedEntities = ss.selectedEntities;
pickedPoint = ss.pickedPoint;
button = ss.button;
return *this;
}
Point SelectStack::GetPoint() const
{
return pickedPoint;
}
void SelectStack::Push(const Handle& h)
{
selectedEntities.push_back(h);
}
int SelectStack::Size() const
{
return selectedEntities.size();
}
Handle SelectStack::operator[](unsigned int idx) const throw (CoreException)
{
if(idx > selectedEntities.size() )
throw CoreException("SelectStack::operator[]() : mindex exceeds size");
return selectedEntities[idx];
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++==
SelectStack SelectStack::Filter(const SelectionFilter& sf) const
{
if(sf.Size()==0)return SelectStack(*this);
// create empty new selectstack
vector<Handle> handleStack;
// process each item in this SelectStack.
// read the entries
// int deep =0;
vector<Handle>::const_iterator hi = selectedEntities.begin();
while(hi != selectedEntities.end()){
// filter for type
if(Handle(*hi).Type() == sf)
{
handleStack.push_back(Handle(*hi));
}
hi++;
}
if(sf.Criteria() == CLOSEST) // currently returns only the closest solution
{ // should be return the $depth closest solutions... oh well.
Handle answer[NUM_BUTTONS];
int valueArray[NUM_BUTTONS];
#include <valuearray.cpp_>
double d;
double distance[NUM_BUTTONS];
for(unsigned int i=0; i < NUM_BUTTONS; i++){ distance[i]=10000.; }
for(unsigned int n = 0; n < handleStack.size(); n++)
{
d = DistanceHandleToPoint(handleStack[n],pickedPoint);
for(unsigned int j=0;j<NUM_BUTTONS;j++)
{
if(valueArray[j] == handleStack[n].Type() && d < distance[j])
{
distance[j] = d;
answer[j] = handleStack[n];
}
}
}
// assemble a SelectStack containing closest entity of each type.
SelectStack tmp(button,pickedPoint); // only changed distances
for(int i=0; i<NUM_BUTTONS; i++){ if(distance[i] < 9999.)tmp.Push(answer[i]); }
return tmp;
}
else // No Criteria
{
SelectStack tmp(button,pickedPoint);
vector<Handle>::iterator j = handleStack.begin();
while(j != handleStack.end())
{
tmp.Push(Handle(*j));
j++;
}
return tmp;
}
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++==
// returns the handle at the top of the
// selected entities
Handle SelectStack::Top() const throw (CoreException)
{
if(selectedEntities.size()==0)
throw CoreException("SelectStack::Top() : zero selected entities");
return Handle(*selectedEntities.rbegin());
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++==
// returns the Selection - handle,
//pick point, and button, at the top of the selected entities
Selection SelectStack::SelectTop() const throw (CoreException)
{
if(selectedEntities.size()==0)
throw CoreException("SelectStack::SelectTop() : zero selected entities");
return Selection(Handle(*selectedEntities.begin()), pickedPoint,button);
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++==
Handle SelectStack::Pop() throw (CoreException)
{
if(selectedEntities.size()==0)
throw CoreException("SelectStack::Pop() : zero selected entities");
Handle tmp(*selectedEntities.rbegin());
selectedEntities.pop_back();
return tmp;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++==
Handle SelectStack::TopofType(int type) throw (CoreException)
{
if(selectedEntities.size()==0)
throw CoreException("SelectStack::TopofType() : zero selected entities");
vector<Handle>::reverse_iterator i = selectedEntities.rbegin();
while(i != selectedEntities.rend()){
if( Handle(*i).Type() == type)return Handle(*i);
i++;
}
throw CoreException("SelectStack::TopOfType() : requested type not found in selection");
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++==
ostream& operator<<(ostream& os, const SelectStack& ss)
{
return os << "SelectStack: button = " << ss.button << " pickedPoint = " << ss.pickedPoint <<
" size = " << ss.selectedEntities.size() << '\n';
}