1#include "PointInteraction.h"
2#include <thrust/sort.h>
4#include <OrbitCamera.h>
8 __global__ void PI_PointInitializeArray(
9 DArray<int> intersected)
11 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
12 if (pId >= intersected.size()) return;
17 __global__ void PI_PointMergeIntersectedIndexOR(
18 DArray<int> intersected1,
19 DArray<int> intersected2,
20 DArray<int> outIntersected,
21 DArray<int> outUnintersected)
23 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
24 if (pId >= intersected1.size()) return;
26 if (intersected1[pId] == 0 && intersected2[pId] == 0)
27 outIntersected[pId] = 0;
29 outIntersected[pId] = 1;
31 outUnintersected[pId] = outIntersected[pId] == 1 ? 0 : 1;
34 __global__ void PI_PointMergeIntersectedIndexXOR(
35 DArray<int> intersected1,
36 DArray<int> intersected2,
37 DArray<int> outIntersected,
38 DArray<int> outUnintersected)
40 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
41 if (pId >= intersected1.size()) return;
43 if (intersected1[pId] == intersected2[pId])
44 outIntersected[pId] = 0;
46 outIntersected[pId] = 1;
48 outUnintersected[pId] = outIntersected[pId] == 1 ? 0 : 1;
51 __global__ void PI_PointMergeIntersectedIndexC(
52 DArray<int> intersected1,
53 DArray<int> intersected2,
54 DArray<int> outIntersected,
55 DArray<int> outUnintersected)
57 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
58 if (pId >= intersected1.size()) return;
60 if (intersected2[pId] == 1)
61 outIntersected[pId] = 0;
63 outIntersected[pId] = intersected1[pId];
65 outUnintersected[pId] = outIntersected[pId] == 1 ? 0 : 1;
68 template<typename TDataType>
69 PointInteraction<TDataType>::PointInteraction()
71 this->ray1 = TRay3D<Real>();
72 this->ray2 = TRay3D<Real>();
73 this->isPressed = false;
75 this->outOtherPointSet()->setDataPtr(std::make_shared<PointSet<TDataType>>());
76 this->outOtherPointSet()->getDataPtr()->getPoints().resize(0);
77 this->outSelectedPointSet()->setDataPtr(std::make_shared<PointSet<TDataType>>());
78 this->outSelectedPointSet()->getDataPtr()->getPoints().resize(0);
81 template<typename TDataType>
82 void PointInteraction<TDataType>::onEvent(PMouseEvent event)
84 if (!event.altKeyPressed()) {
85 if (camera == nullptr)
87 this->camera = event.camera;
89 this->varToggleMultiSelect()->setValue(false);
90 if (event.shiftKeyPressed() || event.controlKeyPressed())
92 this->varToggleMultiSelect()->setValue(true);
93 if (event.shiftKeyPressed() && !event.controlKeyPressed())
95 this->varMultiSelectionType()->getDataPtr()->setCurrentKey(0);
97 else if (!event.shiftKeyPressed() && event.controlKeyPressed())
99 this->varMultiSelectionType()->getDataPtr()->setCurrentKey(1);;
101 else if (event.shiftKeyPressed() && event.controlKeyPressed())
103 this->varMultiSelectionType()->getDataPtr()->setCurrentKey(2);;
106 if (event.actionType == AT_PRESS)
108 this->camera = event.camera;
109 this->isPressed = true;
110 //printf("Mouse pressed: Origin: %f %f %f; Direction: %f %f %f \n", event.ray.origin.x, event.ray.origin.y, event.ray.origin.z, event.ray.direction.x, event.ray.direction.y, event.ray.direction.z);
111 this->ray1.origin = event.ray.origin;
112 this->ray1.direction = event.ray.direction;
115 if (this->varPointPickingType()->getValue() == PickingTypeSelection::Both || this->varPointPickingType()->getValue() == PickingTypeSelection::Click)
117 this->calcIntersectClick();
118 this->printInfoClick();
121 else if (event.actionType == AT_RELEASE)
123 this->isPressed = false;
124 //printf("Mouse released: Origin: %f %f %f; Direction: %f %f %f \n", event.ray.origin.x, event.ray.origin.y, event.ray.origin.z, event.ray.direction.x, event.ray.direction.y, event.ray.direction.z);
125 this->ray2.origin = event.ray.origin;
126 this->ray2.direction = event.ray.direction;
129 if (this->varToggleMultiSelect()->getValue() && this->varTogglePicker()->getValue())
132 this->printInfoDragRelease();
137 //printf("Mouse repeated: Origin: %f %f %f; Direction: %f %f %f \n", event.ray.origin.x, event.ray.origin.y, event.ray.origin.z, event.ray.direction.x, event.ray.direction.y, event.ray.direction.z);
140 this->ray2.origin = event.ray.origin;
141 this->ray2.direction = event.ray.direction;
144 if (this->x2 == this->x1 && this->y2 == this->y1)
146 if (this->varPointPickingType()->getValue() == PickingTypeSelection::Both || this->varPointPickingType()->getValue() == PickingTypeSelection::Click)
147 this->calcIntersectClick();
151 if (this->varPointPickingType()->getValue() == PickingTypeSelection::Both || this->varPointPickingType()->getValue() == PickingTypeSelection::Drag)
153 this->calcIntersectDrag();
154 this->printInfoDragging();
162 template <typename Real, typename Coord>
163 __global__ void PI_CalIntersectedPointsRay(
164 DArray<Coord> points,
165 DArray<int> intersected,
166 DArray<int> unintersected,
167 DArray<Real> pointDistance,
168 TRay3D<Real> mouseray,
171 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
172 if (pId >= points.size()) return;
174 TSphere3D<Real> sphere = TSphere3D<Real>(points[pId], radius);
175 TSegment3D<Real> seg;
176 int temp = mouseray.intersect(sphere, seg);
177 if (temp > 0 || intersected[pId] == 1)
179 intersected[pId] = 1;
180 pointDistance[pId] = abs(TPoint3D<Real>(points[pId][0], points[pId][1], points[pId][2]).distance(TPoint3D<Real>(mouseray.origin[0], mouseray.origin[1], mouseray.origin[2])));
184 intersected[pId] = 0;
185 pointDistance[pId] = 3.4E38;
187 unintersected[pId] = (intersected[pId] == 1 ? 0 : 1);
190 __global__ void PI_CalPointsNearest(
192 DArray<int> intersected,
193 DArray<int> unintersected
196 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
197 if (pId >= intersected.size()) return;
199 if (intersected[pId] == 1)
201 if (pId != min_index)
203 intersected[pId] = 0;
204 unintersected[pId] = 1;
210 template <typename Real, typename Coord>
211 __global__ void PI_CalIntersectedPointsBox(
212 DArray<Coord> points,
213 DArray<int> intersected,
214 DArray<int> unintersected,
215 TPlane3D<Real> plane13,
216 TPlane3D<Real> plane42,
217 TPlane3D<Real> plane14,
218 TPlane3D<Real> plane32,
220 TRay3D<Real> mouseray)
222 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
223 if (pId >= points.size()) return;
226 float temp1 = ((points[pId] - plane13.origin).dot(plane13.normal)) * ((points[pId] - plane42.origin).dot(plane42.normal));
227 float temp2 = ((points[pId] - plane14.origin).dot(plane14.normal)) * ((points[pId] - plane32.origin).dot(plane32.normal));
228 if (temp1 >= 0 && temp2 >= 0)
231 TSphere3D<Real> sphere = TSphere3D<Real>(points[pId], radius);
232 TSegment3D<Real> seg;
233 int temp = mouseray.intersect(sphere, seg);
236 if (flag || intersected[pId] == 1)
237 intersected[pId] = 1;
239 intersected[pId] = 0;
240 unintersected[pId] = (intersected[pId] == 1 ? 0 : 1);
243 template <typename Coord>
244 __global__ void PI_AssignOutPoints(
245 DArray<Coord> points,
246 DArray<Coord> intersected_points,
247 DArray<Coord> unintersected_points,
248 DArray<int> outPointIndex,
249 DArray<int> intersected,
250 DArray<int> unintersected,
251 DArray<int> intersected_o)
253 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
254 if (pId >= points.size()) return;
256 if (intersected_o[pId] == 1)
258 intersected_points[intersected[pId]] = points[pId];
259 outPointIndex[intersected[pId]] = pId;
263 unintersected_points[unintersected[pId]] = points[pId];
267 template<typename TDataType>
268 void PointInteraction<TDataType>::calcPointIntersectClick()
270 auto& initialPointSet = this->inInitialPointSet()->getData();
271 auto& points = initialPointSet.getPoints();
273 DArray<int> intersected;
274 intersected.resize(points.size());
275 cuExecute(points.size(),
276 PI_PointInitializeArray,
279 DArray<int> unintersected;
280 unintersected.resize(points.size());
281 this->tempNumT = points.size();
283 DArray<Real> pointDistance;
284 pointDistance.resize(points.size());
286 cuExecute(points.size(),
287 PI_CalIntersectedPointsRay,
293 this->varInteractionRadius()->getData()
296 int min_index = thrust::min_element(thrust::device, pointDistance.begin(), pointDistance.begin() + pointDistance.size()) - pointDistance.begin();
298 cuExecute(intersected.size(),
305 this->tempPointIntersectedIndex.assign(intersected);
307 if (this->varToggleMultiSelect()->getData())
309 if (this->pointIntersectedIndex.size() == 0)
311 this->pointIntersectedIndex.resize(points.size());
312 cuExecute(points.size(),
313 PI_PointInitializeArray,
314 this->pointIntersectedIndex
317 DArray<int> outIntersected;
318 outIntersected.resize(intersected.size());
319 DArray<int> outUnintersected;
320 outUnintersected.resize(unintersected.size());
321 if (this->varMultiSelectionType()->getValue() == MultiSelectionType::OR)
323 cuExecute(points.size(),
324 PI_PointMergeIntersectedIndexOR,
325 this->pointIntersectedIndex,
331 else if (this->varMultiSelectionType()->getValue() == MultiSelectionType::XOR)
333 cuExecute(points.size(),
334 PI_PointMergeIntersectedIndexXOR,
335 this->pointIntersectedIndex,
341 else if (this->varMultiSelectionType()->getValue() == MultiSelectionType::C)
343 cuExecute(points.size(),
344 PI_PointMergeIntersectedIndexC,
345 this->pointIntersectedIndex,
351 intersected.assign(outIntersected);
352 unintersected.assign(outUnintersected);
356 this->pointIntersectedIndex.assign(intersected);
358 DArray<int> intersected_o;
359 intersected_o.assign(intersected);
361 int intersected_size = thrust::reduce(thrust::device, intersected.begin(), intersected.begin() + intersected.size(), (int)0, thrust::plus<int>());
362 DArray<int> outPointIndex;
363 outPointIndex.resize(intersected_size);
364 thrust::exclusive_scan(thrust::device, intersected.begin(), intersected.begin() + intersected.size(), intersected.begin());
365 DArray<Coord> intersected_points;
366 intersected_points.resize(intersected_size);
368 int unintersected_size = thrust::reduce(thrust::device, unintersected.begin(), unintersected.begin() + unintersected.size(), (int)0, thrust::plus<int>());
369 thrust::exclusive_scan(thrust::device, unintersected.begin(), unintersected.begin() + unintersected.size(), unintersected.begin());
370 DArray<Coord> unintersected_points;
371 unintersected_points.resize(unintersected_size);
373 cuExecute(points.size(),
377 unintersected_points,
383 this->tempNumS = intersected_size;
384 this->outSelectedPointSet()->getDataPtr()->copyFrom(initialPointSet);
385 this->outSelectedPointSet()->getDataPtr()->setPoints(intersected_points);
386 this->outOtherPointSet()->getDataPtr()->copyFrom(initialPointSet);
387 this->outOtherPointSet()->getDataPtr()->setPoints(unintersected_points);
388 if (this->varToggleIndexOutput()->getValue())
390 this->outPointIndex()->getDataPtr()->assign(outPointIndex);
394 this->outPointIndex()->getDataPtr()->assign(intersected_o);
398 template<typename TDataType>
399 void PointInteraction<TDataType>::calcPointIntersectDrag()
409 TRay3D<Real> ray1 = this->camera->castRayInWorldSpace((float)x1, (float)y1);
410 TRay3D<Real> ray2 = this->camera->castRayInWorldSpace((float)x2, (float)y2);
411 TRay3D<Real> ray3 = this->camera->castRayInWorldSpace((float)x1, (float)y2);
412 TRay3D<Real> ray4 = this->camera->castRayInWorldSpace((float)x2, (float)y1);
414 TPlane3D<Real> plane13 = TPlane3D<Real>(ray1.origin, ray1.direction.cross(ray3.direction));
415 TPlane3D<Real> plane42 = TPlane3D<Real>(ray2.origin, ray2.direction.cross(ray4.direction));
416 TPlane3D<Real> plane14 = TPlane3D<Real>(ray4.origin, ray1.direction.cross(ray4.direction));
417 TPlane3D<Real> plane32 = TPlane3D<Real>(ray3.origin, ray2.direction.cross(ray3.direction));
419 auto& initialPointSet = this->inInitialPointSet()->getData();
420 auto& points = initialPointSet.getPoints();
421 DArray<int> intersected;
422 intersected.resize(points.size());
423 cuExecute(points.size(),
424 PI_PointInitializeArray,
427 DArray<int> unintersected;
428 unintersected.resize(points.size());
429 this->tempNumT = points.size();
430 cuExecute(points.size(),
431 PI_CalIntersectedPointsBox,
439 this->varInteractionRadius()->getData(),
443 this->tempPointIntersectedIndex.assign(intersected);
445 if (this->varToggleMultiSelect()->getData())
447 if (this->pointIntersectedIndex.size() == 0)
449 this->pointIntersectedIndex.resize(points.size());
450 cuExecute(points.size(),
451 PI_PointInitializeArray,
452 this->pointIntersectedIndex
455 DArray<int> outIntersected;
456 outIntersected.resize(intersected.size());
457 DArray<int> outUnintersected;
458 outUnintersected.resize(unintersected.size());
459 if (this->varMultiSelectionType()->getValue() == MultiSelectionType::OR)
461 cuExecute(points.size(),
462 PI_PointMergeIntersectedIndexOR,
463 this->pointIntersectedIndex,
469 else if (this->varMultiSelectionType()->getValue() == MultiSelectionType::XOR)
471 cuExecute(points.size(),
472 PI_PointMergeIntersectedIndexXOR,
473 this->pointIntersectedIndex,
479 else if (this->varMultiSelectionType()->getValue() == MultiSelectionType::C)
481 cuExecute(points.size(),
482 PI_PointMergeIntersectedIndexC,
483 this->pointIntersectedIndex,
489 intersected.assign(outIntersected);
490 unintersected.assign(outUnintersected);
494 this->pointIntersectedIndex.assign(intersected);
497 DArray<int> intersected_o;
498 intersected_o.assign(intersected);
500 int intersected_size = thrust::reduce(thrust::device, intersected.begin(), intersected.begin() + intersected.size(), (int)0, thrust::plus<int>());
501 DArray<int> outPointIndex;
502 outPointIndex.resize(intersected_size);
503 thrust::exclusive_scan(thrust::device, intersected.begin(), intersected.begin() + intersected.size(), intersected.begin());
504 DArray<Coord> intersected_points;
505 intersected_points.resize(intersected_size);
507 int unintersected_size = thrust::reduce(thrust::device, unintersected.begin(), unintersected.begin() + unintersected.size(), (int)0, thrust::plus<int>());
508 thrust::exclusive_scan(thrust::device, unintersected.begin(), unintersected.begin() + unintersected.size(), unintersected.begin());
509 DArray<Coord> unintersected_points;
510 unintersected_points.resize(unintersected_size);
512 cuExecute(points.size(),
516 unintersected_points,
522 this->tempNumS = intersected_size;
523 this->outSelectedPointSet()->getDataPtr()->copyFrom(initialPointSet);
524 this->outSelectedPointSet()->getDataPtr()->setPoints(intersected_points);
525 this->outOtherPointSet()->getDataPtr()->copyFrom(initialPointSet);
526 this->outOtherPointSet()->getDataPtr()->setPoints(unintersected_points);
527 if (this->varToggleIndexOutput()->getValue())
529 this->outPointIndex()->getDataPtr()->assign(outPointIndex);
533 this->outPointIndex()->getDataPtr()->assign(intersected_o);
537 template<typename TDataType>
538 void PointInteraction<TDataType>::mergeIndex()
540 auto& initialPointSet = this->inInitialPointSet()->getData();
541 auto& points = initialPointSet.getPoints();
542 DArray<int> intersected;
543 intersected.resize(points.size());
544 cuExecute(points.size(),
545 PI_PointInitializeArray,
548 DArray<int> unintersected;
549 unintersected.resize(points.size());
550 this->tempNumT = points.size();
552 DArray<int> outIntersected;
553 outIntersected.resize(intersected.size());
554 DArray<int> outUnintersected;
555 outUnintersected.resize(unintersected.size());
557 if (this->varMultiSelectionType()->getValue() == MultiSelectionType::OR)
559 cuExecute(points.size(),
560 PI_PointMergeIntersectedIndexOR,
561 this->pointIntersectedIndex,
562 this->tempPointIntersectedIndex,
567 else if (this->varMultiSelectionType()->getValue() == MultiSelectionType::XOR)
569 cuExecute(points.size(),
570 PI_PointMergeIntersectedIndexXOR,
571 this->pointIntersectedIndex,
572 this->tempPointIntersectedIndex,
577 else if (this->varMultiSelectionType()->getValue() == MultiSelectionType::C)
579 cuExecute(points.size(),
580 PI_PointMergeIntersectedIndexC,
581 this->pointIntersectedIndex,
582 this->tempPointIntersectedIndex,
588 intersected.assign(outIntersected);
589 unintersected.assign(outUnintersected);
590 this->pointIntersectedIndex.assign(intersected);
592 DArray<int> intersected_o;
593 intersected_o.assign(intersected);
595 int intersected_size = thrust::reduce(thrust::device, intersected.begin(), intersected.begin() + intersected.size(), (int)0, thrust::plus<int>());
596 DArray<int> outPointIndex;
597 outPointIndex.resize(intersected_size);
598 thrust::exclusive_scan(thrust::device, intersected.begin(), intersected.begin() + intersected.size(), intersected.begin());
599 DArray<Coord> intersected_points;
600 intersected_points.resize(intersected_size);
602 int unintersected_size = thrust::reduce(thrust::device, unintersected.begin(), unintersected.begin() + unintersected.size(), (int)0, thrust::plus<int>());
603 thrust::exclusive_scan(thrust::device, unintersected.begin(), unintersected.begin() + unintersected.size(), unintersected.begin());
604 DArray<Coord> unintersected_points;
605 unintersected_points.resize(unintersected_size);
607 cuExecute(points.size(),
611 unintersected_points,
617 this->tempNumS = intersected_size;
618 this->outSelectedPointSet()->getDataPtr()->copyFrom(initialPointSet);
619 this->outSelectedPointSet()->getDataPtr()->setPoints(intersected_points);
620 this->outOtherPointSet()->getDataPtr()->copyFrom(initialPointSet);
621 this->outOtherPointSet()->getDataPtr()->setPoints(unintersected_points);
622 if (this->varToggleIndexOutput()->getValue())
624 this->outPointIndex()->getDataPtr()->assign(outPointIndex);
628 this->outPointIndex()->getDataPtr()->assign(intersected_o);
632 template<typename TDataType>
633 void PointInteraction<TDataType>::printInfoClick()
635 std::cout << "----------point picking: click----------" << std::endl;
636 std::cout << "multiple picking: " << this->varToggleMultiSelect()->getValue() << std::endl;
637 std::cout << "Interation radius:" << this->varInteractionRadius()->getValue() << std::endl;
638 std::cout << "selected num/ total num:" << this->tempNumS << "/" << this->tempNumT << std::endl;
641 template<typename TDataType>
642 void PointInteraction<TDataType>::printInfoDragging()
644 std::cout << "----------point picking: dragging----------" << std::endl;
645 std::cout << "multiple picking: " << this->varToggleMultiSelect()->getValue() << std::endl;
646 std::cout << "Interation radius:" << this->varInteractionRadius()->getValue() << std::endl;
647 std::cout << "selected num/ total num:" << this->tempNumS << "/" << this->tempNumT << std::endl;
650 template<typename TDataType>
651 void PointInteraction<TDataType>::printInfoDragRelease()
653 std::cout << "----------point picking: drag release----------" << std::endl;
654 std::cout << "multiple picking: " << this->varToggleMultiSelect()->getValue() << std::endl;
655 std::cout << "Interation radius:" << this->varInteractionRadius()->getValue() << std::endl;
656 std::cout << "selected num/ total num:" << this->tempNumS << "/" << this->tempNumT << std::endl;
659 template<typename TDataType>
660 void PointInteraction<TDataType>::calcIntersectClick()
662 if (this->varTogglePicker()->getData())
663 calcPointIntersectClick();
666 template<typename TDataType>
667 void PointInteraction<TDataType>::calcIntersectDrag()
669 if (this->varTogglePicker()->getData())
670 calcPointIntersectDrag();
673 DEFINE_CLASS(PointInteraction);