API Documentation
Loading...
Searching...
No Matches
SelectionArea.hpp
Go to the documentation of this file.
1/*--------------------------------------------------------------------------------------------
2Copyright (c) 2019, NDEVR LLC
3tyler.parke@ndevr.org
4 __ __ ____ _____ __ __ _______
5 | \ | | | __ \ | ___|\ \ / / | __ \
6 | \ | | | | \ \ | |___ \ \ / / | |__) |
7 | . \| | | |__/ / | |___ \ V / | _ /
8 | |\ |_|_____/__|_____|___\_/____| | \ \
9 |__| \__________________________________| \__\
10
11Subject to the terms of the Enterprise+ Agreement, NDEVR hereby grants
12Licensee a limited, non-exclusive, non-transferable, royalty-free license
13(without the right to sublicense) to use the API solely for the purpose of
14Licensee's internal development efforts to develop applications for which
15the API was provided.
16
17The above copyright notice and this permission notice shall be included in all
18copies or substantial portions of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
21INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
22PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
23FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25DEALINGS IN THE SOFTWARE.
26
27Library: Base
28File: SelectionArea
29Included in API: True
30Author(s): Tyler Parke
31 *-----------------------------------------------------------------------------------------**/
32#pragma once
33#include <NDEVR/LineSegment.h>
34#include <NDEVR/Polygon.h>
35#include <NDEVR/RadialObject.h>
36#include <NDEVR/Bounds.h>
37#include <NDEVR/Matrix.h>
38#include <NDEVR/Intersection.h>
39#include <NDEVR/Plane.h>
40namespace NDEVR
41{
42 /**--------------------------------------------------------------------------------------------------
43 The type of selection used.
44 **/
53
54 /**--------------------------------------------------------------------------------------------------
55 \brief An area of N-dimensional space that is considered selected
56 **/
57 template<uint01 t_dims, class t_type>
59 {
60 public:
62 : m_point(Constant<Vertex<t_dims, t_type>>::Invalid)
65 , m_is_inverse(false)
66 , m_is_enabled(true)
67 {}
68
70 : m_matrix(area.m_matrix)
74 , m_mode(area.m_mode)
78 {
79 switch(m_mode)
80 {
81 case e_selection_point: m_point = area.m_point; break;
82 case e_selection_line: m_line = area.m_line; break;
83 case e_selection_bounds: m_bounds = area.m_bounds; break;
85 case e_selection_plane: m_plane = area.m_plane; break;
86 default: lib_assert(false, "unknown selection copy");
87 }
88 }
97 : m_line(segment)
100 , m_is_inverse(false)
101 , m_is_enabled(true)
102 {}
103
105 : m_polygon(poly)
108 , m_is_inverse(false)
109 , m_is_enabled(true)
110 {}
111
113 : m_polygon(std::move(poly))
116 , m_is_inverse(false)
117 , m_is_enabled(true)
118 {}
119
127
135
137 {
138 cleanup();
139 m_mode = area.m_mode;
140 switch(m_mode)
141 {
142 case e_selection_point: m_point = area.m_point; break;
143 case e_selection_line: m_line = area.m_line; break;
144 case e_selection_bounds: m_bounds = area.m_bounds; break;
145 case e_selection_polygon: new (&m_polygon) Polygon<t_type>(area.m_polygon); break;
146 case e_selection_plane: m_plane = area.m_plane; break;
147 default: lib_assert(false, "unknown selection copy");
148 }
151 m_matrix = area.m_matrix;
156 return *this;
157 }
159 {
160 cleanup();
161 }
162
169
171 {
172 cleanup();
174 m_line = segment;
175 }
176
178 {
179 cleanup();
181 new (&m_polygon) Polygon<t_type>(poly);
182 }
183
185 {
186 cleanup();
188 new (&m_polygon) Polygon<t_type>();
189 std::swap(poly, m_polygon);
190 }
191
198
205 SelectionMode mode() const { return m_mode; }
206
207 const Vertex<t_dims, t_type>& point() const { return m_point; }
209
210 const LineSegment<t_dims, t_type>& line() const { return m_line; }
212
213 const Bounds<t_dims, t_type>& bounds() const { return m_bounds; }
215
216 const Polygon<t_type>& polygon() const { return m_polygon; }
218
219 const Plane<t_dims, t_type>& plane() const { return m_plane; }
221
222
223
224 void setTransform(const Matrix<t_type>& matrix)
225 {
226 m_matrix = matrix;
227 m_inverse_matrix = matrix.invert();
228 m_is_pre_transformed = (matrix == Matrix<t_type>(1.0));
229 }
230
232 {
233 if (!IsInvalid(matrix))
234 {
235 m_projection_matrix = matrix;
237 }
238 }
239 const Matrix<t_type>& transform() const
240 {
241 return m_matrix;
242 }
243
245 {
246 return m_projection_matrix;
247 }
249 {
250 return m_inverse_matrix;
251 }
257 {
258 switch (m_mode)
259 {
262 case e_selection_bounds: return m_bounds;
263 case e_selection_polygon: return m_polygon.bounds().template as<t_dims, t_type>();
265 {
267 for (uint01 dim = 0; dim < t_dims; dim++)
268 {
269 if (m_plane.normal[dim] == 1)
270 bounds[dim][MAX] = bounds[dim][MIN] = m_plane.d;
271 else if (m_plane.normal[dim] == -1)
272 bounds[dim][MAX] = bounds[dim][MIN] = -m_plane.d;
273 }
274 return bounds;
275 }
276 default: lib_assert(false, "Unknown selection area mode in as()"); break;
277 }
279 }
280
281 template<uint01 t_new_dims, class t_new_type>
283 {
285 switch (m_mode)
286 {
287 case e_selection_point: new_selection.setSelection(m_point.template as<t_new_dims, t_new_type>()); break;
288 case e_selection_line: new_selection.setSelection(m_line.template as<t_new_dims, t_new_type>()); break;
289 case e_selection_bounds: new_selection.setSelection(m_bounds.template as<t_new_dims, t_new_type>()); break;
290 case e_selection_polygon: new_selection.setSelection(m_polygon.template as<t_new_type>()); break;
291 case e_selection_plane: new_selection.setSelection(m_plane.template as<t_new_dims, t_new_type>()); break;
292 default: lib_assert(false, "Unknown selection area mode in as()"); break;
293 }
295 new_selection.setTransform(m_matrix.template as<t_new_type>());
296 new_selection.setIsInverse(m_is_inverse);
297 new_selection.setIsEnabled(m_is_enabled);
298 return new_selection;
299 }
300 bool isPreTransformed() const
301 {
303 }
304 template<uint01 t_new_dims, class t_new_type>
306 {
308 if (sizeof(t_new_type) > sizeof(t_type))
309 {
310 Matrix<t_new_type> matrix = m_matrix.template as<t_new_type>().invert();
311
312 switch (m_mode)
313 {
314 case e_selection_point: area.setSelection(matrix * m_point.template as<t_new_dims, t_new_type>()); break;
315 case e_selection_line: area.setSelection(matrix * m_line.template as<t_new_dims, t_new_type>()); break;
316 case e_selection_bounds: area.setSelection(matrix * m_bounds.template as<t_new_dims, t_new_type>()); break;
317 case e_selection_polygon: area.setSelection(matrix * m_polygon.template as<t_new_type>()); break;
318 default: lib_assert(false, "Unknown object to pre-transform");
319 }
320 }
321 else//we want higher precision so multiply first
322 {
323 Matrix<t_type> matrix = m_matrix.invert();
324 switch (m_mode)
325 {
326 case e_selection_point: area.setSelection((matrix * m_point).template as<t_new_dims, t_new_type>()); break;
327 case e_selection_line: area.setSelection((matrix * m_line).template as<t_new_dims, t_new_type>()); break;
328 case e_selection_bounds: area.setSelection((matrix * m_bounds).template as<t_new_dims, t_new_type>()); break;
329 case e_selection_polygon: area.setSelection((matrix * m_polygon).template as<t_new_type>()); break;
330 default: lib_assert(false, "Unknown object to pre-transform");
331 }
332 }
336 return area;
337 }
338
340 {
341 switch (m_mode)
342 {
343 case e_selection_point: setSelection(mat * m_point); break;
344 case e_selection_line: setSelection(mat * m_line); break;
345 case e_selection_bounds: setSelection(mat * m_bounds); break;
346 case e_selection_polygon: setSelection(mat * m_polygon); break;
347 default: lib_assert(false, "Unknown object to pre-transform");
348 }
349 }
350 bool isInverse() const
351 {
352 return m_is_inverse;
353 }
354 void setIsInverse(bool is_inverse)
355 {
356 m_is_inverse = is_inverse;
357 }
358 bool isEnabled() const
359 {
360 return m_is_enabled;
361 }
362 void setIsEnabled(bool is_enabled)
363 {
364 m_is_enabled = is_enabled;
365 }
366 bool operator==(const SelectionArea& area) const
367 {
368 if(m_mode != area.m_mode)
369 return false;
370 switch(m_mode)
371 {
373 if(m_bounds != area.m_bounds)
374 return false;
375 break;
377 if(m_line != area.m_line)
378 return false;
379 break;
381 if(m_polygon != area.m_polygon)
382 return false;
383 break;
385 if(m_point != area.m_point)
386 return false;
387 break;
389 if (m_plane != area.m_plane)
390 return false;
391 break;
392 default:
393 lib_assert(false, "unknown selection mode");
394 }
396 }
397 bool operator!=(const SelectionArea& area) const
398 {
399 if(m_mode != area.m_mode)
400 return true;
401 switch(m_mode)
402 {
404 if(m_bounds != area.m_bounds)
405 return true;
406 break;
408 if(m_line != area.m_line)
409 return true;
410 break;
412 if(m_polygon != area.m_polygon)
413 return false;
414 break;
416 if(m_point != area.m_point)
417 return true;
418 break;
420 if (m_plane != area.m_plane)
421 return true;
422 break;
423 default:
424 lib_assert(false, "unknown selection mode");
425 }
427 }
428 protected:
429 void cleanup()
430 {
432 {
433 m_polygon.~Polygon<t_type>();
435 }
436 }
437 protected:
442 union
443 {
449 };
454 };
455
456 /**--------------------------------------------------------------------------------------------------
457 Classifies.
458
459 Author: Tyler Parke
460
461 Date: 2018-03-26
462
463 Parameters:
464 other - The vector.
465 area - The radians.
466
467 \returns The IntersectionTypes.
468 **/
469 template<class t_other_type, uint01 t_dims, class t_type>
470 IntersectionTypes classify(const t_other_type& other, const SelectionArea<t_dims, t_type>& area)
471 {
472 if(!area.isEnabled())
473 {
474 if(area.isInverse())
475 return inside;
476 else
477 return outside;
478 }
479 //t_other_type trans_other = area.isPreTransformed() ? other : area.transform() * other;
480 IntersectionTypes intersection;
481 if (area.isPreTransformed())
482 {
483 switch (area.mode())
484 {
485 case e_selection_line:
486 intersection = classify(other, area.line());
487 break;
489 intersection = classify(other, area.bounds());
490 break;
492 intersection = classify(other, area.polygon());
493 break;
495 intersection = classify(other, area.plane());
496 break;
497 default:
498 lib_assert(false, "unknown intersection");
499 intersection = IntersectionTypes::outside;
500 break;
501 }
502 }
503 else
504 {
505 switch (area.mode())
506 {
507 case e_selection_line:
508 intersection = classify(other, area.inverseTransform() * area.line());
509 break;
511 intersection = classify(other, area.inverseTransform() * area.bounds());
512 break;
514 intersection = classify(area.transform() * other, area.polygon());
515 break;
517 intersection = classify(other, area.inverseTransform() * area.plane());
518 break;
519 default:
520 lib_assert(false, "unknown intersection");
521 intersection = IntersectionTypes::outside;
522 break;
523 }
524 }
525 if(area.isInverse())
526 {
527 switch(intersection)
528 {
529 case outside: intersection = inside; break;
530 case inside: intersection = outside; break;
531 default: break;
532 }
533 }
534 return intersection;
535 }
536 template<class t_other_type, uint01 t_dims, class t_type>
537 IntersectionTypes classify(const SelectionArea<t_dims, t_type>& area, const t_other_type& other)
538 {
539 if(!area.isEnabled())
540 {
541 if(area.isInverse())
542 return inside;
543 else
544 return outside;
545 }
546 IntersectionTypes intersection = outside;
547 if (area.isPreTransformed())
548 {
549 switch (area.mode())
550 {
551 case e_selection_line:
552 intersection = classify(area.line(), other);
553 break;
555 intersection = classify(area.bounds(), other);
556 break;
558 intersection = classify(area.polygon(), other.template as<2, t_type>());
559 break;
561 intersection = classify(area.plane(), other);
562 break;
563 default:
564 break;
565 }
566 }
567 else
568 {
569 switch (area.mode())
570 {
571 case e_selection_line:
572 intersection = classify(area.line(), area.transform() * other);
573 break;
575 intersection = classify(area.bounds(), area.transform() * other);
576 break;
578 intersection = classify(area.polygon(), (area.transform() * other).template as<2, t_type>());
579 break;
581 intersection = classify(area.plane(), area.transform() * other);
582 break;
583 default:
584 break;
585 }
586 }
587 if (area.isInverse())
588 {
589 switch (intersection)
590 {
591 case outside: intersection = inside; break;
592 case inside: intersection = outside; break;
593 default: break;
594 }
595 }
596 return intersection;
597 }
598
599 template<class t_other_type, uint01 t_dims, class t_type>
600 constexpr t_type distanceSquared(const t_other_type& other, const SelectionArea<t_dims, t_type>& area)
601 {
602 return distanceSquared(area, other);
603 }
604 template<class t_other_type, uint01 t_dims, class t_type>
605 constexpr t_type distanceSquared(const SelectionArea<t_dims, t_type>& area, const t_other_type& other)
606 {
607 if (area.isPreTransformed())
608 {
609 switch (area.mode())
610 {
612 return distanceSquared(area.point(), other);
613 case e_selection_line:
614 return distanceSquared(area.line(), other);
616 return distanceSquared(area.polygon(), other);
618 return distanceSquared(area.bounds(), other);
620 //distanceSquared(area.radius(), n_vertex);
621 break;
622 }
623 }
624 else
625 {
626 switch (area.mode())
627 {
629 return distanceSquared(area.point(), area.transform() * other);
630 case e_selection_line:
631 return distanceSquared(area.line(), area.transform() * other);
633 return distanceSquared(area.polygon(), area.transform() * other);
635 return distanceSquared(area.bounds(), area.transform() * other);
637 //distanceSquared(area.radius(), n_vertex);
638 break;
639 }
640 }
642 }
643
644}
#define lib_assert(expression, message)
Definition LibAssert.h:61
A specification of upper and lower bounds in N-dimensions.
Definition Bounds.hpp:52
A line segment represented by two vertices, a start and end.
Definition Line.hpp:49
Definition Matrix.hpp:176
Matrix< t_type, t_cols, t_rows > invert() const
Definition Matrix.hpp:652
Logic for a given plane or N-dimensions. Planes are coordinate systems of one less dimension than the...
Definition Geometry.h:41
An N-sided polygon.
Definition Polygon.hpp:53
An area of N-dimensional space that is considered selected.
Definition SelectionArea.hpp:59
void setProjectionMatrix(const Matrix< t_type > &matrix)
Definition SelectionArea.hpp:231
void setSelection(const Plane< t_dims, t_type > &plane)
Definition SelectionArea.hpp:199
Bounds< t_dims, t_type > & bounds()
Definition SelectionArea.hpp:214
void preTransform(const Matrix< t_type > &mat)
Definition SelectionArea.hpp:339
void setSelection(const Polygon< t_type > &poly)
Definition SelectionArea.hpp:177
const Vertex< t_dims, t_type > & point() const
Definition SelectionArea.hpp:207
SelectionMode mode() const
Definition SelectionArea.hpp:205
Polygon< t_type > & polygon()
Definition SelectionArea.hpp:217
Vertex< t_dims, t_type > m_point
Definition SelectionArea.hpp:444
const Bounds< t_dims, t_type > & bounds() const
Definition SelectionArea.hpp:213
const Matrix< t_type > & inversePerspectiveTransform() const
Definition SelectionArea.hpp:252
Plane< t_dims, t_type > m_plane
Definition SelectionArea.hpp:448
const Matrix< t_type > & inverseTransform() const
Definition SelectionArea.hpp:248
Polygon< t_type > m_polygon
Definition SelectionArea.hpp:447
bool m_is_inverse
Definition SelectionArea.hpp:452
Bounds< t_dims, t_type > m_bounds
Definition SelectionArea.hpp:446
void cleanup()
Definition SelectionArea.hpp:429
void setTransform(const Matrix< t_type > &matrix)
Definition SelectionArea.hpp:224
bool isPreTransformed() const
Definition SelectionArea.hpp:300
void setSelection(Polygon< t_type > &&poly)
Definition SelectionArea.hpp:184
~SelectionArea()
Definition SelectionArea.hpp:158
void setSelection(const LineSegment< t_dims, t_type > &segment)
Definition SelectionArea.hpp:170
Vertex< t_dims, t_type > & point()
Definition SelectionArea.hpp:208
SelectionArea(const Plane< t_dims, t_type > &plane)
Definition SelectionArea.hpp:128
SelectionArea(const Bounds< t_dims, t_type > &bounds)
Definition SelectionArea.hpp:120
const Polygon< t_type > & polygon() const
Definition SelectionArea.hpp:216
void setIsInverse(bool is_inverse)
Definition SelectionArea.hpp:354
Bounds< t_dims, t_type > selectionBounds() const
Definition SelectionArea.hpp:256
LineSegment< t_dims, t_type > & line()
Definition SelectionArea.hpp:211
Matrix< t_type > m_projection_matrix
Definition SelectionArea.hpp:440
SelectionMode m_mode
Definition SelectionArea.hpp:450
bool operator==(const SelectionArea &area) const
Definition SelectionArea.hpp:366
Matrix< t_type > m_inverse_matrix
Definition SelectionArea.hpp:439
const LineSegment< t_dims, t_type > & line() const
Definition SelectionArea.hpp:210
SelectionArea(const Vertex< t_dims, t_type > &point)
Definition SelectionArea.hpp:89
void setSelection(const Bounds< t_dims, t_type > &bounds)
Definition SelectionArea.hpp:192
bool isEnabled() const
Definition SelectionArea.hpp:358
bool m_is_enabled
Definition SelectionArea.hpp:453
const Matrix< t_type > & transform() const
Definition SelectionArea.hpp:239
SelectionArea & operator=(const SelectionArea &area)
Definition SelectionArea.hpp:136
const Matrix< t_type > & projectionTransform() const
Definition SelectionArea.hpp:244
const Plane< t_dims, t_type > & plane() const
Definition SelectionArea.hpp:219
SelectionArea(const LineSegment< t_dims, t_type > &segment)
Definition SelectionArea.hpp:96
bool isInverse() const
Definition SelectionArea.hpp:350
Plane< t_dims, t_type > & plane()
Definition SelectionArea.hpp:220
SelectionArea< t_new_dims, t_new_type > as() const
Definition SelectionArea.hpp:282
SelectionArea(Polygon< t_type > &&poly)
Definition SelectionArea.hpp:112
SelectionArea(const Polygon< t_type > &poly)
Definition SelectionArea.hpp:104
void setIsEnabled(bool is_enabled)
Definition SelectionArea.hpp:362
void setSelection(const Vertex< t_dims, t_type > &point)
Definition SelectionArea.hpp:163
SelectionArea()
Definition SelectionArea.hpp:61
bool m_is_pre_transformed
Definition SelectionArea.hpp:451
LineSegment< t_dims, t_type > m_line
Definition SelectionArea.hpp:445
Matrix< t_type > m_projection_inverse_matrix
Definition SelectionArea.hpp:441
SelectionArea< t_new_dims, t_new_type > preTransformed() const
Definition SelectionArea.hpp:305
SelectionArea(const SelectionArea &area)
Definition SelectionArea.hpp:69
bool operator!=(const SelectionArea &area) const
Definition SelectionArea.hpp:397
Matrix< t_type > m_matrix
Definition SelectionArea.hpp:438
A vertex or point. A specific type of Vector used primarily for spacial location information.
Definition Vertex.hpp:48
Definition ACIColor.h:37
constexpr bool IsInvalid(const t_type &value)
Query if 'value' is valid or invalid. Invalid values should return invalid if used for calculations o...
Definition BaseFunctions.hpp:170
@ MIN
Definition BaseValues.hpp:196
@ MAX
Definition BaseValues.hpp:197
uint8_t uint01
-Defines an alias representing a 1 byte, unsigned integer -Can represent exact integer values 0 throu...
Definition BaseValues.hpp:80
SelectionMode
Definition SelectionArea.hpp:46
@ e_selection_line
Definition SelectionArea.hpp:48
@ e_selection_plane
Definition SelectionArea.hpp:51
@ e_selection_bounds
Definition SelectionArea.hpp:50
@ e_selection_polygon
Definition SelectionArea.hpp:49
@ e_selection_point
Definition SelectionArea.hpp:47
t_type distanceSquared(const Bounds< t_dims, t_type, t_vertex > &bounds, const Vector< t_dims, t_type > &vertex)
Definition Distance.hpp:46
IntersectionTypes
Used for classifying shape intersections.
Definition BaseValues.hpp:210
@ inside
Definition BaseValues.hpp:212
@ outside
Definition BaseValues.hpp:211
IntersectionTypes classify(const Vector< t_dims, t_type > &v1, const Vector< t_dims, t_type > &v2)
Definition Intersection.hpp:329
Definition File.h:211
Defines for a given type (such as sint04, fltp08, UUID, etc) a maximum, minimum, and reserved 'invali...
Definition BaseValues.hpp:233