diff --git a/Apps/Tuto/Attributes/multi_attribs.cpp b/Apps/Tuto/Attributes/multi_attribs.cpp index f29f3aa74a303becec9d75292cd8c783b34213a1..87958ab078ae914f04a82a924348a8a057bede1f 100644 --- a/Apps/Tuto/Attributes/multi_attribs.cpp +++ b/Apps/Tuto/Attributes/multi_attribs.cpp @@ -80,6 +80,13 @@ void applySmooth(MAP& map, const ATT& att_in, ATT& att_out) // check at compile if ATT is an AttributeHandler on orbit VERTEX CHECK_ATTRIBUTEHANDLER_ORBIT(ATT, VERTEX); + // or check at runtime(take care of const!) + if (! checkAttributeHandlerOrbit(att_in)) + { + CGoGNerr << "function applySmooth work only with VertexAttributes !" << CGoGNendl; + return; + } + foreach_cell(map,[&](Vertex v) // for all vertex v of map do { att_out[v] = smooth(map,v,att_in); diff --git a/Apps/Tuto/Attributes/simple_attribs.cpp b/Apps/Tuto/Attributes/simple_attribs.cpp index 6ed647316280c1443da3141f0b81f2694af4db00..3bbcf8ae07f13af840eaab38fc7b1cab7d74f3e3 100644 --- a/Apps/Tuto/Attributes/simple_attribs.cpp +++ b/Apps/Tuto/Attributes/simple_attribs.cpp @@ -125,6 +125,30 @@ void dumpAttribute(const ATTRIB& attr) } +//function that apply on vertice with templated attribute type +template +void VertexTyped(MAP& map, T& va) +{ + foreach_cell(map,[&](Vertex v) // for all vertices + { + va[v] = 1.1 * va[v]; + }); +} + +// version that take a VertexAttribute, check type at runtime and call instancied template version +void VertexGeneric(MAP& map, VertexAttributeGen& vg) +{ + auto va3 = dynamic_cast*>(&vg); + if (va3 != NULL) + return VertexTyped(map,*va3); + + auto vaf = dynamic_cast*>(&vg); + if (vaf != NULL) + return VertexTyped(map,*vaf); +} + + + int main() { // declare a map to handle the mesh @@ -142,6 +166,8 @@ int main() grid.embedIntoGrid(positionAtt, 1.,1.,0.); + VertexGeneric(myMap,positionAtt); + // ATTRIBUTE DECLARATION // add an attribute of type float on orbit EDGE diff --git a/include/Algo/Modelisation/subdivision.h b/include/Algo/Modelisation/subdivision.h index 3b38edd7f3733a96e2a5b64c7cc0c124472363e4..45c9032f71166e0c2165ef6e527cd3d5f3485fd9 100644 --- a/include/Algo/Modelisation/subdivision.h +++ b/include/Algo/Modelisation/subdivision.h @@ -93,18 +93,71 @@ void quadranguleFaces(typename PFP::MAP& map, EMBV& attributs) ; template void CatmullClarkSubdivision(typename PFP::MAP& map, EMBV& attributs) ; -//template -//void CatmullClarkSubdivision(typename PFP::MAP& map, VertexAttribute& position) ; - /** * Loop subdivision scheme */ -//template template void LoopSubdivision(typename PFP::MAP& map, EMBV& attributs) ; -//template -//void LoopSubdivision(typename PFP::MAP& map, VertexAttribute& position) ; +template +void LoopSubdivisionGen(typename PFP::MAP& map, VertexAttributeGen& attrib) +{ + auto va3 = dynamic_cast*>(&attrib); + if (va3 != NULL) + return LoopSubdivision(map,*va3); + + auto va4 = dynamic_cast*>(&attrib); + if (va4 != NULL) + return LoopSubdivision(map,*va4); + + auto var = dynamic_cast*>(&attrib); + if (var != NULL) + return LoopSubdivision(map,*var); + + CGoGNerr << "LoopSubdivision not supported on attribute of type "<< attrib.typeName() << CGoGNendl; +} + +/** + * Loop typed version with attribute name parameter + */ +template +inline void LoopSubdivisionAttribNameTyped(typename PFP::MAP& map, const std::string& nameAttrib) +{ + VertexAttribute va = map.template getAttribute(nameAttrib) ; +} + +/** + * Loop genereo version with attribute name parameter + */ +template +void LoopSubdivisionAttribName(typename PFP::MAP& map, const std::string& nameAttrib) +{ + typedef typename PFP::MAP MAP; + + switch(map.template getAttributeTypeCode(nameAttrib)) + { + case CGoGNFLOAT: + return LoopSubdivisionAttribNameTyped(map,nameAttrib); + break; + case CGoGNDOUBLE: + return LoopSubdivisionAttribNameTyped(map,nameAttrib); + break; + case CGoGNVEC3F: + return LoopSubdivisionAttribNameTyped(map,nameAttrib); + break; + case CGoGNVEC3D: + return LoopSubdivisionAttribNameTyped(map,nameAttrib); + break; + case CGoGNVEC4F: + return LoopSubdivisionAttribNameTyped(map,nameAttrib); + break; + case CGoGNVEC4D: + return LoopSubdivisionAttribNameTyped(map,nameAttrib); + break; + } + CGoGNerr << "LoopSubdivision not supported on attribute "<< nameAttrib << CGoGNendl; +} + /** diff --git a/include/Container/attributeContainer.h b/include/Container/attributeContainer.h index 09a555c2e7254db5ff90871725f4a10d72b9902b..980a976578d6a48b6196c123f2c7aa732b414619 100644 --- a/include/Container/attributeContainer.h +++ b/include/Container/attributeContainer.h @@ -287,7 +287,7 @@ public: * @param attribName nom de l'attribut * @return l'indice de l'attribut */ - unsigned int getAttributeIndex(const std::string& attribName); + unsigned int getAttributeIndex(const std::string& attribName) const; /** * get the name of an attribute, given its index in the container @@ -417,6 +417,8 @@ public: * ATTRIBUTES DATA ACCESS * **************************************/ + inline CGoGNCodeType getTypeCode(const std::string& attribName) const; + /** * get an AttributeMultiVector * @param attrIndex index of the attribute diff --git a/include/Container/attributeContainer.hpp b/include/Container/attributeContainer.hpp index e8cd1febc817b14b55caafe45011e7cb9209cceb..c8049f98eee1231662215de5f6ca1f7a3be99ac5 100644 --- a/include/Container/attributeContainer.hpp +++ b/include/Container/attributeContainer.hpp @@ -421,6 +421,17 @@ AttributeMultiVector* AttributeContainer::getDataVector(const std::string& at return atm; } + +inline CGoGNCodeType AttributeContainer::getTypeCode(const std::string& attribName) const +{ + unsigned int index = getAttributeIndex(attribName) ; + if(index == UNKNOWN) + return CGoGNUNKNOWNTYPE ; + return m_tableAttribs[index]->getTypeCode(); +} + + + inline AttributeMultiVectorGen* AttributeContainer::getVirtualDataVector(const std::string& attribName) { unsigned int index = getAttributeIndex(attribName) ; diff --git a/include/Container/attributeMultiVector.h b/include/Container/attributeMultiVector.h index 5463a355146c1f68fa8e910a48bb18f593750eba..71ee6b2d44a557be408670e9fe95eb62a552029c 100644 --- a/include/Container/attributeMultiVector.h +++ b/include/Container/attributeMultiVector.h @@ -38,6 +38,17 @@ namespace CGoGN { +enum CGoGNCodeType + {CGoGNUNKNOWNTYPE=0, + CGoGNINT,CGoGNUINT, + CGoGNSHORT,CGoGNUSHORT, + CGoGNCHAR,CGoGNUCHAR, + CGoGNFLOAT,CGoGNDOUBLE, + CGoGNVEC2F,CGoGNVEC2D, + CGoGNVEC3F,CGoGNVEC3D, + CGoGNVEC4F,CGoGNVEC4D + }; + class AttributeMultiVectorGen { protected: @@ -51,6 +62,11 @@ protected: */ std::string m_typeName; + /** + * Code of type + */ + CGoGNCodeType m_typeCode; + /** * orbit of the attribute */ @@ -102,6 +118,8 @@ public: void setTypeName(const std::string& n); + CGoGNCodeType getTypeCode() const; + /** * get block size */ @@ -192,6 +210,8 @@ class AttributeMultiVector : public AttributeMultiVectorGen */ std::vector m_tableData; + inline void setTypeCode(); + public: AttributeMultiVector(const std::string& strName, const std::string& strType); diff --git a/include/Container/attributeMultiVector.hpp b/include/Container/attributeMultiVector.hpp index 08ba177d73c2d97a2251c7357dc027c7c54b584f..942e9d47d671843a247598de77dbc1dbbc3e80b7 100644 --- a/include/Container/attributeMultiVector.hpp +++ b/include/Container/attributeMultiVector.hpp @@ -21,6 +21,7 @@ * Contact information: cgogn@unistra.fr * * * *******************************************************************************/ +#include "Geometry/vector_gen.h" namespace CGoGN { @@ -84,6 +85,10 @@ inline unsigned int AttributeMultiVectorGen::getBlockSize() const return _BLOCKSIZE_ ; } +inline CGoGNCodeType AttributeMultiVectorGen::getTypeCode() const +{ + return m_typeCode; +} /***************************************************************************************************/ /***************************************************************************************************/ @@ -413,4 +418,90 @@ void AttributeMultiVector::dump(unsigned int i) const CGoGNout << this->operator[](i); } + +template +inline void AttributeMultiVector::setTypeCode() +{ + m_typeCode = CGoGNUNKNOWNTYPE; +} + +template <> +inline void AttributeMultiVector::setTypeCode() +{ + m_typeCode = CGoGNINT; +} +template <> +inline void AttributeMultiVector::setTypeCode() +{ + m_typeCode = CGoGNUINT; +} +template <> +inline void AttributeMultiVector::setTypeCode() +{ + m_typeCode = CGoGNSHORT; +} +template <> +inline void AttributeMultiVector::setTypeCode() +{ + m_typeCode = CGoGNUSHORT; +} +template <> +inline void AttributeMultiVector::setTypeCode() +{ + m_typeCode = CGoGNCHAR; +} +template <> +inline void AttributeMultiVector::setTypeCode() +{ + m_typeCode = CGoGNUCHAR; +} + +template <> +inline void AttributeMultiVector::setTypeCode() +{ + m_typeCode = CGoGNFLOAT; +} +template <> +inline void AttributeMultiVector::setTypeCode() +{ + m_typeCode = CGoGNDOUBLE; +} + +template <> +inline void AttributeMultiVector::setTypeCode() +{ + m_typeCode = CGoGNVEC2F; +} + +template <> +inline void AttributeMultiVector::setTypeCode() +{ + m_typeCode = CGoGNVEC2D; +} + +template <> +inline void AttributeMultiVector::setTypeCode() +{ + m_typeCode = CGoGNVEC3F; +} + +template <> +inline void AttributeMultiVector::setTypeCode() +{ + m_typeCode = CGoGNVEC3D; +} + +template <> +inline void AttributeMultiVector::setTypeCode() +{ + m_typeCode = CGoGNVEC4F; +} + +template <> +inline void AttributeMultiVector::setTypeCode() +{ + m_typeCode = CGoGNVEC4D; +} + + } // namespace CGoGN diff --git a/include/Topology/generic/attributeHandler.h b/include/Topology/generic/attributeHandler.h index ce3822a87b73c05f524e034f2b6a81368048ca26..4c4342d57aba2fb83d2c2f9434726769e130fbe0 100644 --- a/include/Topology/generic/attributeHandler.h +++ b/include/Topology/generic/attributeHandler.h @@ -72,8 +72,20 @@ public: protected: void setInvalid() { valid = false ; } + void setValid() { valid = true ; } } ; +template +class AttributeHandlerOrbit: public AttributeHandlerGen +{ +public: + AttributeHandlerOrbit(bool v) : + AttributeHandlerGen(v) + {} + + static const unsigned int ORBIT = ORB; +}; + /** * Class that create an access-table to an existing attribute * Main available operations are: @@ -82,7 +94,7 @@ protected: * - begin / end / next to manage indexing */ template -class AttributeHandler : public AttributeHandlerGen +class AttributeHandler : public AttributeHandlerOrbit { protected: // the map that contains the linked attribute @@ -95,7 +107,7 @@ protected: public: typedef T DATA_TYPE ; - static const unsigned int ORBIT = ORB; +// static const unsigned int ORBIT = ORB; /** * Default constructor @@ -253,30 +265,41 @@ public: template using DartAttribute = AttributeHandler; +typedef AttributeHandlerOrbit DartAttributeGen; + + /** * c++11 shortcut for Vertex Attribute (Handler) */ template using VertexAttribute = AttributeHandler; +typedef AttributeHandlerOrbit VertexAttributeGen; + + /** * c++11 shortcut for Edge Attribute (Handler) */ template using EdgeAttribute = AttributeHandler; +typedef AttributeHandlerOrbit EdgeAttributeGen; + /** * c++11 shortcut for Face Attribute (Handler) */ template using FaceAttribute = AttributeHandler; +typedef AttributeHandlerOrbit FaceAttributeGen; + /** * c++11 shortcut for Volume Attribute (Handler) */ template using VolumeAttribute = AttributeHandler; +typedef AttributeHandlerOrbit VolumeAttributeGen; @@ -309,6 +332,12 @@ void foreach_attribute(ATTR& attribute, FUNC func, unsigned int nbth = NumberOfT } +template +inline bool checkAttributeHandlerOrbit(const AttributeHandlerGen& att) +{ + return (dynamic_cast*>(&att)!=NULL) != NULL; +} + } // namespace CGoGN #include "Topology/generic/attributeHandler.hpp" diff --git a/include/Topology/generic/attributeHandler.hpp b/include/Topology/generic/attributeHandler.hpp index 12587292d8674a38c8d1847242392cc689952837..8898b29042e8d7f676ceaf6fa7386d1ec072c311 100644 --- a/include/Topology/generic/attributeHandler.hpp +++ b/include/Topology/generic/attributeHandler.hpp @@ -58,62 +58,62 @@ inline void AttributeHandler::unregisterFromMap() template AttributeHandler::AttributeHandler() : - AttributeHandlerGen(false), + AttributeHandlerOrbit(false), m_map(NULL), m_attrib(NULL) {} template AttributeHandler::AttributeHandler(MAP* m, AttributeMultiVector* amv) : - AttributeHandlerGen(false), + AttributeHandlerOrbit(false), m_map(m), m_attrib(amv) { if(m != NULL && amv != NULL && amv->getIndex() != AttributeContainer::UNKNOWN) { assert(ORB == amv->getOrbit() || !"AttributeHandler: orbit incompatibility") ; - valid = true ; + this->valid = true ; registerInMap() ; } else - valid = false ; + this->valid = false ; } template AttributeHandler::AttributeHandler(const AttributeHandler& ta) : - AttributeHandlerGen(ta.valid), + AttributeHandlerOrbit(ta.valid), m_map(ta.m_map), m_attrib(ta.m_attrib) { - if(valid) + if(this->valid) registerInMap() ; } template template AttributeHandler::AttributeHandler(const AttributeHandler& h) : - AttributeHandlerGen(h.valid), + AttributeHandlerOrbit(h.valid), m_map(h.m_map), m_attrib(h.m_attrib) { if(m_attrib->getOrbit() == ORBIT2) { - if(valid) + if(this->valid) registerInMap() ; } else - valid = false; + this->valid = false; } template inline AttributeHandler& AttributeHandler::operator=(const AttributeHandler& ta) { - if(valid) + if(this->valid) unregisterFromMap() ; m_map = ta.m_map ; m_attrib = ta.m_attrib ; - valid = ta.valid ; - if(valid) + this->valid = ta.valid ; + if(this->valid) registerInMap() ; return *this ; } @@ -122,12 +122,12 @@ template template inline AttributeHandler& AttributeHandler::operator=(const AttributeHandler& ta) { - if(valid) + if(this->valid) unregisterFromMap() ; m_map = ta.map() ; m_attrib = ta.getDataVector() ; - valid = ta.isValid() ; - if(valid) + this->valid = ta.isValid() ; + if(this->valid) registerInMap() ; return *this ; } @@ -135,7 +135,7 @@ inline AttributeHandler& AttributeHandler::operator=(c template AttributeHandler::~AttributeHandler() { - if(valid) + if(this->valid) unregisterFromMap() ; } @@ -191,7 +191,7 @@ inline unsigned int AttributeHandler::nbElements() const template inline T& AttributeHandler::operator[](Cell c) { - assert(valid || !"Invalid AttributeHandler") ; + assert(this->valid || !"Invalid AttributeHandler") ; unsigned int a = m_map->getEmbedding(c) ; if (a == EMBNULL) @@ -203,7 +203,7 @@ inline T& AttributeHandler::operator[](Cell c) template inline const T& AttributeHandler::operator[](Cell c) const { - assert(valid || !"Invalid AttributeHandler") ; + assert(this->valid || !"Invalid AttributeHandler") ; unsigned int a = m_map->getEmbedding(c) ; return m_attrib->operator[](a) ; } @@ -211,21 +211,21 @@ inline const T& AttributeHandler::operator[](Cell c) const template inline T& AttributeHandler::operator[](unsigned int a) { - assert(valid || !"Invalid AttributeHandler") ; + assert(this->valid || !"Invalid AttributeHandler") ; return m_attrib->operator[](a) ; } template inline const T& AttributeHandler::operator[](unsigned int a) const { - assert(valid || !"Invalid AttributeHandler") ; + assert(this->valid || !"Invalid AttributeHandler") ; return m_attrib->operator[](a) ; } template inline unsigned int AttributeHandler::insert(const T& elt) { - assert(valid || !"Invalid AttributeHandler") ; + assert(this->valid || !"Invalid AttributeHandler") ; unsigned int idx = m_map->template getAttributeContainer().insertLine() ; m_attrib->operator[](idx) = elt ; return idx ; @@ -234,7 +234,7 @@ inline unsigned int AttributeHandler::insert(const T& elt) template inline unsigned int AttributeHandler::newElt() { - assert(valid || !"Invalid AttributeHandler") ; + assert(this->valid || !"Invalid AttributeHandler") ; unsigned int idx = m_map->template getAttributeContainer().insertLine() ; return idx ; } @@ -249,21 +249,21 @@ inline void AttributeHandler::setAllValues(const T& v) template inline unsigned int AttributeHandler::begin() const { - assert(valid || !"Invalid AttributeHandler") ; + assert(this->valid || !"Invalid AttributeHandler") ; return m_map->template getAttributeContainer().begin() ; } template inline unsigned int AttributeHandler::end() const { - assert(valid || !"Invalid AttributeHandler") ; + assert(this->valid || !"Invalid AttributeHandler") ; return m_map->template getAttributeContainer().end() ; } template inline void AttributeHandler::next(unsigned int& iter) const { - assert(valid || !"Invalid AttributeHandler") ; + assert(this->valid || !"Invalid AttributeHandler") ; m_map->template getAttributeContainer().next(iter) ; } diff --git a/include/Topology/generic/mapCommon.h b/include/Topology/generic/mapCommon.h index def2fdfa9975f7cd79e5cc6f771c2a2bbfdd916b..ba38e17c02d2acdee2985ee3f589ee430a22741d 100644 --- a/include/Topology/generic/mapCommon.h +++ b/include/Topology/generic/mapCommon.h @@ -149,6 +149,15 @@ public: template inline AttributeHandler getAttribute(const std::string& nameAttr) ; + /** + * @brief get attribute type code + * @param nameAttr name of attribute + * @return code enum + */ + template + inline CGoGNCodeType getAttributeTypeCode(const std::string& nameAttr); + + /** * check if an attribute exist ( get, test if valid and add if necessary) * @param nameAttr attribute name diff --git a/include/Topology/generic/mapCommon.hpp b/include/Topology/generic/mapCommon.hpp index edf6d17bba63106c6e9bb21947386512ae18e2a0..a6af9aeed7366bd9a81492a8bdced4d69e4b7631 100644 --- a/include/Topology/generic/mapCommon.hpp +++ b/include/Topology/generic/mapCommon.hpp @@ -202,6 +202,14 @@ inline AttributeHandler MapCommon::getAttribute(const s return AttributeHandler(static_cast(this), amv) ; } +template +template < unsigned int ORBIT> +inline CGoGNCodeType MapCommon::getAttributeTypeCode(const std::string& nameAttr) +{ + return this->m_attribs[ORBIT].getTypeCode(nameAttr); +} + + template template inline AttributeHandler MapCommon::checkAttribute(const std::string& nameAttr) diff --git a/include/Topology/generic/multi3Attribs.h b/include/Topology/generic/multi3Attribs.h index 8c853ac3d44d47fd64d6583475c32719a33b525a..d48bba81e483a11440b3e3281e579ef9aea45593 100644 --- a/include/Topology/generic/multi3Attribs.h +++ b/include/Topology/generic/multi3Attribs.h @@ -88,7 +88,7 @@ struct RefCompo3Type template -class Cell3Attributes: public AttributeHandlerGen +class Cell3Attributes: public AttributeHandlerOrbit { AttributeHandler& m_h1; @@ -101,7 +101,7 @@ public: Cell3Attributes(AttributeHandler& h1, AttributeHandler& h2, AttributeHandler& h3): - AttributeHandlerGen(true), + AttributeHandlerOrbit(true), m_h1(h1), m_h2(h2), m_h3(h3) {} static const unsigned int ORBIT = ORB; diff --git a/include/Topology/generic/multi4Attribs.h b/include/Topology/generic/multi4Attribs.h index 2aa705d01c945434af9c1381410598a71213419a..8a8881f5bb66c29ac79a4ec92460c35962471c8c 100644 --- a/include/Topology/generic/multi4Attribs.h +++ b/include/Topology/generic/multi4Attribs.h @@ -91,7 +91,7 @@ struct RefCompo4Type //template //class Vertex4Attributes template -class Cell4Attributes: public AttributeHandlerGen +class Cell4Attributes: public AttributeHandlerOrbit { AttributeHandler& m_h1; AttributeHandler& m_h2; @@ -106,7 +106,7 @@ public: AttributeHandler& h2, AttributeHandler& h3, AttributeHandler& h4) : - AttributeHandlerGen(true), + AttributeHandlerOrbit(true), m_h1(h1), m_h2(h2), m_h3(h3), m_h4(h4) {} static const unsigned int ORBIT = ORB; diff --git a/include/Topology/generic/multiAttribs.h b/include/Topology/generic/multiAttribs.h index ff4d77094d10626d930b8c8bfc9441d0869e5174..e31504d59cd6550eb54ed270e1d5a92e16a826f7 100644 --- a/include/Topology/generic/multiAttribs.h +++ b/include/Topology/generic/multiAttribs.h @@ -276,7 +276,7 @@ double length(const T& v) template -class Cell2Attributes: public AttributeHandlerGen +class Cell2Attributes: public AttributeHandlerOrbit { AttributeHandler& m_h1; AttributeHandler& m_h2; @@ -285,7 +285,7 @@ public: typedef RefCompo2Type REF_DATA_TYPE; Cell2Attributes(AttributeHandler& h1, AttributeHandler& h2): - AttributeHandlerGen(true), + AttributeHandlerOrbit(true), m_h1(h1), m_h2(h2) {} static const unsigned int ORBIT = ORB; diff --git a/src/Container/attributeContainer.cpp b/src/Container/attributeContainer.cpp index 6b50a3a9b8dfb8dd22be5ffb5c2d1921c5f4c4fc..c7547307226240fb4c15825b698ad9b6a232b848 100644 --- a/src/Container/attributeContainer.cpp +++ b/src/Container/attributeContainer.cpp @@ -68,7 +68,7 @@ AttributeContainer::~AttributeContainer() * INFO ABOUT ATTRIBUTES * **************************************/ -unsigned int AttributeContainer::getAttributeIndex(const std::string& attribName) +unsigned int AttributeContainer::getAttributeIndex(const std::string& attribName) const { unsigned int index ; bool found = false ;