44 #define OM_PROPERTY_MODEL_CC 46 #include "OMPropertyModel.hh" 48 #include "OMPropertyVisualizerBoolean.hh" 49 #include "OMPropertyVisualizerDouble.hh" 50 #include "OMPropertyVisualizerInteger.hh" 51 #include "OMPropertyVisualizerVector.hh" 52 #include "OMPropertyVisualizerVector2.hh" 53 #include "OMPropertyVisualizerVectorFieldDifference.hh" 55 #ifdef ENABLE_SKELETON_SUPPORT 56 #include "OMPropertyVisualizerSkinWeights.hh" 59 #include "../Utils.hh" 63 #include <QInputDialog> 64 #include <QTextStream> 66 #define PROP_VIS "PropertyVisualization" 68 template<
typename MeshT>
73 mCombineProperty1(nullptr),
74 mCombineProperty2(nullptr),
78 bCombine.setText(tr(
"Combine"));
80 connect(&bCombine, SIGNAL(clicked()),
81 this, SLOT(slotCombine()));
82 widgets->layout()->addWidget(&bCombine);
83 widgets->layout()->addWidget(&mLoadSaveWidget);
85 connect(mLoadSaveWidget.save_property , SIGNAL(clicked()),
86 this, SLOT(slotSaveProperty()));
88 connect(mLoadSaveWidget.load_property , SIGNAL(clicked()),
89 this, SLOT(slotLoadProperty()));
91 widgets->layout()->addWidget(&mPickWidget);
92 connect(mPickWidget.pickButton, SIGNAL(clicked()),
93 this, SLOT(slotPickProperty()));
95 QString iconPath = OpenFlipper::Options::iconDirStr() + OpenFlipper::Options::dirSeparator();
96 mPickWidget.pickButton->setIcon( QIcon(iconPath +
"color-picker.png") );
102 initializeSupportedPropertyTypes();
106 template<
typename MeshT>
111 if (selectedIndices.size() == 2)
113 if (combinable(propertyVisualizers[selectedIndices[0].row()], propertyVisualizers[selectedIndices[1].row()]))
117 mCombineProperty1 = &propertyVisualizers[selectedIndices[0].row()]->getPropertyInfo();
118 mCombineProperty2 = &propertyVisualizers[selectedIndices[1].row()]->getPropertyInfo();
126 if (selectedIndices.size() == 1)
132 if (mPickWidget.pickButton->isChecked())
137 template<
typename MeshT>
141 filter = tr(
"Vertex Property (*.vprop)");
142 filter += tr(
";; HalfEdge Property (*.hprop)");
143 filter += tr(
";; Edge Property (*.eprop)");
144 filter += tr(
";; Face Property (*.fprop)");
145 filter += tr(
";; All Files (*)");
149 template<
typename MeshT>
157 filter = tr(
"Vertex Property (*.vprop)");
159 filter = tr(
"HalfEdge Property (*.hprop)");
161 filter = tr(
"Edge Property (*.eprop)");
163 filter = tr(
"Face Property (*.fprop)");
165 filter += tr(
";; All Files (*)");
178 template<
typename MeshT>
182 if (isVectorType(mCombineProperty1->typeinfo()))
200 template<
typename MeshT>
208 return (isVectorType(typeInfo1) && isVectorType(typeInfo2)) && (propInfo1.entityType() == propInfo2.entityType());
211 template<
typename MeshT>
214 for (QModelIndexList::const_iterator it = currentlySelectedIndices.begin(), it_end = currentlySelectedIndices.end();
215 it != it_end; ++it) {
220 template<
typename MeshT>
223 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) 224 QStringList headerParts = header.split(tr(
", "), QString::SkipEmptyParts );
226 QStringList headerParts = header.split(tr(
", "), Qt::SkipEmptyParts );
229 int headerVersion = headerParts[0].toUInt();
230 if (headerVersion == 1)
232 n = headerParts[1].toUInt();
233 unsigned int nExpected = 0;
235 PropertyInfo::ENTITY_FILTER filter = (PropertyInfo::ENTITY_FILTER)headerParts[2].toInt();
238 case PropertyInfo::EF_FACE:
239 nExpected = mesh_->n_faces();
241 case PropertyInfo::EF_EDGE:
242 nExpected = mesh_->n_edges();
244 case PropertyInfo::EF_HALFEDGE:
245 nExpected = mesh_->n_halfedges();
247 case PropertyInfo::EF_VERTEX:
248 nExpected = mesh_->n_vertices();
257 emit log(
LOGERR,
"Could not load property: unexpected number of entities");
261 QString friendlyName = headerParts[3];
263 if (!isSupported(friendlyName))
265 emit log(
LOGERR, tr(
"Could not load property: unsupported property type %1").arg(friendlyName));
271 QString propName = QInputDialog::getText(
nullptr,
"Property Name",
"Please enter name.",QLineEdit::Normal,headerParts[4]);
272 if (propName ==
"")
return false;
274 bool replace =
false;
281 propName = QInputDialog::getText(0,
"New Property Name",
"Please enter new name.");
282 else if (msgBox->cancel)
284 else if (msgBox->replace)
292 addProperty(propName, friendlyName, filter);
303 emit log(
LOGERR,
"Could not load property: unsupported header format");
309 template<
typename MeshT>
312 #ifdef ENABLE_SKELETON_SUPPORT 315 for (
unsigned int i = 0; i < n; ++i)
317 QString propertyText =
"";
319 while ((tmp = file_stream.readLine()) !=
"")
320 propertyText = propertyText + tmp;
331 template<
typename MeshT>
344 template<
typename MeshT>
347 if ( mPickWidget.pickButton->isChecked() ){
361 template<
typename MeshT>
364 pickModeActive = (_mode == PROP_VIS);
368 lastPickMode = _mode;
371 mPickWidget.pickButton->setChecked(pickModeActive);
380 template<
typename MeshT>
383 if (!pickModeActive)
return;
385 if (_event->type() == QEvent::MouseButtonPress)
387 size_t node_idx, face_idx;
395 if (object->
id() == objectID_ && !currentlySelectedIndices.empty())
399 mPickWidget.pickedHandle->setText(tr(
"%1").arg(primitiveId));
407 template<
typename MeshT>
410 return (typeInfo == proptype_Vec3f) || (typeInfo == proptype_Vec3d);
413 template<
typename MeshT>
415 typename MeshT::prop_iterator props_first,
416 typename MeshT::prop_iterator props_last,
417 PropertyInfo::ENTITY_FILTER filter)
419 for (
typename MeshT::prop_iterator pit = props_first; pit != props_last; ++pit) {
421 if (baseProp && isSupported(baseProp) && isNew(baseProp, filter))
422 addPropertyVisualizer(baseProp, mesh, filter);
426 template<
typename MeshT>
431 gatherProperties(mesh_, mesh_->fprops_begin(), mesh_->fprops_end(), PropertyInfo::EF_FACE);
432 gatherProperties(mesh_, mesh_->eprops_begin(), mesh_->eprops_end(), PropertyInfo::EF_EDGE);
433 gatherProperties(mesh_, mesh_->hprops_begin(), mesh_->hprops_end(), PropertyInfo::EF_HALFEDGE);
434 gatherProperties(mesh_, mesh_->vprops_begin(), mesh_->vprops_end(), PropertyInfo::EF_VERTEX);
447 template<
typename MeshT>
451 TypeInfoWrapperSet::const_iterator propIt = supportedPropertyTypes.find(bp_type);
452 return propIt != supportedPropertyTypes.end();
465 template<
typename MeshT>
468 for (TypeInfoWrapperSet::const_iterator it = supportedPropertyTypes.begin();
469 it != supportedPropertyTypes.end();
472 if (friendlyName.toStdString().compare(it->getName()) == 0)
486 template<
typename MeshT>
489 for (
unsigned int i = 0; i < propertyVisualizers.size(); ++i)
491 const PropertyInfo& propInfo = propertyVisualizers[i]->getPropertyInfo();
492 if (propInfo ==
PropertyInfo(baseProp->
name(), getSupportedTypeInfoWrapper(baseProp) , filter))
505 template<
typename MeshT>
509 TypeInfoWrapperSet::const_iterator propIt = supportedPropertyTypes.find(bp_type);
520 template<
typename MeshT>
523 for (TypeInfoWrapperSet::const_iterator it = supportedPropertyTypes.begin();
524 it != supportedPropertyTypes.end();
527 if (friendlyName.toStdString().compare(it->getName()) == 0)
530 throw std::exception();
544 template<
typename MeshT>
548 if (propInfo.typeinfo() == proptype_bool)
550 else if (propInfo.typeinfo() == proptype_int)
552 else if (propInfo.typeinfo() == proptype_uint)
554 else if (propInfo.typeinfo() == proptype_uint8_t)
556 else if (propInfo.typeinfo() == proptype_double)
558 else if ((propInfo.typeinfo() == proptype_Vec3d) || (propInfo.typeinfo() == proptype_Vec3f))
560 else if ((propInfo.typeinfo() == proptype_Vec2d))
562 else if ((propInfo.typeinfo() == proptype_Vec2f))
564 #ifdef ENABLE_SKELETON_SUPPORT 565 else if (propInfo.typeinfo() == proptype_SkinWeights)
566 propertyVisualizers.push_back(
new OMPropertyVisualizerSkinWeights<MeshT>(mesh, objectID_, propInfo));
581 template<
typename MeshT>
585 QString dtype = friendlyTypeName;
586 QString pname = propName;
590 if ( filter == PropertyInfo::EF_VERTEX )
592 if ( (dtype == tr(
"Vec3d")) || (dtype == tr(
"Vec3f")) )
595 mesh->add_property(prop, pname.toStdString());
597 else if (dtype == tr(
"Vec2d"))
600 mesh->add_property(prop, pname.toStdString());
602 else if (dtype == tr(
"Vec2f"))
605 mesh->add_property(prop, pname.toStdString());
607 else if ( dtype == tr(
"double") )
610 mesh->add_property(prop, pname.toStdString());
612 else if ( dtype == tr(
"unsigned int") )
615 mesh->add_property(prop, pname.toStdString());
617 else if ( dtype == tr(
"uint8_t") )
620 mesh->add_property(prop, pname.toStdString());
622 else if ( dtype == tr(
"int") )
625 mesh->add_property(prop, pname.toStdString());
627 else if ( dtype == tr(
"bool") )
630 mesh->add_property(prop, pname.toStdString());
634 #ifdef ENABLE_SKELETON_SUPPORT 635 else if ( dtype == tr(
"SkinWeights") )
638 mesh->add_property(prop, pname.toStdString());
642 else if ( filter == PropertyInfo::EF_EDGE )
644 if ( (dtype == tr(
"Vec3d")) || (dtype == tr(
"Vec3f")) )
647 mesh->add_property(prop, pname.toStdString());
649 else if ( dtype == tr(
"Vec2d") )
652 mesh->add_property(prop, pname.toStdString());
654 else if ( dtype == tr(
"Vec2f") )
657 mesh->add_property(prop, pname.toStdString());
659 else if ( dtype == tr(
"double") )
662 mesh->add_property(prop, pname.toStdString());
664 else if ( dtype == tr(
"unsgined int") )
667 mesh->add_property(prop, pname.toStdString());
669 else if ( dtype == tr(
"uint8_t") )
672 mesh->add_property(prop, pname.toStdString());
674 else if ( dtype == tr(
"int") )
677 mesh->add_property(prop, pname.toStdString());
679 else if ( dtype == tr(
"bool") )
682 mesh->add_property(prop, pname.toStdString());
685 else if ( filter == PropertyInfo::EF_FACE )
687 if ( (dtype == tr(
"Vec3d")) || (dtype == tr(
"Vec3f")) )
690 mesh->add_property(prop, pname.toStdString());
692 else if ( dtype == tr(
"Vec2d") )
695 mesh->add_property(prop, pname.toStdString());
697 else if ( dtype == tr(
"Vec2f") )
700 mesh->add_property(prop, pname.toStdString());
702 else if ( dtype == tr(
"double") )
705 mesh->add_property(prop, pname.toStdString());
707 else if ( dtype == tr(
"unsigned int") )
710 mesh->add_property(prop, pname.toStdString());
712 else if ( dtype == tr(
"uint8_t") )
715 mesh->add_property(prop, pname.toStdString());
717 else if ( dtype == tr(
"int") )
720 mesh->add_property(prop, pname.toStdString());
722 else if ( dtype == tr(
"bool") )
725 mesh->add_property(prop, pname.toStdString());
728 else if ( filter == PropertyInfo::EF_HALFEDGE )
730 if ( (dtype == tr(
"Vec3d")) || (dtype == tr(
"Vec3f")) )
733 mesh->add_property(prop, pname.toStdString());
735 else if ( dtype == tr(
"double") )
738 mesh->add_property(prop, pname.toStdString());
740 else if ( dtype == tr(
"unsigned int") )
743 mesh->add_property(prop, pname.toStdString());
745 else if ( dtype == tr(
"uint8_t") )
748 mesh->add_property(prop, pname.toStdString());
750 else if ( dtype == tr(
"int") )
753 mesh->add_property(prop, pname.toStdString());
755 else if ( dtype == tr(
"bool") )
758 mesh->add_property(prop, pname.toStdString());
765 template<
typename MeshT>
770 supportedPropertyTypes.insert(proptype_bool);
771 supportedPropertyTypes.insert(proptype_int);
772 supportedPropertyTypes.insert(proptype_uint);
773 supportedPropertyTypes.insert(proptype_uint8_t);
774 supportedPropertyTypes.insert(proptype_double);
775 supportedPropertyTypes.insert(proptype_Vec3d);
776 supportedPropertyTypes.insert(proptype_Vec3f);
777 supportedPropertyTypes.insert(proptype_Vec2d);
778 supportedPropertyTypes.insert(proptype_Vec2f);
780 #ifdef ENABLE_SKELETON_SUPPORT 781 supportedPropertyTypes.insert(proptype_SkinWeights);
bool scenegraphPick(ACG::SceneGraph::PickTarget _pickTarget, const QPoint &_mousePos, size_t &_nodeIdx, size_t &_targetIdx, ACG::Vec3d *_hitPointPtr=0)
Execute picking operation on scenegraph.
bool isSupported(OpenMesh::BaseProperty *const baseProp) const
Checks if visualizing this property is supported.
virtual void setPropertyFromFile(QTextStream &file_stream, unsigned int n, PropertyVisualizer *propVis)
Sets the property values from a given file.
unsigned int getClosestPrimitiveId(unsigned int _face, ACG::Vec3d &_hitPoint)
Returns the ID of the closest primitive.
Wraps the information of a type.
picks faces (should be implemented for all nodes)
virtual void saveProperty()
Saves the currently slected properties.
virtual QString getLoadFilenameFilter()
Returns the filename filter for loading.
bool isPropertyFree(QString propName, PropertyInfo::ENTITY_FILTER filter, TypeInfoWrapper typeInfo)
Checks if the property name is still available.
bool isNew(OpenMesh::BaseProperty *const baseProp, PropertyInfo::ENTITY_FILTER filter)
Checks if we already created a PropertyVisualizer for this property.
Added for signal/slot support.
void connectLogs(PropertyVisualizer *propViz) override
Connects the PropertyVisualizer log signals with the log slot.
virtual bool parseHeader(QString header, PropertyVisualizer *&propVis, unsigned int &n)
Parses the property file header.
virtual void pickModeChanged(const std::string &_mode)
Handles changing of pick mode.
void saveProperty(unsigned int propId)
Saves property.
virtual void gatherProperties() override
Searches for properties and creates PropertyVisualizers.
Asks the user how to proceed after a name clash.
Viewer::ActionMode actionMode()
Get the current Action mode.
void resetPicking()
Disables picking.
virtual QString getSaveFilenameFilter(unsigned int propId)
Returns the filename filter for saving.
void addPropertyVisualizer(OpenMesh::BaseProperty *const baseProp, MeshT *mesh, PropertyInfo::ENTITY_FILTER filter)
Adds a new PropertyVisualizer.
const PropertyInfo & getPropertyInfo() const
Returns the PropertyInfo.
TypeInfoWrapper getSupportedTypeInfoWrapper(OpenMesh::BaseProperty *const baseProp)
Returns the TypeInfoWrapper for the property if it is supported.
Cellection of information about a property.
const std::string & name() const
Return the name of the property.
void addProperty(QString propName, QString friendlyTypeName, PropertyInfo::ENTITY_FILTER filter)
Adds a new property to the mesh.
const std::string pickMode()
Get the current Picking mode.
This class vizualizes a property.
PropertyVisualizer * getPropertyVisualizer(QString propName, PropertyInfo::ENTITY_FILTER filter, TypeInfoWrapper typeInfo)
Returns a PropertyVisualizer.
virtual void updateWidget(const QModelIndexList &selectedIndices)
Updates the widget.
void gatherProperties()
Searches for all properties and creates the visualizers.
virtual void pickProperty()
Toggle picking on and off.
virtual void updateWidget(const QModelIndexList &selectedIndices) override
Updates the widget.
virtual void setPropertyFromFile(QTextStream &file_stream, unsigned int n, PropertyVisualizer *propVis)
Sets the property values from a given file.
virtual void combine()
Combines two properties.
virtual void mouseEvent(QMouseEvent *_event)
Handles mouse events for picking.
bool combinable(PropertyVisualizer *propertyVisualizer1, PropertyVisualizer *propertyVisualizer2)
Checks if two properties are combinable.
virtual void setPropertyFromText(unsigned int index, QString text)=0
Returns the value of a property in text form.
bool getPickedObject(const size_t _node_idx, BaseObjectData *&_object)
Get the picked mesh.
virtual QString getPropertyText(unsigned int index)
Returns the value of a property in text form.