ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
cvCustomAxisHandleRepresentation.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 
9 
10 #include <vtkMath.h>
11 #include <vtkObjectFactory.h>
12 
14 
15 #if !((VTK_MAJOR_VERSION > 9) || \
16  (VTK_MAJOR_VERSION == 9 && VTK_MINOR_VERSION >= 3))
17 
18 //------------------------------------------------------------------------------
20  : CustomAxisEnabled(false) {
21  this->CustomTranslationAxis[0] = 1.0;
22  this->CustomTranslationAxis[1] = 0.0;
23  this->CustomTranslationAxis[2] = 0.0;
24 }
25 
26 //------------------------------------------------------------------------------
28 
29 //------------------------------------------------------------------------------
31  if (!this->CustomAxisEnabled) {
32  this->CustomAxisEnabled = true;
33  // Disable standard axis constraints
34  this->SetTranslationAxis(-1); // -1 = Axis::NONE
35  this->Modified();
36  }
37 }
38 
39 //------------------------------------------------------------------------------
41  if (this->CustomAxisEnabled) {
42  this->CustomAxisEnabled = false;
43  this->Modified();
44  }
45 }
46 
47 //------------------------------------------------------------------------------
49  double axis[3]) {
50  bool changed = false;
51  for (int i = 0; i < 3; i++) {
52  if (this->CustomTranslationAxis[i] != axis[i]) {
53  this->CustomTranslationAxis[i] = axis[i];
54  changed = true;
55  }
56  }
57 
58  if (changed) {
59  // Normalize the axis vector
60  vtkMath::Normalize(this->CustomTranslationAxis);
61  this->Modified();
62  }
63 }
64 
65 //------------------------------------------------------------------------------
67  double y,
68  double z) {
69  double axis[3] = {x, y, z};
70  this->SetCustomTranslationAxis(axis);
71 }
72 
73 //------------------------------------------------------------------------------
75  const double* p2,
76  double* v) const {
77  double p12[3];
78  vtkMath::Subtract(p2, p1, p12);
79 
80  if (this->CustomAxisEnabled) {
81  // Project the translation vector onto the custom axis
82  // Following ParaView's implementation in vtkHandleRepresentation.cxx
83  vtkMath::ProjectVector(p12, this->CustomTranslationAxis, v);
84  } else {
85  // Use standard translation (or axis-constrained if TranslationAxis is
86  // set)
87  int translationAxis =
88  const_cast<cvCustomAxisHandleRepresentation*>(this)
89  ->GetTranslationAxis();
90  if (translationAxis == -1) { // Axis::NONE
91  // Free translation
92  for (int i = 0; i < 3; ++i) {
93  v[i] = p12[i];
94  }
95  } else {
96  // Standard axis constraint (X=0, Y=1, Z=2)
97  for (int i = 0; i < 3; ++i) {
98  if (translationAxis == i) {
99  v[i] = p12[i];
100  } else {
101  v[i] = 0.0;
102  }
103  }
104  }
105  }
106 }
107 
108 //------------------------------------------------------------------------------
110  const double* p2) {
111  double v[3];
112  this->GetTranslationVector(p1, p2, v);
113  this->Translate(v);
114 }
115 
116 //------------------------------------------------------------------------------
118  if (this->CustomAxisEnabled) {
119  // Project the translation vector onto the custom axis
120  // Following ParaView's implementation in vtkHandleRepresentation.cxx
121  double dir[3];
122  vtkMath::ProjectVector(v, this->CustomTranslationAxis, dir);
123 
124  // Apply the translation
125  double* worldPos = this->GetWorldPosition();
126  double newPos[3];
127  for (int i = 0; i < 3; ++i) {
128  newPos[i] = worldPos[i] + dir[i];
129  }
130  this->SetWorldPosition(newPos);
131  } else {
132  // Use base class implementation for standard axes
133  this->Superclass::Translate(v);
134  }
135 }
136 
137 //------------------------------------------------------------------------------
139  vtkIndent indent) {
140  this->Superclass::PrintSelf(os, indent);
141 
142  os << indent
143  << "Custom Axis Enabled: " << (this->CustomAxisEnabled ? "On" : "Off")
144  << "\n";
145  os << indent << "Custom Translation Axis: ("
146  << this->CustomTranslationAxis[0] << ", "
147  << this->CustomTranslationAxis[1] << ", "
148  << this->CustomTranslationAxis[2] << ")\n";
149 }
150 
151 #else
152 
153 // VTK 9.3+ implementation - just use base class
155  vtkIndent indent) {
156  this->Superclass::PrintSelf(os, indent);
157 }
158 
159 #endif
Handle representation with custom translation axis support.
void SetCustomTranslationAxisOff()
Disable custom translation axis mode.
void PrintSelf(ostream &os, vtkIndent indent) override
void SetCustomTranslationAxisOn()
Enable custom translation axis mode.
void Translate(const double *p1, const double *p2) override
Override Translate to support custom axis.
void GetTranslationVector(const double *p1, const double *p2, double *v) const override
Override GetTranslationVector to support custom axis.
void SetCustomTranslationAxis(double axis[3])
Set the custom translation axis vector.
vtkStandardNewMacro(cvCustomAxisHandleRepresentation)
normal_z y
normal_z x
normal_z z