7 #include "uiVisuQt/STransformEditor.hpp" 9 #include <fwCom/Signal.hxx> 11 #include <fwData/TransformationMatrix3D.hpp> 13 #include <fwDataTools/TransformationMatrix3D.hpp> 15 #include <fwGuiQt/container/QtContainer.hpp> 17 #include <fwServices/macros.hpp> 19 #include <boost/regex.hpp> 21 #include <glm/gtc/matrix_transform.hpp> 22 #include <glm/gtc/quaternion.hpp> 23 #include <glm/mat4x4.hpp> 25 #include <QHBoxLayout> 30 #include <QVBoxLayout> 43 m_translationRange[0] = -300;
44 m_translationRange[1] = +300;
45 m_rotationRange[0] = -180;
46 m_rotationRange[1] = 180;
60 static const ::boost::regex s_REGEX(
"[xyz][xyz]?[xyz]?");
64 ::fwServices::IService::ConfigType config = this->
getConfigTree();
66 const std::string rotation = config.get< std::string >(
"rotation.<xmlattr>.enabled",
"yes");
72 else if(rotation ==
"yes")
76 else if( ::boost::regex_match(rotation, s_REGEX) )
78 m_rotation = rotation;
82 SLM_ERROR(
"Attribute 'rotation' should be 'yes', 'no' or a combination of [xyz]");
85 m_rotationRange[0] = config.get<
int >(
"rotation.<xmlattr>.min", m_rotationRange[0]);
86 m_rotationRange[1] = config.get<
int >(
"rotation.<xmlattr>.max", m_rotationRange[1]);
88 const std::string translation = config.get< std::string >(
"translation.<xmlattr>.enabled",
"yes");
90 if(translation ==
"no")
94 else if(translation ==
"yes")
96 m_translation =
"xyz";
98 else if( ::boost::regex_match(translation, s_REGEX) )
100 m_translation = translation;
104 SLM_ERROR(
"Attribute 'translation' should be 'yes', 'no' or a combination of [xyz]");
107 m_translationRange[0] = config.get<
int >(
"translation.<xmlattr>.min", m_translationRange[0]);
108 m_translationRange[1] = config.get<
int >(
"translation.<xmlattr>.max", m_translationRange[1]);
115 const char* description[] = {
"Translation X",
"Translation Y",
"Translation Z",
116 "Rotation X",
"Rotation Y",
"Rotation Z"};
119 ::fwGuiQt::container::QtContainer::sptr qtContainer =
120 ::fwGuiQt::container::QtContainer::dynamicCast( this->getContainer() );
122 QVBoxLayout* layout =
new QVBoxLayout();
124 qtContainer->setLayout( layout );
126 for (
unsigned int i = 0; i < MAX_SLIDER_INDEX; i++)
128 QHBoxLayout* sliderLayout =
new QHBoxLayout();
130 m_sliders[i].m_sliderValue =
new QLineEdit();
131 m_sliders[i].m_labelMin =
new QLabel();
132 m_sliders[i].m_labelMax =
new QLabel();
133 m_sliders[i].m_labelDefinition =
new QLabel();
135 m_sliders[i].m_slider =
new QSlider(Qt::Horizontal);
136 m_sliders[i].m_slider->setTickInterval(1);
138 m_sliders[i].m_labelDefinition->setText(description[i]);
140 sliderLayout->addWidget( m_sliders[i].m_labelDefinition, 0);
141 sliderLayout->addWidget( m_sliders[i].m_labelMin, 0);
142 sliderLayout->addWidget( m_sliders[i].m_slider, 3);
143 sliderLayout->addWidget( m_sliders[i].m_labelMax, 0);
144 sliderLayout->addWidget( m_sliders[i].m_sliderValue, 1);
146 layout->addLayout(sliderLayout, 0);
147 QObject::connect(m_sliders[i].m_slider, SIGNAL(valueChanged(
int)),
this, SLOT(onSliderChanged(
int)));
148 QObject::connect(m_sliders[i].m_sliderValue, SIGNAL(editingFinished()),
this, SLOT(onTextChanged()));
151 for (
unsigned int i = POSITION_X; i <= POSITION_Z; i++)
153 m_sliders[i].m_labelMin->setText(std::to_string(m_translationRange[0]).c_str());
154 m_sliders[i].m_labelMax->setText(std::to_string(m_translationRange[1]).c_str());
155 m_sliders[i].m_slider->setRange(m_translationRange[0], m_translationRange[1]);
158 const char axes[] = {
"xyzxyz"};
160 for (
unsigned int i = POSITION_X; i <= POSITION_Z; i++)
162 const bool visible = m_translation.find(axes[i]) != std::string::npos;
163 m_sliders[i].m_sliderValue->setVisible( visible );
164 m_sliders[i].m_labelMin->setVisible( visible );
165 m_sliders[i].m_labelMax->setVisible( visible );
166 m_sliders[i].m_labelDefinition->setVisible( visible );
167 m_sliders[i].m_slider->setVisible( visible );
170 for (
unsigned int i = ROTATION_X; i <= ROTATION_Z; i++)
172 m_sliders[i].m_labelMin->setText(std::to_string(m_rotationRange[0]).c_str());
173 m_sliders[i].m_labelMax->setText(std::to_string(m_rotationRange[1]).c_str());
174 m_sliders[i].m_slider->setRange(m_rotationRange[0], m_rotationRange[1]);
177 for (
unsigned int i = ROTATION_X; i <= ROTATION_Z; i++)
179 const bool visible = m_rotation.find(axes[i]) != std::string::npos;
180 m_sliders[i].m_sliderValue->setVisible( visible );
181 m_sliders[i].m_labelMin->setVisible( visible );
182 m_sliders[i].m_labelMax->setVisible( visible );
183 m_sliders[i].m_labelDefinition->setVisible( visible );
184 m_sliders[i].m_slider->setVisible( visible );
187 this->updateFromMatrix();
194 for (
unsigned int i = 0; i < MAX_SLIDER_INDEX; i++)
196 QObject::disconnect(m_sliders[i].m_slider, SIGNAL(valueChanged(
int)),
this, SLOT(onSliderChanged(
int)));
197 QObject::disconnect(m_sliders[i].m_sliderValue, SIGNAL(editingFinished()),
this, SLOT(onTextChanged()));
207 this->updateFromMatrix();
212 void STransformEditor::onSliderChanged(
int value)
214 ::fwData::TransformationMatrix3D::sptr matrix = this->getInOut< ::fwData::TransformationMatrix3D >(
"matrix");
216 const double rx = ::glm::radians<double>(m_sliders[ROTATION_X].m_slider->value());
217 const double ry = ::glm::radians<double>(m_sliders[ROTATION_Y].m_slider->value());
218 const double rz = ::glm::radians<double>(m_sliders[ROTATION_Z].m_slider->value());
220 const double tx = m_sliders[POSITION_X].m_slider->value();
221 const double ty = m_sliders[POSITION_Y].m_slider->value();
222 const double tz = m_sliders[POSITION_Z].m_slider->value();
224 ::glm::dquat quat = ::glm::dquat(::glm::dvec3(rx, ry, rz));
225 ::glm::dmat4x4 mat = ::glm::mat4_cast(quat);
227 mat[3] = ::glm::dvec4(tx, ty, tz, 1.);
231 for (
unsigned int i = 0; i < MAX_SLIDER_INDEX; i++)
233 m_sliders[i].m_sliderValue->setText(QString(
"%1").arg(m_sliders[i].m_slider->value()));
245 void STransformEditor::onTextChanged()
247 for (
unsigned int i = 0; i < MAX_SLIDER_INDEX; i++)
249 QString
string = m_sliders[i].m_sliderValue->text();
250 m_sliders[i].m_slider->setValue(
string.toInt());
256 void STransformEditor::updateFromMatrix()
258 ::fwData::TransformationMatrix3D::sptr matrix = this->getInOut< ::fwData::TransformationMatrix3D >(
"matrix");
263 const ::glm::dquat quat(mat);
264 const ::glm::dvec3 angles = ::glm::eulerAngles(quat);
266 const ::glm::dvec4 translation = mat[3];
269 for (
unsigned int i = 0; i < MAX_SLIDER_INDEX; i++)
271 m_sliders[i].m_slider->blockSignals(
true);
272 m_sliders[i].m_sliderValue->blockSignals(
true);
275 for (::glm::length_t i = POSITION_X, j = 0; i <= POSITION_Z; i++, ++j)
277 m_sliders[i].m_slider->setValue(static_cast<int>(translation[j]));
280 for (::glm::length_t i = ROTATION_X, j = 0; i <= ROTATION_Z; i++, ++j)
282 m_sliders[i].m_slider->setValue(static_cast<int>(::glm::degrees<double>(angles[j])));
285 for (
unsigned int i = 0; i < MAX_SLIDER_INDEX; i++)
287 m_sliders[i].m_sliderValue->setText(QString(
"%1").arg(m_sliders[i].m_slider->value()));
290 for (
unsigned int i = 0; i < MAX_SLIDER_INDEX; i++)
292 m_sliders[i].m_slider->blockSignals(
false);
293 m_sliders[i].m_sliderValue->blockSignals(
false);
Class allowing to block a Connection.
Defines the service interface managing the editor service for object.
FWGUI_API void destroy()
Stops sub-views and toobar services. Destroys view, sub-views and toolbar containers.
The namespace uiVisuQt supplies user interface editors done with Qt.
UpdateSlotType::sptr m_slotUpdate
Slot to call update method.
#define SLM_ERROR(message)
#define SLM_ASSERT(message, cond)
work like 'assert' from 'cassert', with in addition a message logged by spylog (with FATAL loglevel) ...
FWGUI_API void create()
Creates view, sub-views and toolbar containers. Manages sub-views and toobar services.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_MODIFIED_SIG
Key in m_signals map of signal m_sigModified.
FWGUI_API void initialize()
Initialize managers.
FWSERVICES_API ConfigType getConfigTree() const
Return the configuration, in an boost property tree.