1#include "EdgeInteraction.h"
2#include <thrust/sort.h>
4#include <OrbitCamera.h>
8 __global__ void EI_EdgeInitializeArray(
9 DArray<int> intersected)
11 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
12 if (pId >= intersected.size()) return;
17 __global__ void EI_EdgeMergeIntersectedIndexOR(
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 EI_EdgeMergeIntersectedIndexXOR(
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 EI_EdgeMergeIntersectedIndexC(
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 EdgeInteraction<TDataType>::EdgeInteraction()
71 this->ray1 = TRay3D<Real>();
72 this->ray2 = TRay3D<Real>();
73 this->isPressed = false;
75 this->outOtherEdgeSet()->setDataPtr(std::make_shared<EdgeSet<TDataType>>());
76 this->outOtherEdgeSet()->getDataPtr()->getEdges().resize(0);
77 this->outSelectedEdgeSet()->setDataPtr(std::make_shared<EdgeSet<TDataType>>());
78 this->outSelectedEdgeSet()->getDataPtr()->getEdges().resize(0);
81 template<typename TDataType>
82 void EdgeInteraction<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->varEdgePickingType()->getValue() == PickingTypeSelection::Both || this->varEdgePickingType()->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->varEdgePickingType()->getValue() == PickingTypeSelection::Both || this->varEdgePickingType()->getValue() == PickingTypeSelection::Click)
147 this->calcIntersectClick();
151 if (this->varEdgePickingType()->getValue() == PickingTypeSelection::Both || this->varEdgePickingType()->getValue() == PickingTypeSelection::Drag)
153 this->calcIntersectDrag();
154 this->printInfoDragging();
162 template <typename Edge, typename Real, typename Coord>
163 __global__ void EI_CalIntersectedEdgesRay(
164 DArray<Coord> points,
166 DArray<int> intersected,
167 DArray<int> unintersected,
168 DArray<Real> lineDistance,
169 TRay3D<Real> mouseray,
172 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
173 if (pId >= edges.size()) return;
175 TSegment3D<Real> seg = TSegment3D<Real>(points[edges[pId].data[0]], points[edges[pId].data[1]]);
178 if (mouseray.distance(seg) <= radius)
181 lineDistance[pId] = abs(TPoint3D<Real>(mouseray.origin[0], mouseray.origin[1], mouseray.origin[2]).distance(seg));
186 lineDistance[pId] = 3.4E38;
189 if (flag || intersected[pId] == 1)
190 intersected[pId] = 1;
192 intersected[pId] = 0;
193 unintersected[pId] = (intersected[pId] == 1 ? 0 : 1);
196 __global__ void EI_CalEdgesNearest(
198 DArray<int> intersected,
199 DArray<int> unintersected
202 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
203 if (pId >= intersected.size()) return;
205 if (intersected[pId] == 1)
207 if (pId != min_index)
209 intersected[pId] = 0;
210 unintersected[pId] = 1;
215 template <typename Edge, typename Real, typename Coord>
216 __global__ void EI_CalIntersectedEdgesBox(
217 DArray<Coord> points,
219 DArray<int> intersected,
220 DArray<int> unintersected,
221 TPlane3D<Real> plane13,
222 TPlane3D<Real> plane42,
223 TPlane3D<Real> plane14,
224 TPlane3D<Real> plane32,
226 TRay3D<Real> mouseray)
228 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
229 if (pId >= edges.size()) return;
235 TSegment3D<Real> s = TSegment3D<Real>(points[edges[pId].data[0]], points[edges[pId].data[1]]);
236 bool temp1 = s.intersect(plane13, p);
237 temp1 = temp1 && (((p.origin - plane14.origin).dot(plane14.normal)) * ((p.origin - plane32.origin).dot(plane32.normal))) > 0;
240 bool temp2 = s.intersect(plane42, p);
241 temp2 = temp2 && (((p.origin - plane14.origin).dot(plane14.normal)) * ((p.origin - plane32.origin).dot(plane32.normal))) > 0;
244 bool temp3 = s.intersect(plane14, p);
245 temp3 = temp3 && (((p.origin - plane13.origin).dot(plane13.normal)) * ((p.origin - plane42.origin).dot(plane42.normal))) > 0;
248 bool temp4 = s.intersect(plane32, p);
249 temp4 = temp4 && (((p.origin - plane13.origin).dot(plane13.normal)) * ((p.origin - plane42.origin).dot(plane42.normal))) > 0;
253 for (int i = 0; i < 2; i++)
255 float temp1 = ((points[edges[pId].data[i]] - plane13.origin).dot(plane13.normal)) * ((points[edges[pId].data[i]] - plane42.origin).dot(plane42.normal));
256 float temp2 = ((points[edges[pId].data[i]] - plane14.origin).dot(plane14.normal)) * ((points[edges[pId].data[i]] - plane32.origin).dot(plane32.normal));
257 if (temp1 >= 0 && temp2 >= 0)
264 TSegment3D<Real> seg = TSegment3D<Real>(points[edges[pId].data[0]], points[edges[pId].data[1]]);
266 if (mouseray.distance(seg) <= radius)
271 if (flag || intersected[pId] == 1)
272 intersected[pId] = 1;
274 intersected[pId] = 0;
275 unintersected[pId] = (intersected[pId] == 1 ? 0 : 1);
278 template <typename Edge>
279 __global__ void EI_AssignOutEdges(
281 DArray<Edge> intersected_edges,
282 DArray<Edge> unintersected_edges,
283 DArray<int> outEdgeIndex,
284 DArray<int> intersected,
285 DArray<int> unintersected,
286 DArray<int> intersected_o)
288 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
289 if (pId >= edges.size()) return;
291 if (intersected_o[pId] == 1)
293 intersected_edges[intersected[pId]] = edges[pId];
294 outEdgeIndex[intersected[pId]] = pId;
298 unintersected_edges[unintersected[pId]] = edges[pId];
302 template<typename TDataType>
303 void EdgeInteraction<TDataType>::calcEdgeIntersectClick()
305 auto& initialEdgeSet = this->inInitialEdgeSet()->getData();
306 auto& edges = initialEdgeSet.getEdges();
307 auto& points = initialEdgeSet.getPoints();
309 this->tempNumT = edges.size();
310 DArray<int> intersected;
311 intersected.resize(edges.size());
312 cuExecute(edges.size(),
313 EI_EdgeInitializeArray,
316 DArray<int> unintersected;
317 unintersected.resize(edges.size());
319 DArray<Real> lineDistance;
320 lineDistance.resize(edges.size());
322 cuExecute(edges.size(),
323 EI_CalIntersectedEdgesRay,
330 this->varInteractionRadius()->getData()
333 int min_index = thrust::min_element(thrust::device, lineDistance.begin(), lineDistance.begin() + lineDistance.size()) - lineDistance.begin();
335 cuExecute(intersected.size(),
342 this->tempEdgeIntersectedIndex.assign(intersected);
344 if (this->varToggleMultiSelect()->getData())
346 if (this->edgeIntersectedIndex.size() == 0)
348 this->edgeIntersectedIndex.resize(edges.size());
349 cuExecute(edges.size(),
350 EI_EdgeInitializeArray,
351 this->edgeIntersectedIndex
354 DArray<int> outIntersected;
355 outIntersected.resize(intersected.size());
356 DArray<int> outUnintersected;
357 outUnintersected.resize(unintersected.size());
358 if (this->varMultiSelectionType()->getValue() == MultiSelectionType::OR)
360 cuExecute(edges.size(),
361 EI_EdgeMergeIntersectedIndexOR,
362 this->edgeIntersectedIndex,
368 else if (this->varMultiSelectionType()->getValue() == MultiSelectionType::XOR)
370 cuExecute(edges.size(),
371 EI_EdgeMergeIntersectedIndexXOR,
372 this->edgeIntersectedIndex,
378 else if (this->varMultiSelectionType()->getValue() == MultiSelectionType::C)
380 cuExecute(edges.size(),
381 EI_EdgeMergeIntersectedIndexC,
382 this->edgeIntersectedIndex,
388 intersected.assign(outIntersected);
389 unintersected.assign(outUnintersected);
393 this->edgeIntersectedIndex.assign(intersected);
396 DArray<int> intersected_o;
397 intersected_o.assign(intersected);
399 int intersected_size = thrust::reduce(thrust::device, intersected.begin(), intersected.begin() + intersected.size(), (int)0, thrust::plus<int>());
400 DArray<int> outEdgeIndex;
401 outEdgeIndex.resize(intersected_size);
402 thrust::exclusive_scan(thrust::device, intersected.begin(), intersected.begin() + intersected.size(), intersected.begin());
403 DArray<Edge> intersected_edges;
404 intersected_edges.resize(intersected_size);
406 int unintersected_size = thrust::reduce(thrust::device, unintersected.begin(), unintersected.begin() + unintersected.size(), (int)0, thrust::plus<int>());
407 thrust::exclusive_scan(thrust::device, unintersected.begin(), unintersected.begin() + unintersected.size(), unintersected.begin());
408 DArray<Edge> unintersected_edges;
409 unintersected_edges.resize(unintersected_size);
411 this->tempNumS = intersected_size;
412 cuExecute(edges.size(),
422 this->outSelectedEdgeSet()->getDataPtr()->copyFrom(initialEdgeSet);
423 this->outSelectedEdgeSet()->getDataPtr()->setEdges(intersected_edges);
424 this->outOtherEdgeSet()->getDataPtr()->copyFrom(initialEdgeSet);
425 this->outOtherEdgeSet()->getDataPtr()->setEdges(unintersected_edges);
426 if (this->varToggleIndexOutput()->getValue())
428 this->outEdgeIndex()->getDataPtr()->assign(outEdgeIndex);
432 this->outEdgeIndex()->getDataPtr()->assign(intersected_o);
436 template<typename TDataType>
437 void EdgeInteraction<TDataType>::calcEdgeIntersectDrag()
447 TRay3D<Real> ray1 = this->camera->castRayInWorldSpace((float)x1, (float)y1);
448 TRay3D<Real> ray2 = this->camera->castRayInWorldSpace((float)x2, (float)y2);
449 TRay3D<Real> ray3 = this->camera->castRayInWorldSpace((float)x1, (float)y2);
450 TRay3D<Real> ray4 = this->camera->castRayInWorldSpace((float)x2, (float)y1);
452 TPlane3D<Real> plane13 = TPlane3D<Real>(ray1.origin, ray1.direction.cross(ray3.direction));
453 TPlane3D<Real> plane42 = TPlane3D<Real>(ray2.origin, ray2.direction.cross(ray4.direction));
454 TPlane3D<Real> plane14 = TPlane3D<Real>(ray4.origin, ray1.direction.cross(ray4.direction));
455 TPlane3D<Real> plane32 = TPlane3D<Real>(ray3.origin, ray2.direction.cross(ray3.direction));
457 auto& initialEdgeSet = this->inInitialEdgeSet()->getData();
458 auto& edges = initialEdgeSet.getEdges();
459 auto& points = initialEdgeSet.getPoints();
460 DArray<int> intersected;
461 intersected.resize(edges.size());
462 cuExecute(edges.size(),
463 EI_EdgeInitializeArray,
466 DArray<int> unintersected;
467 unintersected.resize(edges.size());
468 this->tempNumT = edges.size();
469 cuExecute(edges.size(),
470 EI_CalIntersectedEdgesBox,
479 this->varInteractionRadius()->getData(),
483 this->tempEdgeIntersectedIndex.assign(intersected);
485 if (this->varToggleMultiSelect()->getData())
487 if (this->edgeIntersectedIndex.size() == 0)
489 this->edgeIntersectedIndex.resize(edges.size());
490 cuExecute(edges.size(),
491 EI_EdgeInitializeArray,
492 this->edgeIntersectedIndex
495 DArray<int> outIntersected;
496 outIntersected.resize(intersected.size());
497 DArray<int> outUnintersected;
498 outUnintersected.resize(unintersected.size());
499 if (this->varMultiSelectionType()->getValue() == MultiSelectionType::OR)
501 cuExecute(edges.size(),
502 EI_EdgeMergeIntersectedIndexOR,
503 this->edgeIntersectedIndex,
509 else if (this->varMultiSelectionType()->getValue() == MultiSelectionType::XOR)
511 cuExecute(edges.size(),
512 EI_EdgeMergeIntersectedIndexXOR,
513 this->edgeIntersectedIndex,
519 else if (this->varMultiSelectionType()->getValue() == MultiSelectionType::C)
521 cuExecute(edges.size(),
522 EI_EdgeMergeIntersectedIndexC,
523 this->edgeIntersectedIndex,
529 intersected.assign(outIntersected);
530 unintersected.assign(outUnintersected);
534 this->edgeIntersectedIndex.assign(intersected);
537 DArray<int> intersected_o;
538 intersected_o.assign(intersected);
540 int intersected_size = thrust::reduce(thrust::device, intersected.begin(), intersected.begin() + intersected.size(), (int)0, thrust::plus<int>());
541 DArray<int> outEdgeIndex;
542 outEdgeIndex.resize(intersected_size);
543 thrust::exclusive_scan(thrust::device, intersected.begin(), intersected.begin() + intersected.size(), intersected.begin());
544 DArray<Edge> intersected_edges;
545 intersected_edges.resize(intersected_size);
547 int unintersected_size = thrust::reduce(thrust::device, unintersected.begin(), unintersected.begin() + unintersected.size(), (int)0, thrust::plus<int>());
548 thrust::exclusive_scan(thrust::device, unintersected.begin(), unintersected.begin() + unintersected.size(), unintersected.begin());
549 DArray<Edge> unintersected_edges;
550 unintersected_edges.resize(unintersected_size);
552 cuExecute(edges.size(),
562 this->tempNumS = intersected_size;
563 this->outSelectedEdgeSet()->getDataPtr()->copyFrom(initialEdgeSet);
564 this->outSelectedEdgeSet()->getDataPtr()->setEdges(intersected_edges);
565 this->outOtherEdgeSet()->getDataPtr()->copyFrom(initialEdgeSet);
566 this->outOtherEdgeSet()->getDataPtr()->setEdges(unintersected_edges);
567 if (this->varToggleIndexOutput()->getValue())
569 this->outEdgeIndex()->getDataPtr()->assign(outEdgeIndex);
573 this->outEdgeIndex()->getDataPtr()->assign(intersected_o);
577 template<typename TDataType>
578 void EdgeInteraction<TDataType>::mergeIndex()
580 auto& initialEdgeSet = this->inInitialEdgeSet()->getData();
581 auto& edges = initialEdgeSet.getEdges();
582 auto& points = initialEdgeSet.getPoints();
583 DArray<int> intersected;
584 intersected.resize(edges.size());
585 cuExecute(edges.size(),
586 EI_EdgeInitializeArray,
589 DArray<int> unintersected;
590 unintersected.resize(edges.size());
591 this->tempNumT = edges.size();
593 DArray<int> outIntersected;
594 outIntersected.resize(intersected.size());
595 DArray<int> outUnintersected;
596 outUnintersected.resize(unintersected.size());
598 if (this->varMultiSelectionType()->getValue() == MultiSelectionType::OR)
600 cuExecute(edges.size(),
601 EI_EdgeMergeIntersectedIndexOR,
602 this->edgeIntersectedIndex,
603 this->tempEdgeIntersectedIndex,
608 else if (this->varMultiSelectionType()->getValue() == MultiSelectionType::XOR)
610 cuExecute(edges.size(),
611 EI_EdgeMergeIntersectedIndexXOR,
612 this->edgeIntersectedIndex,
613 this->tempEdgeIntersectedIndex,
618 else if (this->varMultiSelectionType()->getValue() == MultiSelectionType::C)
620 cuExecute(edges.size(),
621 EI_EdgeMergeIntersectedIndexC,
622 this->edgeIntersectedIndex,
623 this->tempEdgeIntersectedIndex,
629 intersected.assign(outIntersected);
630 unintersected.assign(outUnintersected);
631 this->edgeIntersectedIndex.assign(intersected);
633 DArray<int> intersected_o;
634 intersected_o.assign(intersected);
636 int intersected_size = thrust::reduce(thrust::device, intersected.begin(), intersected.begin() + intersected.size(), (int)0, thrust::plus<int>());
637 DArray<int> outEdgeIndex;
638 outEdgeIndex.resize(intersected_size);
639 thrust::exclusive_scan(thrust::device, intersected.begin(), intersected.begin() + intersected.size(), intersected.begin());
640 DArray<Edge> intersected_edges;
641 intersected_edges.resize(intersected_size);
643 int unintersected_size = thrust::reduce(thrust::device, unintersected.begin(), unintersected.begin() + unintersected.size(), (int)0, thrust::plus<int>());
644 thrust::exclusive_scan(thrust::device, unintersected.begin(), unintersected.begin() + unintersected.size(), unintersected.begin());
645 DArray<Edge> unintersected_edges;
646 unintersected_edges.resize(unintersected_size);
648 cuExecute(edges.size(),
658 this->tempNumS = intersected_size;
659 this->outSelectedEdgeSet()->getDataPtr()->copyFrom(initialEdgeSet);
660 this->outSelectedEdgeSet()->getDataPtr()->setEdges(intersected_edges);
661 this->outOtherEdgeSet()->getDataPtr()->copyFrom(initialEdgeSet);
662 this->outOtherEdgeSet()->getDataPtr()->setEdges(unintersected_edges);
663 if (this->varToggleIndexOutput()->getData())
665 this->outEdgeIndex()->getDataPtr()->assign(outEdgeIndex);
669 this->outEdgeIndex()->getDataPtr()->assign(intersected_o);
673 template<typename TDataType>
674 void EdgeInteraction<TDataType>::printInfoClick()
676 std::cout << "----------edge picking: click----------" << std::endl;
677 std::cout << "multiple picking: " << this->varToggleMultiSelect()->getValue() << std::endl;
678 std::cout << "Interation radius:" << this->varInteractionRadius()->getValue() << std::endl;
679 std::cout << "selected num/ total num:" << this->tempNumS << "/" << this->tempNumT << std::endl;
682 template<typename TDataType>
683 void EdgeInteraction<TDataType>::printInfoDragging()
685 std::cout << "----------edge picking: dragging----------" << std::endl;
686 std::cout << "multiple picking: " << this->varToggleMultiSelect()->getValue() << std::endl;
687 std::cout << "Interation radius:" << this->varInteractionRadius()->getValue() << std::endl;
688 std::cout << "selected num/ total num:" << this->tempNumS << "/" << this->tempNumT << std::endl;
691 template<typename TDataType>
692 void EdgeInteraction<TDataType>::printInfoDragRelease()
694 std::cout << "----------edge picking: drag release----------" << std::endl;
695 std::cout << "multiple picking: " << this->varToggleMultiSelect()->getValue() << std::endl;
696 std::cout << "Interation radius:" << this->varInteractionRadius()->getValue() << std::endl;
697 std::cout << "selected num/ total num:" << this->tempNumS << "/" << this->tempNumT << std::endl;
700 template<typename TDataType>
701 void EdgeInteraction<TDataType>::calcIntersectClick()
703 if(this->varTogglePicker()->getData())
704 calcEdgeIntersectClick();
707 template<typename TDataType>
708 void EdgeInteraction<TDataType>::calcIntersectDrag()
710 if (this->varTogglePicker()->getData())
711 calcEdgeIntersectDrag();
714 DEFINE_CLASS(EdgeInteraction);