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{
50 template<uint01 t_dims, class t_type>
52 {
53 public:
55 : m_point(Constant<Vertex<t_dims, t_type>>::NaN)
58 , m_is_inverse(false)
59 , m_is_enabled(true)
60 {}
61
63 : m_matrix(area.m_matrix)
67 , m_mode(area.m_mode)
71 {
72 switch(m_mode)
73 {
74 case e_selection_point: m_point = area.m_point; break;
75 case e_selection_line: m_line = area.m_line; break;
76 case e_selection_bounds: m_bounds = area.m_bounds; break;
78 case e_selection_plane: m_plane = area.m_plane; break;
79 default: lib_assert(false, "unknown selection copy");
80 }
81 }
90 : m_line(segment)
93 , m_is_inverse(false)
94 , m_is_enabled(true)
95 {}
96
98 : m_polygon(poly)
101 , m_is_inverse(false)
102 , m_is_enabled(true)
103 {}
104
106 : m_polygon(std::move(poly))
109 , m_is_inverse(false)
110 , m_is_enabled(true)
111 {}
112
120
128
130 {
131 cleanup();
132 m_mode = area.m_mode;
133 switch(m_mode)
134 {
135 case e_selection_point: m_point = area.m_point; break;
136 case e_selection_line: m_line = area.m_line; break;
137 case e_selection_bounds: m_bounds = area.m_bounds; break;
138 case e_selection_polygon: new (&m_polygon) Polygon<t_type>(area.m_polygon); break;
139 case e_selection_plane: m_plane = area.m_plane; break;
140 default: lib_assert(false, "unknown selection copy");
141 }
144 m_matrix = area.m_matrix;
149 return *this;
150 }
152 {
153 cleanup();
154 }
155
162
164 {
165 cleanup();
167 m_line = segment;
168 }
169
171 {
172 cleanup();
174 new (&m_polygon) Polygon<t_type>(poly);
175 }
176
178 {
179 cleanup();
181 new (&m_polygon) Polygon<t_type>();
182 std::swap(poly, m_polygon);
183 }
184
191
198 SelectionMode mode() const { return m_mode; }
199
200 const Vertex<t_dims, t_type>& point() const { return m_point; }
202
203 const LineSegment<t_dims, t_type>& line() const { return m_line; }
205
206 const Bounds<t_dims, t_type>& bounds() const { return m_bounds; }
208
209 const Polygon<t_type>& polygon() const { return m_polygon; }
211
212 const Plane<t_dims, t_type>& plane() const { return m_plane; }
214
215
216
217 void setTransform(const Matrix<t_type>& matrix)
218 {
219 m_matrix = matrix;
220 m_inverse_matrix = matrix.invert();
221 m_is_pre_transformed = (matrix == Matrix<t_type>(1.0));
222 }
223
225 {
226 if (!isNaN(matrix))
227 {
228 m_projection_matrix = matrix;
230 }
231 }
232 const Matrix<t_type>& transform() const
233 {
234 return m_matrix;
235 }
236
238 {
239 return m_projection_matrix;
240 }
242 {
243 return m_inverse_matrix;
244 }
250 {
251 switch (m_mode)
252 {
255 case e_selection_bounds: return m_bounds;
256 case e_selection_polygon: return m_polygon.bounds().template as<t_dims, t_type>();
258 {
260 for (uint01 dim = 0; dim < t_dims; dim++)
261 {
262 if (m_plane.normal[dim] == 1)
263 bounds[dim][MAX] = bounds[dim][MIN] = m_plane.d;
264 else if (m_plane.normal[dim] == -1)
265 bounds[dim][MAX] = bounds[dim][MIN] = -m_plane.d;
266 }
267 return bounds;
268 }
269 default: lib_assert(false, "Unknown selection area mode in as()"); break;
270 }
272 }
273
274 template<uint01 t_new_dims, class t_new_type>
276 {
278 switch (m_mode)
279 {
280 case e_selection_point: new_selection.setSelection(m_point.template as<t_new_dims, t_new_type>()); break;
281 case e_selection_line: new_selection.setSelection(m_line.template as<t_new_dims, t_new_type>()); break;
282 case e_selection_bounds: new_selection.setSelection(m_bounds.template as<t_new_dims, t_new_type>()); break;
283 case e_selection_polygon: new_selection.setSelection(m_polygon.template as<t_new_type>()); break;
284 case e_selection_plane: new_selection.setSelection(m_plane.template as<t_new_dims, t_new_type>()); break;
285 default: lib_assert(false, "Unknown selection area mode in as()"); break;
286 }
288 new_selection.setTransform(m_matrix.template as<t_new_type>());
289 new_selection.setIsInverse(m_is_inverse);
290 new_selection.setIsEnabled(m_is_enabled);
291 return new_selection;
292 }
293 bool isPreTransformed() const
294 {
296 }
297 template<uint01 t_new_dims, class t_new_type>
299 {
301 if (sizeof(t_new_type) > sizeof(t_type))
302 {
303 Matrix<t_new_type> matrix = m_matrix.template as<t_new_type>().invert();
304
305 switch (m_mode)
306 {
307 case e_selection_point: area.setSelection(matrix * m_point.template as<t_new_dims, t_new_type>()); break;
308 case e_selection_line: area.setSelection(matrix * m_line.template as<t_new_dims, t_new_type>()); break;
309 case e_selection_bounds: area.setSelection(matrix * m_bounds.template as<t_new_dims, t_new_type>()); break;
310 case e_selection_polygon: area.setSelection(matrix * m_polygon.template as<t_new_type>()); break;
311 default: lib_assert(false, "Unknown object to pre-transform");
312 }
313 }
314 else//we want higher precision so multiply first
315 {
316 Matrix<t_type> matrix = m_matrix.invert();
317 switch (m_mode)
318 {
319 case e_selection_point: area.setSelection((matrix * m_point).template as<t_new_dims, t_new_type>()); break;
320 case e_selection_line: area.setSelection((matrix * m_line).template as<t_new_dims, t_new_type>()); break;
321 case e_selection_bounds: area.setSelection((matrix * m_bounds).template as<t_new_dims, t_new_type>()); break;
322 case e_selection_polygon: area.setSelection((matrix * m_polygon).template as<t_new_type>()); break;
323 default: lib_assert(false, "Unknown object to pre-transform");
324 }
325 }
329 return area;
330 }
331
333 {
334 switch (m_mode)
335 {
336 case e_selection_point: setSelection(mat * m_point); break;
337 case e_selection_line: setSelection(mat * m_line); break;
338 case e_selection_bounds: setSelection(mat * m_bounds); break;
339 case e_selection_polygon: setSelection(mat * m_polygon); break;
340 default: lib_assert(false, "Unknown object to pre-transform");
341 }
342 }
343 bool isInverse() const
344 {
345 return m_is_inverse;
346 }
347 void setIsInverse(bool is_inverse)
348 {
349 m_is_inverse = is_inverse;
350 }
351 bool isEnabled() const
352 {
353 return m_is_enabled;
354 }
355 void setIsEnabled(bool is_enabled)
356 {
357 m_is_enabled = is_enabled;
358 }
359 bool operator==(const SelectionArea& area) const
360 {
361 if(m_mode != area.m_mode)
362 return false;
363 switch(m_mode)
364 {
366 if(m_bounds != area.m_bounds)
367 return false;
368 break;
370 if(m_line != area.m_line)
371 return false;
372 break;
374 if(m_polygon != area.m_polygon)
375 return false;
376 break;
378 if(m_point != area.m_point)
379 return false;
380 break;
382 if (m_plane != area.m_plane)
383 return false;
384 break;
385 default:
386 lib_assert(false, "unknown selection mode");
387 }
389 }
390 bool operator!=(const SelectionArea& area) const
391 {
392 if(m_mode != area.m_mode)
393 return true;
394 switch(m_mode)
395 {
397 if(m_bounds != area.m_bounds)
398 return true;
399 break;
401 if(m_line != area.m_line)
402 return true;
403 break;
405 if(m_polygon != area.m_polygon)
406 return false;
407 break;
409 if(m_point != area.m_point)
410 return true;
411 break;
413 if (m_plane != area.m_plane)
414 return true;
415 break;
416 default:
417 lib_assert(false, "unknown selection mode");
418 }
420 }
421 protected:
422 void cleanup()
423 {
425 {
426 m_polygon.~Polygon<t_type>();
428 }
429 }
430 protected:
435 union
436 {
442 };
447 };
448
449 /**--------------------------------------------------------------------------------------------------
450 Fn: IntersectionTypes classify(const t_other_type& other, const SelectionArea<t_dims, t_type>& area)
451
452 Classifies.
453
454 Author: Tyler Parke
455
456 Date: 2018-03-26
457
458 Parameters:
459 other - The vector.
460 area - The radians.
461
462 Returns: The IntersectionTypes.
463 *-----------------------------------------------------------------------------------------------**/
464 template<class t_other_type, uint01 t_dims, class t_type>
465 IntersectionTypes classify(const t_other_type& other, const SelectionArea<t_dims, t_type>& area)
466 {
467 if(!area.isEnabled())
468 {
469 if(area.isInverse())
470 return inside;
471 else
472 return outside;
473 }
474 //t_other_type trans_other = area.isPreTransformed() ? other : area.transform() * other;
475 IntersectionTypes intersection;
476 if (area.isPreTransformed())
477 {
478 switch (area.mode())
479 {
480 case e_selection_line:
481 intersection = classify(other, area.line());
482 break;
484 intersection = classify(other, area.bounds());
485 break;
487 intersection = classify(other, area.polygon());
488 break;
490 intersection = classify(other, area.plane());
491 break;
492 default:
493 lib_assert(false, "unknown intersection");
494 intersection = IntersectionTypes::outside;
495 break;
496 }
497 }
498 else
499 {
500 switch (area.mode())
501 {
502 case e_selection_line:
503 intersection = classify(other, area.inverseTransform() * area.line());
504 break;
506 intersection = classify(other, area.inverseTransform() * area.bounds());
507 break;
509 intersection = classify(area.transform() * other, area.polygon());
510 break;
512 intersection = classify(other, area.inverseTransform() * area.plane());
513 break;
514 default:
515 lib_assert(false, "unknown intersection");
516 intersection = IntersectionTypes::outside;
517 break;
518 }
519 }
520 if(area.isInverse())
521 {
522 switch(intersection)
523 {
524 case outside: intersection = inside; break;
525 case inside: intersection = outside; break;
526 default: break;
527 }
528 }
529 return intersection;
530 }
531 template<class t_other_type, uint01 t_dims, class t_type>
532 IntersectionTypes classify(const SelectionArea<t_dims, t_type>& area, const t_other_type& other)
533 {
534 if(!area.isEnabled())
535 {
536 if(area.isInverse())
537 return inside;
538 else
539 return outside;
540 }
541 IntersectionTypes intersection = outside;
542 if (area.isPreTransformed())
543 {
544 switch (area.mode())
545 {
546 case e_selection_line:
547 intersection = classify(area.line(), other);
548 break;
550 intersection = classify(area.bounds(), other);
551 break;
553 intersection = classify(area.polygon(), other.template as<2, t_type>());
554 break;
556 intersection = classify(area.plane(), other);
557 break;
558 default:
559 break;
560 }
561 }
562 else
563 {
564 switch (area.mode())
565 {
566 case e_selection_line:
567 intersection = classify(area.line(), area.transform() * other);
568 break;
570 intersection = classify(area.bounds(), area.transform() * other);
571 break;
573 intersection = classify(area.polygon(), (area.transform() * other).template as<2, t_type>());
574 break;
576 intersection = classify(area.plane(), area.transform() * other);
577 break;
578 default:
579 break;
580 }
581 }
582 if (area.isInverse())
583 {
584 switch (intersection)
585 {
586 case outside: intersection = inside; break;
587 case inside: intersection = outside; break;
588 default: break;
589 }
590 }
591 return intersection;
592 }
593
594 template<class t_other_type, uint01 t_dims, class t_type>
595 constexpr t_type distanceSquared(const t_other_type& other, const SelectionArea<t_dims, t_type>& area)
596 {
597 return distanceSquared(area, other);
598 }
599 template<class t_other_type, uint01 t_dims, class t_type>
600 constexpr t_type distanceSquared(const SelectionArea<t_dims, t_type>& area, const t_other_type& other)
601 {
602 if (area.isPreTransformed())
603 {
604 switch (area.mode())
605 {
607 return distanceSquared(area.point(), other);
608 case e_selection_line:
609 return distanceSquared(area.line(), other);
611 return distanceSquared(area.polygon(), other);
613 return distanceSquared(area.bounds(), other);
615 //distanceSquared(area.radius(), n_vertex);
616 break;
617 }
618 }
619 else
620 {
621 switch (area.mode())
622 {
624 return distanceSquared(area.point(), area.transform() * other);
625 case e_selection_line:
626 return distanceSquared(area.line(), area.transform() * other);
628 return distanceSquared(area.polygon(), area.transform() * other);
630 return distanceSquared(area.bounds(), area.transform() * other);
632 //distanceSquared(area.radius(), n_vertex);
633 break;
634 }
635 }
637 }
638
639}
#define lib_assert(expression, message)
Asserts some logic in the code. Disabled in non debug mode by default. Can be re-enabled in release u...
Definition LibAssert.h:70
A specification of upper and lower bounds in N-dimensions.
Definition Bounds.hpp:57
A line segment represented by two vertices, a start and end.
Definition Line.hpp:55
Definition Matrix.hpp:173
Matrix< t_type, t_cols, t_rows > invert() const
Definition Matrix.hpp:649
Definition Geometry.h:41
An N-sided polygon.
Definition Polygon.hpp:58
Definition SelectionArea.hpp:52
void setProjectionMatrix(const Matrix< t_type > &matrix)
Definition SelectionArea.hpp:224
void setSelection(const Plane< t_dims, t_type > &plane)
Definition SelectionArea.hpp:192
Bounds< t_dims, t_type > & bounds()
Definition SelectionArea.hpp:207
void preTransform(const Matrix< t_type > &mat)
Definition SelectionArea.hpp:332
void setSelection(const Polygon< t_type > &poly)
Definition SelectionArea.hpp:170
const Vertex< t_dims, t_type > & point() const
Definition SelectionArea.hpp:200
SelectionMode mode() const
Definition SelectionArea.hpp:198
Polygon< t_type > & polygon()
Definition SelectionArea.hpp:210
Vertex< t_dims, t_type > m_point
Definition SelectionArea.hpp:437
const Bounds< t_dims, t_type > & bounds() const
Definition SelectionArea.hpp:206
const Matrix< t_type > & inversePerspectiveTransform() const
Definition SelectionArea.hpp:245
Plane< t_dims, t_type > m_plane
Definition SelectionArea.hpp:441
const Matrix< t_type > & inverseTransform() const
Definition SelectionArea.hpp:241
Polygon< t_type > m_polygon
Definition SelectionArea.hpp:440
bool m_is_inverse
Definition SelectionArea.hpp:445
Bounds< t_dims, t_type > m_bounds
Definition SelectionArea.hpp:439
void cleanup()
Definition SelectionArea.hpp:422
void setTransform(const Matrix< t_type > &matrix)
Definition SelectionArea.hpp:217
bool isPreTransformed() const
Definition SelectionArea.hpp:293
void setSelection(Polygon< t_type > &&poly)
Definition SelectionArea.hpp:177
~SelectionArea()
Definition SelectionArea.hpp:151
void setSelection(const LineSegment< t_dims, t_type > &segment)
Definition SelectionArea.hpp:163
Vertex< t_dims, t_type > & point()
Definition SelectionArea.hpp:201
SelectionArea(const Plane< t_dims, t_type > &plane)
Definition SelectionArea.hpp:121
SelectionArea(const Bounds< t_dims, t_type > &bounds)
Definition SelectionArea.hpp:113
const Polygon< t_type > & polygon() const
Definition SelectionArea.hpp:209
void setIsInverse(bool is_inverse)
Definition SelectionArea.hpp:347
Bounds< t_dims, t_type > selectionBounds() const
Definition SelectionArea.hpp:249
LineSegment< t_dims, t_type > & line()
Definition SelectionArea.hpp:204
Matrix< t_type > m_projection_matrix
Definition SelectionArea.hpp:433
SelectionMode m_mode
Definition SelectionArea.hpp:443
bool operator==(const SelectionArea &area) const
Definition SelectionArea.hpp:359
Matrix< t_type > m_inverse_matrix
Definition SelectionArea.hpp:432
const LineSegment< t_dims, t_type > & line() const
Definition SelectionArea.hpp:203
SelectionArea(const Vertex< t_dims, t_type > &point)
Definition SelectionArea.hpp:82
void setSelection(const Bounds< t_dims, t_type > &bounds)
Definition SelectionArea.hpp:185
bool isEnabled() const
Definition SelectionArea.hpp:351
bool m_is_enabled
Definition SelectionArea.hpp:446
const Matrix< t_type > & transform() const
Definition SelectionArea.hpp:232
SelectionArea & operator=(const SelectionArea &area)
Definition SelectionArea.hpp:129
const Matrix< t_type > & projectionTransform() const
Definition SelectionArea.hpp:237
const Plane< t_dims, t_type > & plane() const
Definition SelectionArea.hpp:212
SelectionArea(const LineSegment< t_dims, t_type > &segment)
Definition SelectionArea.hpp:89
bool isInverse() const
Definition SelectionArea.hpp:343
Plane< t_dims, t_type > & plane()
Definition SelectionArea.hpp:213
SelectionArea< t_new_dims, t_new_type > as() const
Definition SelectionArea.hpp:275
SelectionArea(Polygon< t_type > &&poly)
Definition SelectionArea.hpp:105
SelectionArea(const Polygon< t_type > &poly)
Definition SelectionArea.hpp:97
void setIsEnabled(bool is_enabled)
Definition SelectionArea.hpp:355
void setSelection(const Vertex< t_dims, t_type > &point)
Definition SelectionArea.hpp:156
SelectionArea()
Definition SelectionArea.hpp:54
bool m_is_pre_transformed
Definition SelectionArea.hpp:444
LineSegment< t_dims, t_type > m_line
Definition SelectionArea.hpp:438
Matrix< t_type > m_projection_inverse_matrix
Definition SelectionArea.hpp:434
SelectionArea< t_new_dims, t_new_type > preTransformed() const
Definition SelectionArea.hpp:298
SelectionArea(const SelectionArea &area)
Definition SelectionArea.hpp:62
bool operator!=(const SelectionArea &area) const
Definition SelectionArea.hpp:390
Matrix< t_type > m_matrix
Definition SelectionArea.hpp:431
A vertex.
Definition Vertex.hpp:54
Definition ACIColor.h:37
@ MIN
Definition BaseValues.hpp:226
@ MAX
Definition BaseValues.hpp:227
uint8_t uint01
-Defines an alias representing a 1 byte, unsigned integer -Can represent exact integer values 0 throu...
Definition BaseValues.hpp:98
SelectionMode
Definition SelectionArea.hpp:43
@ e_selection_line
Definition SelectionArea.hpp:45
@ e_selection_plane
Definition SelectionArea.hpp:48
@ e_selection_bounds
Definition SelectionArea.hpp:47
@ e_selection_polygon
Definition SelectionArea.hpp:46
@ e_selection_point
Definition SelectionArea.hpp:44
t_type distanceSquared(const Bounds< t_dims, t_type, t_vertex > &bounds, const Vector< t_dims, t_type > &vertex)
Definition Distance.hpp:42
IntersectionTypes
Used for classifying shape intersections.
Definition BaseValues.hpp:241
@ inside
Definition BaseValues.hpp:243
@ outside
Definition BaseValues.hpp:242
IntersectionTypes classify(const Vector< t_dims, t_type > &v1, const Vector< t_dims, t_type > &v2)
Definition Intersection.hpp:338
constexpr bool isNaN(const t_type &value)
Query if 'value' is valid or invalid.
Definition BaseFunctions.hpp:200
Definition File.h:213
Definition BaseValues.hpp:272