inline virtual void updateGui() { _singleValueLabel.set_visible(false); for (size_t i(0); i < 4; ++i) _scalarvalues[i].hide(); bool singlevalmode = singleValueMode(); if (_components && singlevalmode) { _singleValueLabel.set_visible(true); for (size_t i(0); i < _components; ++i) _scalarvalues[i].show(); } _componentSelect.clear_items(); if (singlevalmode || !_enableDataFiltering) _componentSelect.set_visible(false); else { _componentSelect.set_visible(true); Gtk::TreeModel::iterator iter = _comboBox.get_active(); std::tr1::shared_ptr<Attribute> ptr = (*iter)[_modelColumns.m_ptr]; _componentSelect.append_text("Raw Data"); _componentSelect.append_text("Magnitude"); _componentSelect.append_text("X"); if (ptr->components() > 1) _componentSelect.append_text("Y"); if (ptr->components() > 2) _componentSelect.append_text("Z"); if (ptr->components() > 3) _componentSelect.append_text("W"); //Default to coloring using the magnitude _componentSelect.set_active(1); } for (size_t i(0); i < _components; ++i) _scalarvalues[i].set_sensitive(singlevalmode); }
std::vector<GLfloat> AttributeSelector::getMin() { if (singleValueMode()) { std::vector<GLfloat> _retVal(4); for (size_t i(0); i < 4; ++i) try { _retVal[i] = boost::lexical_cast<double>(_scalarvalues[i].get_text()); } catch (...) {} return _retVal; } Gtk::TreeModel::iterator iter = _comboBox.get_active(); if (!iter) return std::vector<GLfloat>(); std::tr1::shared_ptr<Attribute> ptr = (*iter)[_modelColumns.m_ptr]; if (!ptr) return std::vector<GLfloat>(); return ptr->minVals(); }
virtual void bindAttribute(size_t attrnum, size_t divisor = 1) { Gtk::TreeModel::iterator iter = _comboBox.get_active(); if (singleValueMode()) { setConstantAttribute(attrnum); return; } std::tr1::shared_ptr<Attribute> ptr = (*iter)[_modelColumns.m_ptr]; if (ptr->components() == 4) { ptr->bindAttribute(attrnum, false, divisor); return; } if (ptr->components() != 3) M_throw() << "Cannot create orientation from anything other than a 3 component Attribute"; if ((_lastAttribute != ptr.get()) || (_lastAttributeDataCount != ptr->getUpdateCount()) || _filteredData.empty()) { _lastAttribute = ptr.get(); _lastAttributeDataCount = ptr->getUpdateCount(); const size_t elements = ptr->num_elements(); _filteredData.init(4 * elements); const std::vector<GLfloat>& attrdata = *ptr; GLfloat* glptr = _filteredData.map(); for (size_t i(0); i < elements; ++i) { //First we use the vector and axis to calculate a //rotation twice as big as is needed. Vector vec(attrdata[3 * i + 0], attrdata[3 * i + 1], attrdata[3 * i + 2]); Vector axis(0,0,1); double vecnrm = vec.nrm(); double cosangle = (vec | axis) / vecnrm; //Special case of no rotation or zero length vector if ((vecnrm == 0) || (cosangle == 1)) { glptr[4 * i + 0] = glptr[4 * i + 1] = glptr[4 * i + 2] = 0; glptr[4 * i + 3] = 1; continue; } //Special case where vec and axis are opposites if (cosangle == -1) { //Just rotate around the x axis by 180 degrees glptr[4 * i + 0] = 1; glptr[4 * i + 1] = glptr[4 * i + 2] = glptr[4 * i + 3] = 0; continue; } //Calculate the rotation axis Vector rot_axis = (vec ^ axis) / vecnrm; for (size_t j(0); j < 3; ++j) glptr[4 * i + j] = rot_axis[j]; glptr[4 * i + 3] = cosangle; double sum = 0; for (size_t j(0); j < 4; ++j) sum += glptr[4 * i + j] * glptr[4 * i + j]; sum = std::sqrt(sum); for (size_t j(0); j < 4; ++j) glptr[4 * i + j] /= sum; //As the rotation is twice as big as needed, we must do //a half angle conversion. glptr[4 * i + 3] += 1; sum = 0; for (size_t j(0); j < 4; ++j) sum += glptr[4 * i + j] * glptr[4 * i + j]; sum = std::sqrt(sum); for (size_t j(0); j < 4; ++j) glptr[4 * i + j] /= sum; } _filteredData.unmap(); } _filteredData.attachToAttribute(attrnum, 4, divisor); }
virtual void bindAttribute(size_t attrnum, size_t divisor = 1) { Gtk::TreeModel::iterator iter = _comboBox.get_active(); if (singleValueMode()) setConstantAttribute(attrnum); else { std::shared_ptr<Attribute> ptr = (*iter)[_modelColumns.m_ptr]; //We have an attribute, check the mode the ComboBox is in, //and determine if we have to do something with the data! //Detect if it is in simple pass-through mode if ((_componentSelect.get_visible()) && (_componentSelect.get_active_row_number() == 0)) { ptr->bindAttribute(attrnum, false, divisor); return; } //Check if the data actually needs updating if ((_lastAttribute != ptr.get()) || (_lastAttributeDataCount != ptr->getUpdateCount()) || (_lastComponentSelected != _componentSelect.get_active_row_number()) || (_lastColorMap != _colorMapSelector.getMode()) || _filteredData.empty()) { std::vector<GLfloat> scalardata; generateFilteredData(scalardata, ptr, _lastComponentSelected); if (_autoScaling.get_active() && !scalardata.empty()) { GLfloat min(scalardata[0]), max(scalardata[0]); for (std::vector<GLfloat>::const_iterator iPtr = scalardata.begin(); iPtr != scalardata.end(); ++iPtr) { min = std::min(min, *iPtr); max = std::max(max, *iPtr); } _colorMapSelector.setRange(min, max); } //Now convert to HSV or whatever _filteredData.init(4 * scalardata.size(), 4); GLfloat* data_ptr = _filteredData.map(); for (size_t i(0); i < scalardata.size(); ++i) _colorMapSelector.map(data_ptr + 4 * i, scalardata[i]); _filteredData.unmap(); _lastAttribute = ptr.get(); _lastAttributeDataCount = ptr->getUpdateCount(); _lastComponentSelected = _componentSelect.get_active_row_number(); _lastColorMap = _colorMapSelector.getMode(); } _filteredData.attachToAttribute(attrnum, divisor); } }