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