44#define OVM_PROPERTY_MODEL_CC
46template <
typename MeshT>
55 bCombine.setText(tr(
"Combine"));
57 connect(&bCombine, SIGNAL(clicked()),
58 this, SLOT(slotCombine()));
59 widgets->layout()->addWidget(&bCombine);
61 widgets->layout()->addWidget(&mLoadSaveWidget);
63 connect(mLoadSaveWidget.save_property , SIGNAL(clicked()),
64 this, SLOT(slotSaveProperty()));
66 connect(mLoadSaveWidget.load_property , SIGNAL(clicked()),
67 this, SLOT(slotLoadProperty()));
69 widgets->layout()->addWidget(&mPickWidget);
70 connect(mPickWidget.pickButton, SIGNAL(clicked()),
71 this, SLOT(slotPickProperty()));
73 QString iconPath = OpenFlipper::Options::iconDirStr() + OpenFlipper::Options::dirSeparator();
74 mPickWidget.pickButton->setIcon( QIcon(iconPath +
"color-picker.png") );
79 initializeSupportedPropertyTypes();
82#undef INITIALIZE_PROPTYPES
84template <
typename MeshT>
89 if (selectedIndices.size() == 2)
91 if (combinable(propertyVisualizers[selectedIndices[0].row()], propertyVisualizers[selectedIndices[1].row()]))
95 mCombineProperty1 = &propertyVisualizers[selectedIndices[0].row()]->getPropertyInfo();
96 mCombineProperty2 = &propertyVisualizers[selectedIndices[1].row()]->getPropertyInfo();
106 if (selectedIndices.size() == 1)
112 if (mPickWidget.pickButton->isChecked())
118template <
typename MeshT>
131template <
typename MeshT>
134 if ( mPickWidget.pickButton->isChecked() ){
147template <
typename MeshT>
150 pickModeActive = (_mode == PROP_VIS);
154 lastPickMode = _mode;
157 mPickWidget.pickButton->setChecked(pickModeActive);
166template <
typename MeshT>
169 if (!pickModeActive)
return;
170 if (currentlySelectedIndices.size() < 1)
return;
172 if (_event->type() == QEvent::MouseButtonPress)
199 if (object->
id() == objectID_)
204 mPickWidget.pickedHandle->setText(tr(
"%1").arg(entityId));
212template <
typename MeshT>
215#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
216 QStringList headerParts = header.split(tr(
", "), QString::SkipEmptyParts );
218 QStringList headerParts = header.split(tr(
", "), Qt::SkipEmptyParts );
221 int headerVersion = headerParts[0].toUInt();
222 if (headerVersion == 1)
224 n = headerParts[1].toUInt();
225 unsigned int nExpected = 0;
227 PropertyInfo::ENTITY_FILTER filter = (PropertyInfo::ENTITY_FILTER)headerParts[2].toInt();
230 case PropertyInfo::EF_CELL:
231 nExpected = mesh_->n_cells();
233 case PropertyInfo::EF_FACE:
234 nExpected = mesh_->n_faces();
236 case PropertyInfo::EF_HALFFACE:
237 nExpected = mesh_->n_halffaces();
239 case PropertyInfo::EF_EDGE:
240 nExpected = mesh_->n_edges();
242 case PropertyInfo::EF_HALFEDGE:
243 nExpected = mesh_->n_halfedges();
245 case PropertyInfo::EF_VERTEX:
246 nExpected = mesh_->n_vertices();
255 std::cerr <<
"unexpected number of entities" << std::endl;
259 QString friendlyName = headerParts[3];
261 if (!isSupported(friendlyName))
263 std::cerr <<
"unsupported property type " << friendlyName.toStdString() << std::endl;
268 TypeInfoWrapper typeInfo = getSupportedTypeInfoWrapper(friendlyName, filter);
270 QString propName = QInputDialog::getText(0,
"Property Name",
"Please enter name.",QLineEdit::Normal,headerParts[4]);
271 if (propName ==
"")
return false;
273 bool replace =
false;
274 if (!(isPropertyFree(propName, filter, typeInfo) || replace))
280 propName = QInputDialog::getText(0,
"New Property Name",
"Please enter new name.");
281 else if (msgBox->cancel)
283 else if (msgBox->replace)
291 addProperty(propName, friendlyName, filter);
295 propVis = getPropertyVisualizer(propName, filter, typeInfo);
302 std::cerr <<
"unsupported header format" << std::endl;
308template<
typename MeshT>
312 filter = tr(
"Vertex Property (*.vprop)");
313 filter += tr(
";; HalfEdge Property (*.hprop)");
314 filter += tr(
";; Edge Property (*.eprop)");
315 filter += tr(
";; Halfface Property (*.hfprop)");
316 filter += tr(
";; Face Property (*.fprop)");
317 filter += tr(
";; Cell Property (*.cprop)");
318 filter += tr(
";; All Files (*)");
322template<
typename MeshT>
330 filter = tr(
"Vertex Property (*.vprop)");
332 filter = tr(
"HalfEdge Property (*.hprop)");
334 filter = tr(
"Edge Property (*.eprop)");
336 filter = tr(
"Face Property (*.fprop)");
338 filter += tr(
";; All Files (*)");
353template<
typename MeshT>
356 return getPropertyVisualizer(propName, filter, typeInfo) == 0;
367template<
typename MeshT>
375template<
typename MeshT>
378 for (QModelIndexList::const_iterator it = currentlySelectedIndices.begin(), it_end = currentlySelectedIndices.end();
379 it != it_end; ++it) {
397template<
typename MeshT>
405 return (isVectorType(typeInfo1) && isVectorType(typeInfo2)) && (propInfo1.entityType() == propInfo2.entityType());
408template<
typename MeshT>
409template <
typename PropIter>
411 PropIter props_first, PropIter props_last,
412 PropertyInfo::ENTITY_FILTER filter)
414 for (
auto pit = props_first; pit != props_last; ++pit) {
416 const auto prop_ptr = storage_base->make_property_ptr();
417 if (isSupported(prop_ptr.get()) && isNew(prop_ptr.get(), filter))
418 addPropertyVisualizer(prop_ptr.get(), mesh, filter);
423template<
typename MeshT>
428 gatherProperties(mesh_, mesh_->face_props_begin(), mesh_->face_props_end(), PropertyInfo::EF_FACE);
429 gatherProperties(mesh_, mesh_->edge_props_begin(), mesh_->edge_props_end(), PropertyInfo::EF_EDGE);
430 gatherProperties(mesh_, mesh_->halfedge_props_begin(), mesh_->halfedge_props_end(), PropertyInfo::EF_HALFEDGE);
431 gatherProperties(mesh_, mesh_->vertex_props_begin(), mesh_->vertex_props_end(), PropertyInfo::EF_VERTEX);
432 gatherProperties(mesh_, mesh_->halfface_props_begin(), mesh_->halfface_props_end(), PropertyInfo::EF_HALFFACE);
433 gatherProperties(mesh_, mesh_->cell_props_begin(), mesh_->cell_props_end(), PropertyInfo::EF_CELL);
446template<
typename MeshT>
450 TypeInfoWrapperSet::const_iterator propIt = supportedPropertyTypes.find(bp_type);
451 return propIt != supportedPropertyTypes.end();
464template<
typename MeshT>
467 for (TypeInfoWrapperSet::const_iterator it = supportedPropertyTypes.begin();
468 it != supportedPropertyTypes.end();
471 if (friendlyName.toStdString().compare(it->getName()) == 0)
485template<
typename MeshT>
488 for (
unsigned int i = 0; i < propertyVisualizers.size(); ++i)
490 const PropertyInfo& propInfo = propertyVisualizers[i]->getPropertyInfo();
491 if (propInfo ==
PropertyInfo(baseProp->name(), getSupportedTypeInfoWrapper(baseProp) , filter))
505template<
typename MeshT>
509 TypeInfoWrapperSet::const_iterator propIt = supportedPropertyTypes.find(bp_type);
510 if (propIt != supportedPropertyTypes.end())
514 std::cerr <<
"error" << std::endl;
527template<
typename MeshT>
531 for (TypeInfoWrapperSet::const_iterator it = supportedPropertyTypes.begin();
532 it != supportedPropertyTypes.end();
535 if ((friendlyName.toStdString().compare(it->getName()) == 0) && isEntityType(*it, filter))
538 throw std::exception();
541template<
typename MeshT>
544 return isBoolType(propInfo.typeinfo());
547template<
typename MeshT>
550 return typeInfo == proptype_Cell_bool ||
551 typeInfo == proptype_Face_bool ||
552 typeInfo == proptype_HalfFace_bool ||
553 typeInfo == proptype_Edge_bool ||
554 typeInfo == proptype_HalfEdge_bool ||
555 typeInfo == proptype_Vertex_bool;
558template<
typename MeshT>
561 return isIntType(propInfo.typeinfo());
564template<
typename MeshT>
567 return typeInfo == proptype_Cell_int ||
568 typeInfo == proptype_Face_int ||
569 typeInfo == proptype_HalfFace_int ||
570 typeInfo == proptype_Edge_int ||
571 typeInfo == proptype_HalfEdge_int ||
572 typeInfo == proptype_Vertex_int;
575template<
typename MeshT>
578 return isDoubleType(propInfo.typeinfo());
581template<
typename MeshT>
584 return typeInfo == proptype_Cell_double ||
585 typeInfo == proptype_Face_double ||
586 typeInfo == proptype_HalfFace_double ||
587 typeInfo == proptype_Edge_double ||
588 typeInfo == proptype_HalfEdge_double ||
589 typeInfo == proptype_Vertex_double;
592template<
typename MeshT>
595 return isUnsignedIntType(propInfo.typeinfo());
598template<
typename MeshT>
601 return typeInfo == proptype_Cell_uint ||
602 typeInfo == proptype_Face_uint ||
603 typeInfo == proptype_HalfFace_uint ||
604 typeInfo == proptype_Edge_uint ||
605 typeInfo == proptype_HalfEdge_uint ||
606 typeInfo == proptype_Vertex_uint;
609template<
typename MeshT>
612 return isVec3dType(propInfo.typeinfo());
615template<
typename MeshT>
618 return typeInfo == proptype_Cell_Vec3d ||
619 typeInfo == proptype_Face_Vec3d ||
620 typeInfo == proptype_HalfFace_Vec3d ||
621 typeInfo == proptype_Edge_Vec3d ||
622 typeInfo == proptype_HalfEdge_Vec3d ||
623 typeInfo == proptype_Vertex_Vec3d;
626template<
typename MeshT>
629 return isVec3dOVMType(propInfo.typeinfo());
632template<
typename MeshT>
635 return typeInfo == proptype_Cell_Vec3dOVM ||
636 typeInfo == proptype_Face_Vec3dOVM ||
637 typeInfo == proptype_HalfFace_Vec3dOVM ||
638 typeInfo == proptype_Edge_Vec3dOVM ||
639 typeInfo == proptype_HalfEdge_Vec3dOVM ||
640 typeInfo == proptype_Vertex_Vec3dOVM;
643template<
typename MeshT>
646 return isVec3fType(propInfo.typeinfo());
649template<
typename MeshT>
652 return typeInfo == proptype_Cell_Vec3f ||
653 typeInfo == proptype_Face_Vec3f ||
654 typeInfo == proptype_HalfFace_Vec3f ||
655 typeInfo == proptype_Edge_Vec3f ||
656 typeInfo == proptype_HalfEdge_Vec3f ||
657 typeInfo == proptype_Vertex_Vec3f;
660template<
typename MeshT>
663 return isVec3fType(propInfo) || isVec3dType(propInfo) ;
666template<
typename MeshT>
669 return isVec3fType(typeInfo) || isVec3dType(typeInfo);
672template<
typename MeshT>
675 return isVec3dOVMType(propInfo) ;
678template<
typename MeshT>
681 return isVec3dOVMType(typeInfo);
684template<
typename MeshT>
687 return isMatrix3x3Type(propInfo.typeinfo());
690template<
typename MeshT>
693 return typeInfo == proptype_Cell_Matrix3x3d ||
694 typeInfo == proptype_Face_Matrix3x3d ||
695 typeInfo == proptype_HalfFace_Matrix3x3d ||
696 typeInfo == proptype_Edge_Matrix3x3d ||
697 typeInfo == proptype_HalfEdge_Matrix3x3d ||
698 typeInfo == proptype_Vertex_Matrix3x3d;
701template<
typename MeshT>
705 if (entity_type & PropertyInfo::EF_CELL)
707 result |= (typeInfo == proptype_Cell_bool)
708 || (typeInfo == proptype_Cell_int)
709 || (typeInfo == proptype_Cell_double)
710 || (typeInfo == proptype_Cell_uint)
711 || (typeInfo == proptype_Cell_Vec3d)
712 || (typeInfo == proptype_Cell_Vec3dOVM)
713 || (typeInfo == proptype_Cell_Vec3f);
715 if (entity_type & PropertyInfo::EF_FACE)
717 result |= (typeInfo == proptype_Face_bool)
718 || (typeInfo == proptype_Face_int)
719 || (typeInfo == proptype_Face_double)
720 || (typeInfo == proptype_Face_uint)
721 || (typeInfo == proptype_Face_Vec3d)
722 || (typeInfo == proptype_Face_Vec3dOVM)
723 || (typeInfo == proptype_Face_Vec3f);
725 if (entity_type & PropertyInfo::EF_HALFFACE)
727 result |= (typeInfo == proptype_HalfFace_bool)
728 || (typeInfo == proptype_HalfFace_int)
729 || (typeInfo == proptype_HalfFace_double)
730 || (typeInfo == proptype_HalfFace_uint)
731 || (typeInfo == proptype_HalfFace_Vec3d)
732 || (typeInfo == proptype_HalfFace_Vec3dOVM)
733 || (typeInfo == proptype_HalfFace_Vec3f);
735 if (entity_type & PropertyInfo::EF_EDGE)
737 result |= (typeInfo == proptype_Edge_bool)
738 || (typeInfo == proptype_Edge_int)
739 || (typeInfo == proptype_Edge_double)
740 || (typeInfo == proptype_Edge_uint)
741 || (typeInfo == proptype_Edge_Vec3d)
742 || (typeInfo == proptype_Edge_Vec3dOVM)
743 || (typeInfo == proptype_Edge_Vec3f);
745 if (entity_type & PropertyInfo::EF_HALFEDGE)
747 result |= (typeInfo == proptype_HalfEdge_bool)
748 || (typeInfo == proptype_HalfEdge_int)
749 || (typeInfo == proptype_HalfEdge_double)
750 || (typeInfo == proptype_HalfEdge_uint)
751 || (typeInfo == proptype_HalfEdge_Vec3d)
752 || (typeInfo == proptype_HalfEdge_Vec3dOVM)
753 || (typeInfo == proptype_HalfEdge_Vec3f);
755 if (entity_type & PropertyInfo::EF_VERTEX)
757 result |= (typeInfo == proptype_Vertex_bool)
758 || (typeInfo == proptype_Vertex_int)
759 || (typeInfo == proptype_Vertex_double)
760 || (typeInfo == proptype_Vertex_uint)
761 || (typeInfo == proptype_Vertex_Vec3d)
762 || (typeInfo == proptype_Vertex_Vec3dOVM)
763 || (typeInfo == proptype_Vertex_Vec3f);
779template<
typename MeshT>
783 if (isBoolType(propInfo))
785 else if (isIntType(propInfo))
787 else if (isUnsignedIntType(propInfo))
789 else if (isDoubleType(propInfo))
791 else if (isVectorType(propInfo))
793 else if (isVectorOVMType(propInfo))
795 else if (isMatrix3x3Type(propInfo))
797 connectLogs(propertyVisualizers.back());
810template<
typename MeshT>
814 QString dtype = friendlyTypeName;
815 std::string pname = propName.toStdString();
819 if ( filter == PropertyInfo::EF_VERTEX )
821 if ( (dtype == tr(
"Vec3d")) || (dtype == tr(
"Vec3f")) )
824 mesh->set_persistent(prop,
true);
826 else if ( dtype == tr(
"double") )
829 mesh->set_persistent(prop,
true);
831 else if ( dtype == tr(
"unsigned int") )
834 mesh->set_persistent(prop,
true);
836 else if ( dtype == tr(
"int") )
839 mesh->set_persistent(prop,
true);
841 else if ( dtype == tr(
"bool") )
844 mesh->set_persistent(prop,
true);
847 else if ( filter == PropertyInfo::EF_EDGE )
849 if ( (dtype == tr(
"Vec3d")) || (dtype == tr(
"Vec3f")) )
852 mesh->set_persistent(prop,
true);
854 else if ( dtype == tr(
"double") )
857 mesh->set_persistent(prop,
true);
859 else if ( dtype == tr(
"unsgined int") )
862 mesh->set_persistent(prop,
true);
864 else if ( dtype == tr(
"int") )
867 mesh->set_persistent(prop,
true);
869 else if ( dtype == tr(
"bool") )
872 mesh->set_persistent(prop,
true);
875 else if ( filter == PropertyInfo::EF_FACE )
877 if ( (dtype == tr(
"Vec3d")) || (dtype == tr(
"Vec3f")) )
880 mesh->set_persistent(prop,
true);
882 else if ( dtype == tr(
"double") )
885 mesh->set_persistent(prop,
true);
887 else if ( dtype == tr(
"unsigned int") )
890 mesh->set_persistent(prop,
true);
892 else if ( dtype == tr(
"int") )
895 mesh->set_persistent(prop,
true);
897 else if ( dtype == tr(
"bool") )
900 mesh->set_persistent(prop,
true);
903 else if ( filter == PropertyInfo::EF_HALFEDGE )
905 if ( (dtype == tr(
"Vec3d")) || (dtype == tr(
"Vec3f")) )
908 mesh->set_persistent(prop,
true);
910 else if ( dtype == tr(
"double") )
913 mesh->set_persistent(prop,
true);
915 else if ( dtype == tr(
"unsigned int") )
918 mesh->set_persistent(prop,
true);
920 else if ( dtype == tr(
"int") )
923 mesh->set_persistent(prop,
true);
925 else if ( dtype == tr(
"bool") )
928 mesh->set_persistent(prop,
true);
931 else if ( filter == PropertyInfo::EF_HALFFACE )
933 if ( (dtype == tr(
"Vec3d")) || (dtype == tr(
"Vec3f")) )
936 mesh->set_persistent(prop,
true);
938 else if ( dtype == tr(
"double") )
941 mesh->set_persistent(prop,
true);
943 else if ( dtype == tr(
"unsigned int") )
946 mesh->set_persistent(prop,
true);
948 else if ( dtype == tr(
"int") )
951 mesh->set_persistent(prop,
true);
953 else if ( dtype == tr(
"bool") )
956 mesh->set_persistent(prop,
true);
959 else if ( filter == PropertyInfo::EF_CELL )
961 if ( (dtype == tr(
"Vec3d")) || (dtype == tr(
"Vec3f")) )
964 mesh->set_persistent(prop,
true);
966 else if ( dtype == tr(
"double") )
969 mesh->set_persistent(prop,
true);
971 else if ( dtype == tr(
"unsigned int") )
974 mesh->set_persistent(prop,
true);
976 else if ( dtype == tr(
"int") )
979 mesh->set_persistent(prop,
true);
981 else if ( dtype == tr(
"bool") )
984 mesh->set_persistent(prop,
true);
990template <
typename MeshT>
994#define INSERT_PROPTYPES(primitive) \
995supportedPropertyTypes.insert(proptype_##primitive##_bool); \
996supportedPropertyTypes.insert(proptype_##primitive##_int); \
997supportedPropertyTypes.insert(proptype_##primitive##_uint); \
998supportedPropertyTypes.insert(proptype_##primitive##_double); \
999supportedPropertyTypes.insert(proptype_##primitive##_Vec3d); \
1000supportedPropertyTypes.insert(proptype_##primitive##_Vec3dOVM); \
1001supportedPropertyTypes.insert(proptype_##primitive##_Vec3f); \
1002supportedPropertyTypes.insert(proptype_##primitive##_Matrix3x3d); \
1004 INSERT_PROPTYPES(Cell)
1005 INSERT_PROPTYPES(Face)
1006 INSERT_PROPTYPES(HalfFace)
1007 INSERT_PROPTYPES(Edge)
1008 INSERT_PROPTYPES(HalfEdge)
1009 INSERT_PROPTYPES(Vertex)
1011#undef INSERT_PROPTYPES
Asks the user how to proceed after a name clash.
virtual void saveProperty()
Saves the currently slected properties.
void gatherProperties()
Searches for all properties and creates the visualizers.
virtual QString getSaveFilenameFilter(unsigned int propId)
Returns the filename filter for saving.
void resetPicking()
Disables picking.
TypeInfoWrapper getSupportedTypeInfoWrapper(OpenVolumeMesh::BasePropertyPtr *const baseProp) const
Returns the TypeInfoWrapper for the property if it is supported.
void addPropertyVisualizer(OpenVolumeMesh::BasePropertyPtr *const baseProp, MeshT *mesh, PropertyInfo::ENTITY_FILTER filter)
Adds a new PropertyVisualizer.
virtual void pickProperty()
Toggle picking on and off.
void addProperty(QString propName, QString friendlyTypeName, PropertyInfo::ENTITY_FILTER filter)
Adds a new property to the mesh.
bool isPropertyFree(QString propName, PropertyInfo::ENTITY_FILTER filter, TypeInfoWrapper typeInfo)
Checks if a property name is still available for an entity type and a property type.
bool combinable(PropertyVisualizer *propertyVisualizer1, PropertyVisualizer *propertyVisualizer2) const
Checks if two properties are combinable.
virtual void pickModeChanged(const std::string &_mode)
Handles changing of pick mode.
bool isSupported(OpenVolumeMesh::BasePropertyPtr *const baseProp) const
Checks if visualizing this property is supported.
virtual bool parseHeader(QString header, PropertyVisualizer *&propVis, unsigned int &n)
Parses the property file header.
virtual void mouseEvent(QMouseEvent *_event)
Handles mouse events for picking.
virtual void updateWidget(const QModelIndexList &selectedIndices)
Updates the widget.
virtual void combine()
Combines two properties.
virtual QString getLoadFilenameFilter()
Returns the filename filter for loading.
bool isNew(OpenVolumeMesh::BasePropertyPtr *const baseProp, PropertyInfo::ENTITY_FILTER filter) const
Checks if we already created a PropertyVisualizer for this property.
virtual QString getPropertyText(unsigned int index)=0
Returns the value of a property in text form.
unsigned int getClosestPrimitiveId(unsigned int _face, ACG::Vec3d &_hitPoint)
Returns the ID of the closest primitive.
Cellection of information about a property.
This class vizualizes a property.
const PropertyInfo & getPropertyInfo() const
Returns the PropertyInfo.
virtual void updateWidget(const QModelIndexList &selectedIndices) override
Updates the widget.
void saveProperty(unsigned int propId)
Saves property.
Wraps the information of a type.
PickTarget
What target to use for picking.
@ PICK_EDGE
picks edges (may not be implemented for all nodes)
@ PICK_CELL
picks faces (may not be implemented for all nodes)
@ PICK_FACE
picks faces (should be implemented for all nodes)
@ PICK_VERTEX
picks verices (may not be implemented for all nodes)
const std::string pickMode()
Get the current Picking mode.
bool getPickedObject(const size_t _node_idx, BaseObjectData *&_object)
Get the picked mesh.
bool scenegraphPick(ACG::SceneGraph::PickTarget _pickTarget, const QPoint &_mousePos, size_t &_nodeIdx, size_t &_targetIdx, ACG::Vec3d *_hitPointPtr=0)
Execute picking operation on scenegraph.
Viewer::ActionMode actionMode()
Get the current Action mode.