ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
CustomVtkBoxWidget.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #include "CustomVtkBoxWidget.h"
9 
10 #include <vtkBoxWidget2.h>
11 #include <vtkDoubleArray.h>
12 #include <vtkMath.h>
13 #include <vtkPoints.h>
14 #include <vtkRenderWindowInteractor.h>
15 #include <vtkRenderer.h>
16 #include <vtkTransform.h>
17 
19 
20 /************************************************************************/
21 /* Translate: Iterate through all point sets (corners, vertices) and */
22 /* translate each point */
23 // Inputs:
24 // double *p1 : Coordinates of the point before mouse movement
25 // double *p2 : Coordinates of the point after mouse movement
26 /************************************************************************/
27 void CustomVtkBoxWidget::Translate(double *p1, double *p2) {
28  if (!m_translateX && !m_translateY && !m_translateZ) {
29  return;
30  }
31 
32  double *pts = static_cast<vtkDoubleArray *>(this->Points->GetData())
33  ->GetPointer(0);
34  double v[3];
35 
36  v[0] = m_translateX ? p2[0] - p1[0] : 0;
37  v[1] = m_translateY ? p2[1] - p1[1] : 0;
38  v[2] = m_translateZ ? p2[2] - p1[2] : 0;
39 
40  // Move the corners
41  for (int i = 0; i < 8; i++) {
42  *pts++ += v[0];
43  *pts++ += v[1];
44  *pts++ += v[2];
45  }
46  this->PositionHandles();
47 }
48 
49 /************************************************************************/
50 /* Scale: Scale the box widget */
51 // Inputs:
52 // double *p1 : Coordinates of the point before mouse movement
53 // double *p2 : Coordinates of the point after mouse movement
54 /************************************************************************/
55 void CustomVtkBoxWidget::Scale(double *p1, double *p2, int X, int Y) {
56  if (!m_scale) {
57  return;
58  }
59 
60  double *pts = static_cast<vtkDoubleArray *>(this->Points->GetData())
61  ->GetPointer(0);
62  double *center = static_cast<vtkDoubleArray *>(this->Points->GetData())
63  ->GetPointer(3 * 14);
64  double sf;
65 
66  if (Y > this->Interactor->GetLastEventPosition()[1]) {
67  sf = 1.03;
68  } else {
69  sf = 0.97;
70  }
71 
72  // Move the corners
73  for (int i = 0; i < 8; i++, pts += 3) {
74  pts[0] = sf * (pts[0] - center[0]) + center[0];
75  pts[1] = sf * (pts[1] - center[1]) + center[1];
76  pts[2] = sf * (pts[2] - center[2]) + center[2];
77  }
78  this->PositionHandles();
79 }
80 
81 /************************************************************************/
82 /* Rotate: Rotate the box widget */
83 // Inputs:
84 // int X : Current mouse position x-coordinate
85 // int Y : Current mouse position y-coordinate
86 // double *p1 : Coordinates of the point before mouse movement
87 // double *p2 : Coordinates of the point after mouse movement
88 // double *vpn : Normal vector
89 /************************************************************************/
91  int X, int Y, double *p1, double *p2, double *vpn) {
92  if (!m_rotateX && !m_rotateY && !m_rotateZ) {
93  return;
94  }
95 
96  double *pts = static_cast<vtkDoubleArray *>(this->Points->GetData())
97  ->GetPointer(0);
98  double *center = static_cast<vtkDoubleArray *>(this->Points->GetData())
99  ->GetPointer(3 * 14);
100  double v[3]; // vector of motion
101  double axis[3]; // axis of rotation
102  double theta; // rotation angle
103  int i;
104 
105  v[0] = m_rotateX ? p2[0] - p1[0] : 0;
106  v[1] = m_rotateY ? p2[1] - p1[1] : 0;
107  v[2] = m_rotateZ ? p2[2] - p1[2] : 0;
108 
109  // Create axis of rotation and angle of rotation
110  vtkMath::Cross(vpn, v, axis);
111  if (vtkMath::Normalize(axis) == 0.0) {
112  return;
113  }
114  int *size = this->CurrentRenderer->GetSize();
115  double l2 = (X - this->Interactor->GetLastEventPosition()[0]) *
116  (X - this->Interactor->GetLastEventPosition()[0]) +
117  (Y - this->Interactor->GetLastEventPosition()[1]) *
118  (Y - this->Interactor->GetLastEventPosition()[1]);
119  theta = 360.0 * sqrt(l2 / (size[0] * size[0] + size[1] * size[1]));
120  // vtkTransform :describes linear transformations via a 4x4 matrix
121  // Manipulate the transform to reflect the rotation
122  this->Transform->Identity();
123  this->Transform->Translate(center[0], center[1], center[2]);
124  this->Transform->RotateWXYZ(theta, axis);
125  this->Transform->Translate(-center[0], -center[1], -center[2]);
126 
127  // Set the corners
128  vtkPoints *newPts = vtkPoints::New(VTK_DOUBLE);
129  this->Transform->TransformPoints(this->Points, newPts);
130 
131  for (i = 0; i < 8; i++, pts += 3) { // Transform coordinates of 8 points
132  this->Points->SetPoint(i, newPts->GetPoint(i));
133  }
134 
135  newPts->Delete();
136  this->PositionHandles(); // Recalculate handle coordinates and update
137  // related data
138 }
vtkStandardNewMacro(CustomVtkBoxWidget)
int size
void * X
Definition: SmallVector.cpp:45
The CustomVtkBoxWidget class CustomVtkBoxWidget restricts the transformation.
virtual void Translate(double *p1, double *p2) override
virtual void Scale(double *p1, double *p2, int X, int Y) override
virtual void Rotate(int X, int Y, double *p1, double *p2, double *vpn) override
CLOUDVIEWER_HOST_DEVICE float Cross(const Point &a, const Point &b)
Definition: IoUImpl.h:39
void Transform(benchmark::State &state, const core::Device &device)
Definition: PointCloud.cpp:127
std::vector< Eigen::Vector3f > Points