1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkPiecewiseControlPointsItem.cxx
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
13
14 =========================================================================*/
15
16 #include "vtkBrush.h"
17 #include "vtkCallbackCommand.h"
18 #include "vtkContext2D.h"
19 #include "vtkIdTypeArray.h"
20 #include "vtkPiecewiseFunction.h"
21 #include "vtkPiecewiseControlPointsItem.h"
22 #include "vtkObjectFactory.h"
23 #include "vtkPen.h"
24 #include "vtkPoints2D.h"
25 #include "vtkContextScene.h"
26
27 // to handle mouse.GetButton
28 #include "vtkContextMouseEvent.h"
29
30 #include <cassert>
31 #include <limits>
32 #include <algorithm>
33
34 //-----------------------------------------------------------------------------
35 vtkStandardNewMacro(vtkPiecewiseControlPointsItem);
36
37 //-----------------------------------------------------------------------------
vtkPiecewiseControlPointsItem()38 vtkPiecewiseControlPointsItem::vtkPiecewiseControlPointsItem()
39 {
40 this->PiecewiseFunction = 0;
41 }
42
43 //-----------------------------------------------------------------------------
~vtkPiecewiseControlPointsItem()44 vtkPiecewiseControlPointsItem::~vtkPiecewiseControlPointsItem()
45 {
46 if (this->PiecewiseFunction)
47 {
48 this->PiecewiseFunction->RemoveObserver(this->Callback);
49 this->PiecewiseFunction->Delete();
50 this->PiecewiseFunction = 0;
51 }
52 }
53
54 //-----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)55 void vtkPiecewiseControlPointsItem::PrintSelf(ostream &os, vtkIndent indent)
56 {
57 this->Superclass::PrintSelf(os, indent);
58 os << indent << "PiecewiseFunction: ";
59 if (this->PiecewiseFunction)
60 {
61 os << endl;
62 this->PiecewiseFunction->PrintSelf(os, indent.GetNextIndent());
63 }
64 else
65 {
66 os << "(none)" << endl;
67 }
68 }
69
70 //-----------------------------------------------------------------------------
emitEvent(unsigned long event,void * params)71 void vtkPiecewiseControlPointsItem::emitEvent(unsigned long event, void* params)
72 {
73 if (this->PiecewiseFunction)
74 {
75 this->PiecewiseFunction->InvokeEvent(event, params);
76 }
77 }
78
79 //-----------------------------------------------------------------------------
GetControlPointsMTime()80 unsigned long int vtkPiecewiseControlPointsItem::GetControlPointsMTime()
81 {
82 if (this->PiecewiseFunction)
83 {
84 return this->PiecewiseFunction->GetMTime();
85 }
86 return this->GetMTime();
87 }
88
89 //-----------------------------------------------------------------------------
SetPiecewiseFunction(vtkPiecewiseFunction * t)90 void vtkPiecewiseControlPointsItem::SetPiecewiseFunction(vtkPiecewiseFunction* t)
91 {
92 if (t == this->PiecewiseFunction)
93 {
94 return;
95 }
96 if (this->PiecewiseFunction)
97 {
98 this->PiecewiseFunction->RemoveObserver(this->Callback);
99 }
100 vtkSetObjectBodyMacro(PiecewiseFunction, vtkPiecewiseFunction, t);
101 if (this->PiecewiseFunction)
102 {
103 this->PiecewiseFunction->AddObserver(vtkCommand::StartEvent, this->Callback);
104 this->PiecewiseFunction->AddObserver(vtkCommand::ModifiedEvent, this->Callback);
105 this->PiecewiseFunction->AddObserver(vtkCommand::EndEvent, this->Callback);
106 }
107 this->ResetBounds();
108 this->ComputePoints();
109 }
110
111 //-----------------------------------------------------------------------------
GetNumberOfPoints() const112 vtkIdType vtkPiecewiseControlPointsItem::GetNumberOfPoints()const
113 {
114 return this->PiecewiseFunction ?
115 static_cast<vtkIdType>(this->PiecewiseFunction->GetSize()) : 0;
116 }
117
118 //-----------------------------------------------------------------------------
GetControlPoint(vtkIdType index,double * pos) const119 void vtkPiecewiseControlPointsItem::GetControlPoint(vtkIdType index, double* pos)const
120 {
121 const_cast<vtkPiecewiseFunction*>(this->PiecewiseFunction)
122 ->GetNodeValue(index, pos);
123 }
124
125 //-----------------------------------------------------------------------------
SetControlPoint(vtkIdType index,double * newPos)126 void vtkPiecewiseControlPointsItem::SetControlPoint(vtkIdType index, double* newPos)
127 {
128 double oldPos[4];
129 this->PiecewiseFunction->GetNodeValue(index, oldPos);
130 if (newPos[0] != oldPos[0] || newPos[1] != oldPos[1] ||
131 newPos[2] != oldPos[2])
132 {
133 this->StartChanges();
134 this->PiecewiseFunction->SetNodeValue(index, newPos);
135 this->EndChanges();
136 }
137 }
138
139 //-----------------------------------------------------------------------------
EditPoint(float tX,float tY)140 void vtkPiecewiseControlPointsItem::EditPoint(float tX, float tY)
141 {
142 if (!this->PiecewiseFunction)
143 {
144 return;
145 }
146
147 this->StartChanges();
148
149 double xvms[4];
150 this->PiecewiseFunction->GetNodeValue(this->CurrentPoint, xvms);
151 xvms[2] += tX;
152 xvms[3] += tY;
153 this->PiecewiseFunction->SetNodeValue(this->CurrentPoint, xvms);
154 if (this->CurrentPoint > 0)
155 {
156 this->PiecewiseFunction->GetNodeValue(this->CurrentPoint - 1, xvms);
157 xvms[2] += tX;
158 xvms[3] += tY;
159 this->PiecewiseFunction->SetNodeValue(this->CurrentPoint - 1, xvms);
160 }
161
162 this->EndChanges();
163 }
164
165 //-----------------------------------------------------------------------------
AddPoint(double * newPos)166 vtkIdType vtkPiecewiseControlPointsItem::AddPoint(double* newPos)
167 {
168 if (!this->PiecewiseFunction)
169 {
170 return -1;
171 }
172
173 this->StartChanges();
174 vtkIdType addedPoint = this->PiecewiseFunction->AddPoint(newPos[0], newPos[1]);
175 this->Superclass::AddPointId(addedPoint);
176 this->EndChanges();
177
178 return addedPoint;
179 }
180
181 //-----------------------------------------------------------------------------
RemovePoint(double * currentPoint)182 vtkIdType vtkPiecewiseControlPointsItem::RemovePoint(double* currentPoint)
183 {
184 if (!this->PiecewiseFunction)
185 {
186 return -1;
187 }
188 if (!this->IsPointRemovable(this->GetControlPointId(currentPoint)))
189 {
190 return -1;
191 }
192
193 this->StartChanges();
194
195 #ifndef NDEBUG
196 vtkIdType expectedPoint =
197 #endif
198 this->vtkControlPointsItem::RemovePoint(currentPoint);
199 vtkIdType removedPoint =
200 this->PiecewiseFunction->RemovePoint(currentPoint[0]);
201 assert(removedPoint == expectedPoint);
202
203 this->EndChanges();
204
205 return removedPoint;
206 }
207