LibreCAD
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
lc::EntityContainer< CT > Class Template Reference

The EntityContainer class manages a set of entities. This call will allow to select (but not manipulate) entities. More...

#include <entitycontainer.h>

Collaboration diagram for lc::EntityContainer< CT >:

Public Member Functions

 EntityContainer ()
 EntityContainer Default constructor. Usually you would retrieve a EntityContainer from the document. More...
 
 EntityContainer (const EntityContainer &other)
 EntityContainer Copy Constructor. More...
 
virtual ~EntityContainer ()
 
EntityContaineroperator= (const EntityContainer &ec)
 
void insert (CT entity)
 add an entity to the EntityContainer If the entity already exists, it will be replaced More...
 
void combine (const EntityContainer &entities)
 Add all entities to this container Any entity that already exists will get replaced. More...
 
void remove (CT entity)
 remove an Entity from the document. More...
 
std::vector< CT > asVector (short maxLevel=std::numeric_limits< short >::max()) const
 asVector return all entities as std::vector optionally up until a given level This is useful to return entities for screen rendering where you don't want to render very small entities (< XX pixels) More...
 
CT entityByID (ID_DATATYPE id) const
 entityByID return a entity by it's id, return's a empty shared ptr when not found More...
 
EntityContainer entitiesByLayer (const Layer_CSPtr layer) const
 findEntitiesByLayer Return a entities container with all entities from a specific layer More...
 
EntityContainer entitiesByMetaType (const std::string &metaName) const
 entitiesByMetaType Return all entities that contain's a specific metaInfo More...
 
EntityContainer entitiesFullWithinArea (const geo::Area &area, const short maxLevel=std::numeric_limits< short >::max()) const
 entitiesByArea Find all entities within a selected area based on boundingbox of the entities More...
 
geo::Area boundingBox () const
 
EntityContainer entitiesWithinAndCrossingArea (const geo::Area &area, const short maxLevel=std::numeric_limits< short >::max()) const
 entitiesWithinAndCrossingArea Find all entities within a selected area or where the path is crossing the area bounderies More...
 
EntityContainer entitiesWithinAndCrossingAreaFast (const geo::Area &area, const short maxLevel=std::numeric_limits< short >::max()) const
 entitiesWithinAndCrossingAreaFast Find all entities within a selected area. Unlike entitiesWithinAndCrossingArea it this will return entities based on it's boundig box. That means that the resulting EntityContainer may or may not have entities which are visible. More...
 
std::vector< lc::EntityDistancegetEntityPathsNearCoordinate (const lc::geo::Coordinate &point, double distance) const
 getEntityPathsNearCoordinate More...
 
lc::geo::Area bounds () const
 bound returns the size of the document More...
 
void optimise ()
 optimise this container More...
 
template<typename U , typename T >
void each (T func)
 
template<typename U , typename T >
void each (T func) const
 

Private Attributes

QuadTree< CT > * _tree
 

Detailed Description

template<typename CT>
class lc::EntityContainer< CT >

The EntityContainer class manages a set of entities. This call will allow to select (but not manipulate) entities.

Considerations: Make the underlaying entities older configurable. At this moment a quad tree is used but we could add a option to also support a simple map. When the never of entities are low this might be a little fast, but marginally... A other option could be is to configure the quadtree to set a large number of objects

Todo:
once a while we should create a new entity container to setup the root bounds correctly this would normally not needed when getting a copy. This can be added within the optimise method?

Definition at line 33 of file entitycontainer.h.

Constructor & Destructor Documentation

template<typename CT>
lc::EntityContainer< CT >::EntityContainer ( )
inline

EntityContainer Default constructor. Usually you would retrieve a EntityContainer from the document.

Definition at line 40 of file entitycontainer.h.

40  {
41  _tree = new QuadTree<CT>(geo::Area(geo::Coordinate(-500000., -500000.),
42  geo::Coordinate(500000., 500000.)
43  ));
44  }
QuadTree< CT > * _tree
template<typename CT>
lc::EntityContainer< CT >::EntityContainer ( const EntityContainer< CT > &  other)
inline

EntityContainer Copy Constructor.

Definition at line 50 of file entitycontainer.h.

50  {
51  _tree = new QuadTree<CT>(*other._tree);
52  }
QuadTree< CT > * _tree
template<typename CT>
virtual lc::EntityContainer< CT >::~EntityContainer ( )
inlinevirtual

Definition at line 55 of file entitycontainer.h.

55  {
56  delete _tree;
57  }
QuadTree< CT > * _tree

Member Function Documentation

template<typename CT>
std::vector<CT> lc::EntityContainer< CT >::asVector ( short  maxLevel = std::numeric_limits<short>::max()) const
inline

asVector return all entities as std::vector optionally up until a given level This is useful to return entities for screen rendering where you don't want to render very small entities (< XX pixels)

Returns

Definition at line 103 of file entitycontainer.h.

103  {
104  return _tree->retrieve(maxLevel);
105  }
std::vector< E > retrieve(const geo::Area &area, const short maxLevel=SHRT_MAX) const
retrieve all object's that are located within a given area
Definition: quadtree.h:172
QuadTree< CT > * _tree
template<typename CT>
geo::Area lc::EntityContainer< CT >::boundingBox ( ) const
inline

Calculate boundingBox of all entities in this container

Definition at line 179 of file entitycontainer.h.

179  {
180  geo::Area extends;
181  const std::vector<CT> entities = _tree->retrieve();
182  if (entities.size() > 0) {
183  extends = entities[0]->boundingBox();
184  for (const auto &i : entities) {
185  extends = extends.merge(i->boundingBox());
186  }
187  }
188  return extends;
189  }
std::vector< E > retrieve(const geo::Area &area, const short maxLevel=SHRT_MAX) const
retrieve all object's that are located within a given area
Definition: quadtree.h:172
QuadTree< CT > * _tree
template<typename CT>
lc::geo::Area lc::EntityContainer< CT >::bounds ( ) const
inline

bound returns the size of the document

Returns

Definition at line 322 of file entitycontainer.h.

322  {
323  return _tree->bounds();
324  }
geo::Area bounds() const
bounds of the root portion of the tree
Definition: quadtree.h:223
QuadTree< CT > * _tree
template<typename CT>
void lc::EntityContainer< CT >::combine ( const EntityContainer< CT > &  entities)
inline

Add all entities to this container Any entity that already exists will get replaced.

Parameters
EntityContainerto be combined to the document.

Definition at line 82 of file entitycontainer.h.

82  {
83  for (auto i : entities.asVector(std::numeric_limits<short>::max())) {
84  _tree->insert(i);
85  }
86  }
QuadTree< CT > * _tree
void insert(const E entity)
insert Insert entity into the quad tree
Definition: quadtree.h:541
template<typename CT>
template<typename U , typename T >
void lc::EntityContainer< CT >::each ( func)
inline

Each allows to run a function of all set's of object's within this container

Example:

 LcDrawOptions lcDrawOptions;
 _entityContainer.each< LCVDrawItem >([&](LCVDrawItem_SPtr item) {
     item->draw(painter, &lcDrawOptions, _visibleUserArea);
 });

Definition at line 346 of file entitycontainer.h.

346  {
347  _tree->template each<U>(func);
348  }
QuadTree< CT > * _tree
template<typename CT>
template<typename U , typename T >
void lc::EntityContainer< CT >::each ( func) const
inline

Definition at line 350 of file entitycontainer.h.

350  {
351  _tree->template each<const U>(func);
352  }
QuadTree< CT > * _tree
template<typename CT>
EntityContainer lc::EntityContainer< CT >::entitiesByLayer ( const Layer_CSPtr  layer) const
inline

findEntitiesByLayer Return a entities container with all entities from a specific layer

Parameters
layer
Returns

Definition at line 122 of file entitycontainer.h.

122  {
123  EntityContainer container;
124 
125  for (auto i : asVector(std::numeric_limits<short>::max())) {
126  if (i->layer() == layer) {
127  container.insert(i);
128  }
129  }
130 
131  return container;
132  }
EntityContainer()
EntityContainer Default constructor. Usually you would retrieve a EntityContainer from the document...
std::vector< CT > asVector(short maxLevel=std::numeric_limits< short >::max()) const
asVector return all entities as std::vector optionally up until a given level This is useful to retur...
template<typename CT>
EntityContainer lc::EntityContainer< CT >::entitiesByMetaType ( const std::string &  metaName) const
inline

entitiesByMetaType Return all entities that contain's a specific metaInfo

Parameters
metaTypeName: this does nothing
Returns

Definition at line 141 of file entitycontainer.h.

141  {
142  EntityContainer container;
143 
144  for (auto i : asVector(std::numeric_limits<short>::max())) {
145  // if (i->metaInfo(metaName) != nullptr) {
146  // container.insert(i);
147  // }
148  }
149 
150  return container;
151  }
EntityContainer()
EntityContainer Default constructor. Usually you would retrieve a EntityContainer from the document...
std::vector< CT > asVector(short maxLevel=std::numeric_limits< short >::max()) const
asVector return all entities as std::vector optionally up until a given level This is useful to retur...
template<typename CT>
EntityContainer lc::EntityContainer< CT >::entitiesFullWithinArea ( const geo::Area area,
const short  maxLevel = std::numeric_limits<short>::max() 
) const
inline

entitiesByArea Find all entities within a selected area based on boundingbox of the entities

Parameters
area
Returns
TODO: Consider giving a container to drop entities into. This can be used for example during drawing where we don't require a QuadTree but just a linear array of entities tobe drawn

Definition at line 161 of file entitycontainer.h.

162  {
163  EntityContainer container;
164  std::vector<CT> entities = _tree->retrieve(area, maxLevel);
165 
166  for (auto i : entities) {
167  // If the item fully with's with the selection area sinmply add it
168  if (i->boundingBox().inArea(area)) {
169  container.insert(i);
170  }
171  }
172 
173  return container;
174  }
std::vector< E > retrieve(const geo::Area &area, const short maxLevel=SHRT_MAX) const
retrieve all object's that are located within a given area
Definition: quadtree.h:172
QuadTree< CT > * _tree
EntityContainer()
EntityContainer Default constructor. Usually you would retrieve a EntityContainer from the document...
template<typename CT>
EntityContainer lc::EntityContainer< CT >::entitiesWithinAndCrossingArea ( const geo::Area area,
const short  maxLevel = std::numeric_limits<short>::max() 
) const
inline

entitiesWithinAndCrossingArea Find all entities within a selected area or where the path is crossing the area bounderies

Parameters
area
Returns

TODO: create a version like this to get a rought estimate of what's located within a area this can be used to accelerate drawing performance. TODO: Consider giving a container to drop entities into. This can be used for example during drawing where we don't require a QuadTree but just a linear array of entities tobe drawn

Definition at line 203 of file entitycontainer.h.

204  {
205  EntityContainer container;
206  std::vector<CT> entities = _tree->retrieve(area, maxLevel);
207 
208  for (auto i : entities) {
209 
210  // If the item fully with's with the selection area sinmply add it
211  if (i->boundingBox().inArea(area)) {
212  container.insert(i);
213  continue;
214  }
215 
216  // if it has 2 corners inside area, we know for 100% sure that the entity, or
217  // at least part of it is located within area
218  // We test for 2 (not 1) because for exampke with a arc we can have one corner inside
219  // The area, but still not intersecting with area
220  auto c = i->boundingBox().numCornersInside(area);
221 
222  if (c == 2) {
223  container.insert(i);
224  continue;
225  }
226 
227  // Path to area intersection testing
228  lc::Intersect intersect(Intersect::OnEntity, 10e-4);
229 
230  auto &&v = area.top();
231  visitorDispatcher<bool, lc::GeoEntityVisitor>(intersect, v, *i.get());
232  if (!intersect.result().empty()) {
233  container.insert(i);
234  continue;
235  }
236 
237  v = area.left();
238  visitorDispatcher<bool, GeoEntityVisitor>(intersect, v, *i.get());
239  if (!intersect.result().empty()) {
240  container.insert(i);
241  continue;
242  }
243 
244  v = area.bottom();
245  visitorDispatcher<bool, GeoEntityVisitor>(intersect, v, *i.get());
246  if (!intersect.result().empty()) {
247  container.insert(i);
248  continue;
249  }
250 
251  v = area.right();
252  visitorDispatcher<bool, GeoEntityVisitor>(intersect, v, *i.get());
253  if (!intersect.result().empty()) {
254  container.insert(i);
255  continue;
256  }
257  }
258 
259  return container;
260  }
calculate the intersection pojnts of 2 entities
Definition: intersect.h:35
std::vector< E > retrieve(const geo::Area &area, const short maxLevel=SHRT_MAX) const
retrieve all object's that are located within a given area
Definition: quadtree.h:172
QuadTree< CT > * _tree
EntityContainer()
EntityContainer Default constructor. Usually you would retrieve a EntityContainer from the document...
template<typename CT>
EntityContainer lc::EntityContainer< CT >::entitiesWithinAndCrossingAreaFast ( const geo::Area area,
const short  maxLevel = std::numeric_limits<short>::max() 
) const
inline

entitiesWithinAndCrossingAreaFast Find all entities within a selected area. Unlike entitiesWithinAndCrossingArea it this will return entities based on it's boundig box. That means that the resulting EntityContainer may or may not have entities which are visible.

Returns

Definition at line 272 of file entitycontainer.h.

273  {
274  EntityContainer container;
275 
276  std::vector<CT> &&entities = _tree->retrieve(area, maxLevel);
277 
278  for (auto &i : entities) {
279  // If the item fully with's with the selection area simply add it
280  if (i->boundingBox().overlaps(area)) {
281  container.insert(i);
282  }
283  }
284 
285  return container;
286  }
std::vector< E > retrieve(const geo::Area &area, const short maxLevel=SHRT_MAX) const
retrieve all object's that are located within a given area
Definition: quadtree.h:172
QuadTree< CT > * _tree
EntityContainer()
EntityContainer Default constructor. Usually you would retrieve a EntityContainer from the document...
template<typename CT>
CT lc::EntityContainer< CT >::entityByID ( ID_DATATYPE  id) const
inline

entityByID return a entity by it's id, return's a empty shared ptr when not found

Parameters
id
Returns

Definition at line 112 of file entitycontainer.h.

112  {
113  return _tree->entityByID(id);
114  }
const E entityByID(ID_DATATYPE id) const
Definition: quadtree.h:583
QuadTree< CT > * _tree
template<typename CT>
std::vector<lc::EntityDistance> lc::EntityContainer< CT >::getEntityPathsNearCoordinate ( const lc::geo::Coordinate point,
double  distance 
) const
inline

getEntityPathsNearCoordinate

Parameters
pointpoint where to look for entities
distancemaximum distance from this point where the function would consider adding it to a list
Returns
List of entities near this coordinate. THis includes entities where it's path is close to point

Definition at line 294 of file entitycontainer.h.

295  {
296 
297  const auto area = lc::geo::Area(lc::geo::Coordinate(point.x(), point.y())+distance/2.,
298  lc::geo::Coordinate(point.x(),point.y())+distance/2.);
299  std::vector<CT> ent = _tree->retrieve(area);
300 
301  // Now calculate for each entity if we are near the entities path
302  std::vector<lc::EntityDistance> entities;
303  for (auto item : ent) {
304  Snapable_CSPtr entity = std::dynamic_pointer_cast<const lc::Snapable>(item);
305 
306  if (entity != nullptr) { // Not all entities might be snapable, so we only test if this is possible.
307  lc::geo::Coordinate eCoordinate = entity->nearestPointOnPath(point);
308  if (eCoordinate.distanceTo(point) < distance) {
309  entities.emplace_back(item, eCoordinate);
310  }
311  }
312  }
313 
314  return entities;
315  }
double x() const
Returns x of Coordinate.
Definition: geocoordinate.h:26
double y() const
Returns y of Coordinate.
Definition: geocoordinate.h:34
std::vector< E > retrieve(const geo::Area &area, const short maxLevel=SHRT_MAX) const
retrieve all object's that are located within a given area
Definition: quadtree.h:172
QuadTree< CT > * _tree
double distanceTo(const geo::Coordinate &c) const
template<typename CT>
void lc::EntityContainer< CT >::insert ( CT  entity)
inline

add an entity to the EntityContainer If the entity already exists, it will be replaced

Parameters
entityentity to be added to the document.

Definition at line 72 of file entitycontainer.h.

72  {
73  _tree->insert(entity);
74  }
QuadTree< CT > * _tree
void insert(const E entity)
insert Insert entity into the quad tree
Definition: quadtree.h:541
template<typename CT>
EntityContainer& lc::EntityContainer< CT >::operator= ( const EntityContainer< CT > &  ec)
inline

Definition at line 59 of file entitycontainer.h.

59  {
60  if (this != &ec) {
61  _tree = new QuadTree<CT>(*ec._tree);
62  }
63 
64  return *this;
65  }
QuadTree< CT > * _tree
template<typename CT>
void lc::EntityContainer< CT >::optimise ( )
inline

optimise this container

Definition at line 330 of file entitycontainer.h.

330  {
331  _tree->optimise();
332  }
bool optimise()
optimise Optmise this tree. Current implementation will remove empty nodes up till the root node ...
Definition: quadtree.h:294
QuadTree< CT > * _tree
template<typename CT>
void lc::EntityContainer< CT >::remove ( CT  entity)
inline

remove an Entity from the document.

Parameters
idEntity ID of entity which is to be removed.

Definition at line 92 of file entitycontainer.h.

92  {
93  _tree->erase(entity);
94  }
bool erase(const E entity)
remove Remove entity from quad tree
Definition: quadtree.h:571
QuadTree< CT > * _tree

Member Data Documentation

template<typename CT>
QuadTree<CT>* lc::EntityContainer< CT >::_tree
private

Definition at line 354 of file entitycontainer.h.


The documentation for this class was generated from the following file: