From 4c719ae5d0f176db45880a360cd70dcc9d443d3c Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Wed, 31 Mar 2021 11:10:14 +0200 Subject: [PATCH 001/117] Color4 ToUnsignedA8R8G8B8 function --- vcg/space/color4.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/vcg/space/color4.h b/vcg/space/color4.h index d97e7480..8d7c71c3 100644 --- a/vcg/space/color4.h +++ b/vcg/space/color4.h @@ -261,6 +261,7 @@ inline static Color4 ColorRamp(const float &minf,const float &maxf ,float v ) inline static unsigned short ToUnsignedB5G5R5(const Color4 &) { return 0;} inline static unsigned short ToUnsignedR5G5B5(const Color4 &) { return 0;} +inline static unsigned int ToUnsignedA8R8G8B8(const Color4 &) { return 0;} inline static Color4 FromUnsignedB5G5R5(unsigned short) { @@ -439,6 +440,17 @@ inline unsigned short Color4::ToUnsignedR5G5B5(const Color4 +inline unsigned int Color4::ToUnsignedA8R8G8B8(const Color4 &cc) +{ + unsigned int r = cc[0]; + unsigned int g = cc[1]; + unsigned int b = cc[2]; + unsigned int a = cc[3]; + unsigned int res = (r << 16) | (g << 8) | (b) | (a << 24); + return res; +} + template<> inline Color4 Color4::FromUnsignedR5G5B5(unsigned short val) From 23082f1994e77ad8dd8401b09a8a0d1493ce6ef6 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Thu, 1 Apr 2021 10:11:26 +0200 Subject: [PATCH 002/117] remove unsupported polygonal flag from export ply --- wrap/io_trimesh/export_ply.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrap/io_trimesh/export_ply.h b/wrap/io_trimesh/export_ply.h index d2c9d3cf..3874c5fc 100644 --- a/wrap/io_trimesh/export_ply.h +++ b/wrap/io_trimesh/export_ply.h @@ -844,7 +844,7 @@ namespace vcg { capability |= vcg::tri::io::Mask::IOM_WEDGTEXMULTI ; capability |= vcg::tri::io::Mask::IOM_WEDGNORMAL ; capability |= vcg::tri::io::Mask::IOM_CAMERA ; - capability |= vcg::tri::io::Mask::IOM_BITPOLYGONAL; + //capability |= vcg::tri::io::Mask::IOM_BITPOLYGONAL; return capability; } From d4718bde6a1a9b0ceae22efaf825d87ea9216f43 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Thu, 1 Apr 2021 12:49:48 +0200 Subject: [PATCH 003/117] possibility to export double attributes in ply --- wrap/io_trimesh/export_ply.h | 4 +- wrap/io_trimesh/io_ply.h | 76 +++++++++++++++++++++++++----------- wrap/ply/plylib.h | 42 +++++++++----------- 3 files changed, 73 insertions(+), 49 deletions(-) diff --git a/wrap/io_trimesh/export_ply.h b/wrap/io_trimesh/export_ply.h index 3874c5fc..ca097e96 100644 --- a/wrap/io_trimesh/export_ply.h +++ b/wrap/io_trimesh/export_ply.h @@ -211,7 +211,7 @@ namespace vcg { ); } for(size_t i=0;i0 && (pi.mask & Mask::IOM_EDGEINDEX) ) fprintf(fpout, diff --git a/wrap/io_trimesh/io_ply.h b/wrap/io_trimesh/io_ply.h index f52547e8..d939d610 100644 --- a/wrap/io_trimesh/io_ply.h +++ b/wrap/io_trimesh/io_ply.h @@ -41,6 +41,8 @@ Initial commit #define __VCGLIB_IOTRIMESH_IO_PLY +#include + /** @name Load and Save in Ply format */ @@ -64,37 +66,65 @@ This class can be passed to the ImporterPLY::Open() function for class PlyInfo { public: - typedef ::vcg::ply::PropDescriptor PropDescriptor ; + typedef ::vcg::ply::PropDescriptor PropDescriptor ; - void AddPerElemFloatAttribute(int elemType, const char *attrName, const char * propName=0) - { - static const char *elemStr[2]={"vertex","face"}; - std::vector *elemDescVec[2]={&(this->VertDescriptorVec), &(this->FaceDescriptorVec)}; - std::vector *elemNameVec[2]={&(this->VertAttrNameVec), &(this->FaceAttrNameVec)}; + void addPerElemScalarAttribute(int elemType, vcg::ply::PlyTypes propertyType, const std::string& attrName, std::string propName="") + { + if(propName=="") + propName=attrName; - if(propName==0) propName=attrName; - elemDescVec[elemType]->push_back(PropDescriptor()); - elemNameVec[elemType]->push_back(attrName); - elemDescVec[elemType]->back().elemname=elemStr[elemType]; - elemDescVec[elemType]->back().propname=strdup(propName); - elemDescVec[elemType]->back().stotype1 = vcg::ply::T_FLOAT; - elemDescVec[elemType]->back().memtype1 = vcg::ply::T_FLOAT; - } + if (elemType == 0){ //vertex + VertDescriptorVec.push_back(PropDescriptor()); + VertAttrNameVec.push_back(attrName); + VertDescriptorVec.back().elemname="vertex"; + VertDescriptorVec.back().propname=propName; + VertDescriptorVec.back().stotype1 = propertyType; + VertDescriptorVec.back().memtype1 = propertyType; + } + else if (elemType == 1){ //face + FaceDescriptorVec.push_back(PropDescriptor()); + FaceAttrNameVec.push_back(attrName); + FaceDescriptorVec.back().elemname="face"; + FaceDescriptorVec.back().propname=propName; + FaceDescriptorVec.back().stotype1 = propertyType; + FaceDescriptorVec.back().memtype1 = propertyType; + } + } - void AddPerVertexFloatAttribute(const char *attrName, const char *propName=0) { - AddPerElemFloatAttribute(0,attrName,propName); - } - void AddPerFaceFloatAttribute(const char *attrName, const char *propName=0) { - AddPerElemFloatAttribute(1,attrName,propName); - } + void AddPerElemFloatAttribute(int elemType, const std::string& attrName, std::string propName="") + { + addPerElemScalarAttribute(elemType, vcg::ply::T_FLOAT, attrName, propName); + } + + void AddPerElemDoubleAttribute(int elemType, const std::string& attrName, std::string propName="") + { + addPerElemScalarAttribute(elemType, vcg::ply::T_DOUBLE, attrName, propName); + } + + void addPerVertexScalarAttribute(const std::string& attrName, vcg::ply::PlyTypes attrType, std::string propName="") { + addPerElemScalarAttribute(0,attrType, attrName,propName); + } + + void AddPerVertexFloatAttribute(const std::string& attrName, std::string propName="") { + AddPerElemFloatAttribute(0,attrName,propName); + } + + void addPerFaceScalarAttribute(const std::string& attrName, vcg::ply::PlyTypes attrType, std::string propName="") { + addPerElemScalarAttribute(1,attrType, attrName,propName); + } + + void AddPerFaceFloatAttribute(const std::string& attrName, std::string propName="") { + AddPerElemFloatAttribute(1,attrName,propName); + } /* Note that saving a per vertex point3 attribute is a mess. * Actually require to allocate 3 float attribute and save them. And they are never deallocated... */ template - void AddPerVertexPoint3fAttribute(MeshType &m, const char *attrName, const char *propName="") + void AddPerVertexPoint3fAttribute(MeshType &m, const std::string& attrName, std::string propName="") { - if(propName==0) propName=attrName; + if(propName=="") + propName=attrName; const char *attrxyz[3] = { strdup((std::string(attrName)+std::string("_x")).c_str()), @@ -151,7 +181,7 @@ public: enum Error { - // Funzioni superiori + // Funzioni superiori E_NO_VERTEX = ply::E_MAXPLYERRORS+1, // 15 E_NO_FACE = ply::E_MAXPLYERRORS+2, // 16 E_SHORTFILE = ply::E_MAXPLYERRORS+3, // 17 diff --git a/wrap/ply/plylib.h b/wrap/ply/plylib.h index 59e5eddd..88470b20 100644 --- a/wrap/ply/plylib.h +++ b/wrap/ply/plylib.h @@ -112,33 +112,27 @@ typedef FILE * GZFILE; #endif - // Messaggio di errore -//extern const char * ply_error_msg[]; - - // TIPO FILE - - -// Descrittore esterno di propieta' +// Ply Property descriptor class PropDescriptor { public: - const char * elemname; // Nome dell'elemento - const char * propname; // Nome della propieta' - int stotype1; // Tipo dell'elemento su file (se lista tipo degli elementi della lista) - int memtype1; // Tipo dell'elemento in memoria (se lista tipo degli elementi della lista) - size_t offset1; // Offset del valore in memoria - int islist; // 1 se lista, 0 altrimenti - int alloclist; // 1 se alloca lista, 0 se preallocata - int stotype2; // Tipo del numero di elementi della lista su file - int memtype2; // Tipo del numero di elementi della lista in memoria - size_t offset2; // Offset valore memoria + std::string elemname; // name of the element (e.g. vertex) + std::string propname; // name of the property (e.g. x, y, red...) + int stotype1; // Type of the property in the file + int memtype1; // Type of the property in memory + size_t offset1; // Offset in memory + bool islist; // true if the property is a list + bool alloclist; // 1 se alloca lista, 0 se preallocata + int stotype2; // Type of the number of elements of the list in the file + int memtype2; // Type of the number of elements of the list in memory + size_t offset2; // Offset valore memoria - int format; // duplicazione del formato + int format; // duplicazione del formato - size_t stotypesize() const; // per sapere quanto e'grande un dato descrittore sul file - size_t memtypesize() const; // per sapere quanto e'grande un dato descrittore in memoria - const char *memtypename() const; - const char *stotypename() const; + size_t stotypesize() const; // per sapere quanto e'grande un dato descrittore sul file + size_t memtypesize() const; // per sapere quanto e'grande un dato descrittore in memoria + const char* memtypename() const; + const char* stotypename() const; }; // Reading Callback (used to copy a data prop) @@ -231,7 +225,7 @@ public: std::string name; // Nome dell'elemento int number; // Numero di elementi di questo tipo - std::vector props; // Vettore dinamico delle property + std::vector props; // Vettore dinamico delle property }; @@ -273,7 +267,7 @@ public: // Come sopra ma con descrittore inline int AddToRead( const PropDescriptor & p ) { - return AddToRead(p.elemname,p.propname,p.stotype1, + return AddToRead(p.elemname.c_str(),p.propname.c_str(),p.stotype1, p.memtype1,p.offset1,p.islist,p.alloclist,p.stotype2, p.memtype2,p.offset2 ); From 3fd845e5b7de358b5430f7e2baa8d4f56944b930 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Thu, 1 Apr 2021 18:54:15 +0200 Subject: [PATCH 004/117] const correctness for polygonal mesh --- vcg/simplex/face/component_polygon.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/vcg/simplex/face/component_polygon.h b/vcg/simplex/face/component_polygon.h index 0a7cdd04..1fda9d1b 100644 --- a/vcg/simplex/face/component_polygon.h +++ b/vcg/simplex/face/component_polygon.h @@ -71,9 +71,9 @@ public: */ // ~PFVAdj(){ __Dealloc(); } - inline typename T::VertexType * & V( const int j ) { assert(j>=0 && jVN()); return _vpoly[j]; } - inline typename T::VertexType * V( const int j ) const { assert(j>=0 && jVN()); return _vpoly[j]; } - inline typename T::VertexType * cV( const int j ) const { assert(j>=0 && jVN()); return _vpoly[j]; } + inline typename T::VertexType * & V( const int j ) { assert(j>=0 && jVN()); return _vpoly[j]; } + inline const typename T::VertexType * V( const int j ) const { assert(j>=0 && jVN()); return _vpoly[j]; } + inline const typename T::VertexType * cV( const int j ) const { assert(j>=0 && jVN()); return _vpoly[j]; } /** Return the pointer to the ((j+1)%3)-th vertex of the face. @@ -90,11 +90,15 @@ public: inline const VertexType * cV2( const int j ) const { return cV((j+2)%this->VN());} inline CoordType &P( const int j ) { assert(j>=0 && jVN()); return _vpoly[j]->P(); } + inline CoordType P( const int j ) const { assert(j>=0 && jVN()); return _vpoly[j]->cP(); } inline CoordType cP( const int j ) const { assert(j>=0 && jVN()); return _vpoly[j]->cP(); } inline CoordType & P0( const int j ) { return V(j)->P();} inline CoordType & P1( const int j ) { return V((j+1)%this->VN())->P();} inline CoordType & P2( const int j ) { return V((j+2)%this->VN())->P();} + inline CoordType P0( const int j ) const { return cV(j)->P();} + inline CoordType P1( const int j ) const { return cV((j+1)%this->VN())->P();} + inline CoordType P2( const int j ) const { return cV((j+2)%this->VN())->P();} inline CoordType cP0( const int j ) const { return cV(j)->P();} inline CoordType cP1( const int j ) const { return cV((j+1)%this->VN())->P();} inline CoordType cP2( const int j ) const { return cV((j+2)%this->VN())->P();} From 4001b5aa3403d8529f60c14368feddc201004ca6 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Fri, 2 Apr 2021 10:16:02 +0200 Subject: [PATCH 005/117] small refactor --- wrap/io_trimesh/io_ply.h | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/wrap/io_trimesh/io_ply.h b/wrap/io_trimesh/io_ply.h index d939d610..39144305 100644 --- a/wrap/io_trimesh/io_ply.h +++ b/wrap/io_trimesh/io_ply.h @@ -73,21 +73,20 @@ public: if(propName=="") propName=attrName; + PropDescriptor p; + p.propname=propName; + p.stotype1 = propertyType; + p.memtype1 = propertyType; + if (elemType == 0){ //vertex - VertDescriptorVec.push_back(PropDescriptor()); VertAttrNameVec.push_back(attrName); - VertDescriptorVec.back().elemname="vertex"; - VertDescriptorVec.back().propname=propName; - VertDescriptorVec.back().stotype1 = propertyType; - VertDescriptorVec.back().memtype1 = propertyType; + p.elemname="vertex"; + VertDescriptorVec.push_back(p); } else if (elemType == 1){ //face - FaceDescriptorVec.push_back(PropDescriptor()); FaceAttrNameVec.push_back(attrName); - FaceDescriptorVec.back().elemname="face"; - FaceDescriptorVec.back().propname=propName; - FaceDescriptorVec.back().stotype1 = propertyType; - FaceDescriptorVec.back().memtype1 = propertyType; + p.elemname="face"; + FaceDescriptorVec.push_back(p); } } @@ -117,7 +116,6 @@ public: AddPerElemFloatAttribute(1,attrName,propName); } - /* Note that saving a per vertex point3 attribute is a mess. * Actually require to allocate 3 float attribute and save them. And they are never deallocated... */ template From 6509139fc67909ca20fb23942b944cec31b10cf0 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Fri, 2 Apr 2021 12:09:52 +0200 Subject: [PATCH 006/117] export point3f/d vertex attribute works ply files --- wrap/io_trimesh/export_ply.h | 1592 +++++++++++++++++----------------- wrap/io_trimesh/io_ply.h | 52 +- wrap/ply/plylib.cpp | 4 + wrap/ply/plylib.h | 4 + 4 files changed, 875 insertions(+), 777 deletions(-) diff --git a/wrap/io_trimesh/export_ply.h b/wrap/io_trimesh/export_ply.h index ca097e96..b5be20ca 100644 --- a/wrap/io_trimesh/export_ply.h +++ b/wrap/io_trimesh/export_ply.h @@ -34,827 +34,873 @@ #include #include #include - +#include #include namespace vcg { - namespace tri { - namespace io { +namespace tri { +namespace io { - template - class ExporterPLY - { - // Si occupa di convertire da un tipo all'altro. - // usata nella saveply per matchare i tipi tra stotype e memtype. - // Ad es se in memoria c'e' un int e voglio salvare un float - // src sara in effetti un puntatore a int il cui valore deve - // essere convertito al tipo di ritorno desiderato (stotype) +template +class ExporterPLY +{ + // Si occupa di convertire da un tipo all'altro. + // usata nella saveply per matchare i tipi tra stotype e memtype. + // Ad es se in memoria c'e' un int e voglio salvare un float + // src sara in effetti un puntatore a int il cui valore deve + // essere convertito al tipo di ritorno desiderato (stotype) - template - static void PlyConv(int mem_type, void *src, StoType &dest) - { - switch (mem_type){ - case ply::T_FLOAT : dest = (StoType) (* ((float *) src)); break; - case ply::T_DOUBLE: dest = (StoType) (* ((double *) src)); break; - case ply::T_INT : dest = (StoType) (* ((int *) src)); break; - case ply::T_SHORT : dest = (StoType) (* ((short *) src)); break; - case ply::T_CHAR : dest = (StoType) (* ((char *) src)); break; - case ply::T_UCHAR : dest = (StoType) (* ((unsigned char *)src)); break; - default : assert(0); - } - } + template + static void PlyConv(int mem_type, void *src, StoType &dest) + { + switch (mem_type){ + case ply::T_FLOAT : dest = (StoType) (* ((float *) src)); break; + case ply::T_DOUBLE: dest = (StoType) (* ((double *) src)); break; + case ply::T_INT : dest = (StoType) (* ((int *) src)); break; + case ply::T_SHORT : dest = (StoType) (* ((short *) src)); break; + case ply::T_CHAR : dest = (StoType) (* ((char *) src)); break; + case ply::T_UCHAR : dest = (StoType) (* ((unsigned char *)src)); break; + default : assert(0); + } + } - public: - typedef ::vcg::ply::PropDescriptor PropDescriptor ; - typedef typename SaveMeshType::ConstVertexPointer VertexPointer; - typedef typename SaveMeshType::ScalarType ScalarType; - typedef typename SaveMeshType::VertexType VertexType; - typedef typename SaveMeshType::FaceType FaceType; - typedef typename SaveMeshType::ConstFacePointer FacePointer; - typedef typename SaveMeshType::ConstVertexIterator VertexIterator; - typedef typename SaveMeshType::ConstFaceIterator FaceIterator; - typedef typename SaveMeshType::ConstEdgeIterator EdgeIterator; - typedef typename vcg::Shot::ScalarType ShotScalarType; +public: + typedef ::vcg::ply::PropDescriptor PropDescriptor ; + typedef typename SaveMeshType::ConstVertexPointer VertexPointer; + typedef typename SaveMeshType::ScalarType ScalarType; + typedef typename SaveMeshType::VertexType VertexType; + typedef typename SaveMeshType::FaceType FaceType; + typedef typename SaveMeshType::ConstFacePointer FacePointer; + typedef typename SaveMeshType::ConstVertexIterator VertexIterator; + typedef typename SaveMeshType::ConstFaceIterator FaceIterator; + typedef typename SaveMeshType::ConstEdgeIterator EdgeIterator; + typedef typename vcg::Shot::ScalarType ShotScalarType; - static int Save(const SaveMeshType &m, const char * filename, bool binary=true) - { - PlyInfo pi; - return Save(m,filename,binary,pi); - } + static int Save(const SaveMeshType &m, const char * filename, bool binary=true) + { + PlyInfo pi; + return Save(m,filename,binary,pi); + } - static int Save(const SaveMeshType &m, const char * filename, int savemask, bool binary = true, CallBackPos *cb=0 ) - { - PlyInfo pi; - pi.mask=savemask; - return Save(m,filename,binary,pi,cb); - } + static int Save(const SaveMeshType &m, const char * filename, int savemask, bool binary = true, CallBackPos *cb=0 ) + { + PlyInfo pi; + pi.mask=savemask; + return Save(m,filename,binary,pi,cb); + } - static int Save(const SaveMeshType &m, const char * filename, bool binary, const PlyInfo &pi, CallBackPos *cb=0) // V1.0 - { - FILE * fpout; - const char * hbin = "binary_little_endian"; - const char * hasc = "ascii"; - const char * h; - //Coord ScalarType - const int DGT = vcg::tri::io::Precision::digits(); - const int DGTS = vcg::tri::io::Precision::digits(); - const int DGTVQ = vcg::tri::io::Precision::digits(); - const int DGTVR = vcg::tri::io::Precision::digits(); - const int DGTFQ = vcg::tri::io::Precision::digits(); - bool saveTexIndexFlag = false; + static int Save(const SaveMeshType &m, const char * filename, bool binary, const PlyInfo &pi, CallBackPos *cb=0) // V1.0 + { + FILE * fpout; + const char * hbin = "binary_little_endian"; + const char * hasc = "ascii"; + const char * h; + //Coord ScalarType + const int DGT = vcg::tri::io::Precision::digits(); + const int DGTS = vcg::tri::io::Precision::digits(); + const int DGTVQ = vcg::tri::io::Precision::digits(); + const int DGTVR = vcg::tri::io::Precision::digits(); + const int DGTFQ = vcg::tri::io::Precision::digits(); + bool saveTexIndexFlag = false; - if(binary) h=hbin; - else h=hasc; + if(binary) h=hbin; + else h=hasc; - fpout = fopen(filename,"wb"); - if(fpout==NULL) { - //pi.status=::vcg::ply::E_CANTOPEN; - return ::vcg::ply::E_CANTOPEN; - } - fprintf(fpout, - "ply\n" - "format %s 1.0\n" - "comment VCGLIB generated\n" - ,h - ); + fpout = fopen(filename,"wb"); + if(fpout==NULL) { + //pi.status=::vcg::ply::E_CANTOPEN; + return ::vcg::ply::E_CANTOPEN; + } + fprintf(fpout, + "ply\n" + "format %s 1.0\n" + "comment VCGLIB generated\n" , + h); - if (((pi.mask & Mask::IOM_WEDGTEXCOORD) != 0) || ((pi.mask & Mask::IOM_VERTTEXCOORD) != 0)) - { - const char * TFILE = "TextureFile"; + if (((pi.mask & Mask::IOM_WEDGTEXCOORD) != 0) || ((pi.mask & Mask::IOM_VERTTEXCOORD) != 0)) + { + const char * TFILE = "TextureFile"; - for(size_t i=0; i < m.textures.size(); ++i) - fprintf(fpout,"comment %s %s\n", TFILE, (const char *)(m.textures[i].c_str()) ); + for(size_t i=0; i < m.textures.size(); ++i) + fprintf(fpout,"comment %s %s\n", TFILE, (const char *)(m.textures[i].c_str()) ); - if(m.textures.size()>1 && (HasPerWedgeTexCoord(m) || HasPerVertexTexCoord(m))) saveTexIndexFlag = true; - } + if(m.textures.size()>1 && (HasPerWedgeTexCoord(m) || HasPerVertexTexCoord(m))) saveTexIndexFlag = true; + } - if((pi.mask & Mask::IOM_CAMERA)) - { - const char* cmtp = vcg::tri::io::Precision::typeName(); - fprintf(fpout,"element camera 1\n"); - fprintf(fpout,"property %s view_px\n",cmtp); - fprintf(fpout,"property %s view_py\n",cmtp); - fprintf(fpout,"property %s view_pz\n",cmtp); - fprintf(fpout,"property %s x_axisx\n",cmtp); - fprintf(fpout,"property %s x_axisy\n",cmtp); - fprintf(fpout,"property %s x_axisz\n",cmtp); - fprintf(fpout,"property %s y_axisx\n",cmtp); - fprintf(fpout,"property %s y_axisy\n",cmtp); - fprintf(fpout,"property %s y_axisz\n",cmtp); - fprintf(fpout,"property %s z_axisx\n",cmtp); - fprintf(fpout,"property %s z_axisy\n",cmtp); - fprintf(fpout,"property %s z_axisz\n",cmtp); - fprintf(fpout,"property %s focal\n",cmtp); - fprintf(fpout,"property %s scalex\n",cmtp); - fprintf(fpout,"property %s scaley\n",cmtp); - fprintf(fpout,"property %s centerx\n",cmtp); - fprintf(fpout,"property %s centery\n",cmtp); - fprintf(fpout,"property int viewportx\n"); - fprintf(fpout,"property int viewporty\n"); - fprintf(fpout,"property %s k1\n",cmtp); - fprintf(fpout,"property %s k2\n",cmtp); - fprintf(fpout,"property %s k3\n",cmtp); - fprintf(fpout,"property %s k4\n",cmtp); - } + if((pi.mask & Mask::IOM_CAMERA)) + { + const char* cmtp = vcg::tri::io::Precision::typeName(); + fprintf(fpout,"element camera 1\n"); + fprintf(fpout,"property %s view_px\n",cmtp); + fprintf(fpout,"property %s view_py\n",cmtp); + fprintf(fpout,"property %s view_pz\n",cmtp); + fprintf(fpout,"property %s x_axisx\n",cmtp); + fprintf(fpout,"property %s x_axisy\n",cmtp); + fprintf(fpout,"property %s x_axisz\n",cmtp); + fprintf(fpout,"property %s y_axisx\n",cmtp); + fprintf(fpout,"property %s y_axisy\n",cmtp); + fprintf(fpout,"property %s y_axisz\n",cmtp); + fprintf(fpout,"property %s z_axisx\n",cmtp); + fprintf(fpout,"property %s z_axisy\n",cmtp); + fprintf(fpout,"property %s z_axisz\n",cmtp); + fprintf(fpout,"property %s focal\n",cmtp); + fprintf(fpout,"property %s scalex\n",cmtp); + fprintf(fpout,"property %s scaley\n",cmtp); + fprintf(fpout,"property %s centerx\n",cmtp); + fprintf(fpout,"property %s centery\n",cmtp); + fprintf(fpout,"property int viewportx\n"); + fprintf(fpout,"property int viewporty\n"); + fprintf(fpout,"property %s k1\n",cmtp); + fprintf(fpout,"property %s k2\n",cmtp); + fprintf(fpout,"property %s k3\n",cmtp); + fprintf(fpout,"property %s k4\n",cmtp); + } - const char* vttp = vcg::tri::io::Precision::typeName(); - fprintf(fpout,"element vertex %d\n",m.vn); - fprintf(fpout,"property %s x\n",vttp); - fprintf(fpout,"property %s y\n",vttp); - fprintf(fpout,"property %s z\n",vttp); + const char* vttp = vcg::tri::io::Precision::typeName(); + fprintf(fpout,"element vertex %d\n",m.vn); + fprintf(fpout,"property %s x\n",vttp); + fprintf(fpout,"property %s y\n",vttp); + fprintf(fpout,"property %s z\n",vttp); - if( HasPerVertexNormal(m) &&( pi.mask & Mask::IOM_VERTNORMAL) ) - { - fprintf(fpout,"property %s nx\n",vttp); - fprintf(fpout,"property %s ny\n",vttp); - fprintf(fpout,"property %s nz\n",vttp); - } + if( HasPerVertexNormal(m) &&( pi.mask & Mask::IOM_VERTNORMAL) ) + { + fprintf(fpout,"property %s nx\n",vttp); + fprintf(fpout,"property %s ny\n",vttp); + fprintf(fpout,"property %s nz\n",vttp); + } - if( HasPerVertexFlags(m) &&( pi.mask & Mask::IOM_VERTFLAGS) ) - { - fprintf(fpout, - "property int flags\n" - ); - } + if( HasPerVertexFlags(m) &&( pi.mask & Mask::IOM_VERTFLAGS) ) + { + fprintf(fpout, + "property int flags\n"); + } - if( HasPerVertexColor(m) && (pi.mask & Mask::IOM_VERTCOLOR) ) - { - fprintf(fpout, - "property uchar red\n" - "property uchar green\n" - "property uchar blue\n" - "property uchar alpha\n" - ); - } + if( HasPerVertexColor(m) && (pi.mask & Mask::IOM_VERTCOLOR) ) + { + fprintf(fpout, + "property uchar red\n" + "property uchar green\n" + "property uchar blue\n" + "property uchar alpha\n"); + } - if( HasPerVertexQuality(m) && (pi.mask & Mask::IOM_VERTQUALITY) ) - { - const char* vqtp = vcg::tri::io::Precision::typeName(); - fprintf(fpout,"property %s quality\n",vqtp); - } + if( HasPerVertexQuality(m) && (pi.mask & Mask::IOM_VERTQUALITY) ) + { + const char* vqtp = vcg::tri::io::Precision::typeName(); + fprintf(fpout,"property %s quality\n",vqtp); + } - if( tri::HasPerVertexRadius(m) && (pi.mask & Mask::IOM_VERTRADIUS) ) - { - const char* rdtp = vcg::tri::io::Precision::typeName(); - fprintf(fpout,"property %s radius\n",rdtp); - } - if( ( HasPerVertexTexCoord(m) && pi.mask & Mask::IOM_VERTTEXCOORD ) ) - { - fprintf(fpout, - "property float texture_u\n" - "property float texture_v\n" - ); - } - for(size_t i=0;i::typeName(); + fprintf(fpout,"property %s radius\n",rdtp); + } + if( ( HasPerVertexTexCoord(m) && pi.mask & Mask::IOM_VERTTEXCOORD ) ) + { + fprintf(fpout, + "property float texture_u\n" + "property float texture_v\n"); + } + for(size_t i=0;i::typeName(); + fprintf(fpout, "property %s nx\n", fntp); + fprintf(fpout, "property %s ny\n", fntp); + fprintf(fpout, "property %s nz\n", fntp); + } + + if( HasPerFaceQuality(m) && (pi.mask & Mask::IOM_FACEQUALITY) ) + { + const char* fqtp = vcg::tri::io::Precision::typeName(); + fprintf(fpout,"property %s quality\n",fqtp); + } + + for(size_t i=0;i0 && (pi.mask & Mask::IOM_EDGEINDEX) ) + fprintf( + fpout, + "element edge %d\n" "property int vertex1\n""property int vertex2\n",m.en); + fprintf(fpout, "end_header\n" ); + + // Salvataggio camera + if((pi.mask & Mask::IOM_CAMERA)) + { + if(binary) + { + ShotScalarType t[17]; + + t[ 0] = (ShotScalarType)m.shot.Extrinsics.Tra()[0]; + t[ 1] = (ShotScalarType)m.shot.Extrinsics.Tra()[1]; + t[ 2] = (ShotScalarType)m.shot.Extrinsics.Tra()[2]; + t[ 3] = (ShotScalarType)m.shot.Extrinsics.Rot()[0][0]; + t[ 4] = (ShotScalarType)m.shot.Extrinsics.Rot()[0][1]; + t[ 5] = (ShotScalarType)m.shot.Extrinsics.Rot()[0][2]; + t[ 6] = (ShotScalarType)m.shot.Extrinsics.Rot()[1][0]; + t[ 7] = (ShotScalarType)m.shot.Extrinsics.Rot()[1][1]; + t[ 8] = (ShotScalarType)m.shot.Extrinsics.Rot()[1][2]; + t[ 9] = (ShotScalarType)m.shot.Extrinsics.Rot()[2][0]; + t[10] = (ShotScalarType)m.shot.Extrinsics.Rot()[2][1]; + t[11] = (ShotScalarType)m.shot.Extrinsics.Rot()[2][2]; + t[12] = (ShotScalarType)m.shot.Intrinsics.FocalMm; + t[13] = (ShotScalarType)m.shot.Intrinsics.PixelSizeMm[0]; + t[14] = (ShotScalarType)m.shot.Intrinsics.PixelSizeMm[1]; + t[15] = (ShotScalarType)m.shot.Intrinsics.CenterPx[0]; + t[16] = (ShotScalarType)m.shot.Intrinsics.CenterPx[1]; + fwrite(t,sizeof(ShotScalarType),17,fpout); + + fwrite( &m.shot.Intrinsics.ViewportPx[0],sizeof(int),2,fpout ); + + t[ 0] = (ShotScalarType)m.shot.Intrinsics.k[0]; + t[ 1] = (ShotScalarType)m.shot.Intrinsics.k[1]; + t[ 2] = (ShotScalarType)m.shot.Intrinsics.k[2]; + t[ 3] = (ShotScalarType)m.shot.Intrinsics.k[3]; + fwrite(t,sizeof(ShotScalarType),4,fpout); + } + else + { + fprintf(fpout,"%.*g %.*g %.*g %.*g %.*g %.*g %.*g %.*g %.*g %.*g %.*g %.*g %.*g %.*g %.*g %.*g %.*g %d %d %.*g %.*g %.*g %.*g\n" + ,DGTS,-m.shot.Extrinsics.Tra()[0] + ,DGTS,-m.shot.Extrinsics.Tra()[1] + ,DGTS,-m.shot.Extrinsics.Tra()[2] + ,DGTS,m.shot.Extrinsics.Rot()[0][0] + ,DGTS,m.shot.Extrinsics.Rot()[0][1] + ,DGTS,m.shot.Extrinsics.Rot()[0][2] + ,DGTS,m.shot.Extrinsics.Rot()[1][0] + ,DGTS,m.shot.Extrinsics.Rot()[1][1] + ,DGTS,m.shot.Extrinsics.Rot()[1][2] + ,DGTS,m.shot.Extrinsics.Rot()[2][0] + ,DGTS,m.shot.Extrinsics.Rot()[2][1] + ,DGTS,m.shot.Extrinsics.Rot()[2][2] + ,DGTS,m.shot.Intrinsics.FocalMm + ,DGTS,m.shot.Intrinsics.PixelSizeMm[0] + ,DGTS,m.shot.Intrinsics.PixelSizeMm[1] + ,DGTS,m.shot.Intrinsics.CenterPx[0] + ,DGTS,m.shot.Intrinsics.CenterPx[1] + ,m.shot.Intrinsics.ViewportPx[0] + ,m.shot.Intrinsics.ViewportPx[1] + ,DGTS,m.shot.Intrinsics.k[0] + ,DGTS,m.shot.Intrinsics.k[1] + ,DGTS,m.shot.Intrinsics.k[2] + ,DGTS,m.shot.Intrinsics.k[3] + ); + } + } + + + int j; + std::vector FlagV; + VertexPointer vp; + VertexIterator vi; + SimpleTempData indices(m.vert); + + std::vector > thfv(pi.VertDescriptorVec.size()); + std::vector > thdv(pi.VertDescriptorVec.size()); + std::vector > thiv(pi.VertDescriptorVec.size()); + std::vector > thsv(pi.VertDescriptorVec.size()); + std::vector > thcv(pi.VertDescriptorVec.size()); + std::vector > thuv(pi.VertDescriptorVec.size()); + std::vector > thp3fv(pi.VertDescriptorVec.size()); + std::vector > thp3dv(pi.VertDescriptorVec.size()); + + for(size_t i=0;i::typeName(); - fprintf(fpout, "property %s nx\n", fntp); - fprintf(fpout, "property %s ny\n", fntp); - fprintf(fpout, "property %s nz\n", fntp); + case ply::T_FLOAT : thfv[i] = vcg::tri::Allocator::template FindPerVertexAttribute(m,pi.VertAttrNameVec[i]); break; + case ply::T_DOUBLE : thdv[i] = vcg::tri::Allocator::template FindPerVertexAttribute(m,pi.VertAttrNameVec[i]); break; + case ply::T_INT : thiv[i] = vcg::tri::Allocator::template FindPerVertexAttribute(m,pi.VertAttrNameVec[i]); break; + case ply::T_SHORT : thsv[i] = vcg::tri::Allocator::template FindPerVertexAttribute(m,pi.VertAttrNameVec[i]); break; + case ply::T_CHAR : thcv[i] = vcg::tri::Allocator::template FindPerVertexAttribute(m,pi.VertAttrNameVec[i]); break; + case ply::T_UCHAR : thuv[i] = vcg::tri::Allocator::template FindPerVertexAttribute(m,pi.VertAttrNameVec[i]); break; + default : assert(0); + } + } + else { + switch (pi.VertDescriptorVec[i].stotype1) + { + case ply::T_FLOAT : thp3fv[i] = vcg::tri::Allocator::template FindPerVertexAttribute(m,pi.VertAttrNameVec[i]); break; + case ply::T_DOUBLE : thp3dv[i] = vcg::tri::Allocator::template FindPerVertexAttribute(m,pi.VertAttrNameVec[i]); break; + default : assert(0); + } + } + } + } + std::vector > thff(pi.FaceDescriptorVec.size()); + std::vector > thdf(pi.FaceDescriptorVec.size()); + std::vector > thif(pi.FaceDescriptorVec.size()); + std::vector > thsf(pi.FaceDescriptorVec.size()); + std::vector > thcf(pi.FaceDescriptorVec.size()); + std::vector > thuf(pi.FaceDescriptorVec.size()); + + for(size_t i=0;i::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; + case ply::T_DOUBLE : thdf[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; + case ply::T_INT : thif[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; + case ply::T_SHORT : thsf[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; + case ply::T_CHAR : thcf[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; + case ply::T_UCHAR : thuf[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; + default : assert(0); + } + } + } + + for(j=0,vi=m.vert.begin();vi!=m.vert.end();++vi){ + vp=&(*vi); + indices[vi] = j; + //((m.vn+m.fn) != 0) all vertices and faces have been marked as deleted but the are still in the vert/face vectors + if(cb && ((j%1000)==0) && ((m.vn+m.fn) != 0) )(*cb)( (100*j)/(m.vn+m.fn), "Saving Vertices"); + + if( !HasPerVertexFlags(m) || !vp->IsD() ) + { + if(binary) + { + ScalarType t; + + t = ScalarType(vp->P()[0]); fwrite(&t,sizeof(ScalarType),1,fpout); + t = ScalarType(vp->P()[1]); fwrite(&t,sizeof(ScalarType),1,fpout); + t = ScalarType(vp->P()[2]); fwrite(&t,sizeof(ScalarType),1,fpout); + + if( HasPerVertexNormal(m) && (pi.mask & Mask::IOM_VERTNORMAL) ) + { + t = ScalarType(vp->N()[0]); fwrite(&t,sizeof(ScalarType),1,fpout); + t = ScalarType(vp->N()[1]); fwrite(&t,sizeof(ScalarType),1,fpout); + t = ScalarType(vp->N()[2]); fwrite(&t,sizeof(ScalarType),1,fpout); + } + if( HasPerVertexFlags(m) && (pi.mask & Mask::IOM_VERTFLAGS) ) + fwrite(&(vp->Flags()),sizeof(int),1,fpout); + + if( HasPerVertexColor(m) && (pi.mask & Mask::IOM_VERTCOLOR) ){ + auto c = vp->C(); + fwrite(&c,sizeof(char),4,fpout); } - if( HasPerFaceQuality(m) && (pi.mask & Mask::IOM_FACEQUALITY) ) - { - const char* fqtp = vcg::tri::io::Precision::typeName(); - fprintf(fpout,"property %s quality\n",fqtp); - } + if( HasPerVertexQuality(m) && (pi.mask & Mask::IOM_VERTQUALITY) ){ + auto q = vp->Q(); + fwrite(&q, sizeof(typename VertexType::QualityType),1,fpout); + } - for(size_t i=0;i0 && (pi.mask & Mask::IOM_EDGEINDEX) ) - fprintf(fpout, - "element edge %d\n" - "property int vertex1\n" - "property int vertex2\n" - ,m.en - ); - fprintf(fpout, "end_header\n" ); + if( HasPerVertexRadius(m) && (pi.mask & Mask::IOM_VERTRADIUS) ){ + auto r = vp->R(); + fwrite(&r,sizeof(typename VertexType::RadiusType),1,fpout); + } - // Salvataggio camera - if((pi.mask & Mask::IOM_CAMERA)) - { - if(binary) - { - ShotScalarType t[17]; + if( HasPerVertexTexCoord(m) && (pi.mask & Mask::IOM_VERTTEXCOORD) ) + { + t = ScalarType(vp->T().u()); fwrite(&t,sizeof(ScalarType),1,fpout); + t = ScalarType(vp->T().v()); fwrite(&t,sizeof(ScalarType),1,fpout); + } - t[ 0] = (ShotScalarType)m.shot.Extrinsics.Tra()[0]; - t[ 1] = (ShotScalarType)m.shot.Extrinsics.Tra()[1]; - t[ 2] = (ShotScalarType)m.shot.Extrinsics.Tra()[2]; - t[ 3] = (ShotScalarType)m.shot.Extrinsics.Rot()[0][0]; - t[ 4] = (ShotScalarType)m.shot.Extrinsics.Rot()[0][1]; - t[ 5] = (ShotScalarType)m.shot.Extrinsics.Rot()[0][2]; - t[ 6] = (ShotScalarType)m.shot.Extrinsics.Rot()[1][0]; - t[ 7] = (ShotScalarType)m.shot.Extrinsics.Rot()[1][1]; - t[ 8] = (ShotScalarType)m.shot.Extrinsics.Rot()[1][2]; - t[ 9] = (ShotScalarType)m.shot.Extrinsics.Rot()[2][0]; - t[10] = (ShotScalarType)m.shot.Extrinsics.Rot()[2][1]; - t[11] = (ShotScalarType)m.shot.Extrinsics.Rot()[2][2]; - t[12] = (ShotScalarType)m.shot.Intrinsics.FocalMm; - t[13] = (ShotScalarType)m.shot.Intrinsics.PixelSizeMm[0]; - t[14] = (ShotScalarType)m.shot.Intrinsics.PixelSizeMm[1]; - t[15] = (ShotScalarType)m.shot.Intrinsics.CenterPx[0]; - t[16] = (ShotScalarType)m.shot.Intrinsics.CenterPx[1]; - fwrite(t,sizeof(ShotScalarType),17,fpout); - - fwrite( &m.shot.Intrinsics.ViewportPx[0],sizeof(int),2,fpout ); - - t[ 0] = (ShotScalarType)m.shot.Intrinsics.k[0]; - t[ 1] = (ShotScalarType)m.shot.Intrinsics.k[1]; - t[ 2] = (ShotScalarType)m.shot.Intrinsics.k[2]; - t[ 3] = (ShotScalarType)m.shot.Intrinsics.k[3]; - fwrite(t,sizeof(ShotScalarType),4,fpout); - } - else - { - fprintf(fpout,"%.*g %.*g %.*g %.*g %.*g %.*g %.*g %.*g %.*g %.*g %.*g %.*g %.*g %.*g %.*g %.*g %.*g %d %d %.*g %.*g %.*g %.*g\n" - ,DGTS,-m.shot.Extrinsics.Tra()[0] - ,DGTS,-m.shot.Extrinsics.Tra()[1] - ,DGTS,-m.shot.Extrinsics.Tra()[2] - ,DGTS,m.shot.Extrinsics.Rot()[0][0] - ,DGTS,m.shot.Extrinsics.Rot()[0][1] - ,DGTS,m.shot.Extrinsics.Rot()[0][2] - ,DGTS,m.shot.Extrinsics.Rot()[1][0] - ,DGTS,m.shot.Extrinsics.Rot()[1][1] - ,DGTS,m.shot.Extrinsics.Rot()[1][2] - ,DGTS,m.shot.Extrinsics.Rot()[2][0] - ,DGTS,m.shot.Extrinsics.Rot()[2][1] - ,DGTS,m.shot.Extrinsics.Rot()[2][2] - ,DGTS,m.shot.Intrinsics.FocalMm - ,DGTS,m.shot.Intrinsics.PixelSizeMm[0] - ,DGTS,m.shot.Intrinsics.PixelSizeMm[1] - ,DGTS,m.shot.Intrinsics.CenterPx[0] - ,DGTS,m.shot.Intrinsics.CenterPx[1] - ,m.shot.Intrinsics.ViewportPx[0] - ,m.shot.Intrinsics.ViewportPx[1] - ,DGTS,m.shot.Intrinsics.k[0] - ,DGTS,m.shot.Intrinsics.k[1] - ,DGTS,m.shot.Intrinsics.k[2] - ,DGTS,m.shot.Intrinsics.k[3] - ); - } - } - - - int j; - std::vector FlagV; - VertexPointer vp; - VertexIterator vi; - SimpleTempData indices(m.vert); - - std::vector > thfv(pi.VertDescriptorVec.size()); - std::vector > thdv(pi.VertDescriptorVec.size()); - std::vector > thiv(pi.VertDescriptorVec.size()); - std::vector > thsv(pi.VertDescriptorVec.size()); - std::vector > thcv(pi.VertDescriptorVec.size()); - std::vector > thuv(pi.VertDescriptorVec.size()); - - for(size_t i=0;i::template FindPerVertexAttribute(m,pi.VertAttrNameVec[i]); break; - case ply::T_DOUBLE : thdv[i] = vcg::tri::Allocator::template FindPerVertexAttribute(m,pi.VertAttrNameVec[i]); break; - case ply::T_INT : thiv[i] = vcg::tri::Allocator::template FindPerVertexAttribute(m,pi.VertAttrNameVec[i]); break; - case ply::T_SHORT : thsv[i] = vcg::tri::Allocator::template FindPerVertexAttribute(m,pi.VertAttrNameVec[i]); break; - case ply::T_CHAR : thcv[i] = vcg::tri::Allocator::template FindPerVertexAttribute(m,pi.VertAttrNameVec[i]); break; - case ply::T_UCHAR : thuv[i] = vcg::tri::Allocator::template FindPerVertexAttribute(m,pi.VertAttrNameVec[i]); break; - default : assert(0); - } - } - } - std::vector > thff(pi.FaceDescriptorVec.size()); - std::vector > thdf(pi.FaceDescriptorVec.size()); - std::vector > thif(pi.FaceDescriptorVec.size()); - std::vector > thsf(pi.FaceDescriptorVec.size()); - std::vector > thcf(pi.FaceDescriptorVec.size()); - std::vector > thuf(pi.FaceDescriptorVec.size()); - - for(size_t i=0;i::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; - case ply::T_DOUBLE : thdf[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; - case ply::T_INT : thif[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; - case ply::T_SHORT : thsf[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; - case ply::T_CHAR : thcf[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; - case ply::T_UCHAR : thuf[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; - default : assert(0); - } - } - } - - - - - for(j=0,vi=m.vert.begin();vi!=m.vert.end();++vi){ - vp=&(*vi); - indices[vi] = j; - //((m.vn+m.fn) != 0) all vertices and faces have been marked as deleted but the are still in the vert/face vectors - if(cb && ((j%1000)==0) && ((m.vn+m.fn) != 0) )(*cb)( (100*j)/(m.vn+m.fn), "Saving Vertices"); - - if( !HasPerVertexFlags(m) || !vp->IsD() ) - { - if(binary) - { - ScalarType t; - - t = ScalarType(vp->P()[0]); fwrite(&t,sizeof(ScalarType),1,fpout); - t = ScalarType(vp->P()[1]); fwrite(&t,sizeof(ScalarType),1,fpout); - t = ScalarType(vp->P()[2]); fwrite(&t,sizeof(ScalarType),1,fpout); - - if( HasPerVertexNormal(m) && (pi.mask & Mask::IOM_VERTNORMAL) ) - { - t = ScalarType(vp->N()[0]); fwrite(&t,sizeof(ScalarType),1,fpout); - t = ScalarType(vp->N()[1]); fwrite(&t,sizeof(ScalarType),1,fpout); - t = ScalarType(vp->N()[2]); fwrite(&t,sizeof(ScalarType),1,fpout); - } - if( HasPerVertexFlags(m) && (pi.mask & Mask::IOM_VERTFLAGS) ) - fwrite(&(vp->Flags()),sizeof(int),1,fpout); - - if( HasPerVertexColor(m) && (pi.mask & Mask::IOM_VERTCOLOR) ){ - auto c = vp->C(); - fwrite(&c,sizeof(char),4,fpout); - } - - if( HasPerVertexQuality(m) && (pi.mask & Mask::IOM_VERTQUALITY) ){ - auto q = vp->Q(); - fwrite(&q, sizeof(typename VertexType::QualityType),1,fpout); - } - - if( HasPerVertexRadius(m) && (pi.mask & Mask::IOM_VERTRADIUS) ){ - auto r = vp->R(); - fwrite(&r,sizeof(typename VertexType::RadiusType),1,fpout); - } - - if( HasPerVertexTexCoord(m) && (pi.mask & Mask::IOM_VERTTEXCOORD) ) - { - t = ScalarType(vp->T().u()); fwrite(&t,sizeof(ScalarType),1,fpout); - t = ScalarType(vp->T().v()); fwrite(&t,sizeof(ScalarType),1,fpout); - } - - for(size_t i=0;iP()[0],DGT,vp->P()[1],DGT,vp->P()[2]); - - if( HasPerVertexNormal(m) && (pi.mask & Mask::IOM_VERTNORMAL) ) - fprintf(fpout,"%.*g %.*g %.*g " ,DGT,ScalarType(vp->N()[0]),DGT,ScalarType(vp->N()[1]),DGT,ScalarType(vp->N()[2])); - - if( HasPerVertexFlags(m) && (pi.mask & Mask::IOM_VERTFLAGS)) - fprintf(fpout,"%d ",vp->Flags()); - - if( HasPerVertexColor(m) && (pi.mask & Mask::IOM_VERTCOLOR) ) - fprintf(fpout,"%d %d %d %d ",vp->C()[0],vp->C()[1],vp->C()[2],vp->C()[3] ); - - if( HasPerVertexQuality(m) && (pi.mask & Mask::IOM_VERTQUALITY) ) - fprintf(fpout,"%.*g ",DGTVQ,vp->Q()); - - if( HasPerVertexRadius(m) && (pi.mask & Mask::IOM_VERTRADIUS) ) - fprintf(fpout,"%.*g ",DGTVR,vp->R()); - - if( HasPerVertexTexCoord(m) && (pi.mask & Mask::IOM_VERTTEXCOORD) ) - fprintf(fpout,"%f %f",vp->T().u(),vp->T().v()); - - for(size_t i=0;iIsD() ) - { fcnt++; - if(binary) - { - vv[0]=indices[fp->cV(0)]; - vv[1]=indices[fp->cV(1)]; - vv[2]=indices[fp->cV(2)]; - fwrite(&b3char,sizeof(char),1,fpout); - fwrite(vv,sizeof(int),3,fpout); - - if(HasPerFaceFlags(m)&&( pi.mask & Mask::IOM_FACEFLAGS) ){ - auto fl = fp->Flags(); - fwrite(&fl,sizeof(int),1,fpout); - } - - if( HasPerVertexTexCoord(m) && (!HasPerWedgeTexCoord(m)) && (pi.mask & Mask::IOM_WEDGTEXCOORD) ) // Note that you can save VT as WT if you really want it... - { - fwrite(&b6char,sizeof(char),1,fpout); - float t[6]; - for(int k=0;k<3;++k) - { - t[k*2+0] = fp->V(k)->T().u(); - t[k*2+1] = fp->V(k)->T().v(); - } - fwrite(t,sizeof(float),6,fpout); - } - else if( HasPerWedgeTexCoord(m) && (pi.mask & Mask::IOM_WEDGTEXCOORD) ) - { - fwrite(&b6char,sizeof(char),1,fpout); - float t[6]; - for(int k=0;k<3;++k) - { - t[k*2+0] = fp->WT(k).u(); - t[k*2+1] = fp->WT(k).v(); - } - fwrite(t,sizeof(float),6,fpout); - } - - if(saveTexIndexFlag) - { - int t = fp->WT(0).n(); - fwrite(&t,sizeof(int),1,fpout); - } - - if( HasPerFaceColor(m) && (pi.mask & Mask::IOM_FACECOLOR) ) - fwrite(&( fp->C() ),sizeof(char),4,fpout); - - - if( HasPerWedgeColor(m) && (pi.mask & Mask::IOM_WEDGCOLOR) ) - { - fwrite(&b9char,sizeof(char),1,fpout); - float t[3]; - for(int z=0;z<3;++z) - { - t[0] = float(fp->WC(z)[0])/255; - t[1] = float(fp->WC(z)[1])/255; - t[2] = float(fp->WC(z)[2])/255; - fwrite( t,sizeof(float),3,fpout); - } - } - - if( HasPerFaceNormal(m) && (pi.mask & Mask::IOM_FACENORMAL) ) - { - ScalarType t; - t = ScalarType(fp->N()[0]); fwrite(&t,sizeof(ScalarType),1,fpout); - t = ScalarType(fp->N()[1]); fwrite(&t,sizeof(ScalarType),1,fpout); - t = ScalarType(fp->N()[2]); fwrite(&t,sizeof(ScalarType),1,fpout); + for(size_t i=0;iP()[0],DGT,vp->P()[1],DGT,vp->P()[2]); - if( HasPerFaceQuality(m) && (pi.mask & Mask::IOM_FACEQUALITY) ) - fwrite( &(fp->Q()),sizeof(typename FaceType::ScalarType),1,fpout); + if( HasPerVertexNormal(m) && (pi.mask & Mask::IOM_VERTNORMAL) ) + fprintf(fpout,"%.*g %.*g %.*g " ,DGT,ScalarType(vp->N()[0]),DGT,ScalarType(vp->N()[1]),DGT,ScalarType(vp->N()[2])); + + if( HasPerVertexFlags(m) && (pi.mask & Mask::IOM_VERTFLAGS)) + fprintf(fpout,"%d ",vp->Flags()); + + if( HasPerVertexColor(m) && (pi.mask & Mask::IOM_VERTCOLOR) ) + fprintf(fpout,"%d %d %d %d ",vp->C()[0],vp->C()[1],vp->C()[2],vp->C()[3] ); + + if( HasPerVertexQuality(m) && (pi.mask & Mask::IOM_VERTQUALITY) ) + fprintf(fpout,"%.*g ",DGTVQ,vp->Q()); + + if( HasPerVertexRadius(m) && (pi.mask & Mask::IOM_VERTRADIUS) ) + fprintf(fpout,"%.*g ",DGTVR,vp->R()); + + if( HasPerVertexTexCoord(m) && (pi.mask & Mask::IOM_VERTTEXCOORD) ) + fprintf(fpout,"%f %f",vp->T().u(),vp->T().v()); + + for(size_t i=0;iIsD() ) + { fcnt++; + if(binary) + { + vv[0]=indices[fp->cV(0)]; + vv[1]=indices[fp->cV(1)]; + vv[2]=indices[fp->cV(2)]; + fwrite(&b3char,sizeof(char),1,fpout); + fwrite(vv,sizeof(int),3,fpout); + + if(HasPerFaceFlags(m)&&( pi.mask & Mask::IOM_FACEFLAGS) ){ + auto fl = fp->Flags(); + fwrite(&fl,sizeof(int),1,fpout); + } + + if( HasPerVertexTexCoord(m) && (!HasPerWedgeTexCoord(m)) && (pi.mask & Mask::IOM_WEDGTEXCOORD) ) // Note that you can save VT as WT if you really want it... + { + fwrite(&b6char,sizeof(char),1,fpout); + float t[6]; + for(int k=0;k<3;++k) + { + t[k*2+0] = fp->V(k)->T().u(); + t[k*2+1] = fp->V(k)->T().v(); + } + fwrite(t,sizeof(float),6,fpout); + } + else if( HasPerWedgeTexCoord(m) && (pi.mask & Mask::IOM_WEDGTEXCOORD) ) + { + fwrite(&b6char,sizeof(char),1,fpout); + float t[6]; + for(int k=0;k<3;++k) + { + t[k*2+0] = fp->WT(k).u(); + t[k*2+1] = fp->WT(k).v(); + } + fwrite(t,sizeof(float),6,fpout); + } + + if(saveTexIndexFlag) + { + int t = fp->WT(0).n(); + fwrite(&t,sizeof(int),1,fpout); + } + + if( HasPerFaceColor(m) && (pi.mask & Mask::IOM_FACECOLOR) ) + fwrite(&( fp->C() ),sizeof(char),4,fpout); - for(size_t i=0;iVN()); - for(int k=0;kVN();++k) - fprintf(fpout,"%d ",indices[fp->cV(k)]); + if( HasPerWedgeColor(m) && (pi.mask & Mask::IOM_WEDGCOLOR) ) + { + fwrite(&b9char,sizeof(char),1,fpout); + float t[3]; + for(int z=0;z<3;++z) + { + t[0] = float(fp->WC(z)[0])/255; + t[1] = float(fp->WC(z)[1])/255; + t[2] = float(fp->WC(z)[2])/255; + fwrite( t,sizeof(float),3,fpout); + } + } - if(HasPerFaceFlags(m)&&( pi.mask & Mask::IOM_FACEFLAGS )) - fprintf(fpout,"%d ",fp->Flags()); + if( HasPerFaceNormal(m) && (pi.mask & Mask::IOM_FACENORMAL) ) + { + ScalarType t; + t = ScalarType(fp->N()[0]); fwrite(&t,sizeof(ScalarType),1,fpout); + t = ScalarType(fp->N()[1]); fwrite(&t,sizeof(ScalarType),1,fpout); + t = ScalarType(fp->N()[2]); fwrite(&t,sizeof(ScalarType),1,fpout); + } - if( HasPerVertexTexCoord(m) && (pi.mask & Mask::IOM_WEDGTEXCOORD) ) // you can save VT as WT if you really want it... - { - fprintf(fpout,"%d ",fp->VN()*2); - for(int k=0;kVN();++k) - fprintf(fpout,"%f %f " - ,fp->V(k)->T().u() - ,fp->V(k)->T().v() - ); - } - else if( HasPerWedgeTexCoord(m) && (pi.mask & Mask::IOM_WEDGTEXCOORD) ) - { - fprintf(fpout,"%d ",fp->VN()*2); - for(int k=0;kVN();++k) - fprintf(fpout,"%f %f " - ,fp->WT(k).u() - ,fp->WT(k).v() - ); - } - - if(saveTexIndexFlag) - { - fprintf(fpout,"%d ",fp->WT(0).n()); - } - - if( HasPerFaceColor(m) && (pi.mask & Mask::IOM_FACECOLOR) ) - { - fprintf(fpout, "%u %u %u %u ", fp->C()[0], fp->C()[1], fp->C()[2], fp->C()[3]); - } - else if( HasPerWedgeColor(m) && (pi.mask & Mask::IOM_WEDGCOLOR) ) - { - fprintf(fpout,"9 "); - for(int z=0;z<3;++z) - fprintf(fpout,"%g %g %g " - ,double(fp->WC(z)[0])/255 - ,double(fp->WC(z)[1])/255 - ,double(fp->WC(z)[2])/255 - ); - } - - if (HasPerFaceNormal(m) && (pi.mask & Mask::IOM_FACENORMAL)) - fprintf(fpout,"%.*g %.*g %.*g " ,DGT, ScalarType(fp->N()[0]),DGT,ScalarType(fp->N()[1]),DGT,ScalarType(fp->N()[2])); - - if( HasPerFaceQuality(m) && (pi.mask & Mask::IOM_FACEQUALITY) ) - fprintf(fpout,"%.*g ",DGTFQ,fp->Q()); - - for(size_t i=0;iIsD() ) - { - ++ecnt; - if(binary) - { - eauxvv[0]=indices[ei->cV(0)]; - eauxvv[1]=indices[ei->cV(1)]; - fwrite(eauxvv,sizeof(int),2,fpout); - } - else // ***** ASCII ***** - fprintf(fpout,"%d %d \n", indices[ei->cV(0)], indices[ei->cV(1)]); - } - } - assert(ecnt==m.en); - } - int result = 0; - if (ferror(fpout)) result = ply::E_STREAMERROR; - fclose(fpout); - return result; - } - - static const char *ErrorMsg(int error) - { - static std::vector ply_error_msg; - if(ply_error_msg.empty()) - { - ply_error_msg.resize(PlyInfo::E_MAXPLYINFOERRORS ); - ply_error_msg[ply::E_NOERROR ]="No errors"; - ply_error_msg[ply::E_CANTOPEN ]="Can't open file"; - ply_error_msg[ply::E_NOTHEADER ]="Header not found"; - ply_error_msg[ply::E_UNESPECTEDEOF ]="Eof in header"; - ply_error_msg[ply::E_NOFORMAT ]="Format not found"; - ply_error_msg[ply::E_SYNTAX ]="Syntax error on header"; - ply_error_msg[ply::E_PROPOUTOFELEMENT ]="Property without element"; - ply_error_msg[ply::E_BADTYPENAME ]="Bad type name"; - ply_error_msg[ply::E_ELEMNOTFOUND ]="Element not found"; - ply_error_msg[ply::E_PROPNOTFOUND ]="Property not found"; - ply_error_msg[ply::E_BADTYPE ]="Bad type on addtoread"; - ply_error_msg[ply::E_INCOMPATIBLETYPE ]="Incompatible type"; - ply_error_msg[ply::E_BADCAST ]="Bad cast"; - - ply_error_msg[ply::E_STREAMERROR ] = "Output Stream Error"; - - ply_error_msg[PlyInfo::E_NO_VERTEX ]="No vertex field found"; - ply_error_msg[PlyInfo::E_NO_FACE ]="No face field found"; - ply_error_msg[PlyInfo::E_SHORTFILE ]="Unespected eof"; - ply_error_msg[PlyInfo::E_NO_3VERTINFACE ]="Face with more than 3 vertices"; - ply_error_msg[PlyInfo::E_BAD_VERT_INDEX ]="Bad vertex index in face"; - ply_error_msg[PlyInfo::E_NO_6TCOORD ]="Face with no 6 texture coordinates"; - ply_error_msg[PlyInfo::E_DIFFER_COLORS ]="Number of color differ from vertices"; - } - - if(error>PlyInfo::E_MAXPLYINFOERRORS || error<0) return "Unknown error"; - else return ply_error_msg[error].c_str(); - }; - - static int GetExportMaskCapability() - { - int capability = 0; - capability |= vcg::tri::io::Mask::IOM_VERTCOORD ; - capability |= vcg::tri::io::Mask::IOM_VERTFLAGS ; - capability |= vcg::tri::io::Mask::IOM_VERTCOLOR ; - capability |= vcg::tri::io::Mask::IOM_VERTQUALITY ; - capability |= vcg::tri::io::Mask::IOM_VERTNORMAL ; - capability |= vcg::tri::io::Mask::IOM_VERTRADIUS ; - capability |= vcg::tri::io::Mask::IOM_VERTTEXCOORD ; - capability |= vcg::tri::io::Mask::IOM_FACEINDEX ; - capability |= vcg::tri::io::Mask::IOM_FACEFLAGS ; - capability |= vcg::tri::io::Mask::IOM_FACECOLOR ; - capability |= vcg::tri::io::Mask::IOM_FACEQUALITY ; - // capability |= vcg::tri::io::Mask::IOM_FACENORMAL ; - capability |= vcg::tri::io::Mask::IOM_WEDGCOLOR ; - capability |= vcg::tri::io::Mask::IOM_WEDGTEXCOORD ; - capability |= vcg::tri::io::Mask::IOM_WEDGTEXMULTI ; - capability |= vcg::tri::io::Mask::IOM_WEDGNORMAL ; - capability |= vcg::tri::io::Mask::IOM_CAMERA ; - //capability |= vcg::tri::io::Mask::IOM_BITPOLYGONAL; - return capability; - } + if( HasPerFaceQuality(m) && (pi.mask & Mask::IOM_FACEQUALITY) ) + fwrite( &(fp->Q()),sizeof(typename FaceType::ScalarType),1,fpout); - }; // end class + for(size_t i=0;iVN()); + for(int k=0;kVN();++k) + fprintf(fpout,"%d ",indices[fp->cV(k)]); + + if(HasPerFaceFlags(m)&&( pi.mask & Mask::IOM_FACEFLAGS )) + fprintf(fpout,"%d ",fp->Flags()); + + if( HasPerVertexTexCoord(m) && (pi.mask & Mask::IOM_WEDGTEXCOORD) ) // you can save VT as WT if you really want it... + { + fprintf(fpout,"%d ",fp->VN()*2); + for(int k=0;kVN();++k) + fprintf(fpout,"%f %f " + ,fp->V(k)->T().u() + ,fp->V(k)->T().v() + ); + } + else if( HasPerWedgeTexCoord(m) && (pi.mask & Mask::IOM_WEDGTEXCOORD) ) + { + fprintf(fpout,"%d ",fp->VN()*2); + for(int k=0;kVN();++k) + fprintf(fpout,"%f %f " + ,fp->WT(k).u() + ,fp->WT(k).v() + ); + } + + if(saveTexIndexFlag) + { + fprintf(fpout,"%d ",fp->WT(0).n()); + } + + if( HasPerFaceColor(m) && (pi.mask & Mask::IOM_FACECOLOR) ) + { + fprintf(fpout, "%u %u %u %u ", fp->C()[0], fp->C()[1], fp->C()[2], fp->C()[3]); + } + else if( HasPerWedgeColor(m) && (pi.mask & Mask::IOM_WEDGCOLOR) ) + { + fprintf(fpout,"9 "); + for(int z=0;z<3;++z) + fprintf(fpout,"%g %g %g " + ,double(fp->WC(z)[0])/255 + ,double(fp->WC(z)[1])/255 + ,double(fp->WC(z)[2])/255 + ); + } + + if (HasPerFaceNormal(m) && (pi.mask & Mask::IOM_FACENORMAL)) + fprintf(fpout,"%.*g %.*g %.*g " ,DGT, ScalarType(fp->N()[0]),DGT,ScalarType(fp->N()[1]),DGT,ScalarType(fp->N()[2])); + + if( HasPerFaceQuality(m) && (pi.mask & Mask::IOM_FACEQUALITY) ) + fprintf(fpout,"%.*g ",DGTFQ,fp->Q()); + + for(size_t i=0;iIsD() ) + { + ++ecnt; + if(binary) + { + eauxvv[0]=indices[ei->cV(0)]; + eauxvv[1]=indices[ei->cV(1)]; + fwrite(eauxvv,sizeof(int),2,fpout); + } + else // ***** ASCII ***** + fprintf(fpout,"%d %d \n", indices[ei->cV(0)], indices[ei->cV(1)]); + } + } + assert(ecnt==m.en); + } + int result = 0; + if (ferror(fpout)) result = ply::E_STREAMERROR; + fclose(fpout); + return result; + } + + static const char *ErrorMsg(int error) + { + static std::vector ply_error_msg; + if(ply_error_msg.empty()) + { + ply_error_msg.resize(PlyInfo::E_MAXPLYINFOERRORS ); + ply_error_msg[ply::E_NOERROR ]="No errors"; + ply_error_msg[ply::E_CANTOPEN ]="Can't open file"; + ply_error_msg[ply::E_NOTHEADER ]="Header not found"; + ply_error_msg[ply::E_UNESPECTEDEOF ]="Eof in header"; + ply_error_msg[ply::E_NOFORMAT ]="Format not found"; + ply_error_msg[ply::E_SYNTAX ]="Syntax error on header"; + ply_error_msg[ply::E_PROPOUTOFELEMENT ]="Property without element"; + ply_error_msg[ply::E_BADTYPENAME ]="Bad type name"; + ply_error_msg[ply::E_ELEMNOTFOUND ]="Element not found"; + ply_error_msg[ply::E_PROPNOTFOUND ]="Property not found"; + ply_error_msg[ply::E_BADTYPE ]="Bad type on addtoread"; + ply_error_msg[ply::E_INCOMPATIBLETYPE ]="Incompatible type"; + ply_error_msg[ply::E_BADCAST ]="Bad cast"; + + ply_error_msg[ply::E_STREAMERROR ] = "Output Stream Error"; + + ply_error_msg[PlyInfo::E_NO_VERTEX ]="No vertex field found"; + ply_error_msg[PlyInfo::E_NO_FACE ]="No face field found"; + ply_error_msg[PlyInfo::E_SHORTFILE ]="Unespected eof"; + ply_error_msg[PlyInfo::E_NO_3VERTINFACE ]="Face with more than 3 vertices"; + ply_error_msg[PlyInfo::E_BAD_VERT_INDEX ]="Bad vertex index in face"; + ply_error_msg[PlyInfo::E_NO_6TCOORD ]="Face with no 6 texture coordinates"; + ply_error_msg[PlyInfo::E_DIFFER_COLORS ]="Number of color differ from vertices"; + } + + if(error>PlyInfo::E_MAXPLYINFOERRORS || error<0) return "Unknown error"; + else return ply_error_msg[error].c_str(); + }; + + static int GetExportMaskCapability() + { + int capability = 0; + capability |= vcg::tri::io::Mask::IOM_VERTCOORD ; + capability |= vcg::tri::io::Mask::IOM_VERTFLAGS ; + capability |= vcg::tri::io::Mask::IOM_VERTCOLOR ; + capability |= vcg::tri::io::Mask::IOM_VERTQUALITY ; + capability |= vcg::tri::io::Mask::IOM_VERTNORMAL ; + capability |= vcg::tri::io::Mask::IOM_VERTRADIUS ; + capability |= vcg::tri::io::Mask::IOM_VERTTEXCOORD ; + capability |= vcg::tri::io::Mask::IOM_FACEINDEX ; + capability |= vcg::tri::io::Mask::IOM_FACEFLAGS ; + capability |= vcg::tri::io::Mask::IOM_FACECOLOR ; + capability |= vcg::tri::io::Mask::IOM_FACEQUALITY ; + // capability |= vcg::tri::io::Mask::IOM_FACENORMAL ; + capability |= vcg::tri::io::Mask::IOM_WEDGCOLOR ; + capability |= vcg::tri::io::Mask::IOM_WEDGTEXCOORD ; + capability |= vcg::tri::io::Mask::IOM_WEDGTEXMULTI ; + capability |= vcg::tri::io::Mask::IOM_WEDGNORMAL ; + capability |= vcg::tri::io::Mask::IOM_CAMERA ; + //capability |= vcg::tri::io::Mask::IOM_BITPOLYGONAL; + return capability; + } + + +}; // end class - } // end namespace tri - } // end namespace io +} // end namespace tri +} // end namespace io } // end namespace vcg //@} #endif diff --git a/wrap/io_trimesh/io_ply.h b/wrap/io_trimesh/io_ply.h index 39144305..47b8754c 100644 --- a/wrap/io_trimesh/io_ply.h +++ b/wrap/io_trimesh/io_ply.h @@ -100,22 +100,66 @@ public: addPerElemScalarAttribute(elemType, vcg::ply::T_DOUBLE, attrName, propName); } - void addPerVertexScalarAttribute(const std::string& attrName, vcg::ply::PlyTypes attrType, std::string propName="") { + void addPerVertexScalarAttribute(const std::string& attrName, vcg::ply::PlyTypes attrType, std::string propName="") + { addPerElemScalarAttribute(0,attrType, attrName,propName); } - void AddPerVertexFloatAttribute(const std::string& attrName, std::string propName="") { + void AddPerVertexFloatAttribute(const std::string& attrName, std::string propName="") + { AddPerElemFloatAttribute(0,attrName,propName); } - void addPerFaceScalarAttribute(const std::string& attrName, vcg::ply::PlyTypes attrType, std::string propName="") { + void addPerFaceScalarAttribute(const std::string& attrName, vcg::ply::PlyTypes attrType, std::string propName="") + { addPerElemScalarAttribute(1,attrType, attrName,propName); } - void AddPerFaceFloatAttribute(const std::string& attrName, std::string propName="") { + void AddPerFaceFloatAttribute(const std::string& attrName, std::string propName="") + { AddPerElemFloatAttribute(1,attrName,propName); } + void addPerElemPointAttribute(int elemType, vcg::ply::PlyTypes propertyType, const std::string& attrName, std::string propName="") + { + if(propName=="") + propName=attrName; + + PropDescriptor p; + p.propname=propName; + p.stotype1 = propertyType; + p.memtype1 = propertyType; + p.islist = true; + p.stotype2 = vcg::ply::PlyTypes::T_UINT; + p.stotype2 = vcg::ply::PlyTypes::T_UINT; + + if (elemType == 0){ //vertex + VertAttrNameVec.push_back(attrName); + p.elemname="vertex"; + VertDescriptorVec.push_back(p); + } + else if (elemType == 1){ //face + FaceAttrNameVec.push_back(attrName); + p.elemname="face"; + FaceDescriptorVec.push_back(p); + } + } + + void addPerVertexPoint3mAttribute(const std::string& attrName, vcg::ply::PlyTypes attrType, std::string propName="") + { + addPerElemPointAttribute(0,attrType, attrName,propName); + } + + void addPerVertexPoint3fAttribute(const std::string& attrName, std::string propName="") + { + addPerElemPointAttribute(0,vcg::ply::PlyTypes::T_FLOAT, attrName,propName); + } + + void addPerVertexPoint3dAttribute(const std::string& attrName, std::string propName="") + { + addPerElemPointAttribute(0,vcg::ply::PlyTypes::T_DOUBLE, attrName,propName); + } + /* Note that saving a per vertex point3 attribute is a mess. * Actually require to allocate 3 float attribute and save them. And they are never deallocated... */ template diff --git a/wrap/ply/plylib.cpp b/wrap/ply/plylib.cpp index 8530349f..c4657fd6 100644 --- a/wrap/ply/plylib.cpp +++ b/wrap/ply/plylib.cpp @@ -143,8 +143,12 @@ static int TypeSize[] = { size_t PropDescriptor::memtypesize() const {return TypeSize[memtype1];} size_t PropDescriptor::stotypesize() const {return TypeSize[stotype1];} +size_t PropDescriptor::memtype2size() const {return TypeSize[memtype2];} +size_t PropDescriptor::stotype2size() const {return TypeSize[stotype2];} const char *PropDescriptor::memtypename() const {return PlyFile::typenames[memtype1];} const char *PropDescriptor::stotypename() const {return PlyFile::typenames[stotype1];} +const char *PropDescriptor::memtype2name() const {return PlyFile::typenames[memtype2];} +const char *PropDescriptor::stotype2name() const {return PlyFile::typenames[stotype2];} static char CrossType[9][9]= { diff --git a/wrap/ply/plylib.h b/wrap/ply/plylib.h index 88470b20..36fa757e 100644 --- a/wrap/ply/plylib.h +++ b/wrap/ply/plylib.h @@ -133,6 +133,10 @@ public: size_t memtypesize() const; // per sapere quanto e'grande un dato descrittore in memoria const char* memtypename() const; const char* stotypename() const; + size_t stotype2size() const; // per sapere quanto e'grande un dato descrittore sul file + size_t memtype2size() const; // per sapere quanto e'grande un dato descrittore in memoria + const char* memtype2name() const; + const char* stotype2name() const; }; // Reading Callback (used to copy a data prop) From 702c13910843ea95512146447e36beeb47a8b9eb Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Fri, 2 Apr 2021 16:37:10 +0200 Subject: [PATCH 007/117] ply export custom point attribute - set list size to uchar type --- wrap/io_trimesh/export_ply.h | 10 +++++----- wrap/io_trimesh/io_ply.h | 4 ++-- wrap/ply/plylib.h | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/wrap/io_trimesh/export_ply.h b/wrap/io_trimesh/export_ply.h index b5be20ca..0138dba1 100644 --- a/wrap/io_trimesh/export_ply.h +++ b/wrap/io_trimesh/export_ply.h @@ -416,7 +416,7 @@ public: { case ply::T_FLOAT : thff[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; case ply::T_DOUBLE : thdf[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; - case ply::T_INT : thif[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; + case ply::T_INT : thif[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; case ply::T_SHORT : thsf[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; case ply::T_CHAR : thcf[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; case ply::T_UCHAR : thuf[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; @@ -482,7 +482,7 @@ public: { case ply::T_FLOAT : tf=thfv[i][vp]; fwrite(&tf, sizeof(float),1,fpout); break; case ply::T_DOUBLE : td=thdv[i][vp]; fwrite(&td, sizeof(double),1,fpout); break; - case ply::T_INT : ti=thiv[i][vp]; fwrite(&ti, sizeof(int),1,fpout); break; + case ply::T_INT : ti=thiv[i][vp]; fwrite(&ti, sizeof(int),1,fpout); break; case ply::T_SHORT : ts=thsv[i][vp]; fwrite(&ts, sizeof(short),1,fpout); break; case ply::T_CHAR : tc=thcv[i][vp]; fwrite(&tc, sizeof(char),1,fpout); break; case ply::T_UCHAR : tu=thuv[i][vp]; fwrite(&tu,sizeof(unsigned char),1,fpout); break; @@ -490,18 +490,18 @@ public: } } else { //it is a Poin3f or a Point3d attribute. Saving it as a list - static const unsigned int psize = 3; + static const unsigned char psize = 3; switch (pi.VertDescriptorVec[i].stotype1) { case ply::T_FLOAT : - fwrite(&psize, sizeof(unsigned int), 1,fpout); + fwrite(&psize, sizeof(unsigned char), 1,fpout); fwrite(&thp3fv[i][vp][0], sizeof(float), 1,fpout); fwrite(&thp3fv[i][vp][1], sizeof(float), 1,fpout); fwrite(&thp3fv[i][vp][2], sizeof(float), 1,fpout); break; //fprintf(fpout,"%d %f %f %f", 3, thp3fv[i][vp][0], thp3fv[i][vp][1], thp3fv[i][vp][2]); break; case ply::T_DOUBLE : - fwrite(&psize, sizeof(unsigned int), 1,fpout); + fwrite(&psize, sizeof(unsigned char), 1,fpout); fwrite(&thp3dv[i][vp][0], sizeof(double), 1,fpout); fwrite(&thp3dv[i][vp][1], sizeof(double), 1,fpout); fwrite(&thp3dv[i][vp][2], sizeof(double), 1,fpout); diff --git a/wrap/io_trimesh/io_ply.h b/wrap/io_trimesh/io_ply.h index 47b8754c..92ba9f2d 100644 --- a/wrap/io_trimesh/io_ply.h +++ b/wrap/io_trimesh/io_ply.h @@ -130,8 +130,8 @@ public: p.stotype1 = propertyType; p.memtype1 = propertyType; p.islist = true; - p.stotype2 = vcg::ply::PlyTypes::T_UINT; - p.stotype2 = vcg::ply::PlyTypes::T_UINT; + p.memtype2 = vcg::ply::PlyTypes::T_UCHAR; + p.stotype2 = vcg::ply::PlyTypes::T_UCHAR; if (elemType == 0){ //vertex VertAttrNameVec.push_back(attrName); diff --git a/wrap/ply/plylib.h b/wrap/ply/plylib.h index 36fa757e..0162ae00 100644 --- a/wrap/ply/plylib.h +++ b/wrap/ply/plylib.h @@ -176,7 +176,7 @@ public: int bestored; // 1 se va storata PropDescriptor desc; // Descrittore di memorizzazione - readelemcb cb; // Callback di lettura + readelemcb cb = nullptr; // Callback di lettura }; From c1d973238161f74f6194f0746454725dd39cc00b Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Fri, 2 Apr 2021 17:02:03 +0200 Subject: [PATCH 008/117] support export per face point custom attributes on ply --- wrap/io_trimesh/export_ply.h | 128 +++++++++++++++++++++++++---------- wrap/io_trimesh/io_ply.h | 15 ++++ 2 files changed, 108 insertions(+), 35 deletions(-) diff --git a/wrap/io_trimesh/export_ply.h b/wrap/io_trimesh/export_ply.h index 0138dba1..4f120237 100644 --- a/wrap/io_trimesh/export_ply.h +++ b/wrap/io_trimesh/export_ply.h @@ -284,8 +284,24 @@ public: fprintf(fpout,"property %s quality\n",fqtp); } - for(size_t i=0;i0 && (pi.mask & Mask::IOM_EDGEINDEX) ) fprintf( @@ -406,21 +422,33 @@ public: std::vector > thsf(pi.FaceDescriptorVec.size()); std::vector > thcf(pi.FaceDescriptorVec.size()); std::vector > thuf(pi.FaceDescriptorVec.size()); + std::vector > thp3ff(pi.FaceDescriptorVec.size()); + std::vector > thp3df(pi.FaceDescriptorVec.size()); for(size_t i=0;i::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; - case ply::T_DOUBLE : thdf[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; - case ply::T_INT : thif[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; - case ply::T_SHORT : thsf[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; - case ply::T_CHAR : thcf[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; - case ply::T_UCHAR : thuf[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; - default : assert(0); + if (!pi.FaceDescriptorVec[i].islist) { + switch (pi.FaceDescriptorVec[i].stotype1) + { + case ply::T_FLOAT : thff[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; + case ply::T_DOUBLE : thdf[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; + case ply::T_INT : thif[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; + case ply::T_SHORT : thsf[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; + case ply::T_CHAR : thcf[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; + case ply::T_UCHAR : thuf[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; + default : assert(0); + } + } + else { + switch (pi.FaceDescriptorVec[i].stotype1) + { + case ply::T_FLOAT : thp3ff[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; + case ply::T_DOUBLE : thp3df[i] = vcg::tri::Allocator::template FindPerFaceAttribute(m,pi.FaceAttrNameVec[i]); break; + default : assert(0); + } } } } @@ -579,12 +607,12 @@ public: { switch (pi.VertDescriptorVec[i].memtype1) { - case ply::T_FLOAT : tf=*( (float *) (((char *)vp)+pi.VertDescriptorVec[i].offset1)); fprintf(fpout,"%f ",tf); break; - case ply::T_DOUBLE : td=*( (double *) (((char *)vp)+pi.VertDescriptorVec[i].offset1)); fprintf(fpout,"%lf ",tf); break; - case ply::T_INT : ti=*( (int *) (((char *)vp)+pi.VertDescriptorVec[i].offset1)); fprintf(fpout,"%i ",ti); break; - case ply::T_SHORT : ti=*( (short *) (((char *)vp)+pi.VertDescriptorVec[i].offset1)); fprintf(fpout,"%i ",ti); break; - case ply::T_CHAR : ti=*( (char *) (((char *)vp)+pi.VertDescriptorVec[i].offset1)); fprintf(fpout,"%i ",ti); break; - case ply::T_UCHAR : ti=*( (unsigned char *) (((char *)vp)+pi.VertDescriptorVec[i].offset1)); fprintf(fpout,"%i ",ti); break; + case ply::T_FLOAT : tf=*( (float *) (((char *)vp)+pi.VertDescriptorVec[i].offset1)); fprintf(fpout,"%f ",tf); break; + case ply::T_DOUBLE : td=*( (double *) (((char *)vp)+pi.VertDescriptorVec[i].offset1)); fprintf(fpout,"%lf ",tf); break; + case ply::T_INT : ti=*( (int *) (((char *)vp)+pi.VertDescriptorVec[i].offset1)); fprintf(fpout,"%i ",ti); break; + case ply::T_SHORT : ti=*( (short *) (((char *)vp)+pi.VertDescriptorVec[i].offset1)); fprintf(fpout,"%i ",ti); break; + case ply::T_CHAR : ti=*( (char *) (((char *)vp)+pi.VertDescriptorVec[i].offset1)); fprintf(fpout,"%i ",ti); break; + case ply::T_UCHAR : ti=*( (unsigned char *) (((char *)vp)+pi.VertDescriptorVec[i].offset1)); fprintf(fpout,"%i ",ti); break; default : assert(0); } } @@ -692,15 +720,35 @@ public: if(!pi.FaceAttrNameVec.empty() && !pi.FaceAttrNameVec[i].empty()) { // trying to use named attribute to retrieve the value to store assert(vcg::tri::HasPerFaceAttribute(m,pi.FaceAttrNameVec[i])); - switch (pi.FaceDescriptorVec[i].stotype1) - { - case ply::T_FLOAT : tf=thff[i][fp]; fwrite(&tf, sizeof(float),1,fpout); break; - case ply::T_DOUBLE : td=thdf[i][fp]; fwrite(&td, sizeof(double),1,fpout); break; - case ply::T_INT : ti=thif[i][fp]; fwrite(&ti, sizeof(int),1,fpout); break; - case ply::T_SHORT : ts=thsf[i][fp]; fwrite(&ts, sizeof(short),1,fpout); break; - case ply::T_CHAR : tc=thcf[i][fp]; fwrite(&tc, sizeof(char),1,fpout); break; - case ply::T_UCHAR : tu=thuf[i][fp]; fwrite(&tu,sizeof(unsigned char),1,fpout); break; - default : assert(0); + if (!pi.FaceDescriptorVec[i].islist){ + switch (pi.FaceDescriptorVec[i].stotype1) + { + case ply::T_FLOAT : tf=thff[i][fp]; fwrite(&tf, sizeof(float),1,fpout); break; + case ply::T_DOUBLE : td=thdf[i][fp]; fwrite(&td, sizeof(double),1,fpout); break; + case ply::T_INT : ti=thif[i][fp]; fwrite(&ti, sizeof(int),1,fpout); break; + case ply::T_SHORT : ts=thsf[i][fp]; fwrite(&ts, sizeof(short),1,fpout); break; + case ply::T_CHAR : tc=thcf[i][fp]; fwrite(&tc, sizeof(char),1,fpout); break; + case ply::T_UCHAR : tu=thuf[i][fp]; fwrite(&tu,sizeof(unsigned char),1,fpout); break; + default : assert(0); + } + } + else { + static const unsigned char psize = 3; + switch (pi.FaceDescriptorVec[i].stotype1) + { + case ply::T_FLOAT : + fwrite(&psize, sizeof(unsigned char), 1,fpout); + fwrite(&thp3ff[i][fp][0], sizeof(float), 1,fpout); + fwrite(&thp3ff[i][fp][1], sizeof(float), 1,fpout); + fwrite(&thp3ff[i][fp][2], sizeof(float), 1,fpout); + break; + case ply::T_DOUBLE : + fwrite(&psize, sizeof(unsigned char), 1,fpout); + fwrite(&thp3df[i][fp][0], sizeof(double), 1,fpout); + fwrite(&thp3df[i][fp][1], sizeof(double), 1,fpout); + fwrite(&thp3df[i][fp][2], sizeof(double), 1,fpout); + default : assert(0); + } } } else @@ -777,15 +825,25 @@ public: if(!pi.FaceAttrNameVec.empty() && !pi.FaceAttrNameVec[i].empty()) { // trying to use named attribute to retrieve the value to store assert(vcg::tri::HasPerFaceAttribute(m,pi.FaceAttrNameVec[i])); - switch (pi.FaceDescriptorVec[i].stotype1) - { - case ply::T_FLOAT : tf=thff[i][fp]; fprintf(fpout,"%f ",tf); break; - case ply::T_DOUBLE : td=thdf[i][fp]; fprintf(fpout,"%g ",td); break; - case ply::T_INT : ti=thif[i][fp]; fprintf(fpout,"%i ",ti); break; - case ply::T_SHORT : ti=thsf[i][fp]; fprintf(fpout,"%i ",ti); break; - case ply::T_CHAR : ti=thcf[i][fp]; fprintf(fpout,"%i ",ti); break; - case ply::T_UCHAR : ti=thuf[i][fp]; fprintf(fpout,"%i ",ti); break; - default : assert(0); + if(!pi.FaceDescriptorVec[i].islist) { + switch (pi.FaceDescriptorVec[i].stotype1) + { + case ply::T_FLOAT : tf=thff[i][fp]; fprintf(fpout,"%f ",tf); break; + case ply::T_DOUBLE : td=thdf[i][fp]; fprintf(fpout,"%g ",td); break; + case ply::T_INT : ti=thif[i][fp]; fprintf(fpout,"%i ",ti); break; + case ply::T_SHORT : ti=thsf[i][fp]; fprintf(fpout,"%i ",ti); break; + case ply::T_CHAR : ti=thcf[i][fp]; fprintf(fpout,"%i ",ti); break; + case ply::T_UCHAR : ti=thuf[i][fp]; fprintf(fpout,"%i ",ti); break; + default : assert(0); + } + } + else { + switch (pi.FaceDescriptorVec[i].stotype1) + { + case ply::T_FLOAT : fprintf(fpout,"%d %f %f %f", 3, thp3ff[i][fp][0], thp3ff[i][fp][1], thp3ff[i][fp][2]); break; + case ply::T_DOUBLE : fprintf(fpout,"%d %lf %lf %lf", 3, thp3df[i][fp][0], thp3df[i][fp][1], thp3df[i][fp][2]); break; + default : assert(0); + } } } else diff --git a/wrap/io_trimesh/io_ply.h b/wrap/io_trimesh/io_ply.h index 92ba9f2d..05c25cab 100644 --- a/wrap/io_trimesh/io_ply.h +++ b/wrap/io_trimesh/io_ply.h @@ -160,6 +160,21 @@ public: addPerElemPointAttribute(0,vcg::ply::PlyTypes::T_DOUBLE, attrName,propName); } + void addPerFacePoint3mAttribute(const std::string& attrName, vcg::ply::PlyTypes attrType, std::string propName="") + { + addPerElemPointAttribute(1,attrType, attrName,propName); + } + + void addPerFacePoint3fAttribute(const std::string& attrName, std::string propName="") + { + addPerElemPointAttribute(1,vcg::ply::PlyTypes::T_FLOAT, attrName,propName); + } + + void addPerFacePoint3dAttribute(const std::string& attrName, std::string propName="") + { + addPerElemPointAttribute(1,vcg::ply::PlyTypes::T_DOUBLE, attrName,propName); + } + /* Note that saving a per vertex point3 attribute is a mess. * Actually require to allocate 3 float attribute and save them. And they are never deallocated... */ template From 0a17efe9a809d2fc82838affe5d0a239e9e546fc Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Wed, 7 Apr 2021 13:22:08 +0200 Subject: [PATCH 009/117] missing include import obj --- wrap/io_trimesh/import_obj.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/wrap/io_trimesh/import_obj.h b/wrap/io_trimesh/import_obj.h index 9f9fa909..66ce8526 100644 --- a/wrap/io_trimesh/import_obj.h +++ b/wrap/io_trimesh/import_obj.h @@ -25,6 +25,8 @@ #ifndef __VCGLIB_IMPORT_OBJ #define __VCGLIB_IMPORT_OBJ +#include + #include #include #include @@ -1057,8 +1059,8 @@ public: // adding texture name into textures vector (if not already present) // avoid adding the same name twice auto it = std::find(textures.begin(), textures.end(), textureName); - if(it==textures.end()) { - currentMaterial.index = textures.size(); + if(it==textures.end()) { + currentMaterial.index = textures.size(); textures.push_back(textureName); } else { currentMaterial.index = std::distance(textures.begin(),it); @@ -1080,7 +1082,7 @@ public: { materials[i].map_Kd=textures[0]; materials[i].index=0; - } + } } } From 0882d6258252174ee6635b3d1d337bdedad97ab8 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Tue, 20 Apr 2021 10:25:54 +0200 Subject: [PATCH 010/117] fix import matrix precision in aln parser --- wrap/io_trimesh/alnParser.h | 192 ++++++++++++++++++------------------ 1 file changed, 95 insertions(+), 97 deletions(-) diff --git a/wrap/io_trimesh/alnParser.h b/wrap/io_trimesh/alnParser.h index 1e7fd4a4..1e18593a 100644 --- a/wrap/io_trimesh/alnParser.h +++ b/wrap/io_trimesh/alnParser.h @@ -2,7 +2,7 @@ * MeshLab o o * * An extendible mesh processor o o * * _ O _ * -* Copyright(C) 2005, 2009 \/)\/ * +* Copyright(C) 2005, 2021 \/)\/ * * Visual Computing Lab /\/| * * ISTI - Italian National Research Council | * * \ * @@ -30,126 +30,124 @@ struct RangeMap { - RangeMap() - { - quality = 1.0f; - } + RangeMap() : quality(1.0f) {} - std::string filename; - Matrix44m transformation; - float quality; + std::string filename; + vcg::Matrix44d transformation; + float quality; }; class ALNParser { public: - enum ALNParserCodes {NoError, CantOpen, UnexpectedEOF, ExpectingComment}; + enum ALNParserCodes {NoError, CantOpen, UnexpectedEOF, ExpectingComment}; - static const char* ErrorMsg(int message_code) - { - static const char* error_msg[4] = {"No errors", "Can't open file", "Premature End of file", "I was expecting a comment"}; + static const char* ErrorMsg(int message_code) + { + static const char* error_msg[4] = {"No errors", "Can't open file", "Premature End of file", "I was expecting a comment"}; - if(message_code>3 || message_code<0) - return "Unknown error"; - else - return error_msg[message_code]; - }; + if(message_code>3 || message_code<0) + return "Unknown error"; + else + return error_msg[message_code]; + }; - static int BuildALN(std::vector &rangemaps, std::vector< std::string > &files) - { - rangemaps.clear(); - rangemaps.resize( files.size() ); - std::vector< RangeMap >::iterator rm = rangemaps.begin(); - std::vector< std::string >::iterator it = files.begin(); - std::vector< std::string >::iterator end = files.end(); - for ( ; it!=end; it++, rm++) - { - (*rm).filename = (*it); - (*rm).quality = 1.0f; - (*rm).transformation.SetIdentity(); - } - files.clear(); - return NoError; - }; + static int BuildALN(std::vector &rangemaps, std::vector< std::string > &files) + { + rangemaps.clear(); + rangemaps.resize( files.size() ); + std::vector< RangeMap >::iterator rm = rangemaps.begin(); + std::vector< std::string >::iterator it = files.begin(); + std::vector< std::string >::iterator end = files.end(); + for ( ; it!=end; it++, rm++) + { + (*rm).filename = (*it); + (*rm).quality = 1.0f; + (*rm).transformation.SetIdentity(); + } + files.clear(); + return NoError; + }; - static int ParseALN(std::vector &rangemaps, const char *ALNname) - { - rangemaps.clear(); + static int ParseALN(std::vector &rangemaps, const char *ALNname) + { + rangemaps.clear(); - FILE *stream=fopen(ALNname, "rt"); - if(stream==NULL) - return CantOpen; + FILE *stream=fopen(ALNname, "rt"); + if(stream==NULL) + return CantOpen; - int mesh_number; - fscanf(stream, "%i\n", &mesh_number); + int mesh_number; + fscanf(stream, "%i\n", &mesh_number); - char buffer[1024]; - for (int m=0; m0); + char *occurrence = strchr(buffer, 'W'); + if(occurrence!=NULL && occurrence[1]==':') + rm.quality = (float) atof(occurrence+2); + assert(rm.quality>0); - fscanf(stream,"%f %f %f %f \n",&(rm.transformation[0][0]),&(rm.transformation[0][1]),&(rm.transformation[0][2]),&(rm.transformation[0][3])); - fscanf(stream,"%f %f %f %f \n",&(rm.transformation[1][0]),&(rm.transformation[1][1]),&(rm.transformation[1][2]),&(rm.transformation[1][3])); - fscanf(stream,"%f %f %f %f \n",&(rm.transformation[2][0]),&(rm.transformation[2][1]),&(rm.transformation[2][2]),&(rm.transformation[2][3])); - fscanf(stream,"%f %f %f %f \n",&(rm.transformation[3][0]),&(rm.transformation[3][1]),&(rm.transformation[3][2]),&(rm.transformation[3][3])); + fscanf(stream,"%lf %lf %lf %lf \n",&(rm.transformation[0][0]),&(rm.transformation[0][1]),&(rm.transformation[0][2]),&(rm.transformation[0][3])); + fscanf(stream,"%lf %lf %lf %lf \n",&(rm.transformation[1][0]),&(rm.transformation[1][1]),&(rm.transformation[1][2]),&(rm.transformation[1][3])); + fscanf(stream,"%lf %lf %lf %lf \n",&(rm.transformation[2][0]),&(rm.transformation[2][1]),&(rm.transformation[2][2]),&(rm.transformation[2][3])); + fscanf(stream,"%lf %lf %lf %lf \n",&(rm.transformation[3][0]),&(rm.transformation[3][1]),&(rm.transformation[3][2]),&(rm.transformation[3][3])); - rangemaps.push_back(rm); - } - fclose(stream); - return NoError; - } // end of ParseALN + rangemaps.push_back(rm); + } + fclose(stream); + return NoError; + } // end of ParseALN -static bool SaveALN(const char *alnfile, std::vector &names) -{ - std::vector Tr(names.size()); - for(int i=0; i < static_cast(Tr.size()); ++i) Tr[i].SetIdentity(); - return SaveALN(alnfile,names, Tr); -} -template -static bool SaveALN(const char *alnfile, std::vector &names, std::vector > &Tr) -{ - // printf("Saving aln file %s\n",alnfile); - FILE *fp=fopen(alnfile,"w"); - if(!fp) - { - printf("unable to open file %s\n",alnfile); - return false; - } + static bool SaveALN(const char *alnfile, std::vector &names) + { + std::vector Tr(names.size()); + for(int i=0; i < static_cast(Tr.size()); ++i) Tr[i].SetIdentity(); + return SaveALN(alnfile,names, Tr); + } - fprintf(fp,"%i\n",(int)names.size()); - for(int i=0;i < static_cast(names.size());++i) - { - fprintf(fp,"%s\n",names[i].c_str()); + template + static bool SaveALN(const char *alnfile, std::vector &names, std::vector > &Tr) + { + // printf("Saving aln file %s\n",alnfile); + FILE *fp=fopen(alnfile,"w"); + if(!fp) + { + printf("unable to open file %s\n",alnfile); + return false; + } - fprintf(fp,"#\n"); - fprintf(fp,"%lf %lf %lf %lf \n",(Tr[i][0][0]),(Tr[i][0][1]),(Tr[i][0][2]),(Tr[i][0][3])); - fprintf(fp,"%lf %lf %lf %lf \n",(Tr[i][1][0]),(Tr[i][1][1]),(Tr[i][1][2]),(Tr[i][1][3])); - fprintf(fp,"%lf %lf %lf %lf \n",(Tr[i][2][0]),(Tr[i][2][1]),(Tr[i][2][2]),(Tr[i][2][3])); - fprintf(fp,"%lf %lf %lf %lf \n",(Tr[i][3][0]),(Tr[i][3][1]),(Tr[i][3][2]),(Tr[i][3][3])); - } - fprintf(fp,"0\n"); + fprintf(fp,"%i\n",(int)names.size()); + for(int i=0;i < static_cast(names.size());++i) + { + fprintf(fp,"%s\n",names[i].c_str()); - fclose(fp); - return true; -} + fprintf(fp,"#\n"); + fprintf(fp,"%lf %lf %lf %lf \n",(Tr[i][0][0]),(Tr[i][0][1]),(Tr[i][0][2]),(Tr[i][0][3])); + fprintf(fp,"%lf %lf %lf %lf \n",(Tr[i][1][0]),(Tr[i][1][1]),(Tr[i][1][2]),(Tr[i][1][3])); + fprintf(fp,"%lf %lf %lf %lf \n",(Tr[i][2][0]),(Tr[i][2][1]),(Tr[i][2][2]),(Tr[i][2][3])); + fprintf(fp,"%lf %lf %lf %lf \n",(Tr[i][3][0]),(Tr[i][3][1]),(Tr[i][3][2]),(Tr[i][3][3])); + } + fprintf(fp,"0\n"); + + fclose(fp); + return true; + } }; From 15b1b778d4a260650f3830fdceff028420ce6543 Mon Sep 17 00:00:00 2001 From: Luigi Malomo Date: Thu, 22 Apr 2021 20:49:12 +0200 Subject: [PATCH 011/117] added missing function for polygon face components --- vcg/simplex/face/component_polygon.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/vcg/simplex/face/component_polygon.h b/vcg/simplex/face/component_polygon.h index 1fda9d1b..1265b13b 100644 --- a/vcg/simplex/face/component_polygon.h +++ b/vcg/simplex/face/component_polygon.h @@ -143,8 +143,9 @@ public: typename T::FacePointer &VFp(const int j) { assert(j>=0 && jVN()); return _vfpP[j]; } typename T::FacePointer const VFp(const int j) const { assert(j>=0 && jVN()); return _vfpP[j]; } typename T::FacePointer const cVFp(const int j) const { assert(j>=0 && jVN()); return _vfpP[j]; } - char &VFi(const int j) {return _vfiP[j]; } - char VFi(const int j) const {return _vfiP[j]; } + char & VFi(const int j) { return _vfiP[j]; } + char VFi(const int j) const { return _vfiP[j]; } + char cVFi(const int j) const { return _vfiP[j]; } template void ImportData(const LeftF & leftF){T::ImportData(leftF);} inline void Alloc(const int & ns) { From bd1a92e2f0f5a3b240e5778d816b8e0e7a9e6d1d Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Fri, 23 Apr 2021 16:21:09 +0200 Subject: [PATCH 012/117] fix face flag comments --- vcg/simplex/face/base.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/vcg/simplex/face/base.h b/vcg/simplex/face/base.h index 967c7dbc..639d0753 100644 --- a/vcg/simplex/face/base.h +++ b/vcg/simplex/face/base.h @@ -156,7 +156,7 @@ public: /// deletes the Face from the mesh void SetD() {this->Flags() |=DELETED;} - /// un-delete a Face + /// undelete the Face void ClearD() {this->Flags() &=(~DELETED);} /// marks the Face as readable void SetR() {this->Flags() &=(~NOTREAD);} @@ -168,14 +168,14 @@ public: void ClearW() {this->Flags() |=NOTWRITE;} /// select the Face void SetS() {this->Flags() |=SELECTED;} - /// Un-select a Face + /// unselect the Face void ClearS() {this->Flags() &= ~SELECTED;} - /// select the Face + /// set as visited the Face void SetV() {this->Flags() |=VISITED;} - /// Un-select a Face + /// set as unvisited the Face void ClearV() {this->Flags() &= ~VISITED;} - /// This function checks if the face is selected + /// This function checks if the face is border bool IsB(int i) const {return (this->cFlags() & (BORDER0<Flags() |=(BORDER0< Date: Mon, 26 Apr 2021 14:31:04 +0200 Subject: [PATCH 013/117] complex/algorithms/stat.h const correctness --- vcg/complex/algorithms/stat.h | 83 ++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 40 deletions(-) diff --git a/vcg/complex/algorithms/stat.h b/vcg/complex/algorithms/stat.h index fb2f18b5..f0e8502e 100644 --- a/vcg/complex/algorithms/stat.h +++ b/vcg/complex/algorithms/stat.h @@ -41,64 +41,67 @@ class Stat { public: typedef StatMeshType MeshType; - typedef typename MeshType::ScalarType ScalarType; - typedef typename MeshType::VertexType VertexType; - typedef typename MeshType::VertexPointer VertexPointer; - typedef typename MeshType::VertexIterator VertexIterator; + typedef typename MeshType::ScalarType ScalarType; + typedef typename MeshType::VertexType VertexType; + typedef typename MeshType::VertexPointer VertexPointer; + typedef typename MeshType::VertexIterator VertexIterator; typedef typename MeshType::ConstVertexIterator ConstVertexIterator; - typedef typename MeshType::EdgeType EdgeType; - typedef typename MeshType::EdgeIterator EdgeIterator; - typedef typename MeshType::FaceType FaceType; - typedef typename MeshType::FacePointer FacePointer; - typedef typename MeshType::FaceIterator FaceIterator; - typedef typename MeshType::FaceContainer FaceContainer; - typedef typename MeshType::TetraType TetraType; - typedef typename MeshType::TetraPointer TetraPointer; - typedef typename MeshType::TetraIterator TetraIterator; - typedef typename MeshType::TetraContainer TetraContainer; - typedef typename vcg::Box3 Box3Type; + typedef typename MeshType::EdgeType EdgeType; + typedef typename MeshType::EdgeIterator EdgeIterator; + typedef typename MeshType::FaceType FaceType; + typedef typename MeshType::FacePointer FacePointer; + typedef typename MeshType::FaceIterator FaceIterator; + typedef typename MeshType::ConstFaceIterator ConstFaceIterator; + typedef typename MeshType::FaceContainer FaceContainer; + typedef typename MeshType::TetraType TetraType; + typedef typename MeshType::TetraPointer TetraPointer; + typedef typename MeshType::TetraIterator TetraIterator; + typedef typename MeshType::TetraContainer TetraContainer; + typedef typename vcg::Box3 Box3Type; - static void ComputePerVertexQualityMinMax(MeshType & m, ScalarType &minV, ScalarType &maxV) + static void ComputePerVertexQualityMinMax(const MeshType & m, ScalarType &minV, ScalarType &maxV) { std::pair pp = ComputePerVertexQualityMinMax(m); minV=pp.first; maxV=pp.second; } - static std::pair ComputePerVertexQualityMinMax(MeshType & m) + static std::pair ComputePerVertexQualityMinMax(const MeshType & m) { // assert(0); tri::RequirePerVertexQuality(m); - typename MeshType::template PerMeshAttributeHandle < std::pair > mmqH; - mmqH = tri::Allocator::template GetPerMeshAttribute >(m,"minmaxQ"); + /** Please if you need to create an attribute called minmaxQ, implement an + explicit function that does it. This function should take a const Mesh. **/ + //typename MeshType::template PerMeshAttributeHandle < std::pair > mmqH; + //mmqH = tri::Allocator::template GetPerMeshAttribute >(m,"minmaxQ"); std::pair minmax = std::make_pair(std::numeric_limits::max(), -std::numeric_limits::max()); - for(VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi) + for(ConstVertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi) if(!(*vi).IsD()) { if( (*vi).Q() < minmax.first) minmax.first = (*vi).Q(); if( (*vi).Q() > minmax.second) minmax.second = (*vi).Q(); } - mmqH() = minmax; + //mmqH() = minmax; return minmax; } - static void ComputePerFaceQualityMinMax(MeshType & m, ScalarType &minV, ScalarType &maxV) + static void ComputePerFaceQualityMinMax(const MeshType & m, ScalarType &minV, ScalarType &maxV) { std::pair pp = ComputePerFaceQualityMinMax(m); minV=pp.first; maxV=pp.second; } - static std::pair ComputePerFaceQualityMinMax( MeshType & m) + static std::pair ComputePerFaceQualityMinMax( const MeshType & m) { tri::RequirePerFaceQuality(m); std::pair minmax = std::make_pair(std::numeric_limits::max(),-std::numeric_limits::max()); - FaceIterator fi; + ConstFaceIterator fi; for(fi = m.face.begin(); fi != m.face.end(); ++fi) if(!(*fi).IsD()) { @@ -141,12 +144,12 @@ public: return avgQ /= (ScalarType) m.TN(); } - static ScalarType ComputePerFaceQualityAvg(MeshType & m) + static ScalarType ComputePerFaceQualityAvg(const MeshType & m) { tri::RequirePerFaceQuality(m); ScalarType AvgQ = 0; - FaceIterator fi; + ConstFaceIterator fi; size_t num=0; for(fi = m.face.begin(); fi != m.face.end(); ++fi) { @@ -221,11 +224,11 @@ public: Works for any triangulated model (no problem with open, nonmanifold selfintersecting models). Useful for computing the barycenter of 2D planar figures. */ - static Point3 ComputeShellBarycenter(MeshType & m) + static Point3 ComputeShellBarycenter(const MeshType & m) { Point3 barycenter(0,0,0); ScalarType areaSum=0; - FaceIterator fi; + ConstFaceIterator fi; for(fi = m.face.begin(); fi != m.face.end(); ++fi) if(!(*fi).IsD()) { @@ -264,11 +267,11 @@ public: return area/ScalarType(2.0); } - static ScalarType ComputePolyMeshArea(MeshType & m) + static ScalarType ComputePolyMeshArea(const MeshType & m) { ScalarType area=0; - for(FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi) + for(ConstFaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi) if(!(*fi).IsD()) area += PolyArea(*fi); @@ -293,10 +296,10 @@ public: return sum; } - static void ComputePerVertexQualityDistribution(MeshType & m, Distribution & h, bool selectionOnly = false) // V1.0 + static void ComputePerVertexQualityDistribution(const MeshType & m, Distribution & h, bool selectionOnly = false) // V1.0 { tri::RequirePerVertexQuality(m); - for(VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi) + for(ConstVertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi) if(!(*vi).IsD() && ((!selectionOnly) || (*vi).IsS()) ) { assert(!math::IsNAN((*vi).Q()) && "You should never try to compute Histogram with Invalid Floating points numbers (NaN)"); @@ -304,11 +307,11 @@ public: } } - static void ComputePerFaceQualityDistribution( MeshType & m, Distribution &h, + static void ComputePerFaceQualityDistribution( const MeshType & m, Distribution &h, bool selectionOnly = false) // V1.0 { tri::RequirePerFaceQuality(m); - for(FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi) + for(ConstFaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi) if(!(*fi).IsD() && ((!selectionOnly) || (*fi).IsS()) ) { assert(!math::IsNAN((*fi).Q()) && "You should never try to compute Histogram with Invalid Floating points numbers (NaN)"); @@ -345,27 +348,27 @@ public: }); } - static void ComputePerFaceQualityHistogram( MeshType & m, Histogram &h, bool selectionOnly=false,int HistSize=10000 ) + static void ComputePerFaceQualityHistogram( const MeshType & m, Histogram &h, bool selectionOnly=false,int HistSize=10000 ) { tri::RequirePerFaceQuality(m); std::pair minmax = tri::Stat::ComputePerFaceQualityMinMax(m); h.Clear(); h.SetRange( minmax.first,minmax.second, HistSize ); - for(FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi) + for(ConstFaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi) if(!(*fi).IsD() && ((!selectionOnly) || (*fi).IsS()) ){ assert(!math::IsNAN((*fi).Q()) && "You should never try to compute Histogram with Invalid Floating points numbers (NaN)"); h.Add((*fi).Q()); } } - static void ComputePerVertexQualityHistogram( MeshType & m, Histogram &h, bool selectionOnly = false, int HistSize=10000 ) // V1.0 + static void ComputePerVertexQualityHistogram( const MeshType & m, Histogram &h, bool selectionOnly = false, int HistSize=10000 ) // V1.0 { tri::RequirePerVertexQuality(m); std::pair minmax = ComputePerVertexQualityMinMax(m); h.Clear(); h.SetRange( minmax.first,minmax.second, HistSize); - for(VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi) + for(ConstVertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi) if(!(*vi).IsD() && ((!selectionOnly) || (*vi).IsS()) ) { assert(!math::IsNAN((*vi).Q()) && "You should never try to compute Histogram with Invalid Floating points numbers (NaN)"); @@ -381,7 +384,7 @@ public: { std::vector QV; QV.reserve(m.vn); - for(VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi) + for(ConstVertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi) if(!(*vi).IsD()) QV.push_back((*vi).Q()); std::nth_element(QV.begin(),QV.begin()+m.vn/100,QV.end()); @@ -391,7 +394,7 @@ public: h.Clear(); h.SetRange(newmin, newmax, HistSize*50); - for(VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi) + for(ConstVertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi) if(!(*vi).IsD() && ((!selectionOnly) || (*vi).IsS()) ) h.Add((*vi).Q()); } From 290ac7a0277b5fc7d999e9c21ab8ca65b2f4db7e Mon Sep 17 00:00:00 2001 From: Luigi Malomo Date: Fri, 7 May 2021 17:25:34 +0200 Subject: [PATCH 014/117] bugfix rotation from between 2 vectors --- vcg/math/matrix33.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/vcg/math/matrix33.h b/vcg/math/matrix33.h index 356a10db..c896afca 100644 --- a/vcg/math/matrix33.h +++ b/vcg/math/matrix33.h @@ -523,7 +523,7 @@ Matrix33 RotationMatrix(vcg::Point3 v0,vcg::Point3 v1,bool normalized=t } S dot=(v0*v1); ///control if there is no rotation - if (dot>((S)1-epsilon)) + if (dot>(S(1)-epsilon)) { rotM.SetIdentity(); return rotM; @@ -535,13 +535,13 @@ Matrix33 RotationMatrix(vcg::Point3 v0,vcg::Point3 v1,bool normalized=t //if dot = -1 rotating to opposite vertex //the problem is underdefined, so choose axis such that division is more stable //alternative solution at http://cs.brown.edu/research/pubs/pdfs/1999/Moller-1999-EBA.pdf - if (dot < (S)-1 + epsilon) + if (dot < S(-1) + epsilon) { - S max = std::numeric_limits::min(); + S max = std::numeric_limits::lowest(); int maxInd = 0; for (int i = 0; i < 3; ++i) { - if (v0[i] > max) + if (std::abs(v0[i]) > max) { max = v0[i]; maxInd = i; @@ -552,7 +552,7 @@ Matrix33 RotationMatrix(vcg::Point3 v0,vcg::Point3 v1,bool normalized=t axis[(maxInd+1) % 3] = 0; axis[(maxInd+2) % 3] = 1; - dot = (S)-1; + dot = S(-1); } else { From 1ec2d65a58003c832c0c58b8361d96ea71cf19e4 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Mon, 17 May 2021 10:46:07 +0200 Subject: [PATCH 015/117] fix stl importer for malformed file --- wrap/io_trimesh/import_stl.h | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/wrap/io_trimesh/import_stl.h b/wrap/io_trimesh/import_stl.h index 8225d13a..df7f4791 100644 --- a/wrap/io_trimesh/import_stl.h +++ b/wrap/io_trimesh/import_stl.h @@ -106,7 +106,7 @@ static bool IsSTLColored(const char * filename, bool &coloredFlag, bool &magicsM coloredFlag=false; magicsMode=false; bool binaryFlag; - if(IsSTLBinary(filename,binaryFlag)==false) + if(IsSTLMalformed(filename,binaryFlag)==false) return false; if(binaryFlag==false) @@ -144,11 +144,12 @@ static bool IsSTLColored(const char * filename, bool &coloredFlag, bool &magicsM return true; } -/* Try to guess if a stl is in binary format - * +/* * return false in case of malformed files + * Try to guess if a stl is in binary format, and sets + * the binaryFlag accordingly */ -static bool IsSTLBinary(const char * filename, bool &binaryFlag) +static bool IsSTLMalformed(const char * filename, bool &binaryFlag) { binaryFlag=false; FILE *fp = fopen(filename, "rb"); @@ -157,8 +158,10 @@ static bool IsSTLBinary(const char * filename, bool &binaryFlag) std::size_t file_size = ftell(fp); unsigned int facenum; /* Check for binary or ASCII file */ - fseek(fp, STL_LABEL_SIZE, SEEK_SET); - fread(&facenum, sizeof(unsigned int), 1, fp); + int ret = fseek(fp, STL_LABEL_SIZE, SEEK_SET); + if (ret != 0) return false; + ret = fread(&facenum, sizeof(unsigned int), 1, fp); + if (ret != 1) return false; std::size_t expected_file_size=STL_LABEL_SIZE + 4 + (sizeof(short)+sizeof(STLFacet) )*facenum ; if(file_size == expected_file_size) @@ -197,7 +200,7 @@ static int Open( OpenMeshType &m, const char * filename, int &loadMask, CallBack fclose(fp); loadMask |= Mask::IOM_VERTCOORD | Mask::IOM_FACEINDEX; bool binaryFlag; - if(!IsSTLBinary(filename,binaryFlag)) + if(!IsSTLMalformed(filename,binaryFlag)) return E_MALFORMED; if(binaryFlag) return OpenBinary(m,filename,loadMask,cb); From c150c3f6b66edbb21e96d02d373af264b44afdc2 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Mon, 17 May 2021 17:36:32 +0200 Subject: [PATCH 016/117] fix append and SplitManifoldComponents when wedge text coords are enabled --- vcg/complex/algorithms/clean.h | 3 + vcg/complex/append.h | 580 +++++++++++---------------------- 2 files changed, 200 insertions(+), 383 deletions(-) diff --git a/vcg/complex/algorithms/clean.h b/vcg/complex/algorithms/clean.h index cbed0df5..ce4151fc 100644 --- a/vcg/complex/algorithms/clean.h +++ b/vcg/complex/algorithms/clean.h @@ -689,6 +689,9 @@ public: tmpMesh.vert.EnableVFAdjacency(); tmpMesh.face.EnableVFAdjacency(); + if (m.face.IsWedgeTexCoordEnabled()) + tmpMesh.face.EnableWedgeTexCoord(); + size_t selCnt=0; for(FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi) diff --git a/vcg/complex/append.h b/vcg/complex/append.h index 63c44684..0c64e161 100644 --- a/vcg/complex/append.h +++ b/vcg/complex/append.h @@ -264,215 +264,7 @@ static void Mesh(MeshLeft& ml, ConstMeshRight& mr, const bool selected = false, tri::UpdateSelection::VertexFromFaceLoose(mr,true); } - // phase 1. allocate on ml vert,edge,face, hedge to accomodat those of mr - // and build the remapping for all - - Remap remap; - - // vertex - remap.vert.resize(mr.vert.size(), Remap::InvalidIndex()); - VertexIteratorLeft vp; - size_t svn = UpdateSelection::VertexCount(mr); - if(selected) - vp=Allocator::AddVertices(ml,int(svn)); - else - vp=Allocator::AddVertices(ml,mr.vn); - - for(VertexIteratorRight vi=mr.vert.begin(); vi!=mr.vert.end(); ++vi) - { - if(!(*vi).IsD() && (!selected || (*vi).IsS())) - { - size_t ind=Index(mr,*vi); - remap.vert[ind]=int(Index(ml,*vp)); - ++vp; - } - } - // edge - remap.edge.resize(mr.edge.size(), Remap::InvalidIndex()); - EdgeIteratorLeft ep; - size_t sen = UpdateSelection::EdgeCount(mr); - if(selected) ep=Allocator::AddEdges(ml,sen); - else ep=Allocator::AddEdges(ml,mr.en); - - for(EdgeIteratorRight ei=mr.edge.begin(); ei!=mr.edge.end(); ++ei) - if(!(*ei).IsD() && (!selected || (*ei).IsS())){ - size_t ind=Index(mr,*ei); - remap.edge[ind]=int(Index(ml,*ep)); - ++ep; - } - - // face - remap.face.resize(mr.face.size(), Remap::InvalidIndex()); - FaceIteratorLeft fp; - size_t sfn = UpdateSelection::FaceCount(mr); - if(selected) fp=Allocator::AddFaces(ml,sfn); - else fp=Allocator::AddFaces(ml,mr.fn); - - for(FaceIteratorRight fi=mr.face.begin(); fi!=mr.face.end(); ++fi) - if(!(*fi).IsD() && (!selected || (*fi).IsS())){ - size_t ind=Index(mr,*fi); - remap.face[ind]=int(Index(ml,*fp)); - ++fp; - } - - // hedge - remap.hedge.resize(mr.hedge.size(),Remap::InvalidIndex()); - for(HEdgeIteratorRight hi=mr.hedge.begin(); hi!=mr.hedge.end(); ++hi) - if(!(*hi).IsD() && (!selected || (*hi).IsS())){ - size_t ind=Index(mr,*hi); - assert(remap.hedge[ind]==Remap::InvalidIndex()); - HEdgeIteratorLeft hp = Allocator::AddHEdges(ml,1); - (*hp).ImportData(*(hi)); - remap.hedge[ind]=Index(ml,*hp); - } - - remap.tetra.resize(mr.tetra.size(), Remap::InvalidIndex()); - for (TetraIteratorRight ti = mr.tetra.begin(); ti != mr.tetra.end(); ++ti) - if (!(*ti).IsD() && (!selected || (*ti).IsS())) { - size_t idx = Index(mr, *ti); - assert (remap.tetra[idx] == Remap::InvalidIndex()); - TetraIteratorLeft tp = Allocator::AddTetras(ml, 1); - (*tp).ImportData(*ti); - remap.tetra[idx] = Index(ml, *tp); - } - - // phase 2. - // copy data from mr to its corresponding elements in ml and adjacencies - - // vertex - for(VertexIteratorRight vi=mr.vert.begin();vi!=mr.vert.end();++vi) - if( !(*vi).IsD() && (!selected || (*vi).IsS())){ - ml.vert[remap.vert[Index(mr,*vi)]].ImportData(*vi); - if(adjFlag) ImportVertexAdj(ml,mr,ml.vert[remap.vert[Index(mr,*vi)]],*vi,remap); - } - - // edge - for(EdgeIteratorRight ei=mr.edge.begin();ei!=mr.edge.end();++ei) - if(!(*ei).IsD() && (!selected || (*ei).IsS())){ - ml.edge[remap.edge[Index(mr,*ei)]].ImportData(*ei); - // Edge to Vertex Adj - EdgeLeft &el = ml.edge[remap.edge[Index(mr,*ei)]]; - if(HasEVAdjacency(ml) && HasEVAdjacency(mr)){ - el.V(0) = &ml.vert[remap.vert[Index(mr,ei->cV(0))]]; - el.V(1) = &ml.vert[remap.vert[Index(mr,ei->cV(1))]]; - } - if(adjFlag) ImportEdgeAdj(ml,mr,el,*ei,remap); - } - - // face - const size_t textureOffset = ml.textures.size(); - bool WTFlag = HasPerWedgeTexCoord(mr) && (textureOffset>0); - for(FaceIteratorRight fi=mr.face.begin();fi!=mr.face.end();++fi) - if(!(*fi).IsD() && (!selected || (*fi).IsS())) - { - FaceLeft &fl = ml.face[remap.face[Index(mr,*fi)]]; - fl.Alloc(fi->VN()); - if(HasFVAdjacency(ml) && HasFVAdjacency(mr)){ - for(int i = 0; i < fl.VN(); ++i) - fl.V(i) = &ml.vert[remap.vert[Index(mr,fi->cV(i))]]; - } - fl.ImportData(*fi); - if(WTFlag) - for(int i = 0; i < fl.VN(); ++i) - fl.WT(i).n() += short(textureOffset); - if(adjFlag) ImportFaceAdj(ml,mr,ml.face[remap.face[Index(mr,*fi)]],*fi,remap); - - } - - // hedge - for(HEdgeIteratorRight hi=mr.hedge.begin();hi!=mr.hedge.end();++hi) - if(!(*hi).IsD() && (!selected || (*hi).IsS())){ - ml.hedge[remap.hedge[Index(mr,*hi)]].ImportData(*hi); - ImportHEdgeAdj(ml,mr,ml.hedge[remap.hedge[Index(mr,*hi)]],*hi,remap,selected); - } - - //tetra - for(TetraIteratorRight ti = mr.tetra.begin(); ti != mr.tetra.end(); ++ti) - if(!(*ti).IsD() && (!selected || (*ti).IsS())) - { - TetraLeft &tl = ml.tetra[remap.tetra[Index(mr,*ti)]]; - - if(HasFVAdjacency(ml) && HasFVAdjacency(mr)){ - for(int i = 0; i < 4; ++i) - tl.V(i) = &ml.vert[remap.vert[Index(mr,ti->cV(i))]]; - } - tl.ImportData(*ti); - if(adjFlag) ImportTetraAdj(ml, mr, ml.tetra[remap.tetra[Index(mr,*ti)]], *ti, remap); - - } - - // phase 3. - // take care of other per mesh data: textures, attributes - - // At the end concatenate the vector with texture names. - ml.textures.insert(ml.textures.end(),mr.textures.begin(),mr.textures.end()); - - // Attributes. Copy only those attributes that are present in both meshes - // Two attributes in different meshes are considered the same if they have the same - // name and the same type. This may be deceiving because they could in fact have - // different semantic, but this is up to the developer. - // If the left mesh has attributes that are not in the right mesh, their values for the elements - // of the right mesh will be uninitialized - - unsigned int id_r; - typename std::set< PointerToAttribute >::iterator al, ar; - - // per vertex attributes - for(al = ml.vert_attr.begin(); al != ml.vert_attr.end(); ++al) - if(!(*al)._name.empty()){ - ar = mr.vert_attr.find(*al); - if(ar!= mr.vert_attr.end()){ - id_r = 0; - for(VertexIteratorRight vi=mr.vert.begin();vi!=mr.vert.end();++vi,++id_r) - if( !(*vi).IsD() && (!selected || (*vi).IsS())) - (*al)._handle->CopyValue(remap.vert[Index(mr,*vi)], id_r, (*ar)._handle); - } - } - - // per edge attributes - for(al = ml.edge_attr.begin(); al != ml.edge_attr.end(); ++al) - if(!(*al)._name.empty()){ - ar = mr.edge_attr.find(*al); - if(ar!= mr.edge_attr.end()){ - id_r = 0; - for(EdgeIteratorRight ei=mr.edge.begin();ei!=mr.edge.end();++ei,++id_r) - if( !(*ei).IsD() && (!selected || (*ei).IsS())) - (*al)._handle->CopyValue(remap.edge[Index(mr,*ei)], id_r, (*ar)._handle); - } - } - - // per face attributes - for(al = ml.face_attr.begin(); al != ml.face_attr.end(); ++al) - if(!(*al)._name.empty()){ - ar = mr.face_attr.find(*al); - if(ar!= mr.face_attr.end()){ - id_r = 0; - for(FaceIteratorRight fi=mr.face.begin();fi!=mr.face.end();++fi,++id_r) - if( !(*fi).IsD() && (!selected || (*fi).IsS())) - (*al)._handle->CopyValue(remap.face[Index(mr,*fi)], id_r, (*ar)._handle); - } - } - - // per tetra attributes - for(al = ml.tetra_attr.begin(); al != ml.tetra_attr.end(); ++al) - if(!(*al)._name.empty()){ - ar = mr.tetra_attr.find(*al); - if(ar!= mr.tetra_attr.end()){ - id_r = 0; - for(TetraIteratorRight ti = mr.tetra.begin(); ti != mr.tetra.end(); ++ti, ++id_r) - if( !(*ti).IsD() && (!selected || (*ti).IsS())) - (*al)._handle->CopyValue(remap.tetra[Index(mr, *ti)], id_r, (*ar)._handle); - } - } - // per mesh attributes - // if both ml and mr have an attribute with the same name, no action is done - // if mr has an attribute that is NOT present in ml, the attribute is added to ml - //for(ar = mr.mesh_attr.begin(); ar != mr.mesh_attr.end(); ++ar) - // if(!(*ar)._name.empty()){ - // al = ml.mesh_attr.find(*ar); - // if(al== ml.mesh_attr.end()) - // //... - // } + MeshAppendConst(ml, mr, selected, adjFlag); } /** @@ -494,180 +286,200 @@ static void Mesh(MeshLeft& ml, ConstMeshRight& mr, const bool selected = false, * or, use the Mesh function that takes a non-const Right Mesh argument. */ static void MeshAppendConst( - MeshLeft& ml, - const ConstMeshRight& mr, - const bool selected = false, - const bool adjFlag = false) + MeshLeft& ml, + const ConstMeshRight& mr, + const bool selected = false, + const bool adjFlag = false) { - // phase 1. allocate on ml vert,edge,face, hedge to accomodat those of mr - // and build the remapping for all + // phase 1. allocate on ml vert,edge,face, hedge to accomodat those of mr + // and build the remapping for all - Remap remap; + Remap remap; - // vertex - remap.vert.resize(mr.vert.size(), Remap::InvalidIndex()); - VertexIteratorLeft vp; - size_t svn = UpdateSelection::VertexCount(mr); - if(selected) - vp=Allocator::AddVertices(ml,int(svn)); - else - vp=Allocator::AddVertices(ml,mr.vn); + // vertex + remap.vert.resize(mr.vert.size(), Remap::InvalidIndex()); + VertexIteratorLeft vp; + size_t svn = UpdateSelection::VertexCount(mr); + if(selected) + vp=Allocator::AddVertices(ml,int(svn)); + else + vp=Allocator::AddVertices(ml,mr.vn); - ForEachVertex(mr, [&](const VertexRight& v) - { - if(!selected || v.IsS()) - { - size_t ind=Index(mr,v); - remap.vert[ind]=int(Index(ml,*vp)); - ++vp; - } - }); - // edge - remap.edge.resize(mr.edge.size(), Remap::InvalidIndex()); - EdgeIteratorLeft ep; - size_t sen = UpdateSelection::EdgeCount(mr); - if(selected) ep=Allocator::AddEdges(ml,sen); - else ep=Allocator::AddEdges(ml,mr.en); + ForEachVertex(mr, [&](const VertexRight& v) + { + if(!selected || v.IsS()) + { + size_t ind=Index(mr,v); + remap.vert[ind]=int(Index(ml,*vp)); + ++vp; + } + }); + // edge + remap.edge.resize(mr.edge.size(), Remap::InvalidIndex()); + EdgeIteratorLeft ep; + size_t sen = UpdateSelection::EdgeCount(mr); + if(selected) ep=Allocator::AddEdges(ml,sen); + else ep=Allocator::AddEdges(ml,mr.en); - ForEachEdge(mr, [&](const EdgeRight& e) - { - if(!selected || e.IsS()){ - size_t ind=Index(mr,e); - remap.edge[ind]=int(Index(ml,*ep)); - ++ep; - } - }); + ForEachEdge(mr, [&](const EdgeRight& e) + { + if(!selected || e.IsS()){ + size_t ind=Index(mr,e); + remap.edge[ind]=int(Index(ml,*ep)); + ++ep; + } + }); - // face - remap.face.resize(mr.face.size(), Remap::InvalidIndex()); - FaceIteratorLeft fp; - size_t sfn = UpdateSelection::FaceCount(mr); - if(selected) fp=Allocator::AddFaces(ml,sfn); - else fp=Allocator::AddFaces(ml,mr.fn); + // face + remap.face.resize(mr.face.size(), Remap::InvalidIndex()); + FaceIteratorLeft fp; + size_t sfn = UpdateSelection::FaceCount(mr); + if(selected) fp=Allocator::AddFaces(ml,sfn); + else fp=Allocator::AddFaces(ml,mr.fn); - ForEachFace(mr, [&](const FaceRight& f) - { - if(!selected || f.IsS()){ - size_t ind=Index(mr,f); - remap.face[ind]=int(Index(ml,*fp)); - ++fp; - } - }); + ForEachFace(mr, [&](const FaceRight& f) + { + if(!selected || f.IsS()){ + size_t ind=Index(mr,f); + remap.face[ind]=int(Index(ml,*fp)); + ++fp; + } + }); - // hedge - remap.hedge.resize(mr.hedge.size(),Remap::InvalidIndex()); + // hedge + remap.hedge.resize(mr.hedge.size(),Remap::InvalidIndex()); - ForEachHEdge(mr, [&](const HEdgeRight& he) - { - if(!selected || he.IsS()){ - size_t ind=Index(mr,he); - assert(remap.hedge[ind]==Remap::InvalidIndex()); - HEdgeIteratorLeft hp = Allocator::AddHEdges(ml,1); - (*hp).ImportData(he); - remap.hedge[ind]=Index(ml,*hp); - } - }); + ForEachHEdge(mr, [&](const HEdgeRight& he) + { + if(!selected || he.IsS()){ + size_t ind=Index(mr,he); + assert(remap.hedge[ind]==Remap::InvalidIndex()); + HEdgeIteratorLeft hp = Allocator::AddHEdges(ml,1); + (*hp).ImportData(he); + remap.hedge[ind]=Index(ml,*hp); + } + }); - remap.tetra.resize(mr.tetra.size(), Remap::InvalidIndex()); + remap.tetra.resize(mr.tetra.size(), Remap::InvalidIndex()); - ForEachTetra(mr, [&](const TetraRight& t) - { - if (!selected || t.IsS()) { - size_t idx = Index(mr, t); - assert (remap.tetra[idx] == Remap::InvalidIndex()); - TetraIteratorLeft tp = Allocator::AddTetras(ml, 1); - (*tp).ImportData(t); - remap.tetra[idx] = Index(ml, *tp); - } - }); + ForEachTetra(mr, [&](const TetraRight& t) + { + if (!selected || t.IsS()) { + size_t idx = Index(mr, t); + assert (remap.tetra[idx] == Remap::InvalidIndex()); + TetraIteratorLeft tp = Allocator::AddTetras(ml, 1); + (*tp).ImportData(t); + remap.tetra[idx] = Index(ml, *tp); + } + }); - // phase 2. - // copy data from mr to its corresponding elements in ml and adjacencies + // phase 1.5 + // manage textures, creating a new one only when necessary + // (not making unuseful duplicates on append) and save a mapping - // vertex - ForEachVertex(mr, [&](const VertexRight& v) - { - if(!selected || v.IsS()){ - ml.vert[remap.vert[Index(mr,v)]].ImportData(v); - if(adjFlag) ImportVertexAdj(ml,mr,ml.vert[remap.vert[Index(mr,v)]],v,remap); - } - }); + // for each texture in the right mesh, it maps it to the texture index in the + // left mesh + std::vector mappingTextures(mr.textures.size()); - // edge - ForEachEdge(mr, [&](const EdgeRight& e) - { - if(!selected || e.IsS()){ - ml.edge[remap.edge[Index(mr,e)]].ImportData(e); - // Edge to Vertex Adj - EdgeLeft &el = ml.edge[remap.edge[Index(mr,e)]]; - if(HasEVAdjacency(ml) && HasEVAdjacency(mr)){ - el.V(0) = &ml.vert[remap.vert[Index(mr,e.cV(0))]]; - el.V(1) = &ml.vert[remap.vert[Index(mr,e.cV(1))]]; - } - if(adjFlag) ImportEdgeAdj(ml,mr,el,e,remap); - } - }); + unsigned int baseMlT = ml.textures.size(); + for (unsigned int i = 0; i < mr.textures.size(); ++i) { + auto it = std::find(ml.textures.begin(), ml.textures.end(), mr.textures[i]); + //if the right texture does not exists in the left mesh + if (it == ml.textures.end()) { + //add the texture in the left mesh and create the mapping + mappingTextures[i] = baseMlT++; + ml.textures.push_back(mr.textures[i]); + } + else { + //the ith right texture will map in the texture found in the left mesh + mappingTextures[i] = it - ml.textures.begin(); + } + } + //ml.textures.insert(ml.textures.end(), mr.textures.begin(),mr.textures.end()); - // face - const size_t textureOffset = ml.textures.size(); - bool WTFlag = HasPerWedgeTexCoord(mr) && (textureOffset>0); - ForEachFace(mr, [&](const FaceRight& f) - { - if(!selected || f.IsS()) - { - FaceLeft &fl = ml.face[remap.face[Index(mr,f)]]; - fl.Alloc(f.VN()); - if(HasFVAdjacency(ml) && HasFVAdjacency(mr)){ - for(int i = 0; i < fl.VN(); ++i) - fl.V(i) = &ml.vert[remap.vert[Index(mr,f.cV(i))]]; - } - fl.ImportData(f); - if(WTFlag) - for(int i = 0; i < fl.VN(); ++i) - fl.WT(i).n() += short(textureOffset); - if(adjFlag) ImportFaceAdj(ml,mr,ml.face[remap.face[Index(mr,f)]],f,remap); + // phase 2. + // copy data from mr to its corresponding elements in ml and adjacencies - } - }); + // vertex + ForEachVertex(mr, [&](const VertexRight& v) + { + if(!selected || v.IsS()){ + ml.vert[remap.vert[Index(mr,v)]].ImportData(v); + if(adjFlag) ImportVertexAdj(ml,mr,ml.vert[remap.vert[Index(mr,v)]],v,remap); + } + }); - // hedge - ForEachHEdge(mr, [&](const HEdgeRight& he) - { - if(!selected || he.IsS()){ - ml.hedge[remap.hedge[Index(mr,he)]].ImportData(he); - ImportHEdgeAdj(ml,mr,ml.hedge[remap.hedge[Index(mr,he)]],he,remap,selected); - } - }); + // edge + ForEachEdge(mr, [&](const EdgeRight& e) + { + if(!selected || e.IsS()){ + ml.edge[remap.edge[Index(mr,e)]].ImportData(e); + // Edge to Vertex Adj + EdgeLeft &el = ml.edge[remap.edge[Index(mr,e)]]; + if(HasEVAdjacency(ml) && HasEVAdjacency(mr)){ + el.V(0) = &ml.vert[remap.vert[Index(mr,e.cV(0))]]; + el.V(1) = &ml.vert[remap.vert[Index(mr,e.cV(1))]]; + } + if(adjFlag) ImportEdgeAdj(ml,mr,el,e,remap); + } + }); - //tetra - ForEachTetra(mr, [&](const TetraRight& t) - { - if(!selected || t.IsS()) - { - TetraLeft &tl = ml.tetra[remap.tetra[Index(mr,t)]]; + // face + bool WTFlag = HasPerWedgeTexCoord(mr); + ForEachFace(mr, [&](const FaceRight& f) + { + if(!selected || f.IsS()) + { + FaceLeft &fl = ml.face[remap.face[Index(mr,f)]]; + fl.Alloc(f.VN()); + if(HasFVAdjacency(ml) && HasFVAdjacency(mr)){ + for(int i = 0; i < fl.VN(); ++i) + fl.V(i) = &ml.vert[remap.vert[Index(mr,f.cV(i))]]; + } + fl.ImportData(f); + if(WTFlag) + for(int i = 0; i < fl.VN(); ++i) + fl.WT(i).n() = mappingTextures[f.WT(i).n()]; + if(adjFlag) ImportFaceAdj(ml,mr,ml.face[remap.face[Index(mr,f)]],f,remap); - if(HasFVAdjacency(ml) && HasFVAdjacency(mr)){ - for(int i = 0; i < 4; ++i) - tl.V(i) = &ml.vert[remap.vert[Index(mr,t.cV(i))]]; - } - tl.ImportData(t); - if(adjFlag) ImportTetraAdj(ml, mr, ml.tetra[remap.tetra[Index(mr,t)]], t, remap); + } + }); - } - }); + // hedge + ForEachHEdge(mr, [&](const HEdgeRight& he) + { + if(!selected || he.IsS()){ + ml.hedge[remap.hedge[Index(mr,he)]].ImportData(he); + ImportHEdgeAdj(ml,mr,ml.hedge[remap.hedge[Index(mr,he)]],he,remap,selected); + } + }); - // phase 3. - // take care of other per mesh data: textures, attributes + //tetra + ForEachTetra(mr, [&](const TetraRight& t) + { + if(!selected || t.IsS()) + { + TetraLeft &tl = ml.tetra[remap.tetra[Index(mr,t)]]; - // At the end concatenate the vector with texture names. - ml.textures.insert(ml.textures.end(),mr.textures.begin(),mr.textures.end()); + if(HasFVAdjacency(ml) && HasFVAdjacency(mr)){ + for(int i = 0; i < 4; ++i) + tl.V(i) = &ml.vert[remap.vert[Index(mr,t.cV(i))]]; + } + tl.ImportData(t); + if(adjFlag) ImportTetraAdj(ml, mr, ml.tetra[remap.tetra[Index(mr,t)]], t, remap); - // Attributes. Copy only those attributes that are present in both meshes - // Two attributes in different meshes are considered the same if they have the same - // name and the same type. This may be deceiving because they could in fact have - // different semantic, but this is up to the developer. - // If the left mesh has attributes that are not in the right mesh, their values for the elements - // of the right mesh will be uninitialized + } + }); + + // phase 3. + // take care of other per mesh data: attributes + + // Attributes. Copy only those attributes that are present in both meshes + // Two attributes in different meshes are considered the same if they have the same + // name and the same type. This may be deceiving because they could in fact have + // different semantic, but this is up to the developer. + // If the left mesh has attributes that are not in the right mesh, their values for the elements + // of the right mesh will be uninitialized unsigned int id_r; typename std::set< PointerToAttribute >::iterator al, ar; @@ -740,40 +552,42 @@ static void MeshAppendConst( } } - // per mesh attributes - // if both ml and mr have an attribute with the same name, no action is done - // if mr has an attribute that is NOT present in ml, the attribute is added to ml - //for(ar = mr.mesh_attr.begin(); ar != mr.mesh_attr.end(); ++ar) - // if(!(*ar)._name.empty()){ - // al = ml.mesh_attr.find(*ar); - // if(al== ml.mesh_attr.end()) - // //... - // } + // per mesh attributes + // if both ml and mr have an attribute with the same name, no action is done + // if mr has an attribute that is NOT present in ml, the attribute is added to ml + //for(ar = mr.mesh_attr.begin(); ar != mr.mesh_attr.end(); ++ar) + // if(!(*ar)._name.empty()){ + // al = ml.mesh_attr.find(*ar); + // if(al== ml.mesh_attr.end()) + // //... + // } } -/*! \brief Copy the second mesh over the first one. - The first mesh is destroyed. If requested only the selected elements are copied. -*/ +/** + * \brief Copy the second mesh over the first one. + * The first mesh is destroyed. If requested only the selected elements are copied. + */ static void MeshCopy(MeshLeft& ml, ConstMeshRight& mr, bool selected=false, const bool adjFlag = false) { - ml.Clear(); - Mesh(ml,mr,selected,adjFlag); - ml.bbox.Import(mr.bbox); + ml.Clear(); + Mesh(ml,mr,selected,adjFlag); + ml.bbox.Import(mr.bbox); } static void MeshCopyConst(MeshLeft& ml, const ConstMeshRight& mr, bool selected=false, const bool adjFlag = false) { - ml.Clear(); - MeshAppendConst(ml,mr,selected,adjFlag); - ml.bbox.Import(mr.bbox); + ml.Clear(); + MeshAppendConst(ml,mr,selected,adjFlag); + ml.bbox.Import(mr.bbox); } -/*! \brief %Append only the selected elements of second mesh to the first one. - - It is just a wrap of the main Append::Mesh() - */ +/** + * \brief %Append only the selected elements of second mesh to the first one. + * + * It is just a wrap of the main Append::Mesh() + */ static void Selected(MeshLeft& ml, ConstMeshRight& mr) { - Mesh(ml,mr,true); + Mesh(ml,mr,true); } }; // end of class Append From 5c0ea8b20ea95adfc3a443ef60e02ee54057ec41 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Wed, 19 May 2021 16:08:09 +0200 Subject: [PATCH 017/117] update cmake --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fc28d096..e7073ae0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ # Copyright 2019, 2021, Visual Computing Lab, ISTI - Italian National Research Council # SPDX-License-Identifier: BSL-1.0 -cmake_minimum_required(VERSION 3.13) +cmake_minimum_required(VERSION 3.10) project(VCGLib) # Eigen options From d47e157f687f32bf89b96f1fc64c5b7a053eee37 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Tue, 25 May 2021 11:05:38 +0200 Subject: [PATCH 018/117] remove cmake POLICY CMP0072 --- CMakeLists.txt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e7073ae0..663c74cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,11 +16,6 @@ option(VCG_BUILD_EXAMPLES "Build a set of examples of the library" OFF) set (VCG_INCLUDE_DIRS ${CMAKE_CURRENT_LIST_DIR}) set (VCG_INCLUDE_DIRS ${CMAKE_CURRENT_LIST_DIR} PARENT_SCOPE) -# Prefer GLVND -if(POLICY CMP0072) - cmake_policy(SET CMP0072 NEW) -endif() - ### Build settings set(CMAKE_CXX_STANDARD 11) From 7006311807bd09cbc5da2f8d959c81c6b37ceade Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Thu, 3 Jun 2021 11:07:15 +0200 Subject: [PATCH 019/117] fix append when mesh has texcoords but not textures --- vcg/complex/append.h | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/vcg/complex/append.h b/vcg/complex/append.h index 0c64e161..2d342038 100644 --- a/vcg/complex/append.h +++ b/vcg/complex/append.h @@ -401,11 +401,24 @@ static void MeshAppendConst( // copy data from mr to its corresponding elements in ml and adjacencies // vertex + bool vertTexFlag = HasPerVertexTexCoord(mr); ForEachVertex(mr, [&](const VertexRight& v) { if(!selected || v.IsS()){ - ml.vert[remap.vert[Index(mr,v)]].ImportData(v); - if(adjFlag) ImportVertexAdj(ml,mr,ml.vert[remap.vert[Index(mr,v)]],v,remap); + VertexLeft &vl = ml.vert[remap.vert[Index(mr,v)]]; + vl.ImportData(v); + if(adjFlag) + ImportVertexAdj(ml,mr,vl,v,remap); + if (vertTexFlag){ + if (v.T().n() < mappingTextures.size()) { + //standard case: the texture is contained in the mesh + vl.T().n() = mappingTextures[v.T().n()]; + } + else { + //the mesh has tex coords, but not the texture... + vl.T().n() = v.T().n(); + } + } } }); @@ -425,7 +438,7 @@ static void MeshAppendConst( }); // face - bool WTFlag = HasPerWedgeTexCoord(mr); + bool wedgeTexFlag = HasPerWedgeTexCoord(mr); ForEachFace(mr, [&](const FaceRight& f) { if(!selected || f.IsS()) @@ -437,9 +450,18 @@ static void MeshAppendConst( fl.V(i) = &ml.vert[remap.vert[Index(mr,f.cV(i))]]; } fl.ImportData(f); - if(WTFlag) - for(int i = 0; i < fl.VN(); ++i) - fl.WT(i).n() = mappingTextures[f.WT(i).n()]; + if(wedgeTexFlag) { + for(int i = 0; i < fl.VN(); ++i){ + if (f.WT(i).n() < mappingTextures.size()){ + //standard case: the texture is contained in the mesh + fl.WT(i).n() = mappingTextures[f.WT(i).n()]; + } + else { + //the mesh has tex coords, but not the texture... + fl.WT(i).n() = f.WT(i).n(); + } + } + } if(adjFlag) ImportFaceAdj(ml,mr,ml.face[remap.face[Index(mr,f)]],f,remap); } From a2735f6da4d2ee7afe85d209fd7d15a75e5e367b Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Mon, 7 Jun 2021 11:33:08 +0200 Subject: [PATCH 020/117] missing include shot qt --- wrap/qt/shot_qt.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/wrap/qt/shot_qt.h b/wrap/qt/shot_qt.h index e2dc32e4..e9ca0a6c 100644 --- a/wrap/qt/shot_qt.h +++ b/wrap/qt/shot_qt.h @@ -1,6 +1,10 @@ #ifndef SHOT_QT_H #define SHOT_QT_H +#include +#include + +#include /** This function read a shot from a parsed XML node. From 85d66654308a4ab80068cad36a41cfe080728ad6 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Tue, 8 Jun 2021 10:40:30 +0200 Subject: [PATCH 021/117] import_nvm - using std::cerr to remove ambiguous << operator on qDebug --- wrap/io_trimesh/import_nvm.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wrap/io_trimesh/import_nvm.h b/wrap/io_trimesh/import_nvm.h index 06f70ac5..8991855a 100644 --- a/wrap/io_trimesh/import_nvm.h +++ b/wrap/io_trimesh/import_nvm.h @@ -166,17 +166,17 @@ static int Open( OpenMeshType &m, std::vector > & shots, float x,y,z; unsigned int r,g,b,i_cam, key_sift,n_corr; uint readValues = fscanf(fp,"%f %f %f ",&x,&y,&z); - if (readValues < 3) qDebug() << "Point " << i << ": only " << readValues << " coordinates read!"; + if (readValues < 3) std::cerr << "Point " << i << ": only " << readValues << " coordinates read!"; (*vi).P() = vcg::Point3(x,y,z); readValues = fscanf(fp,"%d %d %d ",&r,&g,&b); - if (readValues < 3) qDebug() << "Point " << i << ": only " << readValues << " color values read!"; + if (readValues < 3) std::cerr << "Point " << i << ": only " << readValues << " color values read!"; (*vi).C() = vcg::Color4b(r,g,b,255); readValues = fscanf(fp,"%d ",&n_corr); - if (readValues < 1) qDebug() << "Point " << i << ": no n correspondences read!"; + if (readValues < 1) std::cerr << "Point " << i << ": no n correspondences read!"; for(uint j = 0; j < n_corr; ++j){ readValues = fscanf(fp,"%d %d %f %f ",&i_cam,&key_sift,&x,&y); - if (readValues != 3) qDebug() << "Point " << i << "; Corresp: " << j << ": only " << readValues << " values read!"; + if (readValues != 3) std::cerr << "Point " << i << "; Corresp: " << j << ": only " << readValues << " values read!"; Correspondence corr(i_cam,key_sift,x,y); ch[i].push_back(corr); } From 7d5d2271e6f5113c698a23320b2751638c945742 Mon Sep 17 00:00:00 2001 From: Luigi Malomo Date: Fri, 11 Jun 2021 16:40:48 +0200 Subject: [PATCH 022/117] fixed gl picking --- wrap/gl/pick.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/wrap/gl/pick.h b/wrap/gl/pick.h index bb4ea942..33461bb5 100644 --- a/wrap/gl/pick.h +++ b/wrap/gl/pick.h @@ -26,7 +26,8 @@ #include #include -#include "gl_type_name.h" + +#include namespace vcg{ @@ -218,11 +219,11 @@ public: int screenW = (int)(vp[2]-vp[0]); int screenH = (int)(vp[3]-vp[1]); - GL_TYPE_NM::ScalarType *buffer = new GL_TYPE_NM::ScalarType[screenW*screenH]; + GLfloat *buffer = new GLfloat[screenW*screenH]; - //I'm not sure glReadPixels can accept GL_DOUBLE tag + //glReadPixels does NOT accept GL_DOUBLE //GLenum err = glGetError(); - glReadPixels(vp[0],vp[1],vp[2],vp[3],GL_DEPTH_COMPONENT,GL_TYPE_NM::SCALAR(),buffer); + glReadPixels(vp[0],vp[1],vp[2],vp[3],GL_DEPTH_COMPONENT,GL_FLOAT,buffer); //err = glGetError(); std::vector result; PickFace(x,y,m,result,width,height); @@ -261,11 +262,10 @@ public: int screenH = vp[3]-vp[1]; - GL_TYPE_NM::ScalarType *buffer = new GL_TYPE_NM::ScalarType[screenW*screenH]; + GLfloat *buffer = new GLfloat[screenW*screenH]; - //I'm not sure glReadPixels can accept GL_DOUBLE tag //GLenum err = glGetError(); - glReadPixels(vp[0],vp[1],vp[2],vp[3],GL_DEPTH_COMPONENT,GL_TYPE_NM::SCALAR(),buffer); + glReadPixels(vp[0],vp[1],vp[2],vp[3],GL_DEPTH_COMPONENT,GL_FLOAT,buffer); //err = glGetError(); std::vector result; From 4b8f73d81c6a3fe3c53b55268b94e892b928d394 Mon Sep 17 00:00:00 2001 From: Luigi Malomo Date: Fri, 11 Jun 2021 17:28:26 +0200 Subject: [PATCH 023/117] refactoring --- vcg/complex/algorithms/curve_on_manifold.h | 2 +- wrap/gl/pick.h | 529 +++++++-------------- 2 files changed, 174 insertions(+), 357 deletions(-) diff --git a/vcg/complex/algorithms/curve_on_manifold.h b/vcg/complex/algorithms/curve_on_manifold.h index 2c8e4abe..e03e1f5f 100644 --- a/vcg/complex/algorithms/curve_on_manifold.h +++ b/vcg/complex/algorithms/curve_on_manifold.h @@ -1141,7 +1141,7 @@ public: } }; -struct EdgePointSplit : public std::unary_function , CoordType> +struct EdgePointSplit { public: std::map, VertexPointer> &edgeToPolyVertMap; diff --git a/wrap/gl/pick.h b/wrap/gl/pick.h index 33461bb5..4d327d14 100644 --- a/wrap/gl/pick.h +++ b/wrap/gl/pick.h @@ -24,403 +24,220 @@ #ifndef __PICK______H #define __PICK______H +// Assumes OpenGL already included + #include #include #include - namespace vcg{ template class GLPickTri { - typedef typename MESH_TYPE::ScalarType ScalarType; - typedef typename MESH_TYPE::CoordType CoordType; - typedef typename MESH_TYPE::FaceIterator FaceIterator; - typedef typename MESH_TYPE::VertexIterator VertexIterator; - typedef typename MESH_TYPE::FacePointer FacePointer; - typedef typename MESH_TYPE::VertexPointer VertexPointer; - typedef typename MESH_TYPE::VertexType VertexType; - public: - static CoordType glProject(const Eigen::Matrix &M, const ScalarType * viewport, const CoordType &p) - { - const ScalarType vx=viewport[0]; - const ScalarType vy=viewport[1]; - const ScalarType vw2=viewport[2]/ScalarType(2.0); - const ScalarType vh2=viewport[3]/ScalarType(2.0); - Eigen::Matrix vp(p[0],p[1],p[2],ScalarType(1.0)); - Eigen::Matrix vpp = M*vp; - Eigen::Matrix ndc = vpp/vpp[3]; + typedef typename MESH_TYPE::ScalarType ScalarType; + typedef typename MESH_TYPE::CoordType CoordType; + typedef typename MESH_TYPE::FaceIterator FaceIterator; + typedef typename MESH_TYPE::VertexIterator VertexIterator; + typedef typename MESH_TYPE::FacePointer FacePointer; + typedef typename MESH_TYPE::VertexPointer VertexPointer; + typedef typename MESH_TYPE::VertexType VertexType; - CoordType sc( - vw2*ndc[0] + vx+vw2, - vh2*ndc[1] + vy+vh2, - ndc[2] - ); + static CoordType glProject(const Eigen::Matrix &M, const ScalarType * viewport, const CoordType &p) + { + const ScalarType vx=viewport[0]; + const ScalarType vy=viewport[1]; + const ScalarType vw2=viewport[2]/ScalarType(2.0); + const ScalarType vh2=viewport[3]/ScalarType(2.0); + Eigen::Matrix vp(p[0],p[1],p[2],ScalarType(1.0)); + Eigen::Matrix vpp = M*vp; + Eigen::Matrix ndc = vpp/vpp[3]; - return sc; - } + CoordType sc(vw2*ndc[0] + vx+vw2, + vh2*ndc[1] + vy+vh2, + ndc[2]); - static void FillProjectedVector(MESH_TYPE &m, std::vector &pVec, const Eigen::Matrix &M, const ScalarType * viewportF) - { - pVec.resize(m.vert.size()); - for(size_t i=0;i::glProject(M, viewportF,CoordType::Construct(m.vert[i].P())); - } - } + return sc; + } - static void glGetMatrixAndViewport(Eigen::Matrix &M, ScalarType *viewportF) - { - Eigen::Matrix4d mp,mm; + static void FillProjectedVector(MESH_TYPE &m, std::vector &pVec, const Eigen::Matrix &M, const ScalarType * viewportF) + { + pVec.resize(m.vert.size()); + for(size_t i=0;i::glProject(M, viewportF,CoordType::Construct(m.vert[i].P())); + } + } - GLint viewport[4]; - glGetIntegerv(GL_VIEWPORT,viewport); - for(int i=0;i<4;++i) viewportF[i]=viewport[i]; + static void glGetMatrixAndViewport(Eigen::Matrix &M, ScalarType *viewportF) + { + Eigen::Matrix4d mp,mm; - glGetDoublev(GL_PROJECTION_MATRIX, mp.data()); - glGetDoublev(GL_MODELVIEW_MATRIX, mm.data()); + GLint viewport[4]; + glGetIntegerv(GL_VIEWPORT,viewport); + for(int i=0;i<4;++i) viewportF[i]=viewport[i]; - M = (mp*mm).cast(); - } + glGetDoublev(GL_PROJECTION_MATRIX, mp.data()); + glGetDoublev(GL_MODELVIEW_MATRIX, mm.data()); - // compute a bbox in Device Coordinate (with the z without the near far normalization and ranged in -1 1) - static Box3 ComputeDCBox(int x, int y, int width, int height) - { - Box3 bb; - bb.SetNull(); - bb.Add(CoordType(x-width/ScalarType(2.0),y-height/ScalarType(2.0),ScalarType(-1.0))); - bb.Add(CoordType(x+width/ScalarType(2.0),y+height/ScalarType(2.0), ScalarType(1.0))); - return bb; - } + M = (mp*mm).cast(); + } -public: + // compute a bbox in Device Coordinate (with the z without the near far normalization and ranged in -1 1) + static Box3 ComputeDCBox(int x, int y, int width, int height) + { + Box3 bb; + bb.SetNull(); + bb.Add(CoordType(x-width/ScalarType(2.0),y-height/ScalarType(2.0),ScalarType(-1.0))); + bb.Add(CoordType(x+width/ScalarType(2.0),y+height/ScalarType(2.0), ScalarType(1.0))); + return bb; + } - static bool PickClosestFace(int x, int y, MESH_TYPE &m, FacePointer &fp,int width=4, int height=4) - { - Eigen::Matrix M; - ScalarType viewportF[4]; - glGetMatrixAndViewport(M,viewportF); - Box3 reg=ComputeDCBox(x,y,width,height); + static bool PickClosestFace(int x, int y, MESH_TYPE &m, FacePointer &fp,int width=4, int height=4) + { + Eigen::Matrix M; + ScalarType viewportF[4]; + glGetMatrixAndViewport(M,viewportF); + Box3 reg=ComputeDCBox(x,y,width,height); - ScalarType bzmin = std::numeric_limits::max(); - fp=0; - for(size_t i=0;i::max(); + fp=0; + for(size_t i=0;i M; - ScalarType viewportF[4]; - glGetMatrixAndViewport(M,viewportF); - ScalarType bzmin = std::numeric_limits::max(); - vp=0; + static bool PickClosestVert(int x, int y, MESH_TYPE &m, VertexPointer &vp,int width=4, int height=4) + { + Eigen::Matrix M; + ScalarType viewportF[4]; + glGetMatrixAndViewport(M,viewportF); + ScalarType bzmin = std::numeric_limits::max(); + vp=0; - Box3 reg=ComputeDCBox(x,y,width,height); + Box3 reg=ComputeDCBox(x,y,width,height); - for(size_t i=0;i &result, int width=4, int height=4) - { - result.clear(); - static Eigen::Matrix lastM; - static MESH_TYPE *lastm=0; - static std::vector pVec; + static int PickVert(int x, int y, MESH_TYPE &m, std::vector &result, int width=4, int height=4) + { + result.clear(); + static Eigen::Matrix lastM; + static MESH_TYPE *lastm=0; + static std::vector pVec; - Eigen::Matrix M; - ScalarType viewportF[4]; - glGetMatrixAndViewport(M,viewportF); + Eigen::Matrix M; + ScalarType viewportF[4]; + glGetMatrixAndViewport(M,viewportF); - Box3 reg =ComputeDCBox(x,y,width,height); + Box3 reg =ComputeDCBox(x,y,width,height); - if ((M != lastM) || (&m != lastm) || (pVec.size() != m.VN())) - { - FillProjectedVector(m,pVec,M,viewportF); - lastM = M; - lastm = &m; - } + if ((M != lastM) || (&m != lastm) || (pVec.size() != m.VN())) + { + FillProjectedVector(m,pVec,M,viewportF); + lastM = M; + lastm = &m; + } - for(size_t i=0;i &result, int width = 4, int height = 4) - { - static Eigen::Matrix lastM; - static MESH_TYPE *lastm = 0; - static std::vector pVec; + static int PickFace(int x, int y, MESH_TYPE &m, std::vector &result, int width = 4, int height = 4) + { + static Eigen::Matrix lastM; + static MESH_TYPE *lastm = 0; + static std::vector pVec; - ScalarType viewportF[4]; - Eigen::Matrix M; - glGetMatrixAndViewport(M, viewportF); - result.clear(); - Box3 reg; - reg.Add(CoordType(x - width / ScalarType(2.0), y - height / ScalarType(2.0), ScalarType(-1.0))); - reg.Add(CoordType(x + width / ScalarType(2.0), y + height / ScalarType(2.0), ScalarType(1.0))); + ScalarType viewportF[4]; + Eigen::Matrix M; + glGetMatrixAndViewport(M, viewportF); + result.clear(); + Box3 reg; + reg.Add(CoordType(x - width / ScalarType(2.0), y - height / ScalarType(2.0), ScalarType(-1.0))); + reg.Add(CoordType(x + width / ScalarType(2.0), y + height / ScalarType(2.0), ScalarType(1.0))); - - if ((M != lastM) || (&m != lastm) || (pVec.size() != m.VN())) - { - FillProjectedVector(m, pVec, M, viewportF); - lastM = M; - lastm = &m; - } + if ((M != lastM) || (&m != lastm) || (pVec.size() != m.VN())) + { + FillProjectedVector(m, pVec, M, viewportF); + lastM = M; + lastm = &m; + } - for (size_t i = 0; i < m.face.size(); ++i) - { - if (!m.face[i].IsD()) - { - const CoordType &p0 = pVec[tri::Index(m, m.face[i].V(0))]; - const CoordType &p1 = pVec[tri::Index(m, m.face[i].V(1))]; - const CoordType &p2 = pVec[tri::Index(m, m.face[i].V(2))]; + for (size_t i = 0; i < m.face.size(); ++i) + { + if (!m.face[i].IsD()) + { + const CoordType &p0 = pVec[tri::Index(m, m.face[i].V(0))]; + const CoordType &p1 = pVec[tri::Index(m, m.face[i].V(1))]; + const CoordType &p2 = pVec[tri::Index(m, m.face[i].V(2))]; - if (!(abs(p0[2]) > 1 || abs(p1[2]) > 1 || abs(p2[2]) > 1) && IntersectionTriangleBox(reg, p0, p1, p2)) - result.push_back(&m.face[i]); - } - } - return result.size(); - } + if (!(abs(p0[2]) > 1 || abs(p1[2]) > 1 || abs(p2[2]) > 1) && IntersectionTriangleBox(reg, p0, p1, p2)) + result.push_back(&m.face[i]); + } + } + return result.size(); + } - // Same of above but it also assumes that you want only visible faces. - // Visibility is computed according to the current depth buffer. - static int PickVisibleFace(int x, int y, MESH_TYPE &m, std::vector &resultZ, int width=4, int height=4) - { - ScalarType vp[4]; - Eigen::Matrix M; - glGetMatrixAndViewport(M,vp); + // Same of above but it also assumes that you want only visible faces. + // Visibility is computed according to the current depth buffer. + static int PickVisibleFace(int x, int y, MESH_TYPE &m, std::vector &resultZ, int width=4, int height=4) + { + ScalarType vp[4]; + Eigen::Matrix M; + glGetMatrixAndViewport(M,vp); - int screenW = (int)(vp[2]-vp[0]); - int screenH = (int)(vp[3]-vp[1]); + int screenW = (int)(vp[2]-vp[0]); + int screenH = (int)(vp[3]-vp[1]); - GLfloat *buffer = new GLfloat[screenW*screenH]; + GLfloat *buffer = new GLfloat[screenW*screenH]; - //glReadPixels does NOT accept GL_DOUBLE - //GLenum err = glGetError(); - glReadPixels(vp[0],vp[1],vp[2],vp[3],GL_DEPTH_COMPONENT,GL_FLOAT,buffer); - //err = glGetError(); - std::vector result; - PickFace(x,y,m,result,width,height); - ScalarType LocalEpsilon(ScalarType(0.001)); - for(size_t i =0;i=0 && p[0]=0 && p[1]= ScalarType(p[2]+1.0)/2.0) - resultZ.push_back(result[i]); - } - } + //glReadPixels does NOT accept GL_DOUBLE + //GLenum err = glGetError(); + glReadPixels(vp[0],vp[1],vp[2],vp[3],GL_DEPTH_COMPONENT,GL_FLOAT,buffer); + //err = glGetError(); + std::vector result; + PickFace(x,y,m,result,width,height); + ScalarType LocalEpsilon(ScalarType(0.001)); + for(size_t i =0;i=0 && p[0]=0 && p[1]= ScalarType(p[2]+1.0)/2.0) + resultZ.push_back(result[i]); + } + } - delete [] buffer; - return resultZ.size(); - } - - -#ifdef _I_REALLY_NEED_OLD_GL_PICK_ - // Same of above but it also assumes that you want only visible faces. - // Visibility is computed according to the current depth buffer. - static int OldPickFaceVisible(int x, int y, MESH_TYPE &m, std::vector &resultZ, int width=4, int height=4, bool sorted=true) - { - // First step - - double mm[16]; - double mp[16]; - GLint vp[4]; - glGetIntegerv(GL_VIEWPORT,vp); - glGetDoublev(GL_MODELVIEW_MATRIX ,mm); - glGetDoublev(GL_PROJECTION_MATRIX ,mp); - int screenW = vp[2]-vp[0]; - int screenH = vp[3]-vp[1]; - - - GLfloat *buffer = new GLfloat[screenW*screenH]; - - //GLenum err = glGetError(); - glReadPixels(vp[0],vp[1],vp[2],vp[3],GL_DEPTH_COMPONENT,GL_FLOAT,buffer); - //err = glGetError(); - - std::vector result; - OldPickFace(x,y,m,result,width,height,sorted); - ScalarType LocalEpsilon(0.001); - for(size_t i =0;i=0 && tx=0 && ty= tz) - resultZ.push_back(result[i]); - } - } - - delete [] buffer; - return resultZ.size(); - } - - static int OldPickFace(int x, int y, MESH_TYPE &m, std::vector &result, int width=4, int height=4,bool sorted=true) - { - result.clear(); - if(width==0 ||height==0) return 0; - long hits; - int sz=m.face.size()*5; - GLuint *selectBuf =new GLuint[sz]; - // static unsigned int selectBuf[16384]; - glSelectBuffer(sz, selectBuf); - glRenderMode(GL_SELECT); - glInitNames(); - - /* Because LoadName() won't work with no names on the stack */ - glPushName(-1); - double mp[16]; - - GLint viewport[4]; - glGetIntegerv(GL_VIEWPORT,viewport); - glMatrixMode(GL_PROJECTION); - glGetDoublev(GL_PROJECTION_MATRIX ,mp); - glPushMatrix(); - glLoadIdentity(); - //gluPickMatrix(x, viewport[3]-y, 4, 4, viewport); - gluPickMatrix(x, y, width, height, viewport); - glMultMatrixd(mp); - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - int fcnt=0; - FaceIterator fi; - for(fi=m.face.begin();fi!=m.face.end();++fi) - { - if(!(*fi).IsD()) - { - glLoadName(fcnt); - glBegin(GL_TRIANGLES); - glVertex( (*fi).V(0)->P() ); - glVertex( (*fi).V(1)->P() ); - glVertex( (*fi).V(2)->P() ); - glEnd(); - } - fcnt++; // the counter should advance even for deleted faces! - } - - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - hits = glRenderMode(GL_RENDER); - //xstring buf; - //if (hits <= 0) return 0; - std::vector< std::pair > H; - for(long ii=0;ii(selectBuf[ii*4+1]/4294967295.0,selectBuf[ii*4+3])); - } - if(sorted) - std::sort(H.begin(),H.end()); - // if(H.size()>0) TRACE("\n Closest is %i\n",H[0].second); - result.resize(H.size()); - for(long ii=0;ii &result, int width=4, int height=4,bool sorted=true) - { - result.clear(); - if(width==0 ||height==0) return 0; - long hits; - int sz=m.vert.size()*5; - GLuint *selectBuf =new GLuint[sz]; - glSelectBuffer(sz, selectBuf); - glRenderMode(GL_SELECT); - glInitNames(); - - /* Because LoadName() won't work with no names on the stack */ - glPushName(-1); - double mp[16]; - - GLint viewport[4]; - glGetIntegerv(GL_VIEWPORT,viewport); - glMatrixMode(GL_PROJECTION); - glGetDoublev(GL_PROJECTION_MATRIX ,mp); - glPushMatrix(); - glLoadIdentity(); - gluPickMatrix(x, y, width, height, viewport); - glMultMatrixd(mp); - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - int vcnt=0; - VertexIterator vi; - for(vi=m.vert.begin();vi!=m.vert.end();++vi) - { - if(!(*vi).IsD()) - { - glLoadName(vcnt); - glBegin(GL_POINTS); - glVertex( (*vi).P() ); - glEnd(); - } - vcnt++; // the counter should advance even for deleted faces! - } - - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - hits = glRenderMode(GL_RENDER); - std::vector< std::pair > H; - for(long ii=0;ii(selectBuf[ii*4+1]/4294967295.0,selectBuf[ii*4+3])); - } - if(sorted) - std::sort(H.begin(),H.end()); - result.resize(H.size()); - for(long ii=0;ii Date: Tue, 15 Jun 2021 12:27:04 +0200 Subject: [PATCH 024/117] update eigen to 3.3.9 --- eigenlib/Eigen/Cholesky | 5 + eigenlib/Eigen/Core | 40 +- eigenlib/Eigen/Eigenvalues | 8 +- eigenlib/Eigen/Geometry | 4 +- eigenlib/Eigen/LU | 4 + eigenlib/Eigen/QR | 8 +- eigenlib/Eigen/QtAlignedMalloc | 6 +- eigenlib/Eigen/SVD | 4 + eigenlib/Eigen/Sparse | 2 + eigenlib/Eigen/SparseQR | 1 - eigenlib/Eigen/StdDeque | 2 +- eigenlib/Eigen/StdList | 2 +- eigenlib/Eigen/StdVector | 2 +- eigenlib/Eigen/src/Cholesky/LDLT.h | 14 +- eigenlib/Eigen/src/Cholesky/LLT.h | 26 +- eigenlib/Eigen/src/Core/Array.h | 10 +- eigenlib/Eigen/src/Core/ArrayBase.h | 12 +- eigenlib/Eigen/src/Core/ArrayWrapper.h | 6 +- eigenlib/Eigen/src/Core/AssignEvaluator.h | 33 +- eigenlib/Eigen/src/Core/Assign_MKL.h | 6 +- eigenlib/Eigen/src/Core/ConditionEstimator.h | 2 +- eigenlib/Eigen/src/Core/CoreEvaluators.h | 43 +- eigenlib/Eigen/src/Core/CwiseNullaryOp.h | 80 +- eigenlib/Eigen/src/Core/CwiseUnaryView.h | 2 + eigenlib/Eigen/src/Core/DenseBase.h | 27 +- eigenlib/Eigen/src/Core/DenseStorage.h | 35 +- eigenlib/Eigen/src/Core/Diagonal.h | 7 +- eigenlib/Eigen/src/Core/Dot.h | 17 +- eigenlib/Eigen/src/Core/EigenBase.h | 4 + eigenlib/Eigen/src/Core/GeneralProduct.h | 21 +- eigenlib/Eigen/src/Core/GenericPacketMath.h | 15 +- eigenlib/Eigen/src/Core/IO.h | 14 - eigenlib/Eigen/src/Core/Map.h | 17 +- eigenlib/Eigen/src/Core/MapBase.h | 11 +- eigenlib/Eigen/src/Core/MathFunctions.h | 95 +-- eigenlib/Eigen/src/Core/MathFunctionsImpl.h | 23 + eigenlib/Eigen/src/Core/Matrix.h | 2 - eigenlib/Eigen/src/Core/MatrixBase.h | 42 +- eigenlib/Eigen/src/Core/NumTraits.h | 2 + eigenlib/Eigen/src/Core/PermutationMatrix.h | 28 - eigenlib/Eigen/src/Core/PlainObjectBase.h | 28 +- eigenlib/Eigen/src/Core/Product.h | 10 +- eigenlib/Eigen/src/Core/ProductEvaluators.h | 65 +- eigenlib/Eigen/src/Core/Redux.h | 2 +- eigenlib/Eigen/src/Core/Ref.h | 7 +- eigenlib/Eigen/src/Core/SelfAdjointView.h | 6 +- eigenlib/Eigen/src/Core/SelfCwiseBinaryOp.h | 12 +- eigenlib/Eigen/src/Core/Solve.h | 4 +- eigenlib/Eigen/src/Core/SolveTriangular.h | 9 +- eigenlib/Eigen/src/Core/StableNorm.h | 5 +- eigenlib/Eigen/src/Core/Transpose.h | 2 + eigenlib/Eigen/src/Core/Transpositions.h | 41 +- eigenlib/Eigen/src/Core/TriangularMatrix.h | 8 +- eigenlib/Eigen/src/Core/arch/AVX/Complex.h | 36 +- eigenlib/Eigen/src/Core/arch/AVX/PacketMath.h | 24 +- .../src/Core/arch/AVX512/MathFunctions.h | 95 ++- .../Eigen/src/Core/arch/AVX512/PacketMath.h | 731 +++++++++--------- .../Eigen/src/Core/arch/AltiVec/Complex.h | 37 +- .../Eigen/src/Core/arch/AltiVec/PacketMath.h | 58 +- eigenlib/Eigen/src/Core/arch/CUDA/Half.h | 220 ++++-- .../Eigen/src/Core/arch/CUDA/PacketMath.h | 2 +- .../Eigen/src/Core/arch/CUDA/PacketMathHalf.h | 9 +- .../Eigen/src/Core/arch/Default/ConjHelper.h | 29 + eigenlib/Eigen/src/Core/arch/NEON/Complex.h | 12 +- .../Eigen/src/Core/arch/NEON/PacketMath.h | 98 ++- eigenlib/Eigen/src/Core/arch/SSE/Complex.h | 40 +- eigenlib/Eigen/src/Core/arch/SSE/PacketMath.h | 24 +- .../Eigen/src/Core/arch/SSE/TypeCasting.h | 28 +- .../Eigen/src/Core/arch/ZVector/Complex.h | 3 + .../Eigen/src/Core/arch/ZVector/PacketMath.h | 2 +- .../src/Core/functors/AssignmentFunctors.h | 2 +- .../Eigen/src/Core/functors/BinaryFunctors.h | 25 +- .../Eigen/src/Core/functors/NullaryFunctors.h | 15 +- .../Eigen/src/Core/functors/StlFunctors.h | 4 + .../Eigen/src/Core/functors/UnaryFunctors.h | 2 +- .../Core/products/GeneralBlockPanelKernel.h | 22 +- .../src/Core/products/GeneralMatrixMatrix.h | 45 +- .../products/GeneralMatrixMatrixTriangular.h | 79 +- .../GeneralMatrixMatrixTriangular_BLAS.h | 20 +- .../Core/products/GeneralMatrixMatrix_BLAS.h | 25 +- .../src/Core/products/GeneralMatrixVector.h | 8 +- .../Core/products/GeneralMatrixVector_BLAS.h | 19 +- .../Eigen/src/Core/products/Parallelizer.h | 18 +- .../Core/products/SelfadjointMatrixMatrix.h | 54 +- .../products/SelfadjointMatrixMatrix_BLAS.h | 72 +- .../Core/products/SelfadjointMatrixVector.h | 14 +- .../products/SelfadjointMatrixVector_BLAS.h | 9 +- .../src/Core/products/SelfadjointProduct.h | 4 +- .../Core/products/TriangularMatrixMatrix.h | 89 ++- .../products/TriangularMatrixMatrix_BLAS.h | 65 +- .../Core/products/TriangularMatrixVector.h | 22 +- .../products/TriangularMatrixVector_BLAS.h | 46 +- .../Core/products/TriangularSolverMatrix.h | 62 +- .../products/TriangularSolverMatrix_BLAS.h | 52 +- eigenlib/Eigen/src/Core/util/BlasUtil.h | 115 ++- .../src/Core/util/DisableStupidWarnings.h | 27 +- .../Eigen/src/Core/util/ForwardDeclarations.h | 6 +- eigenlib/Eigen/src/Core/util/MKL_support.h | 10 +- eigenlib/Eigen/src/Core/util/Macros.h | 79 +- eigenlib/Eigen/src/Core/util/Memory.h | 78 +- eigenlib/Eigen/src/Core/util/Meta.h | 76 ++ .../src/Core/util/ReenableStupidWarnings.h | 8 +- eigenlib/Eigen/src/Core/util/StaticAssert.h | 120 +-- eigenlib/Eigen/src/Core/util/XprHelper.h | 19 +- .../src/Eigenvalues/ComplexEigenSolver.h | 6 +- eigenlib/Eigen/src/Eigenvalues/ComplexSchur.h | 9 +- .../src/Eigenvalues/GeneralizedEigenSolver.h | 5 +- .../src/Eigenvalues/MatrixBaseEigenvalues.h | 2 - eigenlib/Eigen/src/Eigenvalues/RealSchur.h | 31 +- .../src/Eigenvalues/SelfAdjointEigenSolver.h | 10 +- .../SelfAdjointEigenSolver_LAPACKE.h | 23 +- eigenlib/Eigen/src/Geometry/AngleAxis.h | 2 +- eigenlib/Eigen/src/Geometry/Quaternion.h | 61 +- eigenlib/Eigen/src/Geometry/Scaling.h | 2 +- eigenlib/Eigen/src/Geometry/Transform.h | 4 +- eigenlib/Eigen/src/Geometry/Translation.h | 6 - eigenlib/Eigen/src/Geometry/Umeyama.h | 2 +- .../Eigen/src/Geometry/arch/Geometry_SSE.h | 60 +- .../Eigen/src/Householder/BlockHouseholder.h | 3 +- .../BasicPreconditioners.h | 27 +- .../ConjugateGradient.h | 5 +- eigenlib/Eigen/src/Jacobi/Jacobi.h | 261 ++++--- eigenlib/Eigen/src/LU/InverseImpl.h | 2 +- eigenlib/Eigen/src/LU/PartialPivLU.h | 5 +- eigenlib/Eigen/src/LU/arch/Inverse_SSE.h | 4 +- .../Eigen/src/OrderingMethods/Eigen_Colamd.h | 2 +- .../Eigen/src/PaStiXSupport/PaStiXSupport.h | 8 +- .../Eigen/src/PardisoSupport/PardisoSupport.h | 3 +- eigenlib/Eigen/src/QR/ColPivHouseholderQR.h | 12 +- eigenlib/Eigen/src/SVD/BDCSVD.h | 171 ++-- eigenlib/Eigen/src/SVD/JacobiSVD.h | 12 +- eigenlib/Eigen/src/SVD/JacobiSVD_LAPACKE.h | 5 +- eigenlib/Eigen/src/SVD/SVDBase.h | 4 +- .../Eigen/src/SVD/UpperBidiagonalization.h | 4 +- .../src/SparseCholesky/SimplicialCholesky.h | 2 +- .../SparseCholesky/SimplicialCholesky_impl.h | 2 +- eigenlib/Eigen/src/SparseCore/AmbiVector.h | 15 +- .../ConservativeSparseSparseProduct.h | 67 +- eigenlib/Eigen/src/SparseCore/SparseAssign.h | 5 +- .../src/SparseCore/SparseCompressedBase.h | 38 +- .../src/SparseCore/SparseCwiseBinaryOp.h | 10 + .../Eigen/src/SparseCore/SparseCwiseUnaryOp.h | 2 + .../src/SparseCore/SparseDiagonalProduct.h | 4 + eigenlib/Eigen/src/SparseCore/SparseMatrix.h | 17 +- .../src/SparseCore/SparseSelfAdjointView.h | 15 +- .../SparseSparseProductWithPruning.h | 22 +- eigenlib/Eigen/src/SparseCore/SparseView.h | 1 + eigenlib/Eigen/src/SparseLU/SparseLU.h | 6 +- eigenlib/Eigen/src/SparseQR/SparseQR.h | 26 +- eigenlib/Eigen/src/StlSupport/StdDeque.h | 6 +- eigenlib/Eigen/src/StlSupport/details.h | 14 +- .../Eigen/src/SuperLUSupport/SuperLUSupport.h | 4 +- .../Eigen/src/UmfPackSupport/UmfPackSupport.h | 101 ++- .../Eigen/src/plugins/ArrayCwiseBinaryOps.h | 2 +- eigenlib/howto.txt | 3 +- 155 files changed, 2860 insertions(+), 1893 deletions(-) create mode 100644 eigenlib/Eigen/src/Core/arch/Default/ConjHelper.h mode change 100755 => 100644 eigenlib/Eigen/src/Geometry/Scaling.h diff --git a/eigenlib/Eigen/Cholesky b/eigenlib/Eigen/Cholesky index 369d1f5e..1332b540 100644 --- a/eigenlib/Eigen/Cholesky +++ b/eigenlib/Eigen/Cholesky @@ -9,6 +9,7 @@ #define EIGEN_CHOLESKY_MODULE_H #include "Core" +#include "Jacobi" #include "src/Core/util/DisableStupidWarnings.h" @@ -31,7 +32,11 @@ #include "src/Cholesky/LLT.h" #include "src/Cholesky/LDLT.h" #ifdef EIGEN_USE_LAPACKE +#ifdef EIGEN_USE_MKL +#include "mkl_lapacke.h" +#else #include "src/misc/lapacke.h" +#endif #include "src/Cholesky/LLT_LAPACKE.h" #endif diff --git a/eigenlib/Eigen/Core b/eigenlib/Eigen/Core index 82558155..ac7c5b30 100644 --- a/eigenlib/Eigen/Core +++ b/eigenlib/Eigen/Core @@ -14,6 +14,22 @@ // first thing Eigen does: stop the compiler from committing suicide #include "src/Core/util/DisableStupidWarnings.h" +#if defined(__CUDACC__) && !defined(EIGEN_NO_CUDA) + #define EIGEN_CUDACC __CUDACC__ +#endif + +#if defined(__CUDA_ARCH__) && !defined(EIGEN_NO_CUDA) + #define EIGEN_CUDA_ARCH __CUDA_ARCH__ +#endif + +#if defined(__CUDACC_VER_MAJOR__) && (__CUDACC_VER_MAJOR__ >= 9) +#define EIGEN_CUDACC_VER ((__CUDACC_VER_MAJOR__ * 10000) + (__CUDACC_VER_MINOR__ * 100)) +#elif defined(__CUDACC_VER__) +#define EIGEN_CUDACC_VER __CUDACC_VER__ +#else +#define EIGEN_CUDACC_VER 0 +#endif + // Handle NVCC/CUDA/SYCL #if defined(__CUDACC__) || defined(__SYCL_DEVICE_ONLY__) // Do not try asserts on CUDA and SYCL! @@ -37,9 +53,9 @@ #endif #define EIGEN_DEVICE_FUNC __host__ __device__ - // We need math_functions.hpp to ensure that that EIGEN_USING_STD_MATH macro + // We need cuda_runtime.h to ensure that that EIGEN_USING_STD_MATH macro // works properly on the device side - #include + #include #else #define EIGEN_DEVICE_FUNC #endif @@ -155,6 +171,9 @@ #ifdef __AVX512DQ__ #define EIGEN_VECTORIZE_AVX512DQ #endif + #ifdef __AVX512ER__ + #define EIGEN_VECTORIZE_AVX512ER + #endif #endif // include files @@ -229,7 +248,7 @@ #if defined __CUDACC__ #define EIGEN_VECTORIZE_CUDA #include - #if defined __CUDACC_VER__ && __CUDACC_VER__ >= 70500 + #if EIGEN_CUDACC_VER >= 70500 #define EIGEN_HAS_CUDA_FP16 #endif #endif @@ -260,7 +279,10 @@ #include #include #include -#include +#include +#ifndef EIGEN_NO_IO + #include +#endif #include #include #include @@ -321,12 +343,16 @@ inline static const char *SimdInstructionSetsInUse(void) { #error Eigen2-support is only available up to version 3.2. Please go to "http://eigen.tuxfamily.org/index.php?title=Eigen2" for further information #endif +namespace Eigen { + // we use size_t frequently and we'll never remember to prepend it with std:: everytime just to // ensure QNX/QCC support using std::size_t; // gcc 4.6.0 wants std:: for ptrdiff_t using std::ptrdiff_t; +} + /** \defgroup Core_Module Core module * This is the main module of Eigen providing dense matrix and vector support * (both fixed and dynamic size) with all the features corresponding to a BLAS library @@ -348,10 +374,13 @@ using std::ptrdiff_t; #include "src/Core/MathFunctions.h" #include "src/Core/GenericPacketMath.h" #include "src/Core/MathFunctionsImpl.h" +#include "src/Core/arch/Default/ConjHelper.h" #if defined EIGEN_VECTORIZE_AVX512 #include "src/Core/arch/SSE/PacketMath.h" + #include "src/Core/arch/SSE/MathFunctions.h" #include "src/Core/arch/AVX/PacketMath.h" + #include "src/Core/arch/AVX/MathFunctions.h" #include "src/Core/arch/AVX512/PacketMath.h" #include "src/Core/arch/AVX512/MathFunctions.h" #elif defined EIGEN_VECTORIZE_AVX @@ -363,6 +392,7 @@ using std::ptrdiff_t; #include "src/Core/arch/AVX/MathFunctions.h" #include "src/Core/arch/AVX/Complex.h" #include "src/Core/arch/AVX/TypeCasting.h" + #include "src/Core/arch/SSE/TypeCasting.h" #elif defined EIGEN_VECTORIZE_SSE #include "src/Core/arch/SSE/PacketMath.h" #include "src/Core/arch/SSE/MathFunctions.h" @@ -405,6 +435,7 @@ using std::ptrdiff_t; // on CUDA devices #include "src/Core/arch/CUDA/Complex.h" +#include "src/Core/IO.h" #include "src/Core/DenseCoeffsBase.h" #include "src/Core/DenseBase.h" #include "src/Core/MatrixBase.h" @@ -452,7 +483,6 @@ using std::ptrdiff_t; #include "src/Core/Redux.h" #include "src/Core/Visitor.h" #include "src/Core/Fuzzy.h" -#include "src/Core/IO.h" #include "src/Core/Swap.h" #include "src/Core/CommaInitializer.h" #include "src/Core/GeneralProduct.h" diff --git a/eigenlib/Eigen/Eigenvalues b/eigenlib/Eigen/Eigenvalues index 009e529e..7d6ac787 100644 --- a/eigenlib/Eigen/Eigenvalues +++ b/eigenlib/Eigen/Eigenvalues @@ -10,14 +10,14 @@ #include "Core" -#include "src/Core/util/DisableStupidWarnings.h" - #include "Cholesky" #include "Jacobi" #include "Householder" #include "LU" #include "Geometry" +#include "src/Core/util/DisableStupidWarnings.h" + /** \defgroup Eigenvalues_Module Eigenvalues module * * @@ -45,7 +45,11 @@ #include "src/Eigenvalues/GeneralizedEigenSolver.h" #include "src/Eigenvalues/MatrixBaseEigenvalues.h" #ifdef EIGEN_USE_LAPACKE +#ifdef EIGEN_USE_MKL +#include "mkl_lapacke.h" +#else #include "src/misc/lapacke.h" +#endif #include "src/Eigenvalues/RealSchur_LAPACKE.h" #include "src/Eigenvalues/ComplexSchur_LAPACKE.h" #include "src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h" diff --git a/eigenlib/Eigen/Geometry b/eigenlib/Eigen/Geometry index 716d5295..da88c03b 100644 --- a/eigenlib/Eigen/Geometry +++ b/eigenlib/Eigen/Geometry @@ -10,12 +10,12 @@ #include "Core" -#include "src/Core/util/DisableStupidWarnings.h" - #include "SVD" #include "LU" #include +#include "src/Core/util/DisableStupidWarnings.h" + /** \defgroup Geometry_Module Geometry module * * This module provides support for: diff --git a/eigenlib/Eigen/LU b/eigenlib/Eigen/LU index 6f6c5562..6418a86e 100644 --- a/eigenlib/Eigen/LU +++ b/eigenlib/Eigen/LU @@ -28,7 +28,11 @@ #include "src/LU/FullPivLU.h" #include "src/LU/PartialPivLU.h" #ifdef EIGEN_USE_LAPACKE +#ifdef EIGEN_USE_MKL +#include "mkl_lapacke.h" +#else #include "src/misc/lapacke.h" +#endif #include "src/LU/PartialPivLU_LAPACKE.h" #endif #include "src/LU/Determinant.h" diff --git a/eigenlib/Eigen/QR b/eigenlib/Eigen/QR index 80838e3b..1be1863a 100644 --- a/eigenlib/Eigen/QR +++ b/eigenlib/Eigen/QR @@ -10,12 +10,12 @@ #include "Core" -#include "src/Core/util/DisableStupidWarnings.h" - #include "Cholesky" #include "Jacobi" #include "Householder" +#include "src/Core/util/DisableStupidWarnings.h" + /** \defgroup QR_Module QR module * * @@ -36,7 +36,11 @@ #include "src/QR/ColPivHouseholderQR.h" #include "src/QR/CompleteOrthogonalDecomposition.h" #ifdef EIGEN_USE_LAPACKE +#ifdef EIGEN_USE_MKL +#include "mkl_lapacke.h" +#else #include "src/misc/lapacke.h" +#endif #include "src/QR/HouseholderQR_LAPACKE.h" #include "src/QR/ColPivHouseholderQR_LAPACKE.h" #endif diff --git a/eigenlib/Eigen/QtAlignedMalloc b/eigenlib/Eigen/QtAlignedMalloc index 4044d5ac..4f07df02 100644 --- a/eigenlib/Eigen/QtAlignedMalloc +++ b/eigenlib/Eigen/QtAlignedMalloc @@ -14,7 +14,7 @@ #include "src/Core/util/DisableStupidWarnings.h" -void *qMalloc(size_t size) +void *qMalloc(std::size_t size) { return Eigen::internal::aligned_malloc(size); } @@ -24,10 +24,10 @@ void qFree(void *ptr) Eigen::internal::aligned_free(ptr); } -void *qRealloc(void *ptr, size_t size) +void *qRealloc(void *ptr, std::size_t size) { void* newPtr = Eigen::internal::aligned_malloc(size); - memcpy(newPtr, ptr, size); + std::memcpy(newPtr, ptr, size); Eigen::internal::aligned_free(ptr); return newPtr; } diff --git a/eigenlib/Eigen/SVD b/eigenlib/Eigen/SVD index 86143c23..5d0e75f7 100644 --- a/eigenlib/Eigen/SVD +++ b/eigenlib/Eigen/SVD @@ -37,7 +37,11 @@ #include "src/SVD/JacobiSVD.h" #include "src/SVD/BDCSVD.h" #if defined(EIGEN_USE_LAPACKE) && !defined(EIGEN_USE_LAPACKE_STRICT) +#ifdef EIGEN_USE_MKL +#include "mkl_lapacke.h" +#else #include "src/misc/lapacke.h" +#endif #include "src/SVD/JacobiSVD_LAPACKE.h" #endif diff --git a/eigenlib/Eigen/Sparse b/eigenlib/Eigen/Sparse index a2ef7a66..136e681a 100644 --- a/eigenlib/Eigen/Sparse +++ b/eigenlib/Eigen/Sparse @@ -25,7 +25,9 @@ #include "SparseCore" #include "OrderingMethods" +#ifndef EIGEN_MPL2_ONLY #include "SparseCholesky" +#endif #include "SparseLU" #include "SparseQR" #include "IterativeLinearSolvers" diff --git a/eigenlib/Eigen/SparseQR b/eigenlib/Eigen/SparseQR index a6f3b7f7..f5fc5fa7 100644 --- a/eigenlib/Eigen/SparseQR +++ b/eigenlib/Eigen/SparseQR @@ -28,7 +28,6 @@ * */ -#include "OrderingMethods" #include "src/SparseCore/SparseColEtree.h" #include "src/SparseQR/SparseQR.h" diff --git a/eigenlib/Eigen/StdDeque b/eigenlib/Eigen/StdDeque index be3a7f82..bc68397b 100644 --- a/eigenlib/Eigen/StdDeque +++ b/eigenlib/Eigen/StdDeque @@ -14,7 +14,7 @@ #include "Core" #include -#if EIGEN_COMP_MSVC && EIGEN_OS_WIN64 /* MSVC auto aligns in 64 bit builds */ +#if EIGEN_COMP_MSVC && EIGEN_OS_WIN64 && (EIGEN_MAX_STATIC_ALIGN_BYTES<=16) /* MSVC auto aligns up to 16 bytes in 64 bit builds */ #define EIGEN_DEFINE_STL_DEQUE_SPECIALIZATION(...) diff --git a/eigenlib/Eigen/StdList b/eigenlib/Eigen/StdList index 07ba1297..4c6262c0 100644 --- a/eigenlib/Eigen/StdList +++ b/eigenlib/Eigen/StdList @@ -13,7 +13,7 @@ #include "Core" #include -#if EIGEN_COMP_MSVC && EIGEN_OS_WIN64 /* MSVC auto aligns in 64 bit builds */ +#if EIGEN_COMP_MSVC && EIGEN_OS_WIN64 && (EIGEN_MAX_STATIC_ALIGN_BYTES<=16) /* MSVC auto aligns up to 16 bytes in 64 bit builds */ #define EIGEN_DEFINE_STL_LIST_SPECIALIZATION(...) diff --git a/eigenlib/Eigen/StdVector b/eigenlib/Eigen/StdVector index fdfc3776..0c4697ad 100644 --- a/eigenlib/Eigen/StdVector +++ b/eigenlib/Eigen/StdVector @@ -14,7 +14,7 @@ #include "Core" #include -#if EIGEN_COMP_MSVC && EIGEN_OS_WIN64 /* MSVC auto aligns in 64 bit builds */ +#if EIGEN_COMP_MSVC && EIGEN_OS_WIN64 && (EIGEN_MAX_STATIC_ALIGN_BYTES<=16) /* MSVC auto aligns up to 16 bytes in 64 bit builds */ #define EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(...) diff --git a/eigenlib/Eigen/src/Cholesky/LDLT.h b/eigenlib/Eigen/src/Cholesky/LDLT.h index fcee7b2e..15ccf24f 100644 --- a/eigenlib/Eigen/src/Cholesky/LDLT.h +++ b/eigenlib/Eigen/src/Cholesky/LDLT.h @@ -248,7 +248,7 @@ template class LDLT /** \brief Reports whether previous computation was successful. * * \returns \c Success if computation was succesful, - * \c NumericalIssue if the matrix.appears to be negative. + * \c NumericalIssue if the factorization failed because of a zero pivot. */ ComputationInfo info() const { @@ -305,7 +305,8 @@ template<> struct ldlt_inplace if (size <= 1) { transpositions.setIdentity(); - if (numext::real(mat.coeff(0,0)) > static_cast(0) ) sign = PositiveSemiDef; + if(size==0) sign = ZeroSign; + else if (numext::real(mat.coeff(0,0)) > static_cast(0) ) sign = PositiveSemiDef; else if (numext::real(mat.coeff(0,0)) < static_cast(0)) sign = NegativeSemiDef; else sign = ZeroSign; return true; @@ -376,6 +377,8 @@ template<> struct ldlt_inplace if((rs>0) && pivot_is_valid) A21 /= realAkk; + else if(rs>0) + ret = ret && (A21.array()==Scalar(0)).all(); if(found_zero_pivot && pivot_is_valid) ret = false; // factorization failed else if(!pivot_is_valid) found_zero_pivot = true; @@ -568,13 +571,14 @@ void LDLT<_MatrixType,_UpLo>::_solve_impl(const RhsType &rhs, DstType &dst) cons // more precisely, use pseudo-inverse of D (see bug 241) using std::abs; const typename Diagonal::RealReturnType vecD(vectorD()); - // In some previous versions, tolerance was set to the max of 1/highest and the maximal diagonal entry * epsilon - // as motivated by LAPACK's xGELSS: + // In some previous versions, tolerance was set to the max of 1/highest (or rather numeric_limits::min()) + // and the maximal diagonal entry * epsilon as motivated by LAPACK's xGELSS: // RealScalar tolerance = numext::maxi(vecD.array().abs().maxCoeff() * NumTraits::epsilon(),RealScalar(1) / NumTraits::highest()); // However, LDLT is not rank revealing, and so adjusting the tolerance wrt to the highest // diagonal element is not well justified and leads to numerical issues in some cases. // Moreover, Lapack's xSYTRS routines use 0 for the tolerance. - RealScalar tolerance = RealScalar(1) / NumTraits::highest(); + // Using numeric_limits::min() gives us more robustness to denormals. + RealScalar tolerance = (std::numeric_limits::min)(); for (Index i = 0; i < vecD.size(); ++i) { diff --git a/eigenlib/Eigen/src/Cholesky/LLT.h b/eigenlib/Eigen/src/Cholesky/LLT.h index 87ca8d42..e1624d21 100644 --- a/eigenlib/Eigen/src/Cholesky/LLT.h +++ b/eigenlib/Eigen/src/Cholesky/LLT.h @@ -24,7 +24,7 @@ template struct LLT_Traits; * * \tparam _MatrixType the type of the matrix of which we are computing the LL^T Cholesky decomposition * \tparam _UpLo the triangular part that will be used for the decompositon: Lower (default) or Upper. - * The other triangular part won't be read. + * The other triangular part won't be read. * * This class performs a LL^T Cholesky decomposition of a symmetric, positive definite * matrix A such that A = LL^* = U^*U, where L is lower triangular. @@ -41,14 +41,18 @@ template struct LLT_Traits; * Example: \include LLT_example.cpp * Output: \verbinclude LLT_example.out * + * \b Performance: for best performance, it is recommended to use a column-major storage format + * with the Lower triangular part (the default), or, equivalently, a row-major storage format + * with the Upper triangular part. Otherwise, you might get a 20% slowdown for the full factorization + * step, and rank-updates can be up to 3 times slower. + * * This class supports the \link InplaceDecomposition inplace decomposition \endlink mechanism. * + * Note that during the decomposition, only the lower (or upper, as defined by _UpLo) triangular part of A is considered. + * Therefore, the strict lower part does not have to store correct values. + * * \sa MatrixBase::llt(), SelfAdjointView::llt(), class LDLT */ - /* HEY THIS DOX IS DISABLED BECAUSE THERE's A BUG EITHER HERE OR IN LDLT ABOUT THAT (OR BOTH) - * Note that during the decomposition, only the upper triangular part of A is considered. Therefore, - * the strict lower part does not have to store correct values. - */ template class LLT { public: @@ -146,7 +150,7 @@ template class LLT } template - void solveInPlace(MatrixBase &bAndX) const; + void solveInPlace(const MatrixBase &bAndX) const; template LLT& compute(const EigenBase& matrix); @@ -177,7 +181,7 @@ template class LLT /** \brief Reports whether previous computation was successful. * * \returns \c Success if computation was succesful, - * \c NumericalIssue if the matrix.appears to be negative. + * \c NumericalIssue if the matrix.appears not to be positive definite. */ ComputationInfo info() const { @@ -425,7 +429,8 @@ LLT& LLT::compute(const EigenBase eigen_assert(a.rows()==a.cols()); const Index size = a.rows(); m_matrix.resize(size, size); - m_matrix = a.derived(); + if (!internal::is_same_dense(m_matrix, a.derived())) + m_matrix = a.derived(); // Compute matrix L1 norm = max abs column sum. m_l1_norm = RealScalar(0); @@ -485,11 +490,14 @@ void LLT<_MatrixType,_UpLo>::_solve_impl(const RhsType &rhs, DstType &dst) const * * This version avoids a copy when the right hand side matrix b is not needed anymore. * + * \warning The parameter is only marked 'const' to make the C++ compiler accept a temporary expression here. + * This function will const_cast it, so constness isn't honored here. + * * \sa LLT::solve(), MatrixBase::llt() */ template template -void LLT::solveInPlace(MatrixBase &bAndX) const +void LLT::solveInPlace(const MatrixBase &bAndX) const { eigen_assert(m_isInitialized && "LLT is not initialized."); eigen_assert(m_matrix.rows()==bAndX.rows()); diff --git a/eigenlib/Eigen/src/Core/Array.h b/eigenlib/Eigen/src/Core/Array.h index 0d34269f..16770fc7 100644 --- a/eigenlib/Eigen/src/Core/Array.h +++ b/eigenlib/Eigen/src/Core/Array.h @@ -153,8 +153,6 @@ class Array : Base(std::move(other)) { Base::_check_template_params(); - if (RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic) - Base::_set_noalias(other); } EIGEN_DEVICE_FUNC Array& operator=(Array&& other) EIGEN_NOEXCEPT_IF(std::is_nothrow_move_assignable::value) @@ -231,10 +229,16 @@ class Array : Base(other) { } + private: + struct PrivateType {}; + public: + /** \sa MatrixBase::operator=(const EigenBase&) */ template EIGEN_DEVICE_FUNC - EIGEN_STRONG_INLINE Array(const EigenBase &other) + EIGEN_STRONG_INLINE Array(const EigenBase &other, + typename internal::enable_if::value, + PrivateType>::type = PrivateType()) : Base(other.derived()) { } diff --git a/eigenlib/Eigen/src/Core/ArrayBase.h b/eigenlib/Eigen/src/Core/ArrayBase.h index f0232f65..33f644e2 100644 --- a/eigenlib/Eigen/src/Core/ArrayBase.h +++ b/eigenlib/Eigen/src/Core/ArrayBase.h @@ -153,8 +153,8 @@ template class ArrayBase // inline void evalTo(Dest& dst) const { dst = matrix(); } protected: - EIGEN_DEVICE_FUNC - ArrayBase() : Base() {} + EIGEN_DEFAULT_COPY_CONSTRUCTOR(ArrayBase) + EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(ArrayBase) private: explicit ArrayBase(Index); @@ -175,7 +175,7 @@ template class ArrayBase */ template template -EIGEN_STRONG_INLINE Derived & +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived & ArrayBase::operator-=(const ArrayBase &other) { call_assignment(derived(), other.derived(), internal::sub_assign_op()); @@ -188,7 +188,7 @@ ArrayBase::operator-=(const ArrayBase &other) */ template template -EIGEN_STRONG_INLINE Derived & +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived & ArrayBase::operator+=(const ArrayBase& other) { call_assignment(derived(), other.derived(), internal::add_assign_op()); @@ -201,7 +201,7 @@ ArrayBase::operator+=(const ArrayBase& other) */ template template -EIGEN_STRONG_INLINE Derived & +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived & ArrayBase::operator*=(const ArrayBase& other) { call_assignment(derived(), other.derived(), internal::mul_assign_op()); @@ -214,7 +214,7 @@ ArrayBase::operator*=(const ArrayBase& other) */ template template -EIGEN_STRONG_INLINE Derived & +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived & ArrayBase::operator/=(const ArrayBase& other) { call_assignment(derived(), other.derived(), internal::div_assign_op()); diff --git a/eigenlib/Eigen/src/Core/ArrayWrapper.h b/eigenlib/Eigen/src/Core/ArrayWrapper.h index a04521a1..688aadd6 100644 --- a/eigenlib/Eigen/src/Core/ArrayWrapper.h +++ b/eigenlib/Eigen/src/Core/ArrayWrapper.h @@ -32,7 +32,8 @@ struct traits > // Let's remove NestByRefBit enum { Flags0 = traits::type >::Flags, - Flags = Flags0 & ~NestByRefBit + LvalueBitFlag = is_lvalue::value ? LvalueBit : 0, + Flags = (Flags0 & ~(NestByRefBit | LvalueBit)) | LvalueBitFlag }; }; } @@ -129,7 +130,8 @@ struct traits > // Let's remove NestByRefBit enum { Flags0 = traits::type >::Flags, - Flags = Flags0 & ~NestByRefBit + LvalueBitFlag = is_lvalue::value ? LvalueBit : 0, + Flags = (Flags0 & ~(NestByRefBit | LvalueBit)) | LvalueBitFlag }; }; } diff --git a/eigenlib/Eigen/src/Core/AssignEvaluator.h b/eigenlib/Eigen/src/Core/AssignEvaluator.h index 14400d24..dbe435d8 100644 --- a/eigenlib/Eigen/src/Core/AssignEvaluator.h +++ b/eigenlib/Eigen/src/Core/AssignEvaluator.h @@ -39,7 +39,7 @@ public: enum { DstAlignment = DstEvaluator::Alignment, SrcAlignment = SrcEvaluator::Alignment, - DstHasDirectAccess = DstFlags & DirectAccessBit, + DstHasDirectAccess = (DstFlags & DirectAccessBit) == DirectAccessBit, JointAlignment = EIGEN_PLAIN_ENUM_MIN(DstAlignment,SrcAlignment) }; @@ -83,7 +83,7 @@ private: && int(OuterStride)!=Dynamic && int(OuterStride)%int(InnerPacketSize)==0 && (EIGEN_UNALIGNED_VECTORIZE || int(JointAlignment)>=int(InnerRequiredAlignment)), MayLinearize = bool(StorageOrdersAgree) && (int(DstFlags) & int(SrcFlags) & LinearAccessBit), - MayLinearVectorize = bool(MightVectorize) && MayLinearize && DstHasDirectAccess + MayLinearVectorize = bool(MightVectorize) && bool(MayLinearize) && bool(DstHasDirectAccess) && (EIGEN_UNALIGNED_VECTORIZE || (int(DstAlignment)>=int(LinearRequiredAlignment)) || MaxSizeAtCompileTime == Dynamic), /* If the destination isn't aligned, we have to do runtime checks and we don't unroll, so it's only good for large enough sizes. */ @@ -515,7 +515,7 @@ struct dense_assignment_loop template struct dense_assignment_loop { - EIGEN_DEVICE_FUNC static inline void run(Kernel &kernel) + EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel) { typedef typename Kernel::Scalar Scalar; typedef typename Kernel::PacketType PacketType; @@ -563,7 +563,7 @@ struct dense_assignment_loop template struct dense_assignment_loop { - EIGEN_DEVICE_FUNC static inline void run(Kernel &kernel) + EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE void run(Kernel &kernel) { typedef typename Kernel::DstEvaluatorType::XprType DstXprType; typedef typename Kernel::PacketType PacketType; @@ -701,6 +701,26 @@ protected: * Part 5 : Entry point for dense rectangular assignment ***************************************************************************/ +template +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE +void resize_if_allowed(DstXprType &dst, const SrcXprType& src, const Functor &/*func*/) +{ + EIGEN_ONLY_USED_FOR_DEBUG(dst); + EIGEN_ONLY_USED_FOR_DEBUG(src); + eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols()); +} + +template +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE +void resize_if_allowed(DstXprType &dst, const SrcXprType& src, const internal::assign_op &/*func*/) +{ + Index dstRows = src.rows(); + Index dstCols = src.cols(); + if(((dst.rows()!=dstRows) || (dst.cols()!=dstCols))) + dst.resize(dstRows, dstCols); + eigen_assert(dst.rows() == dstRows && dst.cols() == dstCols); +} + template EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void call_dense_assignment_loop(DstXprType& dst, const SrcXprType& src, const Functor &func) { @@ -711,10 +731,7 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void call_dense_assignment_loop(DstXprType // NOTE To properly handle A = (A*A.transpose())/s with A rectangular, // we need to resize the destination after the source evaluator has been created. - Index dstRows = src.rows(); - Index dstCols = src.cols(); - if((dst.rows()!=dstRows) || (dst.cols()!=dstCols)) - dst.resize(dstRows, dstCols); + resize_if_allowed(dst, src, func); DstEvaluatorType dstEvaluator(dst); diff --git a/eigenlib/Eigen/src/Core/Assign_MKL.h b/eigenlib/Eigen/src/Core/Assign_MKL.h index 6c2ab926..6866095b 100755 --- a/eigenlib/Eigen/src/Core/Assign_MKL.h +++ b/eigenlib/Eigen/src/Core/Assign_MKL.h @@ -84,7 +84,8 @@ class vml_assign_traits struct Assignment, SrcXprNested>, assign_op, \ Dense2Dense, typename enable_if::EnableVml>::type> { \ typedef CwiseUnaryOp, SrcXprNested> SrcXprType; \ - static void run(DstXprType &dst, const SrcXprType &src, const assign_op &/*func*/) { \ + static void run(DstXprType &dst, const SrcXprType &src, const assign_op &func) { \ + resize_if_allowed(dst, src, func); \ eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols()); \ if(vml_assign_traits::Traversal==LinearTraversal) { \ VMLOP(dst.size(), (const VMLTYPE*)src.nestedExpression().data(), \ @@ -144,7 +145,8 @@ EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(ceil, Ceil, _) Dense2Dense, typename enable_if::EnableVml>::type> { \ typedef CwiseBinaryOp, SrcXprNested, \ const CwiseNullaryOp,Plain> > SrcXprType; \ - static void run(DstXprType &dst, const SrcXprType &src, const assign_op &/*func*/) { \ + static void run(DstXprType &dst, const SrcXprType &src, const assign_op &func) { \ + resize_if_allowed(dst, src, func); \ eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols()); \ VMLTYPE exponent = reinterpret_cast(src.rhs().functor().m_other); \ if(vml_assign_traits::Traversal==LinearTraversal) \ diff --git a/eigenlib/Eigen/src/Core/ConditionEstimator.h b/eigenlib/Eigen/src/Core/ConditionEstimator.h index aa7efdc7..51a2e5f1 100644 --- a/eigenlib/Eigen/src/Core/ConditionEstimator.h +++ b/eigenlib/Eigen/src/Core/ConditionEstimator.h @@ -160,7 +160,7 @@ rcond_estimate_helper(typename Decomposition::RealScalar matrix_norm, const Deco { typedef typename Decomposition::RealScalar RealScalar; eigen_assert(dec.rows() == dec.cols()); - if (dec.rows() == 0) return RealScalar(1); + if (dec.rows() == 0) return NumTraits::infinity(); if (matrix_norm == RealScalar(0)) return RealScalar(0); if (dec.rows() == 1) return RealScalar(1); const RealScalar inverse_matrix_norm = rcond_invmatrix_L1_norm_estimate(dec); diff --git a/eigenlib/Eigen/src/Core/CoreEvaluators.h b/eigenlib/Eigen/src/Core/CoreEvaluators.h index 1d14af65..910889ef 100644 --- a/eigenlib/Eigen/src/Core/CoreEvaluators.h +++ b/eigenlib/Eigen/src/Core/CoreEvaluators.h @@ -977,7 +977,7 @@ struct evaluator > OuterStrideAtCompileTime = HasSameStorageOrderAsArgType ? int(outer_stride_at_compile_time::ret) : int(inner_stride_at_compile_time::ret), - MaskPacketAccessBit = (InnerStrideAtCompileTime == 1) ? PacketAccessBit : 0, + MaskPacketAccessBit = (InnerStrideAtCompileTime == 1 || HasSameStorageOrderAsArgType) ? PacketAccessBit : 0, FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1 || (InnerPanel && (evaluator::Flags&LinearAccessBit))) ? LinearAccessBit : 0, FlagsRowMajorBit = XprType::Flags&RowMajorBit, @@ -987,7 +987,9 @@ struct evaluator > Flags = Flags0 | FlagsLinearAccessBit | FlagsRowMajorBit, PacketAlignment = unpacket_traits::alignment, - Alignment0 = (InnerPanel && (OuterStrideAtCompileTime!=Dynamic) && (((OuterStrideAtCompileTime * int(sizeof(Scalar))) % int(PacketAlignment)) == 0)) ? int(PacketAlignment) : 0, + Alignment0 = (InnerPanel && (OuterStrideAtCompileTime!=Dynamic) + && (OuterStrideAtCompileTime!=0) + && (((OuterStrideAtCompileTime * int(sizeof(Scalar))) % int(PacketAlignment)) == 0)) ? int(PacketAlignment) : 0, Alignment = EIGEN_PLAIN_ENUM_MIN(evaluator::Alignment, Alignment0) }; typedef block_evaluator block_evaluator_type; @@ -1018,14 +1020,16 @@ struct unary_evaluator, IndexBa EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& block) : m_argImpl(block.nestedExpression()), m_startRow(block.startRow()), - m_startCol(block.startCol()) + m_startCol(block.startCol()), + m_linear_offset(InnerPanel?(XprType::IsRowMajor ? block.startRow()*block.cols() : block.startCol()*block.rows()):0) { } typedef typename XprType::Scalar Scalar; typedef typename XprType::CoeffReturnType CoeffReturnType; enum { - RowsAtCompileTime = XprType::RowsAtCompileTime + RowsAtCompileTime = XprType::RowsAtCompileTime, + ForwardLinearAccess = InnerPanel && bool(evaluator::Flags&LinearAccessBit) }; EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE @@ -1037,7 +1041,10 @@ struct unary_evaluator, IndexBa EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const { - return coeff(RowsAtCompileTime == 1 ? 0 : index, RowsAtCompileTime == 1 ? index : 0); + if (ForwardLinearAccess) + return m_argImpl.coeff(m_linear_offset.value() + index); + else + return coeff(RowsAtCompileTime == 1 ? 0 : index, RowsAtCompileTime == 1 ? index : 0); } EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE @@ -1049,7 +1056,10 @@ struct unary_evaluator, IndexBa EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(Index index) { - return coeffRef(RowsAtCompileTime == 1 ? 0 : index, RowsAtCompileTime == 1 ? index : 0); + if (ForwardLinearAccess) + return m_argImpl.coeffRef(m_linear_offset.value() + index); + else + return coeffRef(RowsAtCompileTime == 1 ? 0 : index, RowsAtCompileTime == 1 ? index : 0); } template @@ -1063,8 +1073,11 @@ struct unary_evaluator, IndexBa EIGEN_STRONG_INLINE PacketType packet(Index index) const { - return packet(RowsAtCompileTime == 1 ? 0 : index, - RowsAtCompileTime == 1 ? index : 0); + if (ForwardLinearAccess) + return m_argImpl.template packet(m_linear_offset.value() + index); + else + return packet(RowsAtCompileTime == 1 ? 0 : index, + RowsAtCompileTime == 1 ? index : 0); } template @@ -1078,15 +1091,19 @@ struct unary_evaluator, IndexBa EIGEN_STRONG_INLINE void writePacket(Index index, const PacketType& x) { - return writePacket(RowsAtCompileTime == 1 ? 0 : index, - RowsAtCompileTime == 1 ? index : 0, - x); + if (ForwardLinearAccess) + return m_argImpl.template writePacket(m_linear_offset.value() + index, x); + else + return writePacket(RowsAtCompileTime == 1 ? 0 : index, + RowsAtCompileTime == 1 ? index : 0, + x); } protected: evaluator m_argImpl; const variable_if_dynamic m_startRow; const variable_if_dynamic m_startCol; + const variable_if_dynamic m_linear_offset; }; // TODO: This evaluator does not actually use the child evaluator; @@ -1556,9 +1573,7 @@ struct evaluator > { } typedef typename XprType::Scalar Scalar; - // FIXME having to check whether ArgType is sparse here i not very nice. - typedef typename internal::conditional::value, - typename XprType::CoeffReturnType,Scalar>::type CoeffReturnType; + typedef typename XprType::CoeffReturnType CoeffReturnType; EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index) const diff --git a/eigenlib/Eigen/src/Core/CwiseNullaryOp.h b/eigenlib/Eigen/src/Core/CwiseNullaryOp.h index dd498f75..ddd607e3 100644 --- a/eigenlib/Eigen/src/Core/CwiseNullaryOp.h +++ b/eigenlib/Eigen/src/Core/CwiseNullaryOp.h @@ -105,7 +105,7 @@ class CwiseNullaryOp : public internal::dense_xpr_base< CwiseNullaryOp template -EIGEN_STRONG_INLINE const CwiseNullaryOp::PlainObject> +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CwiseNullaryOp::PlainObject> DenseBase::NullaryExpr(Index rows, Index cols, const CustomNullaryOp& func) { return CwiseNullaryOp(rows, cols, func); @@ -150,7 +150,7 @@ DenseBase::NullaryExpr(Index size, const CustomNullaryOp& func) */ template template -EIGEN_STRONG_INLINE const CwiseNullaryOp::PlainObject> +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CwiseNullaryOp::PlainObject> DenseBase::NullaryExpr(const CustomNullaryOp& func) { return CwiseNullaryOp(RowsAtCompileTime, ColsAtCompileTime, func); @@ -192,7 +192,7 @@ DenseBase::Constant(Index rows, Index cols, const Scalar& value) * \sa class CwiseNullaryOp */ template -EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType DenseBase::Constant(Index size, const Scalar& value) { return DenseBase::NullaryExpr(size, internal::scalar_constant_op(value)); @@ -208,7 +208,7 @@ DenseBase::Constant(Index size, const Scalar& value) * \sa class CwiseNullaryOp */ template -EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType DenseBase::Constant(const Scalar& value) { EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived) @@ -220,7 +220,7 @@ DenseBase::Constant(const Scalar& value) * \sa LinSpaced(Index,Scalar,Scalar), setLinSpaced(Index,const Scalar&,const Scalar&) */ template -EIGEN_STRONG_INLINE const typename DenseBase::RandomAccessLinSpacedReturnType +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase::RandomAccessLinSpacedReturnType DenseBase::LinSpaced(Sequential_t, Index size, const Scalar& low, const Scalar& high) { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) @@ -232,7 +232,7 @@ DenseBase::LinSpaced(Sequential_t, Index size, const Scalar& low, const * \sa LinSpaced(Scalar,Scalar) */ template -EIGEN_STRONG_INLINE const typename DenseBase::RandomAccessLinSpacedReturnType +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase::RandomAccessLinSpacedReturnType DenseBase::LinSpaced(Sequential_t, const Scalar& low, const Scalar& high) { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) @@ -264,7 +264,7 @@ DenseBase::LinSpaced(Sequential_t, const Scalar& low, const Scalar& hig * \sa setLinSpaced(Index,const Scalar&,const Scalar&), CwiseNullaryOp */ template -EIGEN_STRONG_INLINE const typename DenseBase::RandomAccessLinSpacedReturnType +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase::RandomAccessLinSpacedReturnType DenseBase::LinSpaced(Index size, const Scalar& low, const Scalar& high) { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) @@ -276,7 +276,7 @@ DenseBase::LinSpaced(Index size, const Scalar& low, const Scalar& high) * Special version for fixed size types which does not require the size parameter. */ template -EIGEN_STRONG_INLINE const typename DenseBase::RandomAccessLinSpacedReturnType +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase::RandomAccessLinSpacedReturnType DenseBase::LinSpaced(const Scalar& low, const Scalar& high) { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) @@ -286,7 +286,7 @@ DenseBase::LinSpaced(const Scalar& low, const Scalar& high) /** \returns true if all coefficients in this matrix are approximately equal to \a val, to within precision \a prec */ template -bool DenseBase::isApproxToConstant +EIGEN_DEVICE_FUNC bool DenseBase::isApproxToConstant (const Scalar& val, const RealScalar& prec) const { typename internal::nested_eval::type self(derived()); @@ -301,7 +301,7 @@ bool DenseBase::isApproxToConstant * * \returns true if all coefficients in this matrix are approximately equal to \a value, to within precision \a prec */ template -bool DenseBase::isConstant +EIGEN_DEVICE_FUNC bool DenseBase::isConstant (const Scalar& val, const RealScalar& prec) const { return isApproxToConstant(val, prec); @@ -312,7 +312,7 @@ bool DenseBase::isConstant * \sa setConstant(), Constant(), class CwiseNullaryOp */ template -EIGEN_STRONG_INLINE void DenseBase::fill(const Scalar& val) +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void DenseBase::fill(const Scalar& val) { setConstant(val); } @@ -322,7 +322,7 @@ EIGEN_STRONG_INLINE void DenseBase::fill(const Scalar& val) * \sa fill(), setConstant(Index,const Scalar&), setConstant(Index,Index,const Scalar&), setZero(), setOnes(), Constant(), class CwiseNullaryOp, setZero(), setOnes() */ template -EIGEN_STRONG_INLINE Derived& DenseBase::setConstant(const Scalar& val) +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase::setConstant(const Scalar& val) { return derived() = Constant(rows(), cols(), val); } @@ -337,7 +337,7 @@ EIGEN_STRONG_INLINE Derived& DenseBase::setConstant(const Scalar& val) * \sa MatrixBase::setConstant(const Scalar&), setConstant(Index,Index,const Scalar&), class CwiseNullaryOp, MatrixBase::Constant(const Scalar&) */ template -EIGEN_STRONG_INLINE Derived& +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& PlainObjectBase::setConstant(Index size, const Scalar& val) { resize(size); @@ -356,7 +356,7 @@ PlainObjectBase::setConstant(Index size, const Scalar& val) * \sa MatrixBase::setConstant(const Scalar&), setConstant(Index,const Scalar&), class CwiseNullaryOp, MatrixBase::Constant(const Scalar&) */ template -EIGEN_STRONG_INLINE Derived& +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& PlainObjectBase::setConstant(Index rows, Index cols, const Scalar& val) { resize(rows, cols); @@ -380,7 +380,7 @@ PlainObjectBase::setConstant(Index rows, Index cols, const Scalar& val) * \sa LinSpaced(Index,const Scalar&,const Scalar&), CwiseNullaryOp */ template -EIGEN_STRONG_INLINE Derived& DenseBase::setLinSpaced(Index newSize, const Scalar& low, const Scalar& high) +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase::setLinSpaced(Index newSize, const Scalar& low, const Scalar& high) { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) return derived() = Derived::NullaryExpr(newSize, internal::linspaced_op(low,high,newSize)); @@ -400,7 +400,7 @@ EIGEN_STRONG_INLINE Derived& DenseBase::setLinSpaced(Index newSize, con * \sa LinSpaced(Index,const Scalar&,const Scalar&), setLinSpaced(Index, const Scalar&, const Scalar&), CwiseNullaryOp */ template -EIGEN_STRONG_INLINE Derived& DenseBase::setLinSpaced(const Scalar& low, const Scalar& high) +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase::setLinSpaced(const Scalar& low, const Scalar& high) { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) return setLinSpaced(size(), low, high); @@ -423,7 +423,7 @@ EIGEN_STRONG_INLINE Derived& DenseBase::setLinSpaced(const Scalar& low, * \sa Zero(), Zero(Index) */ template -EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType DenseBase::Zero(Index rows, Index cols) { return Constant(rows, cols, Scalar(0)); @@ -446,7 +446,7 @@ DenseBase::Zero(Index rows, Index cols) * \sa Zero(), Zero(Index,Index) */ template -EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType DenseBase::Zero(Index size) { return Constant(size, Scalar(0)); @@ -463,7 +463,7 @@ DenseBase::Zero(Index size) * \sa Zero(Index), Zero(Index,Index) */ template -EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType DenseBase::Zero() { return Constant(Scalar(0)); @@ -478,7 +478,7 @@ DenseBase::Zero() * \sa class CwiseNullaryOp, Zero() */ template -bool DenseBase::isZero(const RealScalar& prec) const +EIGEN_DEVICE_FUNC bool DenseBase::isZero(const RealScalar& prec) const { typename internal::nested_eval::type self(derived()); for(Index j = 0; j < cols(); ++j) @@ -496,7 +496,7 @@ bool DenseBase::isZero(const RealScalar& prec) const * \sa class CwiseNullaryOp, Zero() */ template -EIGEN_STRONG_INLINE Derived& DenseBase::setZero() +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase::setZero() { return setConstant(Scalar(0)); } @@ -511,7 +511,7 @@ EIGEN_STRONG_INLINE Derived& DenseBase::setZero() * \sa DenseBase::setZero(), setZero(Index,Index), class CwiseNullaryOp, DenseBase::Zero() */ template -EIGEN_STRONG_INLINE Derived& +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& PlainObjectBase::setZero(Index newSize) { resize(newSize); @@ -529,7 +529,7 @@ PlainObjectBase::setZero(Index newSize) * \sa DenseBase::setZero(), setZero(Index), class CwiseNullaryOp, DenseBase::Zero() */ template -EIGEN_STRONG_INLINE Derived& +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& PlainObjectBase::setZero(Index rows, Index cols) { resize(rows, cols); @@ -553,7 +553,7 @@ PlainObjectBase::setZero(Index rows, Index cols) * \sa Ones(), Ones(Index), isOnes(), class Ones */ template -EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType DenseBase::Ones(Index rows, Index cols) { return Constant(rows, cols, Scalar(1)); @@ -576,7 +576,7 @@ DenseBase::Ones(Index rows, Index cols) * \sa Ones(), Ones(Index,Index), isOnes(), class Ones */ template -EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType DenseBase::Ones(Index newSize) { return Constant(newSize, Scalar(1)); @@ -593,7 +593,7 @@ DenseBase::Ones(Index newSize) * \sa Ones(Index), Ones(Index,Index), isOnes(), class Ones */ template -EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase::ConstantReturnType DenseBase::Ones() { return Constant(Scalar(1)); @@ -608,7 +608,7 @@ DenseBase::Ones() * \sa class CwiseNullaryOp, Ones() */ template -bool DenseBase::isOnes +EIGEN_DEVICE_FUNC bool DenseBase::isOnes (const RealScalar& prec) const { return isApproxToConstant(Scalar(1), prec); @@ -622,7 +622,7 @@ bool DenseBase::isOnes * \sa class CwiseNullaryOp, Ones() */ template -EIGEN_STRONG_INLINE Derived& DenseBase::setOnes() +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase::setOnes() { return setConstant(Scalar(1)); } @@ -637,7 +637,7 @@ EIGEN_STRONG_INLINE Derived& DenseBase::setOnes() * \sa MatrixBase::setOnes(), setOnes(Index,Index), class CwiseNullaryOp, MatrixBase::Ones() */ template -EIGEN_STRONG_INLINE Derived& +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& PlainObjectBase::setOnes(Index newSize) { resize(newSize); @@ -655,7 +655,7 @@ PlainObjectBase::setOnes(Index newSize) * \sa MatrixBase::setOnes(), setOnes(Index), class CwiseNullaryOp, MatrixBase::Ones() */ template -EIGEN_STRONG_INLINE Derived& +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& PlainObjectBase::setOnes(Index rows, Index cols) { resize(rows, cols); @@ -679,7 +679,7 @@ PlainObjectBase::setOnes(Index rows, Index cols) * \sa Identity(), setIdentity(), isIdentity() */ template -EIGEN_STRONG_INLINE const typename MatrixBase::IdentityReturnType +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase::IdentityReturnType MatrixBase::Identity(Index rows, Index cols) { return DenseBase::NullaryExpr(rows, cols, internal::scalar_identity_op()); @@ -696,7 +696,7 @@ MatrixBase::Identity(Index rows, Index cols) * \sa Identity(Index,Index), setIdentity(), isIdentity() */ template -EIGEN_STRONG_INLINE const typename MatrixBase::IdentityReturnType +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase::IdentityReturnType MatrixBase::Identity() { EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived) @@ -771,7 +771,7 @@ struct setIdentity_impl * \sa class CwiseNullaryOp, Identity(), Identity(Index,Index), isIdentity() */ template -EIGEN_STRONG_INLINE Derived& MatrixBase::setIdentity() +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& MatrixBase::setIdentity() { return internal::setIdentity_impl::run(derived()); } @@ -787,7 +787,7 @@ EIGEN_STRONG_INLINE Derived& MatrixBase::setIdentity() * \sa MatrixBase::setIdentity(), class CwiseNullaryOp, MatrixBase::Identity() */ template -EIGEN_STRONG_INLINE Derived& MatrixBase::setIdentity(Index rows, Index cols) +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& MatrixBase::setIdentity(Index rows, Index cols) { derived().resize(rows, cols); return setIdentity(); @@ -800,7 +800,7 @@ EIGEN_STRONG_INLINE Derived& MatrixBase::setIdentity(Index rows, Index * \sa MatrixBase::Unit(Index), MatrixBase::UnitX(), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW() */ template -EIGEN_STRONG_INLINE const typename MatrixBase::BasisReturnType MatrixBase::Unit(Index newSize, Index i) +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase::BasisReturnType MatrixBase::Unit(Index newSize, Index i) { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) return BasisReturnType(SquareMatrixType::Identity(newSize,newSize), i); @@ -815,7 +815,7 @@ EIGEN_STRONG_INLINE const typename MatrixBase::BasisReturnType MatrixBa * \sa MatrixBase::Unit(Index,Index), MatrixBase::UnitX(), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW() */ template -EIGEN_STRONG_INLINE const typename MatrixBase::BasisReturnType MatrixBase::Unit(Index i) +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase::BasisReturnType MatrixBase::Unit(Index i) { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) return BasisReturnType(SquareMatrixType::Identity(),i); @@ -828,7 +828,7 @@ EIGEN_STRONG_INLINE const typename MatrixBase::BasisReturnType MatrixBa * \sa MatrixBase::Unit(Index,Index), MatrixBase::Unit(Index), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW() */ template -EIGEN_STRONG_INLINE const typename MatrixBase::BasisReturnType MatrixBase::UnitX() +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase::BasisReturnType MatrixBase::UnitX() { return Derived::Unit(0); } /** \returns an expression of the Y axis unit vector (0,1{,0}^*) @@ -838,7 +838,7 @@ EIGEN_STRONG_INLINE const typename MatrixBase::BasisReturnType MatrixBa * \sa MatrixBase::Unit(Index,Index), MatrixBase::Unit(Index), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW() */ template -EIGEN_STRONG_INLINE const typename MatrixBase::BasisReturnType MatrixBase::UnitY() +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase::BasisReturnType MatrixBase::UnitY() { return Derived::Unit(1); } /** \returns an expression of the Z axis unit vector (0,0,1{,0}^*) @@ -848,7 +848,7 @@ EIGEN_STRONG_INLINE const typename MatrixBase::BasisReturnType MatrixBa * \sa MatrixBase::Unit(Index,Index), MatrixBase::Unit(Index), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW() */ template -EIGEN_STRONG_INLINE const typename MatrixBase::BasisReturnType MatrixBase::UnitZ() +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase::BasisReturnType MatrixBase::UnitZ() { return Derived::Unit(2); } /** \returns an expression of the W axis unit vector (0,0,0,1) @@ -858,7 +858,7 @@ EIGEN_STRONG_INLINE const typename MatrixBase::BasisReturnType MatrixBa * \sa MatrixBase::Unit(Index,Index), MatrixBase::Unit(Index), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW() */ template -EIGEN_STRONG_INLINE const typename MatrixBase::BasisReturnType MatrixBase::UnitW() +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase::BasisReturnType MatrixBase::UnitW() { return Derived::Unit(3); } } // end namespace Eigen diff --git a/eigenlib/Eigen/src/Core/CwiseUnaryView.h b/eigenlib/Eigen/src/Core/CwiseUnaryView.h index 27103305..5a30fa8d 100644 --- a/eigenlib/Eigen/src/Core/CwiseUnaryView.h +++ b/eigenlib/Eigen/src/Core/CwiseUnaryView.h @@ -121,6 +121,8 @@ class CwiseUnaryViewImpl { return derived().nestedExpression().outerStride() * sizeof(typename internal::traits::Scalar) / sizeof(Scalar); } + protected: + EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(CwiseUnaryViewImpl) }; } // end namespace Eigen diff --git a/eigenlib/Eigen/src/Core/DenseBase.h b/eigenlib/Eigen/src/Core/DenseBase.h index bd74e8a1..c55a6823 100644 --- a/eigenlib/Eigen/src/Core/DenseBase.h +++ b/eigenlib/Eigen/src/Core/DenseBase.h @@ -40,7 +40,7 @@ static inline void check_DenseIndex_is_signed() { */ template class DenseBase #ifndef EIGEN_PARSED_BY_DOXYGEN - : public DenseCoeffsBase + : public DenseCoeffsBase::value> #else : public DenseCoeffsBase #endif // not EIGEN_PARSED_BY_DOXYGEN @@ -71,7 +71,7 @@ template class DenseBase typedef Scalar value_type; typedef typename NumTraits::Real RealScalar; - typedef DenseCoeffsBase Base; + typedef DenseCoeffsBase::value> Base; using Base::derived; using Base::const_cast_derived; @@ -296,7 +296,7 @@ template class DenseBase EIGEN_DEVICE_FUNC Derived& operator=(const ReturnByValue& func); - /** \ínternal + /** \internal * Copies \a other into *this without evaluating other. \returns a reference to *this. * \deprecated */ template @@ -463,7 +463,17 @@ template class DenseBase EIGEN_DEVICE_FUNC void visit(Visitor& func) const; - inline const WithFormat format(const IOFormat& fmt) const; + /** \returns a WithFormat proxy object allowing to print a matrix the with given + * format \a fmt. + * + * See class IOFormat for some examples. + * + * \sa class IOFormat, class WithFormat + */ + inline const WithFormat format(const IOFormat& fmt) const + { + return WithFormat(derived(), fmt); + } /** \returns the unique coefficient of a 1x1 expression */ EIGEN_DEVICE_FUNC @@ -474,9 +484,9 @@ template class DenseBase return derived().coeff(0,0); } - bool all() const; - bool any() const; - Index count() const; + EIGEN_DEVICE_FUNC bool all() const; + EIGEN_DEVICE_FUNC bool any() const; + EIGEN_DEVICE_FUNC Index count() const; typedef VectorwiseOp RowwiseReturnType; typedef const VectorwiseOp ConstRowwiseReturnType; @@ -577,11 +587,12 @@ template class DenseBase } protected: + EIGEN_DEFAULT_COPY_CONSTRUCTOR(DenseBase) /** Default constructor. Do nothing. */ EIGEN_DEVICE_FUNC DenseBase() { /* Just checks for self-consistency of the flags. - * Only do it when debugging Eigen, as this borders on paranoiac and could slow compilation down + * Only do it when debugging Eigen, as this borders on paranoia and could slow compilation down */ #ifdef EIGEN_INTERNAL_DEBUGGING EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, int(IsRowMajor)) diff --git a/eigenlib/Eigen/src/Core/DenseStorage.h b/eigenlib/Eigen/src/Core/DenseStorage.h index 82201d96..7d6d4e66 100644 --- a/eigenlib/Eigen/src/Core/DenseStorage.h +++ b/eigenlib/Eigen/src/Core/DenseStorage.h @@ -13,9 +13,9 @@ #define EIGEN_MATRIXSTORAGE_H #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN - #define EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN EIGEN_DENSE_STORAGE_CTOR_PLUGIN; + #define EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(X) X; EIGEN_DENSE_STORAGE_CTOR_PLUGIN; #else - #define EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN + #define EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(X) #endif namespace Eigen { @@ -184,12 +184,16 @@ template class DenseSt { internal::plain_array m_data; public: - EIGEN_DEVICE_FUNC DenseStorage() {} + EIGEN_DEVICE_FUNC DenseStorage() { + EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = Size) + } EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(internal::constructor_without_unaligned_array_assert()) {} EIGEN_DEVICE_FUNC - DenseStorage(const DenseStorage& other) : m_data(other.m_data) {} + DenseStorage(const DenseStorage& other) : m_data(other.m_data) { + EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = Size) + } EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other) { @@ -197,7 +201,7 @@ template class DenseSt return *this; } EIGEN_DEVICE_FUNC DenseStorage(Index size, Index rows, Index cols) { - EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN + EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({}) eigen_internal_assert(size==rows*cols && rows==_Rows && cols==_Cols); EIGEN_UNUSED_VARIABLE(size); EIGEN_UNUSED_VARIABLE(rows); @@ -343,7 +347,7 @@ template class DenseStorage(size)), m_rows(rows), m_cols(cols) { - EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN + EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({}) eigen_internal_assert(size==rows*cols && rows>=0 && cols >=0); } EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) @@ -351,6 +355,7 @@ template class DenseStorage class DenseStorage(m_data, m_rows*m_cols); - if (size) + if (size>0) // >0 and not simply !=0 to let the compiler knows that size cannot be negative m_data = internal::conditional_aligned_new_auto(size); else m_data = 0; - EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN + EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({}) } m_rows = rows; m_cols = cols; @@ -422,7 +427,7 @@ template class DenseStorage(size)), m_cols(cols) { - EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN + EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({}) eigen_internal_assert(size==rows*cols && rows==_Rows && cols >=0); EIGEN_UNUSED_VARIABLE(rows); } @@ -430,6 +435,7 @@ template class DenseStorage(_Rows*other.m_cols)) , m_cols(other.m_cols) { + EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = m_cols*_Rows) internal::smart_copy(other.m_data, other.m_data+_Rows*m_cols, m_data); } EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other) @@ -473,11 +479,11 @@ template class DenseStorage(m_data, _Rows*m_cols); - if (size) + if (size>0) // >0 and not simply !=0 to let the compiler knows that size cannot be negative m_data = internal::conditional_aligned_new_auto(size); else m_data = 0; - EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN + EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({}) } m_cols = cols; } @@ -495,7 +501,7 @@ template class DenseStorage(size)), m_rows(rows) { - EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN + EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({}) eigen_internal_assert(size==rows*cols && rows>=0 && cols == _Cols); EIGEN_UNUSED_VARIABLE(cols); } @@ -503,6 +509,7 @@ template class DenseStorage(other.m_rows*_Cols)) , m_rows(other.m_rows) { + EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = m_rows*_Cols) internal::smart_copy(other.m_data, other.m_data+other.m_rows*_Cols, m_data); } EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other) @@ -546,11 +553,11 @@ template class DenseStorage(m_data, _Cols*m_rows); - if (size) + if (size>0) // >0 and not simply !=0 to let the compiler knows that size cannot be negative m_data = internal::conditional_aligned_new_auto(size); else m_data = 0; - EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN + EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({}) } m_rows = rows; } diff --git a/eigenlib/Eigen/src/Core/Diagonal.h b/eigenlib/Eigen/src/Core/Diagonal.h index bfea0584..afcaf357 100644 --- a/eigenlib/Eigen/src/Core/Diagonal.h +++ b/eigenlib/Eigen/src/Core/Diagonal.h @@ -21,7 +21,7 @@ namespace Eigen { * \param MatrixType the type of the object in which we are taking a sub/main/super diagonal * \param DiagIndex the index of the sub/super diagonal. The default is 0 and it means the main diagonal. * A positive value means a superdiagonal, a negative value means a subdiagonal. - * You can also use Dynamic so the index can be set at runtime. + * You can also use DynamicIndex so the index can be set at runtime. * * The matrix is not required to be square. * @@ -70,7 +70,10 @@ template class Diagonal EIGEN_DENSE_PUBLIC_INTERFACE(Diagonal) EIGEN_DEVICE_FUNC - explicit inline Diagonal(MatrixType& matrix, Index a_index = DiagIndex) : m_matrix(matrix), m_index(a_index) {} + explicit inline Diagonal(MatrixType& matrix, Index a_index = DiagIndex) : m_matrix(matrix), m_index(a_index) + { + eigen_assert( a_index <= m_matrix.cols() && -a_index <= m_matrix.rows() ); + } EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Diagonal) diff --git a/eigenlib/Eigen/src/Core/Dot.h b/eigenlib/Eigen/src/Core/Dot.h index 06ef18b8..1fe7a84a 100644 --- a/eigenlib/Eigen/src/Core/Dot.h +++ b/eigenlib/Eigen/src/Core/Dot.h @@ -31,7 +31,8 @@ struct dot_nocheck typedef scalar_conj_product_op::Scalar,typename traits::Scalar> conj_prod; typedef typename conj_prod::result_type ResScalar; EIGEN_DEVICE_FUNC - static inline ResScalar run(const MatrixBase& a, const MatrixBase& b) + EIGEN_STRONG_INLINE + static ResScalar run(const MatrixBase& a, const MatrixBase& b) { return a.template binaryExpr(b).sum(); } @@ -43,7 +44,8 @@ struct dot_nocheck typedef scalar_conj_product_op::Scalar,typename traits::Scalar> conj_prod; typedef typename conj_prod::result_type ResScalar; EIGEN_DEVICE_FUNC - static inline ResScalar run(const MatrixBase& a, const MatrixBase& b) + EIGEN_STRONG_INLINE + static ResScalar run(const MatrixBase& a, const MatrixBase& b) { return a.transpose().template binaryExpr(b).sum(); } @@ -65,6 +67,7 @@ struct dot_nocheck template template EIGEN_DEVICE_FUNC +EIGEN_STRONG_INLINE typename ScalarBinaryOpTraits::Scalar,typename internal::traits::Scalar>::ReturnType MatrixBase::dot(const MatrixBase& other) const { @@ -102,7 +105,7 @@ EIGEN_STRONG_INLINE typename NumTraits::Scala * \sa lpNorm(), dot(), squaredNorm() */ template -inline typename NumTraits::Scalar>::Real MatrixBase::norm() const +EIGEN_STRONG_INLINE typename NumTraits::Scalar>::Real MatrixBase::norm() const { return numext::sqrt(squaredNorm()); } @@ -117,7 +120,7 @@ inline typename NumTraits::Scalar>::Real Matr * \sa norm(), normalize() */ template -inline const typename MatrixBase::PlainObject +EIGEN_STRONG_INLINE const typename MatrixBase::PlainObject MatrixBase::normalized() const { typedef typename internal::nested_eval::type _Nested; @@ -139,7 +142,7 @@ MatrixBase::normalized() const * \sa norm(), normalized() */ template -inline void MatrixBase::normalize() +EIGEN_STRONG_INLINE void MatrixBase::normalize() { RealScalar z = squaredNorm(); // NOTE: after extensive benchmarking, this conditional does not impact performance, at least on recent x86 CPU @@ -160,7 +163,7 @@ inline void MatrixBase::normalize() * \sa stableNorm(), stableNormalize(), normalized() */ template -inline const typename MatrixBase::PlainObject +EIGEN_STRONG_INLINE const typename MatrixBase::PlainObject MatrixBase::stableNormalized() const { typedef typename internal::nested_eval::type _Nested; @@ -185,7 +188,7 @@ MatrixBase::stableNormalized() const * \sa stableNorm(), stableNormalized(), normalize() */ template -inline void MatrixBase::stableNormalize() +EIGEN_STRONG_INLINE void MatrixBase::stableNormalize() { RealScalar w = cwiseAbs().maxCoeff(); RealScalar z = (derived()/w).squaredNorm(); diff --git a/eigenlib/Eigen/src/Core/EigenBase.h b/eigenlib/Eigen/src/Core/EigenBase.h index f76995af..b195506a 100644 --- a/eigenlib/Eigen/src/Core/EigenBase.h +++ b/eigenlib/Eigen/src/Core/EigenBase.h @@ -14,6 +14,7 @@ namespace Eigen { /** \class EigenBase + * \ingroup Core_Module * * Common base class for all classes T such that MatrixBase has an operator=(T) and a constructor MatrixBase(T). * @@ -128,6 +129,7 @@ template struct EigenBase */ template template +EIGEN_DEVICE_FUNC Derived& DenseBase::operator=(const EigenBase &other) { call_assignment(derived(), other.derived()); @@ -136,6 +138,7 @@ Derived& DenseBase::operator=(const EigenBase &other) template template +EIGEN_DEVICE_FUNC Derived& DenseBase::operator+=(const EigenBase &other) { call_assignment(derived(), other.derived(), internal::add_assign_op()); @@ -144,6 +147,7 @@ Derived& DenseBase::operator+=(const EigenBase &other) template template +EIGEN_DEVICE_FUNC Derived& DenseBase::operator-=(const EigenBase &other) { call_assignment(derived(), other.derived(), internal::sub_assign_op()); diff --git a/eigenlib/Eigen/src/Core/GeneralProduct.h b/eigenlib/Eigen/src/Core/GeneralProduct.h index 0f16cd8e..6f0cc80e 100644 --- a/eigenlib/Eigen/src/Core/GeneralProduct.h +++ b/eigenlib/Eigen/src/Core/GeneralProduct.h @@ -24,12 +24,17 @@ template struct product_type_selector; template struct product_size_category { - enum { is_large = MaxSize == Dynamic || - Size >= EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD || - (Size==Dynamic && MaxSize>=EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD), - value = is_large ? Large - : Size == 1 ? 1 - : Small + enum { + #ifndef EIGEN_CUDA_ARCH + is_large = MaxSize == Dynamic || + Size >= EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD || + (Size==Dynamic && MaxSize>=EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD), + #else + is_large = 0, + #endif + value = is_large ? Large + : Size == 1 ? 1 + : Small }; }; @@ -379,8 +384,6 @@ template<> struct gemv_dense_selector * * \sa lazyProduct(), operator*=(const MatrixBase&), Cwise::operator*() */ -#ifndef __CUDACC__ - template template inline const Product @@ -412,8 +415,6 @@ MatrixBase::operator*(const MatrixBase &other) const return Product(derived(), other.derived()); } -#endif // __CUDACC__ - /** \returns an expression of the matrix product of \c *this and \a other without implicit evaluation. * * The returned product will behave like any other expressions: the coefficients of the product will be diff --git a/eigenlib/Eigen/src/Core/GenericPacketMath.h b/eigenlib/Eigen/src/Core/GenericPacketMath.h index 27033a2d..e5944377 100644 --- a/eigenlib/Eigen/src/Core/GenericPacketMath.h +++ b/eigenlib/Eigen/src/Core/GenericPacketMath.h @@ -230,7 +230,7 @@ pload1(const typename unpacket_traits::type *a) { return pset1( * duplicated to form: {from[0],from[0],from[1],from[1],from[2],from[2],from[3],from[3]} * Currently, this function is only used for scalar * complex products. */ -template EIGEN_DEVICE_FUNC inline Packet +template EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet ploaddup(const typename unpacket_traits::type* from) { return *from; } /** \internal \returns a packet with elements of \a *from quadrupled. @@ -278,7 +278,7 @@ inline void pbroadcast2(const typename unpacket_traits::type *a, } /** \internal \brief Returns a packet with coefficients (a,a+1,...,a+packet_size-1). */ -template inline Packet +template EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet plset(const typename unpacket_traits::type& a) { return a; } /** \internal copy the packet \a from to \a *to, \a to must be 16 bytes aligned */ @@ -351,10 +351,7 @@ template EIGEN_DEVICE_FUNC inline Packet preverse(const Packet& /** \internal \returns \a a with real and imaginary part flipped (for complex type only) */ template EIGEN_DEVICE_FUNC inline Packet pcplxflip(const Packet& a) { - // FIXME: uncomment the following in case we drop the internal imag and real functions. -// using std::imag; -// using std::real; - return Packet(imag(a),real(a)); + return Packet(a.imag(),a.real()); } /************************** @@ -482,7 +479,7 @@ EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void pstoret(Scalar* to, const Packet& fro * by the current computation. */ template -inline Packet ploadt_ro(const typename unpacket_traits::type* from) +EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet ploadt_ro(const typename unpacket_traits::type* from) { return ploadt(from); } @@ -524,10 +521,10 @@ inline void palign(PacketType& first, const PacketType& second) #ifndef __CUDACC__ template<> inline std::complex pmul(const std::complex& a, const std::complex& b) -{ return std::complex(real(a)*real(b) - imag(a)*imag(b), imag(a)*real(b) + real(a)*imag(b)); } +{ return std::complex(a.real()*b.real() - a.imag()*b.imag(), a.imag()*b.real() + a.real()*b.imag()); } template<> inline std::complex pmul(const std::complex& a, const std::complex& b) -{ return std::complex(real(a)*real(b) - imag(a)*imag(b), imag(a)*real(b) + real(a)*imag(b)); } +{ return std::complex(a.real()*b.real() - a.imag()*b.imag(), a.imag()*b.real() + a.real()*b.imag()); } #endif diff --git a/eigenlib/Eigen/src/Core/IO.h b/eigenlib/Eigen/src/Core/IO.h index 644228c3..da7fd6cc 100644 --- a/eigenlib/Eigen/src/Core/IO.h +++ b/eigenlib/Eigen/src/Core/IO.h @@ -109,20 +109,6 @@ class WithFormat IOFormat m_format; }; -/** \returns a WithFormat proxy object allowing to print a matrix the with given - * format \a fmt. - * - * See class IOFormat for some examples. - * - * \sa class IOFormat, class WithFormat - */ -template -inline const WithFormat -DenseBase::format(const IOFormat& fmt) const -{ - return WithFormat(derived(), fmt); -} - namespace internal { // NOTE: This helper is kept for backward compatibility with previous code specializing diff --git a/eigenlib/Eigen/src/Core/Map.h b/eigenlib/Eigen/src/Core/Map.h index 06d19670..548bf9a2 100644 --- a/eigenlib/Eigen/src/Core/Map.h +++ b/eigenlib/Eigen/src/Core/Map.h @@ -20,11 +20,17 @@ struct traits > { typedef traits TraitsBase; enum { + PlainObjectTypeInnerSize = ((traits::Flags&RowMajorBit)==RowMajorBit) + ? PlainObjectType::ColsAtCompileTime + : PlainObjectType::RowsAtCompileTime, + InnerStrideAtCompileTime = StrideType::InnerStrideAtCompileTime == 0 ? int(PlainObjectType::InnerStrideAtCompileTime) : int(StrideType::InnerStrideAtCompileTime), OuterStrideAtCompileTime = StrideType::OuterStrideAtCompileTime == 0 - ? int(PlainObjectType::OuterStrideAtCompileTime) + ? (InnerStrideAtCompileTime==Dynamic || PlainObjectTypeInnerSize==Dynamic + ? Dynamic + : int(InnerStrideAtCompileTime) * int(PlainObjectTypeInnerSize)) : int(StrideType::OuterStrideAtCompileTime), Alignment = int(MapOptions)&int(AlignedMask), Flags0 = TraitsBase::Flags & (~NestByRefBit), @@ -107,10 +113,11 @@ template class Ma EIGEN_DEVICE_FUNC inline Index outerStride() const { - return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer() - : IsVectorAtCompileTime ? this->size() - : int(Flags)&RowMajorBit ? this->cols() - : this->rows(); + return int(StrideType::OuterStrideAtCompileTime) != 0 ? m_stride.outer() + : int(internal::traits::OuterStrideAtCompileTime) != Dynamic ? Index(internal::traits::OuterStrideAtCompileTime) + : IsVectorAtCompileTime ? (this->size() * innerStride()) + : (int(Flags)&RowMajorBit) ? (this->cols() * innerStride()) + : (this->rows() * innerStride()); } /** Constructor in the fixed-size case. diff --git a/eigenlib/Eigen/src/Core/MapBase.h b/eigenlib/Eigen/src/Core/MapBase.h index 020f939a..92c3b281 100644 --- a/eigenlib/Eigen/src/Core/MapBase.h +++ b/eigenlib/Eigen/src/Core/MapBase.h @@ -43,6 +43,7 @@ template class MapBase enum { RowsAtCompileTime = internal::traits::RowsAtCompileTime, ColsAtCompileTime = internal::traits::ColsAtCompileTime, + InnerStrideAtCompileTime = internal::traits::InnerStrideAtCompileTime, SizeAtCompileTime = Base::SizeAtCompileTime }; @@ -181,14 +182,19 @@ template class MapBase #endif protected: + EIGEN_DEFAULT_COPY_CONSTRUCTOR(MapBase) + EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(MapBase) template EIGEN_DEVICE_FUNC void checkSanity(typename internal::enable_if<(internal::traits::Alignment>0),void*>::type = 0) const { #if EIGEN_MAX_ALIGN_BYTES>0 + // innerStride() is not set yet when this function is called, so we optimistically assume the lowest plausible value: + const Index minInnerStride = InnerStrideAtCompileTime == Dynamic ? 1 : Index(InnerStrideAtCompileTime); + EIGEN_ONLY_USED_FOR_DEBUG(minInnerStride); eigen_assert(( ((internal::UIntPtr(m_data) % internal::traits::Alignment) == 0) - || (cols() * rows() * innerStride() * sizeof(Scalar)) < internal::traits::Alignment ) && "data is not aligned"); + || (cols() * rows() * minInnerStride * sizeof(Scalar)) < internal::traits::Alignment ) && "data is not aligned"); #endif } @@ -290,6 +296,9 @@ template class MapBase // In theory we could simply refer to Base:Base::operator=, but MSVC does not like Base::Base, // see bugs 821 and 920. using ReadOnlyMapBase::Base::operator=; + protected: + EIGEN_DEFAULT_COPY_CONSTRUCTOR(MapBase) + EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(MapBase) }; #undef EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS diff --git a/eigenlib/Eigen/src/Core/MathFunctions.h b/eigenlib/Eigen/src/Core/MathFunctions.h index 8d47fb8a..01736c2a 100644 --- a/eigenlib/Eigen/src/Core/MathFunctions.h +++ b/eigenlib/Eigen/src/Core/MathFunctions.h @@ -287,7 +287,7 @@ struct abs2_impl_default // IsComplex EIGEN_DEVICE_FUNC static inline RealScalar run(const Scalar& x) { - return real(x)*real(x) + imag(x)*imag(x); + return x.real()*x.real() + x.imag()*x.imag(); } }; @@ -313,14 +313,17 @@ struct abs2_retval ****************************************************************************/ template -struct norm1_default_impl +struct norm1_default_impl; + +template +struct norm1_default_impl { typedef typename NumTraits::Real RealScalar; EIGEN_DEVICE_FUNC static inline RealScalar run(const Scalar& x) { EIGEN_USING_STD_MATH(abs); - return abs(real(x)) + abs(imag(x)); + return abs(x.real()) + abs(x.imag()); } }; @@ -348,31 +351,7 @@ struct norm1_retval * Implementation of hypot * ****************************************************************************/ -template -struct hypot_impl -{ - typedef typename NumTraits::Real RealScalar; - static inline RealScalar run(const Scalar& x, const Scalar& y) - { - EIGEN_USING_STD_MATH(abs); - EIGEN_USING_STD_MATH(sqrt); - RealScalar _x = abs(x); - RealScalar _y = abs(y); - Scalar p, qp; - if(_x>_y) - { - p = _x; - qp = _y / p; - } - else - { - p = _y; - qp = _x / p; - } - if(p==RealScalar(0)) return RealScalar(0); - return p * sqrt(RealScalar(1) + qp*qp); - } -}; +template struct hypot_impl; template struct hypot_retval @@ -495,7 +474,7 @@ namespace std_fallback { typedef typename NumTraits::Real RealScalar; EIGEN_USING_STD_MATH(log); Scalar x1p = RealScalar(1) + x; - return ( x1p == Scalar(1) ) ? x : x * ( log(x1p) / (x1p - RealScalar(1)) ); + return numext::equal_strict(x1p, Scalar(1)) ? x : x * ( log(x1p) / (x1p - RealScalar(1)) ); } } @@ -640,21 +619,28 @@ template struct random_default_impl { static inline Scalar run(const Scalar& x, const Scalar& y) - { - typedef typename conditional::IsSigned,std::ptrdiff_t,std::size_t>::type ScalarX; - if(y=x the result converted to an unsigned long is still correct. - std::size_t range = ScalarX(y)-ScalarX(x); - std::size_t offset = 0; - // rejection sampling - std::size_t divisor = 1; - std::size_t multiplier = 1; - if(range::type ScalarU; + // ScalarX is the widest of ScalarU and unsigned int. + // We'll deal only with ScalarX and unsigned int below thus avoiding signed + // types and arithmetic and signed overflows (which are undefined behavior). + typedef typename conditional<(ScalarU(-1) > unsigned(-1)), ScalarU, unsigned>::type ScalarX; + // The following difference doesn't overflow, provided our integer types are two's + // complement and have the same number of padding bits in signed and unsigned variants. + // This is the case in most modern implementations of C++. + ScalarX range = ScalarX(y) - ScalarX(x); + ScalarX offset = 0; + ScalarX divisor = 1; + ScalarX multiplier = 1; + const unsigned rand_max = RAND_MAX; + if (range <= rand_max) divisor = (rand_max + 1) / (range + 1); + else multiplier = 1 + range / (rand_max + 1); + // Rejection sampling. do { - offset = (std::size_t(std::rand()) * multiplier) / divisor; + offset = (unsigned(std::rand()) * multiplier) / divisor; } while (offset > range); return Scalar(ScalarX(x) + offset); } @@ -679,8 +665,8 @@ struct random_default_impl { static inline Scalar run(const Scalar& x, const Scalar& y) { - return Scalar(random(real(x), real(y)), - random(imag(x), imag(y))); + return Scalar(random(x.real(), y.real()), + random(x.imag(), y.imag())); } static inline Scalar run() { @@ -933,6 +919,9 @@ inline EIGEN_MATHFUNC_RETVAL(abs2, Scalar) abs2(const Scalar& x) return EIGEN_MATHFUNC_IMPL(abs2, Scalar)::run(x); } +EIGEN_DEVICE_FUNC +inline bool abs2(bool x) { return x; } + template EIGEN_DEVICE_FUNC inline EIGEN_MATHFUNC_RETVAL(norm1, Scalar) norm1(const Scalar& x) @@ -1030,7 +1019,8 @@ inline int log2(int x) /** \returns the square root of \a x. * - * It is essentially equivalent to \code using std::sqrt; return sqrt(x); \endcode, + * It is essentially equivalent to + * \code using std::sqrt; return sqrt(x); \endcode * but slightly faster for float/double and some compilers (e.g., gcc), thanks to * specializations when SSE is enabled. * @@ -1061,11 +1051,24 @@ double log(const double &x) { return ::log(x); } template EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE -typename NumTraits::Real abs(const T &x) { +typename internal::enable_if::IsSigned || NumTraits::IsComplex,typename NumTraits::Real>::type +abs(const T &x) { EIGEN_USING_STD_MATH(abs); return abs(x); } +template +EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE +typename internal::enable_if::IsSigned || NumTraits::IsComplex),typename NumTraits::Real>::type +abs(const T &x) { + return x; +} + +#if defined(__SYCL_DEVICE_ONLY__) +EIGEN_ALWAYS_INLINE float abs(float x) { return cl::sycl::fabs(x); } +EIGEN_ALWAYS_INLINE double abs(double x) { return cl::sycl::fabs(x); } +#endif // defined(__SYCL_DEVICE_ONLY__) + #ifdef __CUDACC__ template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE float abs(const float &x) { return ::fabsf(x); } diff --git a/eigenlib/Eigen/src/Core/MathFunctionsImpl.h b/eigenlib/Eigen/src/Core/MathFunctionsImpl.h index 3c9ef22f..9c1ceb0e 100644 --- a/eigenlib/Eigen/src/Core/MathFunctionsImpl.h +++ b/eigenlib/Eigen/src/Core/MathFunctionsImpl.h @@ -71,6 +71,29 @@ T generic_fast_tanh_float(const T& a_x) return pdiv(p, q); } +template +EIGEN_STRONG_INLINE +RealScalar positive_real_hypot(const RealScalar& x, const RealScalar& y) +{ + EIGEN_USING_STD_MATH(sqrt); + RealScalar p, qp; + p = numext::maxi(x,y); + if(p==RealScalar(0)) return RealScalar(0); + qp = numext::mini(y,x) / p; + return p * sqrt(RealScalar(1) + qp*qp); +} + +template +struct hypot_impl +{ + typedef typename NumTraits::Real RealScalar; + static inline RealScalar run(const Scalar& x, const Scalar& y) + { + EIGEN_USING_STD_MATH(abs); + return positive_real_hypot(abs(x), abs(y)); + } +}; + } // end namespace internal } // end namespace Eigen diff --git a/eigenlib/Eigen/src/Core/Matrix.h b/eigenlib/Eigen/src/Core/Matrix.h index 90c336d8..7f4a7af9 100644 --- a/eigenlib/Eigen/src/Core/Matrix.h +++ b/eigenlib/Eigen/src/Core/Matrix.h @@ -274,8 +274,6 @@ class Matrix : Base(std::move(other)) { Base::_check_template_params(); - if (RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic) - Base::_set_noalias(other); } EIGEN_DEVICE_FUNC Matrix& operator=(Matrix&& other) EIGEN_NOEXCEPT_IF(std::is_nothrow_move_assignable::value) diff --git a/eigenlib/Eigen/src/Core/MatrixBase.h b/eigenlib/Eigen/src/Core/MatrixBase.h index f7cf04cd..f8bcc8c6 100644 --- a/eigenlib/Eigen/src/Core/MatrixBase.h +++ b/eigenlib/Eigen/src/Core/MatrixBase.h @@ -160,20 +160,11 @@ template class MatrixBase EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator-=(const MatrixBase& other); -#ifdef __CUDACC__ template EIGEN_DEVICE_FUNC - const Product - operator*(const MatrixBase &other) const - { return this->lazyProduct(other); } -#else - - template const Product operator*(const MatrixBase &other) const; -#endif - template EIGEN_DEVICE_FUNC const Product @@ -294,7 +285,7 @@ template class MatrixBase * fuzzy comparison such as isApprox() * \sa isApprox(), operator!= */ template - inline bool operator==(const MatrixBase& other) const + EIGEN_DEVICE_FUNC inline bool operator==(const MatrixBase& other) const { return cwiseEqual(other).all(); } /** \returns true if at least one pair of coefficients of \c *this and \a other are not exactly equal to each other. @@ -302,7 +293,7 @@ template class MatrixBase * fuzzy comparison such as isApprox() * \sa isApprox(), operator== */ template - inline bool operator!=(const MatrixBase& other) const + EIGEN_DEVICE_FUNC inline bool operator!=(const MatrixBase& other) const { return cwiseNotEqual(other).any(); } NoAlias noalias(); @@ -453,19 +444,28 @@ template class MatrixBase ///////// MatrixFunctions module ///////// typedef typename internal::stem_function::type StemFunction; - const MatrixExponentialReturnValue exp() const; +#define EIGEN_MATRIX_FUNCTION(ReturnType, Name, Description) \ + /** \returns an expression of the matrix Description of \c *this. \brief This function requires the unsupported MatrixFunctions module. To compute the coefficient-wise Description use ArrayBase::##Name . */ \ + const ReturnType Name() const; +#define EIGEN_MATRIX_FUNCTION_1(ReturnType, Name, Description, Argument) \ + /** \returns an expression of the matrix Description of \c *this. \brief This function requires the unsupported MatrixFunctions module. To compute the coefficient-wise Description use ArrayBase::##Name . */ \ + const ReturnType Name(Argument) const; + + EIGEN_MATRIX_FUNCTION(MatrixExponentialReturnValue, exp, exponential) + /** \brief Helper function for the unsupported MatrixFunctions module.*/ const MatrixFunctionReturnValue matrixFunction(StemFunction f) const; - const MatrixFunctionReturnValue cosh() const; - const MatrixFunctionReturnValue sinh() const; - const MatrixFunctionReturnValue cos() const; - const MatrixFunctionReturnValue sin() const; - const MatrixSquareRootReturnValue sqrt() const; - const MatrixLogarithmReturnValue log() const; - const MatrixPowerReturnValue pow(const RealScalar& p) const; - const MatrixComplexPowerReturnValue pow(const std::complex& p) const; + EIGEN_MATRIX_FUNCTION(MatrixFunctionReturnValue, cosh, hyperbolic cosine) + EIGEN_MATRIX_FUNCTION(MatrixFunctionReturnValue, sinh, hyperbolic sine) + EIGEN_MATRIX_FUNCTION(MatrixFunctionReturnValue, cos, cosine) + EIGEN_MATRIX_FUNCTION(MatrixFunctionReturnValue, sin, sine) + EIGEN_MATRIX_FUNCTION(MatrixSquareRootReturnValue, sqrt, square root) + EIGEN_MATRIX_FUNCTION(MatrixLogarithmReturnValue, log, logarithm) + EIGEN_MATRIX_FUNCTION_1(MatrixPowerReturnValue, pow, power to \c p, const RealScalar& p) + EIGEN_MATRIX_FUNCTION_1(MatrixComplexPowerReturnValue, pow, power to \c p, const std::complex& p) protected: - EIGEN_DEVICE_FUNC MatrixBase() : Base() {} + EIGEN_DEFAULT_COPY_CONSTRUCTOR(MatrixBase) + EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(MatrixBase) private: EIGEN_DEVICE_FUNC explicit MatrixBase(int); diff --git a/eigenlib/Eigen/src/Core/NumTraits.h b/eigenlib/Eigen/src/Core/NumTraits.h index dd61195b..daf48987 100644 --- a/eigenlib/Eigen/src/Core/NumTraits.h +++ b/eigenlib/Eigen/src/Core/NumTraits.h @@ -215,6 +215,8 @@ struct NumTraits > static inline RealScalar epsilon() { return NumTraits::epsilon(); } EIGEN_DEVICE_FUNC static inline RealScalar dummy_precision() { return NumTraits::dummy_precision(); } + + static inline int digits10() { return NumTraits::digits10(); } }; template<> struct NumTraits diff --git a/eigenlib/Eigen/src/Core/PermutationMatrix.h b/eigenlib/Eigen/src/Core/PermutationMatrix.h index b1fb455b..47c06ba7 100644 --- a/eigenlib/Eigen/src/Core/PermutationMatrix.h +++ b/eigenlib/Eigen/src/Core/PermutationMatrix.h @@ -87,17 +87,6 @@ class PermutationBase : public EigenBase return derived(); } - #ifndef EIGEN_PARSED_BY_DOXYGEN - /** This is a special case of the templated operator=. Its purpose is to - * prevent a default operator= from hiding the templated operator=. - */ - Derived& operator=(const PermutationBase& other) - { - indices() = other.indices(); - return derived(); - } - #endif - /** \returns the number of rows */ inline Index rows() const { return Index(indices().size()); } @@ -333,12 +322,6 @@ class PermutationMatrix : public PermutationBase& other) : m_indices(other.indices()) {} - #ifndef EIGEN_PARSED_BY_DOXYGEN - /** Standard copy constructor. Defined only to prevent a default copy constructor - * from hiding the other templated constructor */ - inline PermutationMatrix(const PermutationMatrix& other) : m_indices(other.indices()) {} - #endif - /** Generic constructor from expression of the indices. The indices * array has the meaning that the permutations sends each integer i to indices[i]. * @@ -373,17 +356,6 @@ class PermutationMatrix : public PermutationBase struct check_rows_cols_for_overflow { { // http://hg.mozilla.org/mozilla-central/file/6c8a909977d3/xpcom/ds/CheckedInt.h#l242 // we assume Index is signed - Index max_index = (size_t(1) << (8 * sizeof(Index) - 1)) - 1; // assume Index is signed + Index max_index = (std::size_t(1) << (8 * sizeof(Index) - 1)) - 1; // assume Index is signed bool error = (rows == 0 || cols == 0) ? false : (rows > max_index / cols); if (error) @@ -577,6 +577,10 @@ class PlainObjectBase : public internal::dense_xpr_base::type * while the AlignedMap() functions return aligned Map objects and thus should be called only with 16-byte-aligned * \a data pointers. * + * Here is an example using strides: + * \include Matrix_Map_stride.cpp + * Output: \verbinclude Matrix_Map_stride.out + * * \see class Map */ //@{ @@ -733,8 +737,10 @@ class PlainObjectBase : public internal::dense_xpr_base::type EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void _init2(Index rows, Index cols, typename internal::enable_if::type* = 0) { - EIGEN_STATIC_ASSERT(bool(NumTraits::IsInteger) && - bool(NumTraits::IsInteger), + const bool t0_is_integer_alike = internal::is_valid_index_type::value; + const bool t1_is_integer_alike = internal::is_valid_index_type::value; + EIGEN_STATIC_ASSERT(t0_is_integer_alike && + t1_is_integer_alike, FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED) resize(rows,cols); } @@ -769,9 +775,9 @@ class PlainObjectBase : public internal::dense_xpr_base::type && ((!internal::is_same::XprKind,ArrayXpr>::value || Base::SizeAtCompileTime==Dynamic)),T>::type* = 0) { // NOTE MSVC 2008 complains if we directly put bool(NumTraits::IsInteger) as the EIGEN_STATIC_ASSERT argument. - const bool is_integer = NumTraits::IsInteger; - EIGEN_UNUSED_VARIABLE(is_integer); - EIGEN_STATIC_ASSERT(is_integer, + const bool is_integer_alike = internal::is_valid_index_type::value; + EIGEN_UNUSED_VARIABLE(is_integer_alike); + EIGEN_STATIC_ASSERT(is_integer_alike, FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED) resize(size); } @@ -812,6 +818,13 @@ class PlainObjectBase : public internal::dense_xpr_base::type this->_set_noalias(other); } + // Initialize an arbitrary matrix from an object convertible to the Derived type. + template + EIGEN_DEVICE_FUNC + EIGEN_STRONG_INLINE void _init1(const Derived& other){ + this->_set_noalias(other); + } + // Initialize an arbitrary matrix from a generic Eigen expression template EIGEN_DEVICE_FUNC @@ -834,7 +847,7 @@ class PlainObjectBase : public internal::dense_xpr_base::type this->derived() = r; } - // For fixed -size arrays: + // For fixed-size Array template EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void _init1(const Scalar& val0, @@ -846,6 +859,7 @@ class PlainObjectBase : public internal::dense_xpr_base::type Base::setConstant(val0); } + // For fixed-size Array template EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void _init1(const Index& val0, diff --git a/eigenlib/Eigen/src/Core/Product.h b/eigenlib/Eigen/src/Core/Product.h index ae0c94b3..676c4802 100644 --- a/eigenlib/Eigen/src/Core/Product.h +++ b/eigenlib/Eigen/src/Core/Product.h @@ -97,8 +97,8 @@ class Product : public ProductImpl<_Lhs,_Rhs,Option, && "if you wanted a coeff-wise or a dot product use the respective explicit functions"); } - EIGEN_DEVICE_FUNC inline Index rows() const { return m_lhs.rows(); } - EIGEN_DEVICE_FUNC inline Index cols() const { return m_rhs.cols(); } + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index rows() const { return m_lhs.rows(); } + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index cols() const { return m_rhs.cols(); } EIGEN_DEVICE_FUNC const LhsNestedCleaned& lhs() const { return m_lhs; } EIGEN_DEVICE_FUNC const RhsNestedCleaned& rhs() const { return m_rhs; } @@ -127,7 +127,7 @@ public: using Base::derived; typedef typename Base::Scalar Scalar; - operator const Scalar() const + EIGEN_STRONG_INLINE operator const Scalar() const { return internal::evaluator(derived()).coeff(0,0); } @@ -162,7 +162,7 @@ class ProductImpl public: - EIGEN_DEVICE_FUNC Scalar coeff(Index row, Index col) const + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar coeff(Index row, Index col) const { EIGEN_STATIC_ASSERT(EnableCoeff, THIS_METHOD_IS_ONLY_FOR_INNER_OR_LAZY_PRODUCTS); eigen_assert( (Option==LazyProduct) || (this->rows() == 1 && this->cols() == 1) ); @@ -170,7 +170,7 @@ class ProductImpl return internal::evaluator(derived()).coeff(row,col); } - EIGEN_DEVICE_FUNC Scalar coeff(Index i) const + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar coeff(Index i) const { EIGEN_STATIC_ASSERT(EnableCoeff, THIS_METHOD_IS_ONLY_FOR_INNER_OR_LAZY_PRODUCTS); eigen_assert( (Option==LazyProduct) || (this->rows() == 1 && this->cols() == 1) ); diff --git a/eigenlib/Eigen/src/Core/ProductEvaluators.h b/eigenlib/Eigen/src/Core/ProductEvaluators.h index 583b7f59..bce1310c 100644 --- a/eigenlib/Eigen/src/Core/ProductEvaluators.h +++ b/eigenlib/Eigen/src/Core/ProductEvaluators.h @@ -32,7 +32,7 @@ struct evaluator > typedef Product XprType; typedef product_evaluator Base; - EIGEN_DEVICE_FUNC explicit evaluator(const XprType& xpr) : Base(xpr) {} + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit evaluator(const XprType& xpr) : Base(xpr) {} }; // Catch "scalar * ( A * B )" and transform it to "(A*scalar) * B" @@ -55,7 +55,7 @@ struct evaluator, const Product > XprType; typedef evaluator > Base; - EIGEN_DEVICE_FUNC explicit evaluator(const XprType& xpr) + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit evaluator(const XprType& xpr) : Base(xpr.lhs().functor().m_other * xpr.rhs().lhs() * xpr.rhs().rhs()) {} }; @@ -68,7 +68,7 @@ struct evaluator, DiagIndex> > typedef Diagonal, DiagIndex> XprType; typedef evaluator, DiagIndex> > Base; - EIGEN_DEVICE_FUNC explicit evaluator(const XprType& xpr) + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit evaluator(const XprType& xpr) : Base(Diagonal, DiagIndex>( Product(xpr.nestedExpression().lhs(), xpr.nestedExpression().rhs()), xpr.index() )) @@ -207,6 +207,12 @@ struct evaluator_assume_aliasing +struct evaluator_assume_aliasing::Scalar>, const OtherXpr, + const Product >, DenseShape > { + static const bool value = true; +}; + template struct assignment_from_xpr_op_product { @@ -240,19 +246,19 @@ template struct generic_product_impl { template - static inline void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) + static EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) { dst.coeffRef(0,0) = (lhs.transpose().cwiseProduct(rhs)).sum(); } template - static inline void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) + static EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) { dst.coeffRef(0,0) += (lhs.transpose().cwiseProduct(rhs)).sum(); } template - static void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) + static EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) { dst.coeffRef(0,0) -= (lhs.transpose().cwiseProduct(rhs)).sum(); } }; @@ -306,25 +312,25 @@ struct generic_product_impl }; template - static inline void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) + static EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) { internal::outer_product_selector_run(dst, lhs, rhs, set(), is_row_major()); } template - static inline void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) + static EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) { internal::outer_product_selector_run(dst, lhs, rhs, add(), is_row_major()); } template - static inline void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) + static EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) { internal::outer_product_selector_run(dst, lhs, rhs, sub(), is_row_major()); } template - static inline void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha) + static EIGEN_STRONG_INLINE void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha) { internal::outer_product_selector_run(dst, lhs, rhs, adds(alpha), is_row_major()); } @@ -390,7 +396,7 @@ struct generic_product_impl // but easier on the compiler side call_assignment_no_alias(dst, lhs.lazyProduct(rhs), internal::assign_op()); } - + template static EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) { @@ -404,6 +410,32 @@ struct generic_product_impl // dst.noalias() -= lhs.lazyProduct(rhs); call_assignment_no_alias(dst, lhs.lazyProduct(rhs), internal::sub_assign_op()); } + + // Catch "dst {,+,-}= (s*A)*B" and evaluate it lazily by moving out the scalar factor: + // dst {,+,-}= s * (A.lazyProduct(B)) + // This is a huge benefit for heap-allocated matrix types as it save one costly allocation. + // For them, this strategy is also faster than simply by-passing the heap allocation through + // stack allocation. + // For fixed sizes matrices, this is less obvious, it is sometimes x2 faster, but sometimes x3 slower, + // and the behavior depends also a lot on the compiler... so let's be conservative and enable them for dynamic-size only, + // that is when coming from generic_product_impl<...,GemmProduct> in file GeneralMatrixMatrix.h + template + static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE + void eval_dynamic(Dst& dst, const CwiseBinaryOp, + const CwiseNullaryOp, Plain1>, Xpr2>& lhs, const Rhs& rhs, const Func &func) + { + call_assignment_no_alias(dst, lhs.lhs().functor().m_other * lhs.rhs().lazyProduct(rhs), func); + } + + // Here, we we always have LhsT==Lhs, but we need to make it a template type to make the above + // overload more specialized. + template + static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE + void eval_dynamic(Dst& dst, const LhsT& lhs, const Rhs& rhs, const Func &func) + { + call_assignment_no_alias(dst, lhs.lazyProduct(rhs), func); + } + // template // static inline void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha) @@ -779,7 +811,11 @@ public: _Vectorizable = bool(int(MatrixFlags)&PacketAccessBit) && _SameTypes && (_ScalarAccessOnDiag || (bool(int(DiagFlags)&PacketAccessBit))), _LinearAccessMask = (MatrixType::RowsAtCompileTime==1 || MatrixType::ColsAtCompileTime==1) ? LinearAccessBit : 0, Flags = ((HereditaryBits|_LinearAccessMask) & (unsigned int)(MatrixFlags)) | (_Vectorizable ? PacketAccessBit : 0), - Alignment = evaluator::Alignment + Alignment = evaluator::Alignment, + + AsScalarProduct = (DiagonalType::SizeAtCompileTime==1) + || (DiagonalType::SizeAtCompileTime==Dynamic && MatrixType::RowsAtCompileTime==1 && ProductOrder==OnTheLeft) + || (DiagonalType::SizeAtCompileTime==Dynamic && MatrixType::ColsAtCompileTime==1 && ProductOrder==OnTheRight) }; diagonal_product_evaluator_base(const MatrixType &mat, const DiagonalType &diag) @@ -791,7 +827,10 @@ public: EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar coeff(Index idx) const { - return m_diagImpl.coeff(idx) * m_matImpl.coeff(idx); + if(AsScalarProduct) + return m_diagImpl.coeff(0) * m_matImpl.coeff(idx); + else + return m_diagImpl.coeff(idx) * m_matImpl.coeff(idx); } protected: diff --git a/eigenlib/Eigen/src/Core/Redux.h b/eigenlib/Eigen/src/Core/Redux.h index b6e8f888..760e9f86 100644 --- a/eigenlib/Eigen/src/Core/Redux.h +++ b/eigenlib/Eigen/src/Core/Redux.h @@ -407,7 +407,7 @@ protected: */ template template -typename internal::traits::Scalar +EIGEN_STRONG_INLINE typename internal::traits::Scalar DenseBase::redux(const Func& func) const { eigen_assert(this->rows()>0 && this->cols()>0 && "you are using an empty matrix"); diff --git a/eigenlib/Eigen/src/Core/Ref.h b/eigenlib/Eigen/src/Core/Ref.h index bdf24f52..17a1496b 100644 --- a/eigenlib/Eigen/src/Core/Ref.h +++ b/eigenlib/Eigen/src/Core/Ref.h @@ -28,12 +28,13 @@ struct traits > template struct match { enum { + IsVectorAtCompileTime = PlainObjectType::IsVectorAtCompileTime || Derived::IsVectorAtCompileTime, HasDirectAccess = internal::has_direct_access::ret, - StorageOrderMatch = PlainObjectType::IsVectorAtCompileTime || Derived::IsVectorAtCompileTime || ((PlainObjectType::Flags&RowMajorBit)==(Derived::Flags&RowMajorBit)), + StorageOrderMatch = IsVectorAtCompileTime || ((PlainObjectType::Flags&RowMajorBit)==(Derived::Flags&RowMajorBit)), InnerStrideMatch = int(StrideType::InnerStrideAtCompileTime)==int(Dynamic) || int(StrideType::InnerStrideAtCompileTime)==int(Derived::InnerStrideAtCompileTime) || (int(StrideType::InnerStrideAtCompileTime)==0 && int(Derived::InnerStrideAtCompileTime)==1), - OuterStrideMatch = Derived::IsVectorAtCompileTime + OuterStrideMatch = IsVectorAtCompileTime || int(StrideType::OuterStrideAtCompileTime)==int(Dynamic) || int(StrideType::OuterStrideAtCompileTime)==int(Derived::OuterStrideAtCompileTime), // NOTE, this indirection of evaluator::Alignment is needed // to workaround a very strange bug in MSVC related to the instantiation @@ -95,6 +96,8 @@ protected: template EIGEN_DEVICE_FUNC void construct(Expression& expr) { + EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(PlainObjectType,Expression); + if(PlainObjectType::RowsAtCompileTime==1) { eigen_assert(expr.rows()==1 || expr.cols()==1); diff --git a/eigenlib/Eigen/src/Core/SelfAdjointView.h b/eigenlib/Eigen/src/Core/SelfAdjointView.h index 504c98f0..b2e51f37 100644 --- a/eigenlib/Eigen/src/Core/SelfAdjointView.h +++ b/eigenlib/Eigen/src/Core/SelfAdjointView.h @@ -71,7 +71,9 @@ template class SelfAdjointView EIGEN_DEVICE_FUNC explicit inline SelfAdjointView(MatrixType& matrix) : m_matrix(matrix) - {} + { + EIGEN_STATIC_ASSERT(UpLo==Lower || UpLo==Upper,SELFADJOINTVIEW_ACCEPTS_UPPER_AND_LOWER_MODE_ONLY); + } EIGEN_DEVICE_FUNC inline Index rows() const { return m_matrix.rows(); } @@ -189,7 +191,7 @@ template class SelfAdjointView TriangularView >::type(tmp2); } - typedef SelfAdjointView ConjugateReturnType; + typedef SelfAdjointView ConjugateReturnType; /** \sa MatrixBase::conjugate() const */ EIGEN_DEVICE_FUNC inline const ConjugateReturnType conjugate() const diff --git a/eigenlib/Eigen/src/Core/SelfCwiseBinaryOp.h b/eigenlib/Eigen/src/Core/SelfCwiseBinaryOp.h index 719ed72a..7c89c2e2 100644 --- a/eigenlib/Eigen/src/Core/SelfCwiseBinaryOp.h +++ b/eigenlib/Eigen/src/Core/SelfCwiseBinaryOp.h @@ -15,33 +15,29 @@ namespace Eigen { // TODO generalize the scalar type of 'other' template -EIGEN_STRONG_INLINE Derived& DenseBase::operator*=(const Scalar& other) +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase::operator*=(const Scalar& other) { - typedef typename Derived::PlainObject PlainObject; internal::call_assignment(this->derived(), PlainObject::Constant(rows(),cols(),other), internal::mul_assign_op()); return derived(); } template -EIGEN_STRONG_INLINE Derived& ArrayBase::operator+=(const Scalar& other) +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& ArrayBase::operator+=(const Scalar& other) { - typedef typename Derived::PlainObject PlainObject; internal::call_assignment(this->derived(), PlainObject::Constant(rows(),cols(),other), internal::add_assign_op()); return derived(); } template -EIGEN_STRONG_INLINE Derived& ArrayBase::operator-=(const Scalar& other) +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& ArrayBase::operator-=(const Scalar& other) { - typedef typename Derived::PlainObject PlainObject; internal::call_assignment(this->derived(), PlainObject::Constant(rows(),cols(),other), internal::sub_assign_op()); return derived(); } template -EIGEN_STRONG_INLINE Derived& DenseBase::operator/=(const Scalar& other) +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase::operator/=(const Scalar& other) { - typedef typename Derived::PlainObject PlainObject; internal::call_assignment(this->derived(), PlainObject::Constant(rows(),cols(),other), internal::div_assign_op()); return derived(); } diff --git a/eigenlib/Eigen/src/Core/Solve.h b/eigenlib/Eigen/src/Core/Solve.h index 960a5859..a8daea51 100644 --- a/eigenlib/Eigen/src/Core/Solve.h +++ b/eigenlib/Eigen/src/Core/Solve.h @@ -34,12 +34,12 @@ template struct s template struct solve_traits { - typedef Matrix PlainObject; + RhsType::MaxColsAtCompileTime>::type PlainObject; }; template diff --git a/eigenlib/Eigen/src/Core/SolveTriangular.h b/eigenlib/Eigen/src/Core/SolveTriangular.h index 049890b2..fd0acb1a 100644 --- a/eigenlib/Eigen/src/Core/SolveTriangular.h +++ b/eigenlib/Eigen/src/Core/SolveTriangular.h @@ -19,7 +19,7 @@ namespace internal { template struct triangular_solve_vector; -template +template struct triangular_solve_matrix; // small helper struct extracting some traits on the underlying solver operation @@ -98,8 +98,8 @@ struct triangular_solver_selector BlockingType blocking(rhs.rows(), rhs.cols(), size, 1, false); triangular_solve_matrix - ::run(size, othersize, &actualLhs.coeffRef(0,0), actualLhs.outerStride(), &rhs.coeffRef(0,0), rhs.outerStride(), blocking); + (Rhs::Flags&RowMajorBit) ? RowMajor : ColMajor, Rhs::InnerStrideAtCompileTime> + ::run(size, othersize, &actualLhs.coeffRef(0,0), actualLhs.outerStride(), &rhs.coeffRef(0,0), rhs.innerStride(), rhs.outerStride(), blocking); } }; @@ -169,6 +169,9 @@ void TriangularViewImpl::solveInPlace(const MatrixBase::Flags & RowMajorBit) && OtherDerived::IsVectorAtCompileTime && OtherDerived::SizeAtCompileTime!=1}; typedef typename internal::conditional::stableNorm() const typedef typename internal::nested_eval::type DerivedCopy; typedef typename internal::remove_all::type DerivedCopyClean; - DerivedCopy copy(derived()); + const DerivedCopy copy(derived()); enum { CanAlign = ( (int(DerivedCopyClean::Flags)&DirectAccessBit) || (int(internal::evaluator::Alignment)>0) // FIXME Alignment)>0 might not be enough - ) && (blockSize*sizeof(Scalar)*20) // if we cannot allocate on the stack, then let's not bother about this optimization }; typedef typename internal::conditional, internal::evaluator::Alignment>, typename DerivedCopyClean::ConstSegmentReturnType>::type SegmentWrapper; diff --git a/eigenlib/Eigen/src/Core/Transpose.h b/eigenlib/Eigen/src/Core/Transpose.h index 79b767bc..960dc451 100644 --- a/eigenlib/Eigen/src/Core/Transpose.h +++ b/eigenlib/Eigen/src/Core/Transpose.h @@ -146,6 +146,8 @@ template class TransposeImpl { return derived().nestedExpression().coeffRef(index); } + protected: + EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(TransposeImpl) }; /** \returns an expression of the transpose of *this. diff --git a/eigenlib/Eigen/src/Core/Transpositions.h b/eigenlib/Eigen/src/Core/Transpositions.h index 19c17bb4..7718625e 100644 --- a/eigenlib/Eigen/src/Core/Transpositions.h +++ b/eigenlib/Eigen/src/Core/Transpositions.h @@ -33,17 +33,6 @@ class TranspositionsBase indices() = other.indices(); return derived(); } - - #ifndef EIGEN_PARSED_BY_DOXYGEN - /** This is a special case of the templated operator=. Its purpose is to - * prevent a default operator= from hiding the templated operator=. - */ - Derived& operator=(const TranspositionsBase& other) - { - indices() = other.indices(); - return derived(); - } - #endif /** \returns the number of transpositions */ Index size() const { return indices().size(); } @@ -171,12 +160,6 @@ class Transpositions : public TranspositionsBase& other) : m_indices(other.indices()) {} - #ifndef EIGEN_PARSED_BY_DOXYGEN - /** Standard copy constructor. Defined only to prevent a default copy constructor - * from hiding the other templated constructor */ - inline Transpositions(const Transpositions& other) : m_indices(other.indices()) {} - #endif - /** Generic constructor from expression of the transposition indices. */ template explicit inline Transpositions(const MatrixBase& indices) : m_indices(indices) @@ -189,17 +172,6 @@ class Transpositions : public TranspositionsBase > const Product operator*(const MatrixBase& matrix, const Transpose& trt) { - return Product(matrix.derived(), trt.derived()); + return Product(matrix.derived(), trt); } /** \returns the \a matrix with the inverse transpositions applied to the rows. diff --git a/eigenlib/Eigen/src/Core/TriangularMatrix.h b/eigenlib/Eigen/src/Core/TriangularMatrix.h index 667ef09d..9abb7e31 100644 --- a/eigenlib/Eigen/src/Core/TriangularMatrix.h +++ b/eigenlib/Eigen/src/Core/TriangularMatrix.h @@ -217,9 +217,7 @@ template class TriangularView explicit inline TriangularView(MatrixType& matrix) : m_matrix(matrix) {} - using Base::operator=; - TriangularView& operator=(const TriangularView &other) - { return Base::operator=(other); } + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(TriangularView) /** \copydoc EigenBase::rows() */ EIGEN_DEVICE_FUNC @@ -544,6 +542,10 @@ template class TriangularViewImpl<_Mat template EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TriangularViewType& _assignProduct(const ProductType& prod, const Scalar& alpha, bool beta); + protected: + EIGEN_DEFAULT_COPY_CONSTRUCTOR(TriangularViewImpl) + EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(TriangularViewImpl) + }; /*************************************************************************** diff --git a/eigenlib/Eigen/src/Core/arch/AVX/Complex.h b/eigenlib/Eigen/src/Core/arch/AVX/Complex.h index 99439c8a..7fa61969 100644 --- a/eigenlib/Eigen/src/Core/arch/AVX/Complex.h +++ b/eigenlib/Eigen/src/Core/arch/AVX/Complex.h @@ -204,23 +204,7 @@ template<> struct conj_helper } }; -template<> struct conj_helper -{ - EIGEN_STRONG_INLINE Packet4cf pmadd(const Packet8f& x, const Packet4cf& y, const Packet4cf& c) const - { return padd(c, pmul(x,y)); } - - EIGEN_STRONG_INLINE Packet4cf pmul(const Packet8f& x, const Packet4cf& y) const - { return Packet4cf(Eigen::internal::pmul(x, y.v)); } -}; - -template<> struct conj_helper -{ - EIGEN_STRONG_INLINE Packet4cf pmadd(const Packet4cf& x, const Packet8f& y, const Packet4cf& c) const - { return padd(c, pmul(x,y)); } - - EIGEN_STRONG_INLINE Packet4cf pmul(const Packet4cf& x, const Packet8f& y) const - { return Packet4cf(Eigen::internal::pmul(x.v, y)); } -}; +EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet4cf,Packet8f) template<> EIGEN_STRONG_INLINE Packet4cf pdiv(const Packet4cf& a, const Packet4cf& b) { @@ -400,23 +384,7 @@ template<> struct conj_helper } }; -template<> struct conj_helper -{ - EIGEN_STRONG_INLINE Packet2cd pmadd(const Packet4d& x, const Packet2cd& y, const Packet2cd& c) const - { return padd(c, pmul(x,y)); } - - EIGEN_STRONG_INLINE Packet2cd pmul(const Packet4d& x, const Packet2cd& y) const - { return Packet2cd(Eigen::internal::pmul(x, y.v)); } -}; - -template<> struct conj_helper -{ - EIGEN_STRONG_INLINE Packet2cd pmadd(const Packet2cd& x, const Packet4d& y, const Packet2cd& c) const - { return padd(c, pmul(x,y)); } - - EIGEN_STRONG_INLINE Packet2cd pmul(const Packet2cd& x, const Packet4d& y) const - { return Packet2cd(Eigen::internal::pmul(x.v, y)); } -}; +EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet2cd,Packet4d) template<> EIGEN_STRONG_INLINE Packet2cd pdiv(const Packet2cd& a, const Packet2cd& b) { diff --git a/eigenlib/Eigen/src/Core/arch/AVX/PacketMath.h b/eigenlib/Eigen/src/Core/arch/AVX/PacketMath.h index 195d40fb..923a124b 100644 --- a/eigenlib/Eigen/src/Core/arch/AVX/PacketMath.h +++ b/eigenlib/Eigen/src/Core/arch/AVX/PacketMath.h @@ -159,11 +159,12 @@ template<> EIGEN_STRONG_INLINE Packet8i pdiv(const Packet8i& /*a*/, co #ifdef __FMA__ template<> EIGEN_STRONG_INLINE Packet8f pmadd(const Packet8f& a, const Packet8f& b, const Packet8f& c) { -#if ( EIGEN_COMP_GNUC_STRICT || (EIGEN_COMP_CLANG && (EIGEN_COMP_CLANG<308)) ) - // clang stupidly generates a vfmadd213ps instruction plus some vmovaps on registers, - // and gcc stupidly generates a vfmadd132ps instruction, - // so let's enforce it to generate a vfmadd231ps instruction since the most common use case is to accumulate - // the result of the product. +#if ( (EIGEN_COMP_GNUC_STRICT && EIGEN_COMP_GNUC<80) || (EIGEN_COMP_CLANG) ) + // Clang stupidly generates a vfmadd213ps instruction plus some vmovaps on registers, + // and even register spilling with clang>=6.0 (bug 1637). + // Gcc stupidly generates a vfmadd132ps instruction. + // So let's enforce it to generate a vfmadd231ps instruction since the most common use + // case is to accumulate the result of the product. Packet8f res = c; __asm__("vfmadd231ps %[a], %[b], %[c]" : [c] "+x" (res) : [a] "x" (a), [b] "x" (b)); return res; @@ -172,7 +173,7 @@ template<> EIGEN_STRONG_INLINE Packet8f pmadd(const Packet8f& a, const Packet8f& #endif } template<> EIGEN_STRONG_INLINE Packet4d pmadd(const Packet4d& a, const Packet4d& b, const Packet4d& c) { -#if ( EIGEN_COMP_GNUC_STRICT || (EIGEN_COMP_CLANG && (EIGEN_COMP_CLANG<308)) ) +#if ( (EIGEN_COMP_GNUC_STRICT && EIGEN_COMP_GNUC<80) || (EIGEN_COMP_CLANG) ) // see above Packet4d res = c; __asm__("vfmadd231pd %[a], %[b], %[c]" : [c] "+x" (res) : [a] "x" (a), [b] "x" (b)); @@ -308,9 +309,9 @@ template<> EIGEN_STRONG_INLINE void pstore1(int* to, const int& a) } #ifndef EIGEN_VECTORIZE_AVX512 -template<> EIGEN_STRONG_INLINE void prefetch(const float* addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); } -template<> EIGEN_STRONG_INLINE void prefetch(const double* addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); } -template<> EIGEN_STRONG_INLINE void prefetch(const int* addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); } +template<> EIGEN_STRONG_INLINE void prefetch(const float* addr) { _mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0); } +template<> EIGEN_STRONG_INLINE void prefetch(const double* addr) { _mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0); } +template<> EIGEN_STRONG_INLINE void prefetch(const int* addr) { _mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0); } #endif template<> EIGEN_STRONG_INLINE float pfirst(const Packet8f& a) { @@ -333,9 +334,12 @@ template<> EIGEN_STRONG_INLINE Packet4d preverse(const Packet4d& a) { __m256d tmp = _mm256_shuffle_pd(a,a,5); return _mm256_permute2f128_pd(tmp, tmp, 1); - + #if 0 + // This version is unlikely to be faster as _mm256_shuffle_ps and _mm256_permute_pd + // exhibit the same latency/throughput, but it is here for future reference/benchmarking... __m256d swap_halves = _mm256_permute2f128_pd(a,a,1); return _mm256_permute_pd(swap_halves,5); + #endif } // pabs should be ok diff --git a/eigenlib/Eigen/src/Core/arch/AVX512/MathFunctions.h b/eigenlib/Eigen/src/Core/arch/AVX512/MathFunctions.h index 399be0ee..b259c1e1 100644 --- a/eigenlib/Eigen/src/Core/arch/AVX512/MathFunctions.h +++ b/eigenlib/Eigen/src/Core/arch/AVX512/MathFunctions.h @@ -29,6 +29,7 @@ namespace internal { #define _EIGEN_DECLARE_CONST_Packet8d_FROM_INT64(NAME, X) \ const Packet8d p8d_##NAME = _mm512_castsi512_pd(_mm512_set1_epi64(X)) + // Natural logarithm // Computes log(x) as log(2^e * m) = C*e + log(m), where the constant C =log(2) // and m is in the range [sqrt(1/2),sqrt(2)). In this range, the logarithm can @@ -47,6 +48,7 @@ plog(const Packet16f& _x) { // The smallest non denormalized float number. _EIGEN_DECLARE_CONST_Packet16f_FROM_INT(min_norm_pos, 0x00800000); _EIGEN_DECLARE_CONST_Packet16f_FROM_INT(minus_inf, 0xff800000); + _EIGEN_DECLARE_CONST_Packet16f_FROM_INT(pos_inf, 0x7f800000); _EIGEN_DECLARE_CONST_Packet16f_FROM_INT(nan, 0x7fc00000); // Polynomial coefficients. @@ -64,11 +66,9 @@ plog(const Packet16f& _x) { _EIGEN_DECLARE_CONST_Packet16f(cephes_log_q2, 0.693359375f); // invalid_mask is set to true when x is NaN - __mmask16 invalid_mask = - _mm512_cmp_ps_mask(x, _mm512_setzero_ps(), _CMP_NGE_UQ); - __mmask16 iszero_mask = - _mm512_cmp_ps_mask(x, _mm512_setzero_ps(), _CMP_EQ_UQ); - + __mmask16 invalid_mask = _mm512_cmp_ps_mask(x, _mm512_setzero_ps(), _CMP_NGE_UQ); + __mmask16 iszero_mask = _mm512_cmp_ps_mask(x, _mm512_setzero_ps(), _CMP_EQ_OQ); + // Truncate input values to the minimum positive normal. x = pmax(x, p16f_min_norm_pos); @@ -88,9 +88,9 @@ plog(const Packet16f& _x) { // x = x + x - 1.0; // } else { x = x - 1.0; } __mmask16 mask = _mm512_cmp_ps_mask(x, p16f_cephes_SQRTHF, _CMP_LT_OQ); - Packet16f tmp = _mm512_mask_blend_ps(mask, x, _mm512_setzero_ps()); + Packet16f tmp = _mm512_mask_blend_ps(mask, _mm512_setzero_ps(), x); x = psub(x, p16f_1); - e = psub(e, _mm512_mask_blend_ps(mask, p16f_1, _mm512_setzero_ps())); + e = psub(e, _mm512_mask_blend_ps(mask, _mm512_setzero_ps(), p16f_1)); x = padd(x, tmp); Packet16f x2 = pmul(x, x); @@ -118,10 +118,18 @@ plog(const Packet16f& _x) { x = padd(x, y); x = padd(x, y2); - // Filter out invalid inputs, i.e. negative arg will be NAN, 0 will be -INF. - return _mm512_mask_blend_ps(iszero_mask, p16f_minus_inf, - _mm512_mask_blend_ps(invalid_mask, p16f_nan, x)); + __mmask16 pos_inf_mask = _mm512_cmp_ps_mask(_x,p16f_pos_inf,_CMP_EQ_OQ); + // Filter out invalid inputs, i.e.: + // - negative arg will be NAN, + // - 0 will be -INF. + // - +INF will be +INF + return _mm512_mask_blend_ps(iszero_mask, + _mm512_mask_blend_ps(invalid_mask, + _mm512_mask_blend_ps(pos_inf_mask,x,p16f_pos_inf), + p16f_nan), + p16f_minus_inf); } + #endif // Exponential function. Works by writing "x = m*log(2) + r" where @@ -257,50 +265,39 @@ pexp(const Packet8d& _x) { template <> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED Packet16f psqrt(const Packet16f& _x) { - _EIGEN_DECLARE_CONST_Packet16f(one_point_five, 1.5f); - _EIGEN_DECLARE_CONST_Packet16f(minus_half, -0.5f); - _EIGEN_DECLARE_CONST_Packet16f_FROM_INT(flt_min, 0x00800000); + Packet16f neg_half = pmul(_x, pset1(-.5f)); + __mmask16 denormal_mask = _mm512_kand( + _mm512_cmp_ps_mask(_x, pset1((std::numeric_limits::min)()), + _CMP_LT_OQ), + _mm512_cmp_ps_mask(_x, _mm512_setzero_ps(), _CMP_GE_OQ)); - Packet16f neg_half = pmul(_x, p16f_minus_half); - - // select only the inverse sqrt of positive normal inputs (denormals are - // flushed to zero and cause infs as well). - __mmask16 non_zero_mask = _mm512_cmp_ps_mask(_x, p16f_flt_min, _CMP_GE_OQ); - Packet16f x = _mm512_mask_blend_ps(non_zero_mask, _mm512_rsqrt14_ps(_x), - _mm512_setzero_ps()); + Packet16f x = _mm512_rsqrt14_ps(_x); // Do a single step of Newton's iteration. - x = pmul(x, pmadd(neg_half, pmul(x, x), p16f_one_point_five)); + x = pmul(x, pmadd(neg_half, pmul(x, x), pset1(1.5f))); - // Multiply the original _x by it's reciprocal square root to extract the - // square root. - return pmul(_x, x); + // Flush results for denormals to zero. + return _mm512_mask_blend_ps(denormal_mask, pmul(_x,x), _mm512_setzero_ps()); } template <> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED Packet8d psqrt(const Packet8d& _x) { - _EIGEN_DECLARE_CONST_Packet8d(one_point_five, 1.5); - _EIGEN_DECLARE_CONST_Packet8d(minus_half, -0.5); - _EIGEN_DECLARE_CONST_Packet8d_FROM_INT64(dbl_min, 0x0010000000000000LL); + Packet8d neg_half = pmul(_x, pset1(-.5)); + __mmask16 denormal_mask = _mm512_kand( + _mm512_cmp_pd_mask(_x, pset1((std::numeric_limits::min)()), + _CMP_LT_OQ), + _mm512_cmp_pd_mask(_x, _mm512_setzero_pd(), _CMP_GE_OQ)); - Packet8d neg_half = pmul(_x, p8d_minus_half); + Packet8d x = _mm512_rsqrt14_pd(_x); - // select only the inverse sqrt of positive normal inputs (denormals are - // flushed to zero and cause infs as well). - __mmask8 non_zero_mask = _mm512_cmp_pd_mask(_x, p8d_dbl_min, _CMP_GE_OQ); - Packet8d x = _mm512_mask_blend_pd(non_zero_mask, _mm512_rsqrt14_pd(_x), - _mm512_setzero_pd()); - - // Do a first step of Newton's iteration. - x = pmul(x, pmadd(neg_half, pmul(x, x), p8d_one_point_five)); + // Do a single step of Newton's iteration. + x = pmul(x, pmadd(neg_half, pmul(x, x), pset1(1.5))); // Do a second step of Newton's iteration. - x = pmul(x, pmadd(neg_half, pmul(x, x), p8d_one_point_five)); + x = pmul(x, pmadd(neg_half, pmul(x, x), pset1(1.5))); - // Multiply the original _x by it's reciprocal square root to extract the - // square root. - return pmul(_x, x); + return _mm512_mask_blend_pd(denormal_mask, pmul(_x,x), _mm512_setzero_pd()); } #else template <> @@ -333,20 +330,18 @@ prsqrt(const Packet16f& _x) { // select only the inverse sqrt of positive normal inputs (denormals are // flushed to zero and cause infs as well). __mmask16 le_zero_mask = _mm512_cmp_ps_mask(_x, p16f_flt_min, _CMP_LT_OQ); - Packet16f x = _mm512_mask_blend_ps(le_zero_mask, _mm512_setzero_ps(), - _mm512_rsqrt14_ps(_x)); + Packet16f x = _mm512_mask_blend_ps(le_zero_mask, _mm512_rsqrt14_ps(_x), _mm512_setzero_ps()); // Fill in NaNs and Infs for the negative/zero entries. __mmask16 neg_mask = _mm512_cmp_ps_mask(_x, _mm512_setzero_ps(), _CMP_LT_OQ); Packet16f infs_and_nans = _mm512_mask_blend_ps( - neg_mask, p16f_nan, - _mm512_mask_blend_ps(le_zero_mask, p16f_inf, _mm512_setzero_ps())); + neg_mask, _mm512_mask_blend_ps(le_zero_mask, _mm512_setzero_ps(), p16f_inf), p16f_nan); // Do a single step of Newton's iteration. x = pmul(x, pmadd(neg_half, pmul(x, x), p16f_one_point_five)); // Insert NaNs and Infs in all the right places. - return _mm512_mask_blend_ps(le_zero_mask, infs_and_nans, x); + return _mm512_mask_blend_ps(le_zero_mask, x, infs_and_nans); } template <> @@ -363,14 +358,12 @@ prsqrt(const Packet8d& _x) { // select only the inverse sqrt of positive normal inputs (denormals are // flushed to zero and cause infs as well). __mmask8 le_zero_mask = _mm512_cmp_pd_mask(_x, p8d_dbl_min, _CMP_LT_OQ); - Packet8d x = _mm512_mask_blend_pd(le_zero_mask, _mm512_setzero_pd(), - _mm512_rsqrt14_pd(_x)); + Packet8d x = _mm512_mask_blend_pd(le_zero_mask, _mm512_rsqrt14_pd(_x), _mm512_setzero_pd()); // Fill in NaNs and Infs for the negative/zero entries. __mmask8 neg_mask = _mm512_cmp_pd_mask(_x, _mm512_setzero_pd(), _CMP_LT_OQ); Packet8d infs_and_nans = _mm512_mask_blend_pd( - neg_mask, p8d_nan, - _mm512_mask_blend_pd(le_zero_mask, p8d_inf, _mm512_setzero_pd())); + neg_mask, _mm512_mask_blend_pd(le_zero_mask, _mm512_setzero_pd(), p8d_inf), p8d_nan); // Do a first step of Newton's iteration. x = pmul(x, pmadd(neg_half, pmul(x, x), p8d_one_point_five)); @@ -379,9 +372,9 @@ prsqrt(const Packet8d& _x) { x = pmul(x, pmadd(neg_half, pmul(x, x), p8d_one_point_five)); // Insert NaNs and Infs in all the right places. - return _mm512_mask_blend_pd(le_zero_mask, infs_and_nans, x); + return _mm512_mask_blend_pd(le_zero_mask, x, infs_and_nans); } -#else +#elif defined(EIGEN_VECTORIZE_AVX512ER) template <> EIGEN_STRONG_INLINE Packet16f prsqrt(const Packet16f& x) { return _mm512_rsqrt28_ps(x); diff --git a/eigenlib/Eigen/src/Core/arch/AVX512/PacketMath.h b/eigenlib/Eigen/src/Core/arch/AVX512/PacketMath.h index f6500a16..000b7762 100644 --- a/eigenlib/Eigen/src/Core/arch/AVX512/PacketMath.h +++ b/eigenlib/Eigen/src/Core/arch/AVX512/PacketMath.h @@ -19,10 +19,10 @@ namespace internal { #endif #ifndef EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS -#define EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS (2*sizeof(void*)) +#define EIGEN_ARCH_DEFAULT_NUMBER_OF_REGISTERS 32 #endif -#ifdef __FMA__ +#ifdef EIGEN_VECTORIZE_FMA #ifndef EIGEN_HAS_SINGLE_INSTRUCTION_MADD #define EIGEN_HAS_SINGLE_INSTRUCTION_MADD #endif @@ -54,13 +54,14 @@ template<> struct packet_traits : default_packet_traits AlignedOnScalar = 1, size = 16, HasHalfPacket = 1, -#if EIGEN_GNUC_AT_LEAST(5, 3) + HasBlend = 0, +#if EIGEN_GNUC_AT_LEAST(5, 3) || (!EIGEN_COMP_GNUC_STRICT) #ifdef EIGEN_VECTORIZE_AVX512DQ HasLog = 1, #endif HasExp = 1, - HasSqrt = 1, - HasRsqrt = 1, + HasSqrt = EIGEN_FAST_MATH, + HasRsqrt = EIGEN_FAST_MATH, #endif HasDiv = 1 }; @@ -74,8 +75,8 @@ template<> struct packet_traits : default_packet_traits AlignedOnScalar = 1, size = 8, HasHalfPacket = 1, -#if EIGEN_GNUC_AT_LEAST(5, 3) - HasSqrt = 1, +#if EIGEN_GNUC_AT_LEAST(5, 3) || (!EIGEN_COMP_GNUC_STRICT) + HasSqrt = EIGEN_FAST_MATH, HasRsqrt = EIGEN_FAST_MATH, #endif HasDiv = 1 @@ -98,6 +99,7 @@ template <> struct unpacket_traits { typedef float type; typedef Packet8f half; + typedef Packet16i integer_packet; enum { size = 16, alignment=Aligned64 }; }; template <> @@ -132,7 +134,7 @@ EIGEN_STRONG_INLINE Packet16f pload1(const float* from) { } template <> EIGEN_STRONG_INLINE Packet8d pload1(const double* from) { - return _mm512_broadcastsd_pd(_mm_load_pd1(from)); + return _mm512_set1_pd(*from); } template <> @@ -158,6 +160,11 @@ EIGEN_STRONG_INLINE Packet8d padd(const Packet8d& a, const Packet8d& b) { return _mm512_add_pd(a, b); } +template <> +EIGEN_STRONG_INLINE Packet16i padd(const Packet16i& a, + const Packet16i& b) { + return _mm512_add_epi32(a, b); +} template <> EIGEN_STRONG_INLINE Packet16f psub(const Packet16f& a, @@ -169,6 +176,11 @@ EIGEN_STRONG_INLINE Packet8d psub(const Packet8d& a, const Packet8d& b) { return _mm512_sub_pd(a, b); } +template <> +EIGEN_STRONG_INLINE Packet16i psub(const Packet16i& a, + const Packet16i& b) { + return _mm512_sub_epi32(a, b); +} template <> EIGEN_STRONG_INLINE Packet16f pnegate(const Packet16f& a) { @@ -202,6 +214,11 @@ EIGEN_STRONG_INLINE Packet8d pmul(const Packet8d& a, const Packet8d& b) { return _mm512_mul_pd(a, b); } +template <> +EIGEN_STRONG_INLINE Packet16i pmul(const Packet16i& a, + const Packet16i& b) { + return _mm512_mul_epi32(a, b); +} template <> EIGEN_STRONG_INLINE Packet16f pdiv(const Packet16f& a, @@ -214,7 +231,7 @@ EIGEN_STRONG_INLINE Packet8d pdiv(const Packet8d& a, return _mm512_div_pd(a, b); } -#ifdef __FMA__ +#ifdef EIGEN_VECTORIZE_FMA template <> EIGEN_STRONG_INLINE Packet16f pmadd(const Packet16f& a, const Packet16f& b, const Packet16f& c) { @@ -230,23 +247,73 @@ EIGEN_STRONG_INLINE Packet8d pmadd(const Packet8d& a, const Packet8d& b, template <> EIGEN_STRONG_INLINE Packet16f pmin(const Packet16f& a, const Packet16f& b) { - return _mm512_min_ps(a, b); + // Arguments are reversed to match NaN propagation behavior of std::min. + return _mm512_min_ps(b, a); } template <> EIGEN_STRONG_INLINE Packet8d pmin(const Packet8d& a, const Packet8d& b) { - return _mm512_min_pd(a, b); + // Arguments are reversed to match NaN propagation behavior of std::min. + return _mm512_min_pd(b, a); } template <> EIGEN_STRONG_INLINE Packet16f pmax(const Packet16f& a, const Packet16f& b) { - return _mm512_max_ps(a, b); + // Arguments are reversed to match NaN propagation behavior of std::max. + return _mm512_max_ps(b, a); } template <> EIGEN_STRONG_INLINE Packet8d pmax(const Packet8d& a, const Packet8d& b) { - return _mm512_max_pd(a, b); + // Arguments are reversed to match NaN propagation behavior of std::max. + return _mm512_max_pd(b, a); +} + +#ifdef EIGEN_VECTORIZE_AVX512DQ +template EIGEN_STRONG_INLINE Packet8f extract256(Packet16f x) { return _mm512_extractf32x8_ps(x,I_); } +template EIGEN_STRONG_INLINE Packet2d extract128(Packet8d x) { return _mm512_extractf64x2_pd(x,I_); } +EIGEN_STRONG_INLINE Packet16f cat256(Packet8f a, Packet8f b) { return _mm512_insertf32x8(_mm512_castps256_ps512(a),b,1); } +#else +// AVX512F does not define _mm512_extractf32x8_ps to extract _m256 from _m512 +template EIGEN_STRONG_INLINE Packet8f extract256(Packet16f x) { + return _mm256_castsi256_ps(_mm512_extracti64x4_epi64( _mm512_castps_si512(x),I_)); +} + +// AVX512F does not define _mm512_extractf64x2_pd to extract _m128 from _m512 +template EIGEN_STRONG_INLINE Packet2d extract128(Packet8d x) { + return _mm_castsi128_pd(_mm512_extracti32x4_epi32( _mm512_castpd_si512(x),I_)); +} + +EIGEN_STRONG_INLINE Packet16f cat256(Packet8f a, Packet8f b) { + return _mm512_castsi512_ps(_mm512_inserti64x4(_mm512_castsi256_si512(_mm256_castps_si256(a)), + _mm256_castps_si256(b),1)); +} +#endif + +// Helper function for bit packing snippet of low precision comparison. +// It packs the flags from 32x16 to 16x16. +EIGEN_STRONG_INLINE __m256i Pack32To16(Packet16f rf) { + // Split data into small pieces and handle with AVX instructions + // to guarantee internal order of vector. + // Operation: + // dst[15:0] := Saturate16(rf[31:0]) + // dst[31:16] := Saturate16(rf[63:32]) + // ... + // dst[255:240] := Saturate16(rf[255:224]) + __m256i lo = _mm256_castps_si256(extract256<0>(rf)); + __m256i hi = _mm256_castps_si256(extract256<1>(rf)); + __m128i result_lo = _mm_packs_epi32(_mm256_extractf128_si256(lo, 0), + _mm256_extractf128_si256(lo, 1)); + __m128i result_hi = _mm_packs_epi32(_mm256_extractf128_si256(hi, 0), + _mm256_extractf128_si256(hi, 1)); + return _mm256_insertf128_si256(_mm256_castsi128_si256(result_lo), result_hi, 1); +} + +template <> +EIGEN_STRONG_INLINE Packet16i pand(const Packet16i& a, + const Packet16i& b) { + return _mm512_and_si512(a,b); } template <> @@ -255,24 +322,7 @@ EIGEN_STRONG_INLINE Packet16f pand(const Packet16f& a, #ifdef EIGEN_VECTORIZE_AVX512DQ return _mm512_and_ps(a, b); #else - Packet16f res = _mm512_undefined_ps(); - Packet4f lane0_a = _mm512_extractf32x4_ps(a, 0); - Packet4f lane0_b = _mm512_extractf32x4_ps(b, 0); - res = _mm512_insertf32x4(res, _mm_and_ps(lane0_a, lane0_b), 0); - - Packet4f lane1_a = _mm512_extractf32x4_ps(a, 1); - Packet4f lane1_b = _mm512_extractf32x4_ps(b, 1); - res = _mm512_insertf32x4(res, _mm_and_ps(lane1_a, lane1_b), 1); - - Packet4f lane2_a = _mm512_extractf32x4_ps(a, 2); - Packet4f lane2_b = _mm512_extractf32x4_ps(b, 2); - res = _mm512_insertf32x4(res, _mm_and_ps(lane2_a, lane2_b), 2); - - Packet4f lane3_a = _mm512_extractf32x4_ps(a, 3); - Packet4f lane3_b = _mm512_extractf32x4_ps(b, 3); - res = _mm512_insertf32x4(res, _mm_and_ps(lane3_a, lane3_b), 3); - - return res; + return _mm512_castsi512_ps(pand(_mm512_castps_si512(a),_mm512_castps_si512(b))); #endif } template <> @@ -288,35 +338,21 @@ EIGEN_STRONG_INLINE Packet8d pand(const Packet8d& a, Packet4d lane1_a = _mm512_extractf64x4_pd(a, 1); Packet4d lane1_b = _mm512_extractf64x4_pd(b, 1); - res = _mm512_insertf64x4(res, _mm256_and_pd(lane1_a, lane1_b), 1); - - return res; + return _mm512_insertf64x4(res, _mm256_and_pd(lane1_a, lane1_b), 1); #endif } + template <> -EIGEN_STRONG_INLINE Packet16f por(const Packet16f& a, - const Packet16f& b) { +EIGEN_STRONG_INLINE Packet16i por(const Packet16i& a, const Packet16i& b) { + return _mm512_or_si512(a, b); +} + +template <> +EIGEN_STRONG_INLINE Packet16f por(const Packet16f& a, const Packet16f& b) { #ifdef EIGEN_VECTORIZE_AVX512DQ return _mm512_or_ps(a, b); #else - Packet16f res = _mm512_undefined_ps(); - Packet4f lane0_a = _mm512_extractf32x4_ps(a, 0); - Packet4f lane0_b = _mm512_extractf32x4_ps(b, 0); - res = _mm512_insertf32x4(res, _mm_or_ps(lane0_a, lane0_b), 0); - - Packet4f lane1_a = _mm512_extractf32x4_ps(a, 1); - Packet4f lane1_b = _mm512_extractf32x4_ps(b, 1); - res = _mm512_insertf32x4(res, _mm_or_ps(lane1_a, lane1_b), 1); - - Packet4f lane2_a = _mm512_extractf32x4_ps(a, 2); - Packet4f lane2_b = _mm512_extractf32x4_ps(b, 2); - res = _mm512_insertf32x4(res, _mm_or_ps(lane2_a, lane2_b), 2); - - Packet4f lane3_a = _mm512_extractf32x4_ps(a, 3); - Packet4f lane3_b = _mm512_extractf32x4_ps(b, 3); - res = _mm512_insertf32x4(res, _mm_or_ps(lane3_a, lane3_b), 3); - - return res; + return _mm512_castsi512_ps(por(_mm512_castps_si512(a),_mm512_castps_si512(b))); #endif } @@ -326,109 +362,67 @@ EIGEN_STRONG_INLINE Packet8d por(const Packet8d& a, #ifdef EIGEN_VECTORIZE_AVX512DQ return _mm512_or_pd(a, b); #else - Packet8d res = _mm512_undefined_pd(); - Packet4d lane0_a = _mm512_extractf64x4_pd(a, 0); - Packet4d lane0_b = _mm512_extractf64x4_pd(b, 0); - res = _mm512_insertf64x4(res, _mm256_or_pd(lane0_a, lane0_b), 0); - - Packet4d lane1_a = _mm512_extractf64x4_pd(a, 1); - Packet4d lane1_b = _mm512_extractf64x4_pd(b, 1); - res = _mm512_insertf64x4(res, _mm256_or_pd(lane1_a, lane1_b), 1); - - return res; + return _mm512_castsi512_pd(por(_mm512_castpd_si512(a),_mm512_castpd_si512(b))); #endif } template <> -EIGEN_STRONG_INLINE Packet16f pxor(const Packet16f& a, - const Packet16f& b) { +EIGEN_STRONG_INLINE Packet16i pxor(const Packet16i& a, const Packet16i& b) { + return _mm512_xor_si512(a, b); +} + +template <> +EIGEN_STRONG_INLINE Packet16f pxor(const Packet16f& a, const Packet16f& b) { #ifdef EIGEN_VECTORIZE_AVX512DQ return _mm512_xor_ps(a, b); #else - Packet16f res = _mm512_undefined_ps(); - Packet4f lane0_a = _mm512_extractf32x4_ps(a, 0); - Packet4f lane0_b = _mm512_extractf32x4_ps(b, 0); - res = _mm512_insertf32x4(res, _mm_xor_ps(lane0_a, lane0_b), 0); - - Packet4f lane1_a = _mm512_extractf32x4_ps(a, 1); - Packet4f lane1_b = _mm512_extractf32x4_ps(b, 1); - res = _mm512_insertf32x4(res, _mm_xor_ps(lane1_a, lane1_b), 1); - - Packet4f lane2_a = _mm512_extractf32x4_ps(a, 2); - Packet4f lane2_b = _mm512_extractf32x4_ps(b, 2); - res = _mm512_insertf32x4(res, _mm_xor_ps(lane2_a, lane2_b), 2); - - Packet4f lane3_a = _mm512_extractf32x4_ps(a, 3); - Packet4f lane3_b = _mm512_extractf32x4_ps(b, 3); - res = _mm512_insertf32x4(res, _mm_xor_ps(lane3_a, lane3_b), 3); - - return res; + return _mm512_castsi512_ps(pxor(_mm512_castps_si512(a),_mm512_castps_si512(b))); #endif } + template <> -EIGEN_STRONG_INLINE Packet8d pxor(const Packet8d& a, - const Packet8d& b) { +EIGEN_STRONG_INLINE Packet8d pxor(const Packet8d& a, const Packet8d& b) { #ifdef EIGEN_VECTORIZE_AVX512DQ return _mm512_xor_pd(a, b); #else - Packet8d res = _mm512_undefined_pd(); - Packet4d lane0_a = _mm512_extractf64x4_pd(a, 0); - Packet4d lane0_b = _mm512_extractf64x4_pd(b, 0); - res = _mm512_insertf64x4(res, _mm256_xor_pd(lane0_a, lane0_b), 0); - - Packet4d lane1_a = _mm512_extractf64x4_pd(a, 1); - Packet4d lane1_b = _mm512_extractf64x4_pd(b, 1); - res = _mm512_insertf64x4(res, _mm256_xor_pd(lane1_a, lane1_b), 1); - - return res; + return _mm512_castsi512_pd(pxor(_mm512_castpd_si512(a),_mm512_castpd_si512(b))); #endif } template <> -EIGEN_STRONG_INLINE Packet16f pandnot(const Packet16f& a, - const Packet16f& b) { +EIGEN_STRONG_INLINE Packet16i pandnot(const Packet16i& a, const Packet16i& b) { + return _mm512_andnot_si512(b, a); +} + +template <> +EIGEN_STRONG_INLINE Packet16f pandnot(const Packet16f& a, const Packet16f& b) { #ifdef EIGEN_VECTORIZE_AVX512DQ - return _mm512_andnot_ps(a, b); + return _mm512_andnot_ps(b, a); #else - Packet16f res = _mm512_undefined_ps(); - Packet4f lane0_a = _mm512_extractf32x4_ps(a, 0); - Packet4f lane0_b = _mm512_extractf32x4_ps(b, 0); - res = _mm512_insertf32x4(res, _mm_andnot_ps(lane0_a, lane0_b), 0); - - Packet4f lane1_a = _mm512_extractf32x4_ps(a, 1); - Packet4f lane1_b = _mm512_extractf32x4_ps(b, 1); - res = _mm512_insertf32x4(res, _mm_andnot_ps(lane1_a, lane1_b), 1); - - Packet4f lane2_a = _mm512_extractf32x4_ps(a, 2); - Packet4f lane2_b = _mm512_extractf32x4_ps(b, 2); - res = _mm512_insertf32x4(res, _mm_andnot_ps(lane2_a, lane2_b), 2); - - Packet4f lane3_a = _mm512_extractf32x4_ps(a, 3); - Packet4f lane3_b = _mm512_extractf32x4_ps(b, 3); - res = _mm512_insertf32x4(res, _mm_andnot_ps(lane3_a, lane3_b), 3); - - return res; + return _mm512_castsi512_ps(pandnot(_mm512_castps_si512(a),_mm512_castps_si512(b))); #endif } template <> -EIGEN_STRONG_INLINE Packet8d pandnot(const Packet8d& a, - const Packet8d& b) { +EIGEN_STRONG_INLINE Packet8d pandnot(const Packet8d& a,const Packet8d& b) { #ifdef EIGEN_VECTORIZE_AVX512DQ - return _mm512_andnot_pd(a, b); + return _mm512_andnot_pd(b, a); #else - Packet8d res = _mm512_undefined_pd(); - Packet4d lane0_a = _mm512_extractf64x4_pd(a, 0); - Packet4d lane0_b = _mm512_extractf64x4_pd(b, 0); - res = _mm512_insertf64x4(res, _mm256_andnot_pd(lane0_a, lane0_b), 0); - - Packet4d lane1_a = _mm512_extractf64x4_pd(a, 1); - Packet4d lane1_b = _mm512_extractf64x4_pd(b, 1); - res = _mm512_insertf64x4(res, _mm256_andnot_pd(lane1_a, lane1_b), 1); - - return res; + return _mm512_castsi512_pd(pandnot(_mm512_castpd_si512(a),_mm512_castpd_si512(b))); #endif } +template EIGEN_STRONG_INLINE Packet16i parithmetic_shift_right(Packet16i a) { + return _mm512_srai_epi32(a, N); +} + +template EIGEN_STRONG_INLINE Packet16i plogical_shift_right(Packet16i a) { + return _mm512_srli_epi32(a, N); +} + +template EIGEN_STRONG_INLINE Packet16i plogical_shift_left(Packet16i a) { + return _mm512_slli_epi32(a, N); +} + template <> EIGEN_STRONG_INLINE Packet16f pload(const float* from) { EIGEN_DEBUG_ALIGNED_LOAD return _mm512_load_ps(from); @@ -461,75 +455,55 @@ EIGEN_STRONG_INLINE Packet16i ploadu(const int* from) { // {a0, a0 a1, a1, a2, a2, a3, a3, a4, a4, a5, a5, a6, a6, a7, a7} template <> EIGEN_STRONG_INLINE Packet16f ploaddup(const float* from) { - Packet8f lane0 = _mm256_broadcast_ps((const __m128*)(const void*)from); - // mimic an "inplace" permutation of the lower 128bits using a blend - lane0 = _mm256_blend_ps( - lane0, _mm256_castps128_ps256(_mm_permute_ps( - _mm256_castps256_ps128(lane0), _MM_SHUFFLE(1, 0, 1, 0))), - 15); - // then we can perform a consistent permutation on the global register to get - // everything in shape: - lane0 = _mm256_permute_ps(lane0, _MM_SHUFFLE(3, 3, 2, 2)); - - Packet8f lane1 = _mm256_broadcast_ps((const __m128*)(const void*)(from + 4)); - // mimic an "inplace" permutation of the lower 128bits using a blend - lane1 = _mm256_blend_ps( - lane1, _mm256_castps128_ps256(_mm_permute_ps( - _mm256_castps256_ps128(lane1), _MM_SHUFFLE(1, 0, 1, 0))), - 15); - // then we can perform a consistent permutation on the global register to get - // everything in shape: - lane1 = _mm256_permute_ps(lane1, _MM_SHUFFLE(3, 3, 2, 2)); + // an unaligned load is required here as there is no requirement + // on the alignment of input pointer 'from' + __m256i low_half = _mm256_loadu_si256(reinterpret_cast(from)); + __m512 even_elements = _mm512_castsi512_ps(_mm512_cvtepu32_epi64(low_half)); + __m512 pairs = _mm512_permute_ps(even_elements, _MM_SHUFFLE(2, 2, 0, 0)); + return pairs; +} #ifdef EIGEN_VECTORIZE_AVX512DQ - Packet16f res = _mm512_undefined_ps(); - return _mm512_insertf32x8(res, lane0, 0); - return _mm512_insertf32x8(res, lane1, 1); - return res; -#else - Packet16f res = _mm512_undefined_ps(); - res = _mm512_insertf32x4(res, _mm256_extractf128_ps(lane0, 0), 0); - res = _mm512_insertf32x4(res, _mm256_extractf128_ps(lane0, 1), 1); - res = _mm512_insertf32x4(res, _mm256_extractf128_ps(lane1, 0), 2); - res = _mm512_insertf32x4(res, _mm256_extractf128_ps(lane1, 1), 3); - return res; -#endif -} +// FIXME: this does not look optimal, better load a Packet4d and shuffle... // Loads 4 doubles from memory a returns the packet {a0, a0 a1, a1, a2, a2, a3, // a3} template <> EIGEN_STRONG_INLINE Packet8d ploaddup(const double* from) { - Packet4d lane0 = _mm256_broadcast_pd((const __m128d*)(const void*)from); - lane0 = _mm256_permute_pd(lane0, 3 << 2); - - Packet4d lane1 = _mm256_broadcast_pd((const __m128d*)(const void*)(from + 2)); - lane1 = _mm256_permute_pd(lane1, 3 << 2); - - Packet8d res = _mm512_undefined_pd(); - res = _mm512_insertf64x4(res, lane0, 0); - return _mm512_insertf64x4(res, lane1, 1); + __m512d x = _mm512_setzero_pd(); + x = _mm512_insertf64x2(x, _mm_loaddup_pd(&from[0]), 0); + x = _mm512_insertf64x2(x, _mm_loaddup_pd(&from[1]), 1); + x = _mm512_insertf64x2(x, _mm_loaddup_pd(&from[2]), 2); + x = _mm512_insertf64x2(x, _mm_loaddup_pd(&from[3]), 3); + return x; } +#else +template <> +EIGEN_STRONG_INLINE Packet8d ploaddup(const double* from) { + __m512d x = _mm512_setzero_pd(); + x = _mm512_mask_broadcastsd_pd(x, 0x3<<0, _mm_load_sd(from+0)); + x = _mm512_mask_broadcastsd_pd(x, 0x3<<2, _mm_load_sd(from+1)); + x = _mm512_mask_broadcastsd_pd(x, 0x3<<4, _mm_load_sd(from+2)); + x = _mm512_mask_broadcastsd_pd(x, 0x3<<6, _mm_load_sd(from+3)); + return x; +} +#endif // Loads 4 floats from memory a returns the packet // {a0, a0 a0, a0, a1, a1, a1, a1, a2, a2, a2, a2, a3, a3, a3, a3} template <> EIGEN_STRONG_INLINE Packet16f ploadquad(const float* from) { - Packet16f tmp = _mm512_undefined_ps(); - tmp = _mm512_insertf32x4(tmp, _mm_load_ps1(from), 0); - tmp = _mm512_insertf32x4(tmp, _mm_load_ps1(from + 1), 1); - tmp = _mm512_insertf32x4(tmp, _mm_load_ps1(from + 2), 2); - tmp = _mm512_insertf32x4(tmp, _mm_load_ps1(from + 3), 3); - return tmp; + Packet16f tmp = _mm512_castps128_ps512(ploadu(from)); + const Packet16i scatter_mask = _mm512_set_epi32(3,3,3,3, 2,2,2,2, 1,1,1,1, 0,0,0,0); + return _mm512_permutexvar_ps(scatter_mask, tmp); } + // Loads 2 doubles from memory a returns the packet // {a0, a0 a0, a0, a1, a1, a1, a1} template <> EIGEN_STRONG_INLINE Packet8d ploadquad(const double* from) { - Packet8d tmp = _mm512_undefined_pd(); - Packet2d tmp0 = _mm_load_pd1(from); - Packet2d tmp1 = _mm_load_pd1(from + 1); - Packet4d lane0 = _mm256_broadcastsd_pd(tmp0); - Packet4d lane1 = _mm256_broadcastsd_pd(tmp1); + __m256d lane0 = _mm256_set1_pd(*from); + __m256d lane1 = _mm256_set1_pd(*(from+1)); + __m512d tmp = _mm512_undefined_pd(); tmp = _mm512_insertf64x4(tmp, lane0, 0); return _mm512_insertf64x4(tmp, lane1, 1); } @@ -565,7 +539,7 @@ EIGEN_STRONG_INLINE void pstoreu(int* to, const Packet16i& from) { template <> EIGEN_DEVICE_FUNC inline Packet16f pgather(const float* from, Index stride) { - Packet16i stride_vector = _mm512_set1_epi32(stride); + Packet16i stride_vector = _mm512_set1_epi32(convert_index(stride)); Packet16i stride_multiplier = _mm512_set_epi32(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); Packet16i indices = _mm512_mullo_epi32(stride_vector, stride_multiplier); @@ -575,7 +549,7 @@ EIGEN_DEVICE_FUNC inline Packet16f pgather(const float* from, template <> EIGEN_DEVICE_FUNC inline Packet8d pgather(const double* from, Index stride) { - Packet8i stride_vector = _mm256_set1_epi32(stride); + Packet8i stride_vector = _mm256_set1_epi32(convert_index(stride)); Packet8i stride_multiplier = _mm256_set_epi32(7, 6, 5, 4, 3, 2, 1, 0); Packet8i indices = _mm256_mullo_epi32(stride_vector, stride_multiplier); @@ -586,7 +560,7 @@ template <> EIGEN_DEVICE_FUNC inline void pscatter(float* to, const Packet16f& from, Index stride) { - Packet16i stride_vector = _mm512_set1_epi32(stride); + Packet16i stride_vector = _mm512_set1_epi32(convert_index(stride)); Packet16i stride_multiplier = _mm512_set_epi32(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); Packet16i indices = _mm512_mullo_epi32(stride_vector, stride_multiplier); @@ -596,7 +570,7 @@ template <> EIGEN_DEVICE_FUNC inline void pscatter(double* to, const Packet8d& from, Index stride) { - Packet8i stride_vector = _mm256_set1_epi32(stride); + Packet8i stride_vector = _mm256_set1_epi32(convert_index(stride)); Packet8i stride_multiplier = _mm256_set_epi32(7, 6, 5, 4, 3, 2, 1, 0); Packet8i indices = _mm256_mullo_epi32(stride_vector, stride_multiplier); _mm512_i32scatter_pd(to, indices, from, 8); @@ -618,9 +592,9 @@ EIGEN_STRONG_INLINE void pstore1(int* to, const int& a) { pstore(to, pa); } -template<> EIGEN_STRONG_INLINE void prefetch(const float* addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); } -template<> EIGEN_STRONG_INLINE void prefetch(const double* addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); } -template<> EIGEN_STRONG_INLINE void prefetch(const int* addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); } +template<> EIGEN_STRONG_INLINE void prefetch(const float* addr) { _mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0); } +template<> EIGEN_STRONG_INLINE void prefetch(const double* addr) { _mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0); } +template<> EIGEN_STRONG_INLINE void prefetch(const int* addr) { _mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0); } template <> EIGEN_STRONG_INLINE float pfirst(const Packet16f& a) { @@ -648,20 +622,20 @@ template<> EIGEN_STRONG_INLINE Packet8d preverse(const Packet8d& a) template<> EIGEN_STRONG_INLINE Packet16f pabs(const Packet16f& a) { // _mm512_abs_ps intrinsic not found, so hack around it - return (__m512)_mm512_and_si512((__m512i)a, _mm512_set1_epi32(0x7fffffff)); + return _mm512_castsi512_ps(_mm512_and_si512(_mm512_castps_si512(a), _mm512_set1_epi32(0x7fffffff))); } template <> EIGEN_STRONG_INLINE Packet8d pabs(const Packet8d& a) { // _mm512_abs_ps intrinsic not found, so hack around it - return (__m512d)_mm512_and_si512((__m512i)a, - _mm512_set1_epi64(0x7fffffffffffffff)); + return _mm512_castsi512_pd(_mm512_and_si512(_mm512_castpd_si512(a), + _mm512_set1_epi64(0x7fffffffffffffff))); } #ifdef EIGEN_VECTORIZE_AVX512DQ // AVX512F does not define _mm512_extractf32x8_ps to extract _m256 from _m512 #define EIGEN_EXTRACT_8f_FROM_16f(INPUT, OUTPUT) \ - __m256 OUTPUT##_0 = _mm512_extractf32x8_ps(INPUT, 0) __m256 OUTPUT##_1 = \ - _mm512_extractf32x8_ps(INPUT, 1) + __m256 OUTPUT##_0 = _mm512_extractf32x8_ps(INPUT, 0); \ + __m256 OUTPUT##_1 = _mm512_extractf32x8_ps(INPUT, 1) #else #define EIGEN_EXTRACT_8f_FROM_16f(INPUT, OUTPUT) \ __m256 OUTPUT##_0 = _mm256_insertf128_ps( \ @@ -674,17 +648,136 @@ EIGEN_STRONG_INLINE Packet8d pabs(const Packet8d& a) { #ifdef EIGEN_VECTORIZE_AVX512DQ #define EIGEN_INSERT_8f_INTO_16f(OUTPUT, INPUTA, INPUTB) \ - OUTPUT = _mm512_insertf32x8(OUTPUT, INPUTA, 0); \ - OUTPUT = _mm512_insertf32x8(OUTPUT, INPUTB, 1); + OUTPUT = _mm512_insertf32x8(_mm512_castps256_ps512(INPUTA), INPUTB, 1); #else #define EIGEN_INSERT_8f_INTO_16f(OUTPUT, INPUTA, INPUTB) \ + OUTPUT = _mm512_undefined_ps(); \ OUTPUT = _mm512_insertf32x4(OUTPUT, _mm256_extractf128_ps(INPUTA, 0), 0); \ OUTPUT = _mm512_insertf32x4(OUTPUT, _mm256_extractf128_ps(INPUTA, 1), 1); \ OUTPUT = _mm512_insertf32x4(OUTPUT, _mm256_extractf128_ps(INPUTB, 0), 2); \ OUTPUT = _mm512_insertf32x4(OUTPUT, _mm256_extractf128_ps(INPUTB, 1), 3); #endif -template<> EIGEN_STRONG_INLINE Packet16f preduxp(const Packet16f* -vecs) + +template <> +EIGEN_STRONG_INLINE float predux(const Packet16f& a) { +#ifdef EIGEN_VECTORIZE_AVX512DQ + __m256 lane0 = _mm512_extractf32x8_ps(a, 0); + __m256 lane1 = _mm512_extractf32x8_ps(a, 1); + Packet8f x = _mm256_add_ps(lane0, lane1); + return predux(x); +#else + __m128 lane0 = _mm512_extractf32x4_ps(a, 0); + __m128 lane1 = _mm512_extractf32x4_ps(a, 1); + __m128 lane2 = _mm512_extractf32x4_ps(a, 2); + __m128 lane3 = _mm512_extractf32x4_ps(a, 3); + __m128 sum = _mm_add_ps(_mm_add_ps(lane0, lane1), _mm_add_ps(lane2, lane3)); + sum = _mm_hadd_ps(sum, sum); + sum = _mm_hadd_ps(sum, _mm_permute_ps(sum, 1)); + return _mm_cvtss_f32(sum); +#endif +} +template <> +EIGEN_STRONG_INLINE double predux(const Packet8d& a) { + __m256d lane0 = _mm512_extractf64x4_pd(a, 0); + __m256d lane1 = _mm512_extractf64x4_pd(a, 1); + __m256d sum = _mm256_add_pd(lane0, lane1); + __m256d tmp0 = _mm256_hadd_pd(sum, _mm256_permute2f128_pd(sum, sum, 1)); + return _mm_cvtsd_f64(_mm256_castpd256_pd128(_mm256_hadd_pd(tmp0, tmp0))); +} + +template <> +EIGEN_STRONG_INLINE Packet8f predux_downto4(const Packet16f& a) { +#ifdef EIGEN_VECTORIZE_AVX512DQ + Packet8f lane0 = _mm512_extractf32x8_ps(a, 0); + Packet8f lane1 = _mm512_extractf32x8_ps(a, 1); + return padd(lane0, lane1); +#else + Packet4f lane0 = _mm512_extractf32x4_ps(a, 0); + Packet4f lane1 = _mm512_extractf32x4_ps(a, 1); + Packet4f lane2 = _mm512_extractf32x4_ps(a, 2); + Packet4f lane3 = _mm512_extractf32x4_ps(a, 3); + Packet4f sum0 = padd(lane0, lane2); + Packet4f sum1 = padd(lane1, lane3); + return _mm256_insertf128_ps(_mm256_castps128_ps256(sum0), sum1, 1); +#endif +} +template <> +EIGEN_STRONG_INLINE Packet4d predux_downto4(const Packet8d& a) { + Packet4d lane0 = _mm512_extractf64x4_pd(a, 0); + Packet4d lane1 = _mm512_extractf64x4_pd(a, 1); + Packet4d res = padd(lane0, lane1); + return res; +} + +template <> +EIGEN_STRONG_INLINE float predux_mul(const Packet16f& a) { +//#ifdef EIGEN_VECTORIZE_AVX512DQ +#if 0 + Packet8f lane0 = _mm512_extractf32x8_ps(a, 0); + Packet8f lane1 = _mm512_extractf32x8_ps(a, 1); + Packet8f res = pmul(lane0, lane1); + res = pmul(res, _mm256_permute2f128_ps(res, res, 1)); + res = pmul(res, _mm_permute_ps(res, _MM_SHUFFLE(0, 0, 3, 2))); + return pfirst(pmul(res, _mm_permute_ps(res, _MM_SHUFFLE(0, 0, 0, 1)))); +#else + __m128 lane0 = _mm512_extractf32x4_ps(a, 0); + __m128 lane1 = _mm512_extractf32x4_ps(a, 1); + __m128 lane2 = _mm512_extractf32x4_ps(a, 2); + __m128 lane3 = _mm512_extractf32x4_ps(a, 3); + __m128 res = pmul(pmul(lane0, lane1), pmul(lane2, lane3)); + res = pmul(res, _mm_permute_ps(res, _MM_SHUFFLE(0, 0, 3, 2))); + return pfirst(pmul(res, _mm_permute_ps(res, _MM_SHUFFLE(0, 0, 0, 1)))); +#endif +} +template <> +EIGEN_STRONG_INLINE double predux_mul(const Packet8d& a) { + __m256d lane0 = _mm512_extractf64x4_pd(a, 0); + __m256d lane1 = _mm512_extractf64x4_pd(a, 1); + __m256d res = pmul(lane0, lane1); + res = pmul(res, _mm256_permute2f128_pd(res, res, 1)); + return pfirst(pmul(res, _mm256_shuffle_pd(res, res, 1))); +} + +template <> +EIGEN_STRONG_INLINE float predux_min(const Packet16f& a) { + __m128 lane0 = _mm512_extractf32x4_ps(a, 0); + __m128 lane1 = _mm512_extractf32x4_ps(a, 1); + __m128 lane2 = _mm512_extractf32x4_ps(a, 2); + __m128 lane3 = _mm512_extractf32x4_ps(a, 3); + __m128 res = _mm_min_ps(_mm_min_ps(lane0, lane1), _mm_min_ps(lane2, lane3)); + res = _mm_min_ps(res, _mm_permute_ps(res, _MM_SHUFFLE(0, 0, 3, 2))); + return pfirst(_mm_min_ps(res, _mm_permute_ps(res, _MM_SHUFFLE(0, 0, 0, 1)))); +} +template <> +EIGEN_STRONG_INLINE double predux_min(const Packet8d& a) { + __m256d lane0 = _mm512_extractf64x4_pd(a, 0); + __m256d lane1 = _mm512_extractf64x4_pd(a, 1); + __m256d res = _mm256_min_pd(lane0, lane1); + res = _mm256_min_pd(res, _mm256_permute2f128_pd(res, res, 1)); + return pfirst(_mm256_min_pd(res, _mm256_shuffle_pd(res, res, 1))); +} + +template <> +EIGEN_STRONG_INLINE float predux_max(const Packet16f& a) { + __m128 lane0 = _mm512_extractf32x4_ps(a, 0); + __m128 lane1 = _mm512_extractf32x4_ps(a, 1); + __m128 lane2 = _mm512_extractf32x4_ps(a, 2); + __m128 lane3 = _mm512_extractf32x4_ps(a, 3); + __m128 res = _mm_max_ps(_mm_max_ps(lane0, lane1), _mm_max_ps(lane2, lane3)); + res = _mm_max_ps(res, _mm_permute_ps(res, _MM_SHUFFLE(0, 0, 3, 2))); + return pfirst(_mm_max_ps(res, _mm_permute_ps(res, _MM_SHUFFLE(0, 0, 0, 1)))); +} + +template <> +EIGEN_STRONG_INLINE double predux_max(const Packet8d& a) { + __m256d lane0 = _mm512_extractf64x4_pd(a, 0); + __m256d lane1 = _mm512_extractf64x4_pd(a, 1); + __m256d res = _mm256_max_pd(lane0, lane1); + res = _mm256_max_pd(res, _mm256_permute2f128_pd(res, res, 1)); + return pfirst(_mm256_max_pd(res, _mm256_shuffle_pd(res, res, 1))); +} + +template<> EIGEN_STRONG_INLINE Packet16f preduxp(const Packet16f* vecs) { EIGEN_EXTRACT_8f_FROM_16f(vecs[0], vecs0); EIGEN_EXTRACT_8f_FROM_16f(vecs[1], vecs1); @@ -873,174 +966,7 @@ template<> EIGEN_STRONG_INLINE Packet8d preduxp(const Packet8d* vecs) return _mm512_insertf64x4(final_output, final_1, 1); } - -template <> -EIGEN_STRONG_INLINE float predux(const Packet16f& a) { - //#ifdef EIGEN_VECTORIZE_AVX512DQ -#if 0 - Packet8f lane0 = _mm512_extractf32x8_ps(a, 0); - Packet8f lane1 = _mm512_extractf32x8_ps(a, 1); - Packet8f sum = padd(lane0, lane1); - Packet8f tmp0 = _mm256_hadd_ps(sum, _mm256_permute2f128_ps(a, a, 1)); - tmp0 = _mm256_hadd_ps(tmp0, tmp0); - return pfirst(_mm256_hadd_ps(tmp0, tmp0)); -#else - Packet4f lane0 = _mm512_extractf32x4_ps(a, 0); - Packet4f lane1 = _mm512_extractf32x4_ps(a, 1); - Packet4f lane2 = _mm512_extractf32x4_ps(a, 2); - Packet4f lane3 = _mm512_extractf32x4_ps(a, 3); - Packet4f sum = padd(padd(lane0, lane1), padd(lane2, lane3)); - sum = _mm_hadd_ps(sum, sum); - sum = _mm_hadd_ps(sum, _mm_permute_ps(sum, 1)); - return pfirst(sum); -#endif -} -template <> -EIGEN_STRONG_INLINE double predux(const Packet8d& a) { - Packet4d lane0 = _mm512_extractf64x4_pd(a, 0); - Packet4d lane1 = _mm512_extractf64x4_pd(a, 1); - Packet4d sum = padd(lane0, lane1); - Packet4d tmp0 = _mm256_hadd_pd(sum, _mm256_permute2f128_pd(sum, sum, 1)); - return pfirst(_mm256_hadd_pd(tmp0, tmp0)); -} - -template <> -EIGEN_STRONG_INLINE Packet8f predux_downto4(const Packet16f& a) { -#ifdef EIGEN_VECTORIZE_AVX512DQ - Packet8f lane0 = _mm512_extractf32x8_ps(a, 0); - Packet8f lane1 = _mm512_extractf32x8_ps(a, 1); - return padd(lane0, lane1); -#else - Packet4f lane0 = _mm512_extractf32x4_ps(a, 0); - Packet4f lane1 = _mm512_extractf32x4_ps(a, 1); - Packet4f lane2 = _mm512_extractf32x4_ps(a, 2); - Packet4f lane3 = _mm512_extractf32x4_ps(a, 3); - Packet4f sum0 = padd(lane0, lane2); - Packet4f sum1 = padd(lane1, lane3); - return _mm256_insertf128_ps(_mm256_castps128_ps256(sum0), sum1, 1); -#endif -} -template <> -EIGEN_STRONG_INLINE Packet4d predux_downto4(const Packet8d& a) { - Packet4d lane0 = _mm512_extractf64x4_pd(a, 0); - Packet4d lane1 = _mm512_extractf64x4_pd(a, 1); - Packet4d res = padd(lane0, lane1); - return res; -} - -template <> -EIGEN_STRONG_INLINE float predux_mul(const Packet16f& a) { -//#ifdef EIGEN_VECTORIZE_AVX512DQ -#if 0 - Packet8f lane0 = _mm512_extractf32x8_ps(a, 0); - Packet8f lane1 = _mm512_extractf32x8_ps(a, 1); - Packet8f res = pmul(lane0, lane1); - res = pmul(res, _mm256_permute2f128_ps(res, res, 1)); - res = pmul(res, _mm_permute_ps(res, _MM_SHUFFLE(0, 0, 3, 2))); - return pfirst(pmul(res, _mm_permute_ps(res, _MM_SHUFFLE(0, 0, 0, 1)))); -#else - Packet4f lane0 = _mm512_extractf32x4_ps(a, 0); - Packet4f lane1 = _mm512_extractf32x4_ps(a, 1); - Packet4f lane2 = _mm512_extractf32x4_ps(a, 2); - Packet4f lane3 = _mm512_extractf32x4_ps(a, 3); - Packet4f res = pmul(pmul(lane0, lane1), pmul(lane2, lane3)); - res = pmul(res, _mm_permute_ps(res, _MM_SHUFFLE(0, 0, 3, 2))); - return pfirst(pmul(res, _mm_permute_ps(res, _MM_SHUFFLE(0, 0, 0, 1)))); -#endif -} -template <> -EIGEN_STRONG_INLINE double predux_mul(const Packet8d& a) { - Packet4d lane0 = _mm512_extractf64x4_pd(a, 0); - Packet4d lane1 = _mm512_extractf64x4_pd(a, 1); - Packet4d res = pmul(lane0, lane1); - res = pmul(res, _mm256_permute2f128_pd(res, res, 1)); - return pfirst(pmul(res, _mm256_shuffle_pd(res, res, 1))); -} - -template <> -EIGEN_STRONG_INLINE float predux_min(const Packet16f& a) { - Packet4f lane0 = _mm512_extractf32x4_ps(a, 0); - Packet4f lane1 = _mm512_extractf32x4_ps(a, 1); - Packet4f lane2 = _mm512_extractf32x4_ps(a, 2); - Packet4f lane3 = _mm512_extractf32x4_ps(a, 3); - Packet4f res = _mm_min_ps(_mm_min_ps(lane0, lane1), _mm_min_ps(lane2, lane3)); - res = _mm_min_ps(res, _mm_permute_ps(res, _MM_SHUFFLE(0, 0, 3, 2))); - return pfirst(_mm_min_ps(res, _mm_permute_ps(res, _MM_SHUFFLE(0, 0, 0, 1)))); -} -template <> -EIGEN_STRONG_INLINE double predux_min(const Packet8d& a) { - Packet4d lane0 = _mm512_extractf64x4_pd(a, 0); - Packet4d lane1 = _mm512_extractf64x4_pd(a, 1); - Packet4d res = _mm256_min_pd(lane0, lane1); - res = _mm256_min_pd(res, _mm256_permute2f128_pd(res, res, 1)); - return pfirst(_mm256_min_pd(res, _mm256_shuffle_pd(res, res, 1))); -} - -template <> -EIGEN_STRONG_INLINE float predux_max(const Packet16f& a) { - Packet4f lane0 = _mm512_extractf32x4_ps(a, 0); - Packet4f lane1 = _mm512_extractf32x4_ps(a, 1); - Packet4f lane2 = _mm512_extractf32x4_ps(a, 2); - Packet4f lane3 = _mm512_extractf32x4_ps(a, 3); - Packet4f res = _mm_max_ps(_mm_max_ps(lane0, lane1), _mm_max_ps(lane2, lane3)); - res = _mm_max_ps(res, _mm_permute_ps(res, _MM_SHUFFLE(0, 0, 3, 2))); - return pfirst(_mm_max_ps(res, _mm_permute_ps(res, _MM_SHUFFLE(0, 0, 0, 1)))); -} -template <> -EIGEN_STRONG_INLINE double predux_max(const Packet8d& a) { - Packet4d lane0 = _mm512_extractf64x4_pd(a, 0); - Packet4d lane1 = _mm512_extractf64x4_pd(a, 1); - Packet4d res = _mm256_max_pd(lane0, lane1); - res = _mm256_max_pd(res, _mm256_permute2f128_pd(res, res, 1)); - return pfirst(_mm256_max_pd(res, _mm256_shuffle_pd(res, res, 1))); -} - -template -struct palign_impl { - static EIGEN_STRONG_INLINE void run(Packet16f& first, - const Packet16f& second) { - if (Offset != 0) { - __m512i first_idx = _mm512_set_epi32( - Offset + 15, Offset + 14, Offset + 13, Offset + 12, Offset + 11, - Offset + 10, Offset + 9, Offset + 8, Offset + 7, Offset + 6, - Offset + 5, Offset + 4, Offset + 3, Offset + 2, Offset + 1, Offset); - - __m512i second_idx = - _mm512_set_epi32(Offset - 1, Offset - 2, Offset - 3, Offset - 4, - Offset - 5, Offset - 6, Offset - 7, Offset - 8, - Offset - 9, Offset - 10, Offset - 11, Offset - 12, - Offset - 13, Offset - 14, Offset - 15, Offset - 16); - - unsigned short mask = 0xFFFF; - mask <<= (16 - Offset); - - first = _mm512_permutexvar_ps(first_idx, first); - Packet16f tmp = _mm512_permutexvar_ps(second_idx, second); - first = _mm512_mask_blend_ps(mask, first, tmp); - } - } -}; -template -struct palign_impl { - static EIGEN_STRONG_INLINE void run(Packet8d& first, const Packet8d& second) { - if (Offset != 0) { - __m512i first_idx = _mm512_set_epi32( - 0, Offset + 7, 0, Offset + 6, 0, Offset + 5, 0, Offset + 4, 0, - Offset + 3, 0, Offset + 2, 0, Offset + 1, 0, Offset); - - __m512i second_idx = _mm512_set_epi32( - 0, Offset - 1, 0, Offset - 2, 0, Offset - 3, 0, Offset - 4, 0, - Offset - 5, 0, Offset - 6, 0, Offset - 7, 0, Offset - 8); - - unsigned char mask = 0xFF; - mask <<= (8 - Offset); - - first = _mm512_permutexvar_pd(first_idx, first); - Packet8d tmp = _mm512_permutexvar_pd(second_idx, second); - first = _mm512_mask_blend_pd(mask, first, tmp); - } - } -}; + #define PACK_OUTPUT(OUTPUT, INPUT, INDEX, STRIDE) \ @@ -1302,13 +1228,76 @@ EIGEN_STRONG_INLINE Packet16f pblend(const Selector<16>& /*ifPacket*/, return Packet16f(); } template <> -EIGEN_STRONG_INLINE Packet8d pblend(const Selector<8>& /*ifPacket*/, - const Packet8d& /*thenPacket*/, - const Packet8d& /*elsePacket*/) { - assert(false && "To be implemented"); - return Packet8d(); +EIGEN_STRONG_INLINE Packet8d pblend(const Selector<8>& ifPacket, + const Packet8d& thenPacket, + const Packet8d& elsePacket) { + __mmask8 m = (ifPacket.select[0] ) + | (ifPacket.select[1]<<1) + | (ifPacket.select[2]<<2) + | (ifPacket.select[3]<<3) + | (ifPacket.select[4]<<4) + | (ifPacket.select[5]<<5) + | (ifPacket.select[6]<<6) + | (ifPacket.select[7]<<7); + return _mm512_mask_blend_pd(m, elsePacket, thenPacket); } +template<> EIGEN_STRONG_INLINE Packet16i pcast(const Packet16f& a) { + return _mm512_cvttps_epi32(a); +} + +template<> EIGEN_STRONG_INLINE Packet16f pcast(const Packet16i& a) { + return _mm512_cvtepi32_ps(a); +} + +template +struct palign_impl { + static EIGEN_STRONG_INLINE void run(Packet16f& first, + const Packet16f& second) { + if (Offset != 0) { + __m512i first_idx = _mm512_set_epi32( + Offset + 15, Offset + 14, Offset + 13, Offset + 12, Offset + 11, + Offset + 10, Offset + 9, Offset + 8, Offset + 7, Offset + 6, + Offset + 5, Offset + 4, Offset + 3, Offset + 2, Offset + 1, Offset); + + __m512i second_idx = + _mm512_set_epi32(Offset - 1, Offset - 2, Offset - 3, Offset - 4, + Offset - 5, Offset - 6, Offset - 7, Offset - 8, + Offset - 9, Offset - 10, Offset - 11, Offset - 12, + Offset - 13, Offset - 14, Offset - 15, Offset - 16); + + unsigned short mask = 0xFFFF; + mask <<= (16 - Offset); + + first = _mm512_permutexvar_ps(first_idx, first); + Packet16f tmp = _mm512_permutexvar_ps(second_idx, second); + first = _mm512_mask_blend_ps(mask, first, tmp); + } + } +}; +template +struct palign_impl { + static EIGEN_STRONG_INLINE void run(Packet8d& first, const Packet8d& second) { + if (Offset != 0) { + __m512i first_idx = _mm512_set_epi32( + 0, Offset + 7, 0, Offset + 6, 0, Offset + 5, 0, Offset + 4, 0, + Offset + 3, 0, Offset + 2, 0, Offset + 1, 0, Offset); + + __m512i second_idx = _mm512_set_epi32( + 0, Offset - 1, 0, Offset - 2, 0, Offset - 3, 0, Offset - 4, 0, + Offset - 5, 0, Offset - 6, 0, Offset - 7, 0, Offset - 8); + + unsigned char mask = 0xFF; + mask <<= (8 - Offset); + + first = _mm512_permutexvar_pd(first_idx, first); + Packet8d tmp = _mm512_permutexvar_pd(second_idx, second); + first = _mm512_mask_blend_pd(mask, first, tmp); + } + } +}; + + } // end namespace internal } // end namespace Eigen diff --git a/eigenlib/Eigen/src/Core/arch/AltiVec/Complex.h b/eigenlib/Eigen/src/Core/arch/AltiVec/Complex.h index 59367ba2..3e665730 100644 --- a/eigenlib/Eigen/src/Core/arch/AltiVec/Complex.h +++ b/eigenlib/Eigen/src/Core/arch/AltiVec/Complex.h @@ -65,7 +65,7 @@ template<> struct unpacket_traits { typedef std::complex type; template<> EIGEN_STRONG_INLINE Packet2cf pset1(const std::complex& from) { Packet2cf res; - if((ptrdiff_t(&from) % 16) == 0) + if((std::ptrdiff_t(&from) % 16) == 0) res.v = pload((const float *)&from); else res.v = ploadu((const float *)&from); @@ -224,23 +224,7 @@ template<> struct conj_helper } }; -template<> struct conj_helper -{ - EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet4f& x, const Packet2cf& y, const Packet2cf& c) const - { return padd(c, pmul(x,y)); } - - EIGEN_STRONG_INLINE Packet2cf pmul(const Packet4f& x, const Packet2cf& y) const - { return Packet2cf(internal::pmul(x, y.v)); } -}; - -template<> struct conj_helper -{ - EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet4f& y, const Packet2cf& c) const - { return padd(c, pmul(x,y)); } - - EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& x, const Packet4f& y) const - { return Packet2cf(internal::pmul(x.v, y)); } -}; +EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet2cf,Packet4f) template<> EIGEN_STRONG_INLINE Packet2cf pdiv(const Packet2cf& a, const Packet2cf& b) { @@ -416,23 +400,8 @@ template<> struct conj_helper return pconj(internal::pmul(a, b)); } }; -template<> struct conj_helper -{ - EIGEN_STRONG_INLINE Packet1cd pmadd(const Packet2d& x, const Packet1cd& y, const Packet1cd& c) const - { return padd(c, pmul(x,y)); } - EIGEN_STRONG_INLINE Packet1cd pmul(const Packet2d& x, const Packet1cd& y) const - { return Packet1cd(internal::pmul(x, y.v)); } -}; - -template<> struct conj_helper -{ - EIGEN_STRONG_INLINE Packet1cd pmadd(const Packet1cd& x, const Packet2d& y, const Packet1cd& c) const - { return padd(c, pmul(x,y)); } - - EIGEN_STRONG_INLINE Packet1cd pmul(const Packet1cd& x, const Packet2d& y) const - { return Packet1cd(internal::pmul(x.v, y)); } -}; +EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet1cd,Packet2d) template<> EIGEN_STRONG_INLINE Packet1cd pdiv(const Packet1cd& a, const Packet1cd& b) { diff --git a/eigenlib/Eigen/src/Core/arch/AltiVec/PacketMath.h b/eigenlib/Eigen/src/Core/arch/AltiVec/PacketMath.h index e7d4f4d8..08a27d15 100755 --- a/eigenlib/Eigen/src/Core/arch/AltiVec/PacketMath.h +++ b/eigenlib/Eigen/src/Core/arch/AltiVec/PacketMath.h @@ -90,7 +90,7 @@ static Packet16uc p16uc_DUPLICATE32_HI = { 0,1,2,3, 0,1,2,3, 4,5,6,7, 4,5,6,7 }; #define _EIGEN_MASK_ALIGNMENT 0xfffffff0 #endif -#define _EIGEN_ALIGNED_PTR(x) ((ptrdiff_t)(x) & _EIGEN_MASK_ALIGNMENT) +#define _EIGEN_ALIGNED_PTR(x) ((std::ptrdiff_t)(x) & _EIGEN_MASK_ALIGNMENT) // Handle endianness properly while loading constants // Define global static constants: @@ -103,7 +103,7 @@ static Packet16uc p16uc_PSET32_WODD = vec_sld((Packet16uc) vec_splat((Packet4u static Packet16uc p16uc_PSET32_WEVEN = vec_sld(p16uc_DUPLICATE32_HI, (Packet16uc) vec_splat((Packet4ui)p16uc_FORWARD, 3), 8);//{ 4,5,6,7, 4,5,6,7, 12,13,14,15, 12,13,14,15 }; static Packet16uc p16uc_HALF64_0_16 = vec_sld((Packet16uc)p4i_ZERO, vec_splat((Packet16uc) vec_abs(p4i_MINUS16), 3), 8); //{ 0,0,0,0, 0,0,0,0, 16,16,16,16, 16,16,16,16}; #else -static Packet16uc p16uc_FORWARD = p16uc_REVERSE32; +static Packet16uc p16uc_FORWARD = p16uc_REVERSE32; static Packet16uc p16uc_REVERSE64 = { 8,9,10,11, 12,13,14,15, 0,1,2,3, 4,5,6,7 }; static Packet16uc p16uc_PSET32_WODD = vec_sld((Packet16uc) vec_splat((Packet4ui)p16uc_FORWARD, 1), (Packet16uc) vec_splat((Packet4ui)p16uc_FORWARD, 3), 8);//{ 0,1,2,3, 0,1,2,3, 8,9,10,11, 8,9,10,11 }; static Packet16uc p16uc_PSET32_WEVEN = vec_sld((Packet16uc) vec_splat((Packet4ui)p16uc_FORWARD, 0), (Packet16uc) vec_splat((Packet4ui)p16uc_FORWARD, 2), 8);//{ 4,5,6,7, 4,5,6,7, 12,13,14,15, 12,13,14,15 }; @@ -388,10 +388,28 @@ template<> EIGEN_STRONG_INLINE Packet4i pdiv(const Packet4i& /*a*/, co template<> EIGEN_STRONG_INLINE Packet4f pmadd(const Packet4f& a, const Packet4f& b, const Packet4f& c) { return vec_madd(a,b,c); } template<> EIGEN_STRONG_INLINE Packet4i pmadd(const Packet4i& a, const Packet4i& b, const Packet4i& c) { return a*b + c; } -template<> EIGEN_STRONG_INLINE Packet4f pmin(const Packet4f& a, const Packet4f& b) { return vec_min(a, b); } +template<> EIGEN_STRONG_INLINE Packet4f pmin(const Packet4f& a, const Packet4f& b) +{ + #ifdef __VSX__ + Packet4f ret; + __asm__ ("xvcmpgesp %x0,%x1,%x2\n\txxsel %x0,%x1,%x2,%x0" : "=&wa" (ret) : "wa" (a), "wa" (b)); + return ret; + #else + return vec_min(a, b); + #endif +} template<> EIGEN_STRONG_INLINE Packet4i pmin(const Packet4i& a, const Packet4i& b) { return vec_min(a, b); } -template<> EIGEN_STRONG_INLINE Packet4f pmax(const Packet4f& a, const Packet4f& b) { return vec_max(a, b); } +template<> EIGEN_STRONG_INLINE Packet4f pmax(const Packet4f& a, const Packet4f& b) +{ + #ifdef __VSX__ + Packet4f ret; + __asm__ ("xvcmpgtsp %x0,%x2,%x1\n\txxsel %x0,%x1,%x2,%x0" : "=&wa" (ret) : "wa" (a), "wa" (b)); + return ret; + #else + return vec_max(a, b); + #endif +} template<> EIGEN_STRONG_INLINE Packet4i pmax(const Packet4i& a, const Packet4i& b) { return vec_max(a, b); } template<> EIGEN_STRONG_INLINE Packet4f pand(const Packet4f& a, const Packet4f& b) { return vec_and(a, b); } @@ -450,15 +468,15 @@ template<> EIGEN_STRONG_INLINE Packet4f ploadu(const float* from) template<> EIGEN_STRONG_INLINE Packet4f ploaddup(const float* from) { Packet4f p; - if((ptrdiff_t(from) % 16) == 0) p = pload(from); - else p = ploadu(from); + if((std::ptrdiff_t(from) % 16) == 0) p = pload(from); + else p = ploadu(from); return vec_perm(p, p, p16uc_DUPLICATE32_HI); } template<> EIGEN_STRONG_INLINE Packet4i ploaddup(const int* from) { Packet4i p; - if((ptrdiff_t(from) % 16) == 0) p = pload(from); - else p = ploadu(from); + if((std::ptrdiff_t(from) % 16) == 0) p = pload(from); + else p = ploadu(from); return vec_perm(p, p, p16uc_DUPLICATE32_HI); } @@ -764,7 +782,7 @@ typedef __vector __bool long Packet2bl; static Packet2l p2l_ONE = { 1, 1 }; static Packet2l p2l_ZERO = reinterpret_cast(p4i_ZERO); -static Packet2d p2d_ONE = { 1.0, 1.0 }; +static Packet2d p2d_ONE = { 1.0, 1.0 }; static Packet2d p2d_ZERO = reinterpret_cast(p4f_ZERO); static Packet2d p2d_MZERO = { -0.0, -0.0 }; @@ -910,9 +928,19 @@ template<> EIGEN_STRONG_INLINE Packet2d pdiv(const Packet2d& a, const // for some weird raisons, it has to be overloaded for packet of integers template<> EIGEN_STRONG_INLINE Packet2d pmadd(const Packet2d& a, const Packet2d& b, const Packet2d& c) { return vec_madd(a, b, c); } -template<> EIGEN_STRONG_INLINE Packet2d pmin(const Packet2d& a, const Packet2d& b) { return vec_min(a, b); } +template<> EIGEN_STRONG_INLINE Packet2d pmin(const Packet2d& a, const Packet2d& b) +{ + Packet2d ret; + __asm__ ("xvcmpgedp %x0,%x1,%x2\n\txxsel %x0,%x1,%x2,%x0" : "=&wa" (ret) : "wa" (a), "wa" (b)); + return ret; + } -template<> EIGEN_STRONG_INLINE Packet2d pmax(const Packet2d& a, const Packet2d& b) { return vec_max(a, b); } +template<> EIGEN_STRONG_INLINE Packet2d pmax(const Packet2d& a, const Packet2d& b) +{ + Packet2d ret; + __asm__ ("xvcmpgtdp %x0,%x2,%x1\n\txxsel %x0,%x1,%x2,%x0" : "=&wa" (ret) : "wa" (a), "wa" (b)); + return ret; +} template<> EIGEN_STRONG_INLINE Packet2d pand(const Packet2d& a, const Packet2d& b) { return vec_and(a, b); } @@ -935,8 +963,8 @@ template<> EIGEN_STRONG_INLINE Packet2d ploadu(const double* from) template<> EIGEN_STRONG_INLINE Packet2d ploaddup(const double* from) { Packet2d p; - if((ptrdiff_t(from) % 16) == 0) p = pload(from); - else p = ploadu(from); + if((std::ptrdiff_t(from) % 16) == 0) p = pload(from); + else p = ploadu(from); return vec_splat_dbl<0>(p); } @@ -969,7 +997,7 @@ template<> EIGEN_STRONG_INLINE Packet2d preduxp(const Packet2d* vecs) Packet2d v[2], sum; v[0] = vecs[0] + reinterpret_cast(vec_sld(reinterpret_cast(vecs[0]), reinterpret_cast(vecs[0]), 8)); v[1] = vecs[1] + reinterpret_cast(vec_sld(reinterpret_cast(vecs[1]), reinterpret_cast(vecs[1]), 8)); - + #ifdef _BIG_ENDIAN sum = reinterpret_cast(vec_sld(reinterpret_cast(v[0]), reinterpret_cast(v[1]), 8)); #else @@ -1022,7 +1050,7 @@ ptranspose(PacketBlock& kernel) { template<> EIGEN_STRONG_INLINE Packet2d pblend(const Selector<2>& ifPacket, const Packet2d& thenPacket, const Packet2d& elsePacket) { Packet2l select = { ifPacket.select[0], ifPacket.select[1] }; - Packet2bl mask = vec_cmpeq(reinterpret_cast(select), reinterpret_cast(p2l_ONE)); + Packet2bl mask = reinterpret_cast( vec_cmpeq(reinterpret_cast(select), reinterpret_cast(p2l_ONE)) ); return vec_sel(elsePacket, thenPacket, mask); } #endif // __VSX__ diff --git a/eigenlib/Eigen/src/Core/arch/CUDA/Half.h b/eigenlib/Eigen/src/Core/arch/CUDA/Half.h index 52892db3..59717b4f 100644 --- a/eigenlib/Eigen/src/Core/arch/CUDA/Half.h +++ b/eigenlib/Eigen/src/Core/arch/CUDA/Half.h @@ -13,7 +13,7 @@ // Redistribution and use in source and binary forms, with or without // modification, are permitted. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, @@ -29,7 +29,7 @@ // type Eigen::half (inheriting from CUDA's __half struct) with // operator overloads such that it behaves basically as an arithmetic // type. It will be quite slow on CPUs (so it is recommended to stay -// in fp32 for CPUs, except for simple parameter conversions, I/O +// in float32_bits for CPUs, except for simple parameter conversions, I/O // to disk and the likes), but fast on GPUs. @@ -42,6 +42,7 @@ #define EIGEN_EXPLICIT_CAST(tgt_type) operator tgt_type() #endif +#include namespace Eigen { @@ -50,38 +51,45 @@ struct half; namespace half_impl { #if !defined(EIGEN_HAS_CUDA_FP16) - -// Make our own __half definition that is similar to CUDA's. -struct __half { - EIGEN_DEVICE_FUNC __half() {} - explicit EIGEN_DEVICE_FUNC __half(unsigned short raw) : x(raw) {} +// Make our own __half_raw definition that is similar to CUDA's. +struct __half_raw { + EIGEN_DEVICE_FUNC __half_raw() : x(0) {} + explicit EIGEN_DEVICE_FUNC __half_raw(unsigned short raw) : x(raw) {} unsigned short x; }; - +#elif defined(EIGEN_CUDACC_VER) && EIGEN_CUDACC_VER < 90000 +// In CUDA < 9.0, __half is the equivalent of CUDA 9's __half_raw +typedef __half __half_raw; #endif -EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC __half raw_uint16_to_half(unsigned short x); -EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC __half float_to_half_rtne(float ff); -EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC float half_to_float(__half h); +EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC __half_raw raw_uint16_to_half(unsigned short x); +EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC __half_raw float_to_half_rtne(float ff); +EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC float half_to_float(__half_raw h); -struct half_base : public __half { +struct half_base : public __half_raw { EIGEN_DEVICE_FUNC half_base() {} - EIGEN_DEVICE_FUNC half_base(const half_base& h) : __half(h) {} - EIGEN_DEVICE_FUNC half_base(const __half& h) : __half(h) {} + EIGEN_DEVICE_FUNC half_base(const half_base& h) : __half_raw(h) {} + EIGEN_DEVICE_FUNC half_base(const __half_raw& h) : __half_raw(h) {} +#if defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_CUDACC_VER) && EIGEN_CUDACC_VER >= 90000 + EIGEN_DEVICE_FUNC half_base(const __half& h) : __half_raw(*(__half_raw*)&h) {} +#endif }; } // namespace half_impl // Class definition. struct half : public half_impl::half_base { - #if !defined(EIGEN_HAS_CUDA_FP16) - typedef half_impl::__half __half; + #if !defined(EIGEN_HAS_CUDA_FP16) || (defined(EIGEN_CUDACC_VER) && EIGEN_CUDACC_VER < 90000) + typedef half_impl::__half_raw __half_raw; #endif EIGEN_DEVICE_FUNC half() {} - EIGEN_DEVICE_FUNC half(const __half& h) : half_impl::half_base(h) {} + EIGEN_DEVICE_FUNC half(const __half_raw& h) : half_impl::half_base(h) {} EIGEN_DEVICE_FUNC half(const half& h) : half_impl::half_base(h) {} +#if defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_CUDACC_VER) && EIGEN_CUDACC_VER >= 90000 + EIGEN_DEVICE_FUNC half(const __half& h) : half_impl::half_base(h) {} +#endif explicit EIGEN_DEVICE_FUNC half(bool b) : half_impl::half_base(half_impl::raw_uint16_to_half(b ? 0x3c00 : 0)) {} @@ -138,71 +146,125 @@ struct half : public half_impl::half_base { } }; +} // end namespace Eigen + +namespace std { +template<> +struct numeric_limits { + static const bool is_specialized = true; + static const bool is_signed = true; + static const bool is_integer = false; + static const bool is_exact = false; + static const bool has_infinity = true; + static const bool has_quiet_NaN = true; + static const bool has_signaling_NaN = true; + static const float_denorm_style has_denorm = denorm_present; + static const bool has_denorm_loss = false; + static const std::float_round_style round_style = std::round_to_nearest; + static const bool is_iec559 = false; + static const bool is_bounded = false; + static const bool is_modulo = false; + static const int digits = 11; + static const int digits10 = 3; // according to http://half.sourceforge.net/structstd_1_1numeric__limits_3_01half__float_1_1half_01_4.html + static const int max_digits10 = 5; // according to http://half.sourceforge.net/structstd_1_1numeric__limits_3_01half__float_1_1half_01_4.html + static const int radix = 2; + static const int min_exponent = -13; + static const int min_exponent10 = -4; + static const int max_exponent = 16; + static const int max_exponent10 = 4; + static const bool traps = true; + static const bool tinyness_before = false; + + static Eigen::half (min)() { return Eigen::half_impl::raw_uint16_to_half(0x400); } + static Eigen::half lowest() { return Eigen::half_impl::raw_uint16_to_half(0xfbff); } + static Eigen::half (max)() { return Eigen::half_impl::raw_uint16_to_half(0x7bff); } + static Eigen::half epsilon() { return Eigen::half_impl::raw_uint16_to_half(0x0800); } + static Eigen::half round_error() { return Eigen::half(0.5); } + static Eigen::half infinity() { return Eigen::half_impl::raw_uint16_to_half(0x7c00); } + static Eigen::half quiet_NaN() { return Eigen::half_impl::raw_uint16_to_half(0x7e00); } + static Eigen::half signaling_NaN() { return Eigen::half_impl::raw_uint16_to_half(0x7e00); } + static Eigen::half denorm_min() { return Eigen::half_impl::raw_uint16_to_half(0x1); } +}; + +// If std::numeric_limits is specialized, should also specialize +// std::numeric_limits, std::numeric_limits, and +// std::numeric_limits +// https://stackoverflow.com/a/16519653/ +template<> +struct numeric_limits : numeric_limits {}; +template<> +struct numeric_limits : numeric_limits {}; +template<> +struct numeric_limits : numeric_limits {}; +} // end namespace std + +namespace Eigen { + namespace half_impl { -#if defined(EIGEN_HAS_CUDA_FP16) && defined(__CUDA_ARCH__) && __CUDA_ARCH__ >= 530 +#if defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 530 // Intrinsics for native fp16 support. Note that on current hardware, -// these are no faster than fp32 arithmetic (you need to use the half2 +// these are no faster than float32_bits arithmetic (you need to use the half2 // versions to get the ALU speed increased), but you do save the // conversion steps back and forth. -__device__ half operator + (const half& a, const half& b) { +EIGEN_STRONG_INLINE __device__ half operator + (const half& a, const half& b) { return __hadd(a, b); } -__device__ half operator * (const half& a, const half& b) { +EIGEN_STRONG_INLINE __device__ half operator * (const half& a, const half& b) { return __hmul(a, b); } -__device__ half operator - (const half& a, const half& b) { +EIGEN_STRONG_INLINE __device__ half operator - (const half& a, const half& b) { return __hsub(a, b); } -__device__ half operator / (const half& a, const half& b) { +EIGEN_STRONG_INLINE __device__ half operator / (const half& a, const half& b) { float num = __half2float(a); float denom = __half2float(b); return __float2half(num / denom); } -__device__ half operator - (const half& a) { +EIGEN_STRONG_INLINE __device__ half operator - (const half& a) { return __hneg(a); } -__device__ half& operator += (half& a, const half& b) { +EIGEN_STRONG_INLINE __device__ half& operator += (half& a, const half& b) { a = a + b; return a; } -__device__ half& operator *= (half& a, const half& b) { +EIGEN_STRONG_INLINE __device__ half& operator *= (half& a, const half& b) { a = a * b; return a; } -__device__ half& operator -= (half& a, const half& b) { +EIGEN_STRONG_INLINE __device__ half& operator -= (half& a, const half& b) { a = a - b; return a; } -__device__ half& operator /= (half& a, const half& b) { +EIGEN_STRONG_INLINE __device__ half& operator /= (half& a, const half& b) { a = a / b; return a; } -__device__ bool operator == (const half& a, const half& b) { +EIGEN_STRONG_INLINE __device__ bool operator == (const half& a, const half& b) { return __heq(a, b); } -__device__ bool operator != (const half& a, const half& b) { +EIGEN_STRONG_INLINE __device__ bool operator != (const half& a, const half& b) { return __hne(a, b); } -__device__ bool operator < (const half& a, const half& b) { +EIGEN_STRONG_INLINE __device__ bool operator < (const half& a, const half& b) { return __hlt(a, b); } -__device__ bool operator <= (const half& a, const half& b) { +EIGEN_STRONG_INLINE __device__ bool operator <= (const half& a, const half& b) { return __hle(a, b); } -__device__ bool operator > (const half& a, const half& b) { +EIGEN_STRONG_INLINE __device__ bool operator > (const half& a, const half& b) { return __hgt(a, b); } -__device__ bool operator >= (const half& a, const half& b) { +EIGEN_STRONG_INLINE __device__ bool operator >= (const half& a, const half& b) { return __hge(a, b); } #else // Emulate support for half floats // Definitions for CPUs and older CUDA, mostly working through conversion -// to/from fp32. +// to/from float32_bits. EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator + (const half& a, const half& b) { return half(float(a) + float(b)); @@ -238,10 +300,10 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator /= (half& a, const half& b) return a; } EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool operator == (const half& a, const half& b) { - return float(a) == float(b); + return numext::equal_strict(float(a),float(b)); } EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool operator != (const half& a, const half& b) { - return float(a) != float(b); + return numext::not_equal_strict(float(a), float(b)); } EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool operator < (const half& a, const half& b) { return float(a) < float(b); @@ -269,34 +331,35 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half operator / (const half& a, Index b) { // these in hardware. If we need more performance on older/other CPUs, they are // also possible to vectorize directly. -EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC __half raw_uint16_to_half(unsigned short x) { - __half h; +EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC __half_raw raw_uint16_to_half(unsigned short x) { + __half_raw h; h.x = x; return h; } -union FP32 { +union float32_bits { unsigned int u; float f; }; -EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC __half float_to_half_rtne(float ff) { -#if defined(EIGEN_HAS_CUDA_FP16) && defined(__CUDA_ARCH__) && __CUDA_ARCH__ >= 300 - return __float2half(ff); +EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC __half_raw float_to_half_rtne(float ff) { +#if defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 300 + __half tmp_ff = __float2half(ff); + return *(__half_raw*)&tmp_ff; #elif defined(EIGEN_HAS_FP16_C) - __half h; + __half_raw h; h.x = _cvtss_sh(ff, 0); return h; #else - FP32 f; f.f = ff; + float32_bits f; f.f = ff; - const FP32 f32infty = { 255 << 23 }; - const FP32 f16max = { (127 + 16) << 23 }; - const FP32 denorm_magic = { ((127 - 15) + (23 - 10) + 1) << 23 }; + const float32_bits f32infty = { 255 << 23 }; + const float32_bits f16max = { (127 + 16) << 23 }; + const float32_bits denorm_magic = { ((127 - 15) + (23 - 10) + 1) << 23 }; unsigned int sign_mask = 0x80000000u; - __half o; + __half_raw o; o.x = static_cast(0x0u); unsigned int sign = f.u & sign_mask; @@ -335,17 +398,17 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC __half float_to_half_rtne(float ff) { #endif } -EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC float half_to_float(__half h) { -#if defined(EIGEN_HAS_CUDA_FP16) && defined(__CUDA_ARCH__) && __CUDA_ARCH__ >= 300 +EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC float half_to_float(__half_raw h) { +#if defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 300 return __half2float(h); #elif defined(EIGEN_HAS_FP16_C) return _cvtsh_ss(h.x); #else - const FP32 magic = { 113 << 23 }; + const float32_bits magic = { 113 << 23 }; const unsigned int shifted_exp = 0x7c00 << 13; // exponent mask after shift - FP32 o; + float32_bits o; o.u = (h.x & 0x7fff) << 13; // exponent/mantissa bits unsigned int exp = shifted_exp & o.u; // just the exponent @@ -370,7 +433,7 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool (isinf)(const half& a) { return (a.x & 0x7fff) == 0x7c00; } EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool (isnan)(const half& a) { -#if defined(EIGEN_HAS_CUDA_FP16) && defined(__CUDA_ARCH__) && __CUDA_ARCH__ >= 530 +#if defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 530 return __hisnan(a); #else return (a.x & 0x7fff) > 0x7c00; @@ -386,11 +449,15 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half abs(const half& a) { return result; } EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half exp(const half& a) { - return half(::expf(float(a))); +#if EIGEN_CUDACC_VER >= 80000 && defined EIGEN_CUDA_ARCH && EIGEN_CUDA_ARCH >= 530 + return half(hexp(a)); +#else + return half(::expf(float(a))); +#endif } EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half log(const half& a) { -#if defined(EIGEN_HAS_CUDA_FP16) && defined __CUDACC_VER__ && __CUDACC_VER__ >= 80000 && defined(__CUDA_ARCH__) && __CUDA_ARCH__ >= 530 - return Eigen::half(::hlog(a)); +#if defined(EIGEN_HAS_CUDA_FP16) && EIGEN_CUDACC_VER >= 80000 && defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 530 + return half(::hlog(a)); #else return half(::logf(float(a))); #endif @@ -402,7 +469,11 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half log10(const half& a) { return half(::log10f(float(a))); } EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half sqrt(const half& a) { - return half(::sqrtf(float(a))); +#if EIGEN_CUDACC_VER >= 80000 && defined EIGEN_CUDA_ARCH && EIGEN_CUDA_ARCH >= 530 + return half(hsqrt(a)); +#else + return half(::sqrtf(float(a))); +#endif } EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half pow(const half& a, const half& b) { return half(::powf(float(a), float(b))); @@ -420,14 +491,22 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half tanh(const half& a) { return half(::tanhf(float(a))); } EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half floor(const half& a) { +#if EIGEN_CUDACC_VER >= 80000 && defined EIGEN_CUDA_ARCH && EIGEN_CUDA_ARCH >= 300 + return half(hfloor(a)); +#else return half(::floorf(float(a))); +#endif } EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half ceil(const half& a) { +#if EIGEN_CUDACC_VER >= 80000 && defined EIGEN_CUDA_ARCH && EIGEN_CUDA_ARCH >= 300 + return half(hceil(a)); +#else return half(::ceilf(float(a))); +#endif } EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half (min)(const half& a, const half& b) { -#if defined(EIGEN_HAS_CUDA_FP16) && defined(__CUDA_ARCH__) && __CUDA_ARCH__ >= 530 +#if defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 530 return __hlt(b, a) ? b : a; #else const float f1 = static_cast(a); @@ -436,7 +515,7 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half (min)(const half& a, const half& b) { #endif } EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half (max)(const half& a, const half& b) { -#if defined(EIGEN_HAS_CUDA_FP16) && defined(__CUDA_ARCH__) && __CUDA_ARCH__ >= 530 +#if defined(EIGEN_HAS_CUDA_FP16) && defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 530 return __hlt(a, b) ? b : a; #else const float f1 = static_cast(a); @@ -477,6 +556,13 @@ template<> struct is_arithmetic { enum { value = true }; }; template<> struct NumTraits : GenericNumTraits { + enum { + IsSigned = true, + IsInteger = false, + IsComplex = false, + RequireInitialization = false + }; + EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Eigen::half epsilon() { return half_impl::raw_uint16_to_half(0x0800); } @@ -507,7 +593,7 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Eigen::half exph(const Eigen::half& a) { return Eigen::half(::expf(float(a))); } EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Eigen::half logh(const Eigen::half& a) { -#if defined __CUDACC_VER__ && __CUDACC_VER__ >= 80000 && defined(__CUDA_ARCH__) && __CUDA_ARCH__ >= 530 +#if EIGEN_CUDACC_VER >= 80000 && defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 530 return Eigen::half(::hlog(a)); #else return Eigen::half(::logf(float(a))); @@ -541,14 +627,18 @@ struct hash { // Add the missing shfl_xor intrinsic -#if defined(__CUDA_ARCH__) && __CUDA_ARCH__ >= 300 +#if defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 300 __device__ EIGEN_STRONG_INLINE Eigen::half __shfl_xor(Eigen::half var, int laneMask, int width=warpSize) { + #if EIGEN_CUDACC_VER < 90000 return static_cast(__shfl_xor(static_cast(var), laneMask, width)); + #else + return static_cast(__shfl_xor_sync(0xFFFFFFFF, static_cast(var), laneMask, width)); + #endif } #endif -// ldg() has an overload for __half, but we also need one for Eigen::half. -#if defined(__CUDA_ARCH__) && __CUDA_ARCH__ >= 350 +// ldg() has an overload for __half_raw, but we also need one for Eigen::half. +#if defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 350 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Eigen::half __ldg(const Eigen::half* ptr) { return Eigen::half_impl::raw_uint16_to_half( __ldg(reinterpret_cast(ptr))); @@ -556,7 +646,7 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Eigen::half __ldg(const Eigen::half* ptr) #endif -#if defined(__CUDA_ARCH__) +#if defined(EIGEN_CUDA_ARCH) namespace Eigen { namespace numext { diff --git a/eigenlib/Eigen/src/Core/arch/CUDA/PacketMath.h b/eigenlib/Eigen/src/Core/arch/CUDA/PacketMath.h index ad66399e..4dda6318 100644 --- a/eigenlib/Eigen/src/Core/arch/CUDA/PacketMath.h +++ b/eigenlib/Eigen/src/Core/arch/CUDA/PacketMath.h @@ -291,7 +291,7 @@ template<> EIGEN_DEVICE_FUNC inline double2 pabs(const double2& a) { EIGEN_DEVICE_FUNC inline void ptranspose(PacketBlock& kernel) { - double tmp = kernel.packet[0].y; + float tmp = kernel.packet[0].y; kernel.packet[0].y = kernel.packet[1].x; kernel.packet[1].x = tmp; diff --git a/eigenlib/Eigen/src/Core/arch/CUDA/PacketMathHalf.h b/eigenlib/Eigen/src/Core/arch/CUDA/PacketMathHalf.h index ae54225f..f749c573 100644 --- a/eigenlib/Eigen/src/Core/arch/CUDA/PacketMathHalf.h +++ b/eigenlib/Eigen/src/Core/arch/CUDA/PacketMathHalf.h @@ -99,7 +99,8 @@ template<> __device__ EIGEN_STRONG_INLINE Eigen::half pfirst(const half2& template<> __device__ EIGEN_STRONG_INLINE half2 pabs(const half2& a) { half2 result; - result.x = a.x & 0x7FFF7FFF; + unsigned temp = *(reinterpret_cast(&(a))); + *(reinterpret_cast(&(result))) = temp & 0x7FFF7FFF; return result; } @@ -229,7 +230,7 @@ template<> __device__ EIGEN_STRONG_INLINE Eigen::half predux(const half2& #else float a1 = __low2float(a); float a2 = __high2float(a); - return Eigen::half(half_impl::raw_uint16_to_half(__float2half_rn(a1 + a2))); + return Eigen::half(__float2half_rn(a1 + a2)); #endif } @@ -263,7 +264,7 @@ template<> __device__ EIGEN_STRONG_INLINE Eigen::half predux_mul(const ha #else float a1 = __low2float(a); float a2 = __high2float(a); - return Eigen::half(half_impl::raw_uint16_to_half(__float2half_rn(a1 * a2))); + return Eigen::half(__float2half_rn(a1 * a2)); #endif } @@ -275,7 +276,7 @@ template<> __device__ EIGEN_STRONG_INLINE half2 plog1p(const half2& a) { return __floats2half2_rn(r1, r2); } -#if defined __CUDACC_VER__ && __CUDACC_VER__ >= 80000 && defined __CUDA_ARCH__ && __CUDA_ARCH__ >= 530 +#if EIGEN_CUDACC_VER >= 80000 && defined EIGEN_CUDA_ARCH && EIGEN_CUDA_ARCH >= 530 template<> __device__ EIGEN_STRONG_INLINE half2 plog(const half2& a) { diff --git a/eigenlib/Eigen/src/Core/arch/Default/ConjHelper.h b/eigenlib/Eigen/src/Core/arch/Default/ConjHelper.h new file mode 100644 index 00000000..4cfe34e0 --- /dev/null +++ b/eigenlib/Eigen/src/Core/arch/Default/ConjHelper.h @@ -0,0 +1,29 @@ + +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2017 Gael Guennebaud +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_ARCH_CONJ_HELPER_H +#define EIGEN_ARCH_CONJ_HELPER_H + +#define EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(PACKET_CPLX, PACKET_REAL) \ + template<> struct conj_helper { \ + EIGEN_STRONG_INLINE PACKET_CPLX pmadd(const PACKET_REAL& x, const PACKET_CPLX& y, const PACKET_CPLX& c) const \ + { return padd(c, pmul(x,y)); } \ + EIGEN_STRONG_INLINE PACKET_CPLX pmul(const PACKET_REAL& x, const PACKET_CPLX& y) const \ + { return PACKET_CPLX(Eigen::internal::pmul(x, y.v)); } \ + }; \ + \ + template<> struct conj_helper { \ + EIGEN_STRONG_INLINE PACKET_CPLX pmadd(const PACKET_CPLX& x, const PACKET_REAL& y, const PACKET_CPLX& c) const \ + { return padd(c, pmul(x,y)); } \ + EIGEN_STRONG_INLINE PACKET_CPLX pmul(const PACKET_CPLX& x, const PACKET_REAL& y) const \ + { return PACKET_CPLX(Eigen::internal::pmul(x.v, y)); } \ + }; + +#endif // EIGEN_ARCH_CONJ_HELPER_H diff --git a/eigenlib/Eigen/src/Core/arch/NEON/Complex.h b/eigenlib/Eigen/src/Core/arch/NEON/Complex.h index 57e9b431..306a309b 100644 --- a/eigenlib/Eigen/src/Core/arch/NEON/Complex.h +++ b/eigenlib/Eigen/src/Core/arch/NEON/Complex.h @@ -67,7 +67,7 @@ template<> struct unpacket_traits { typedef std::complex type; template<> EIGEN_STRONG_INLINE Packet2cf pset1(const std::complex& from) { float32x2_t r64; - r64 = vld1_f32((float *)&from); + r64 = vld1_f32((const float *)&from); return Packet2cf(vcombine_f32(r64, r64)); } @@ -142,7 +142,7 @@ template<> EIGEN_DEVICE_FUNC inline void pscatter, Packet2cf to[stride*1] = std::complex(vgetq_lane_f32(from.v, 2), vgetq_lane_f32(from.v, 3)); } -template<> EIGEN_STRONG_INLINE void prefetch >(const std::complex * addr) { EIGEN_ARM_PREFETCH((float *)addr); } +template<> EIGEN_STRONG_INLINE void prefetch >(const std::complex * addr) { EIGEN_ARM_PREFETCH((const float *)addr); } template<> EIGEN_STRONG_INLINE std::complex pfirst(const Packet2cf& a) { @@ -265,6 +265,8 @@ template<> struct conj_helper } }; +EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet2cf,Packet4f) + template<> EIGEN_STRONG_INLINE Packet2cf pdiv(const Packet2cf& a, const Packet2cf& b) { // TODO optimize it for NEON @@ -275,7 +277,7 @@ template<> EIGEN_STRONG_INLINE Packet2cf pdiv(const Packet2cf& a, con s = vmulq_f32(b.v, b.v); rev_s = vrev64q_f32(s); - return Packet2cf(pdiv(res.v, vaddq_f32(s,rev_s))); + return Packet2cf(pdiv(res.v, vaddq_f32(s,rev_s))); } EIGEN_DEVICE_FUNC inline void @@ -381,7 +383,7 @@ template<> EIGEN_STRONG_INLINE Packet1cd ploaddup(const std::complex< template<> EIGEN_STRONG_INLINE void pstore >(std::complex * to, const Packet1cd& from) { EIGEN_DEBUG_ALIGNED_STORE pstore((double*)to, from.v); } template<> EIGEN_STRONG_INLINE void pstoreu >(std::complex * to, const Packet1cd& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((double*)to, from.v); } -template<> EIGEN_STRONG_INLINE void prefetch >(const std::complex * addr) { EIGEN_ARM_PREFETCH((double *)addr); } +template<> EIGEN_STRONG_INLINE void prefetch >(const std::complex * addr) { EIGEN_ARM_PREFETCH((const double *)addr); } template<> EIGEN_DEVICE_FUNC inline Packet1cd pgather, Packet1cd>(const std::complex* from, Index stride) { @@ -456,6 +458,8 @@ template<> struct conj_helper } }; +EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet1cd,Packet2d) + template<> EIGEN_STRONG_INLINE Packet1cd pdiv(const Packet1cd& a, const Packet1cd& b) { // TODO optimize it for NEON diff --git a/eigenlib/Eigen/src/Core/arch/NEON/PacketMath.h b/eigenlib/Eigen/src/Core/arch/NEON/PacketMath.h index d392bf3f..3d5ed0d2 100644 --- a/eigenlib/Eigen/src/Core/arch/NEON/PacketMath.h +++ b/eigenlib/Eigen/src/Core/arch/NEON/PacketMath.h @@ -36,29 +36,63 @@ namespace internal { #endif #endif +#if EIGEN_COMP_MSVC + +// In MSVC's arm_neon.h header file, all NEON vector types +// are aliases to the same underlying type __n128. +// We thus have to wrap them to make them different C++ types. +// (See also bug 1428) + +template +struct eigen_packet_wrapper +{ + operator T&() { return m_val; } + operator const T&() const { return m_val; } + eigen_packet_wrapper() {} + eigen_packet_wrapper(const T &v) : m_val(v) {} + eigen_packet_wrapper& operator=(const T &v) { + m_val = v; + return *this; + } + + T m_val; +}; +typedef eigen_packet_wrapper Packet2f; +typedef eigen_packet_wrapper Packet4f; +typedef eigen_packet_wrapper Packet4i; +typedef eigen_packet_wrapper Packet2i; +typedef eigen_packet_wrapper Packet4ui; + +#else + typedef float32x2_t Packet2f; typedef float32x4_t Packet4f; typedef int32x4_t Packet4i; typedef int32x2_t Packet2i; typedef uint32x4_t Packet4ui; +#endif // EIGEN_COMP_MSVC + #define _EIGEN_DECLARE_CONST_Packet4f(NAME,X) \ const Packet4f p4f_##NAME = pset1(X) #define _EIGEN_DECLARE_CONST_Packet4f_FROM_INT(NAME,X) \ - const Packet4f p4f_##NAME = vreinterpretq_f32_u32(pset1(X)) + const Packet4f p4f_##NAME = vreinterpretq_f32_u32(pset1(X)) #define _EIGEN_DECLARE_CONST_Packet4i(NAME,X) \ const Packet4i p4i_##NAME = pset1(X) -// arm64 does have the pld instruction. If available, let's trust the __builtin_prefetch built-in function -// which available on LLVM and GCC (at least) -#if EIGEN_HAS_BUILTIN(__builtin_prefetch) || EIGEN_COMP_GNUC +#if EIGEN_ARCH_ARM64 + // __builtin_prefetch tends to do nothing on ARM64 compilers because the + // prefetch instructions there are too detailed for __builtin_prefetch to map + // meaningfully to them. + #define EIGEN_ARM_PREFETCH(ADDR) __asm__ __volatile__("prfm pldl1keep, [%[addr]]\n" ::[addr] "r"(ADDR) : ); +#elif EIGEN_HAS_BUILTIN(__builtin_prefetch) || EIGEN_COMP_GNUC #define EIGEN_ARM_PREFETCH(ADDR) __builtin_prefetch(ADDR); #elif defined __pld #define EIGEN_ARM_PREFETCH(ADDR) __pld(ADDR) -#elif !EIGEN_ARCH_ARM64 - #define EIGEN_ARM_PREFETCH(ADDR) __asm__ __volatile__ ( " pld [%[addr]]\n" :: [addr] "r" (ADDR) : "cc" ); +#elif EIGEN_ARCH_ARM32 + #define EIGEN_ARM_PREFETCH(ADDR) __asm__ __volatile__ ("pld [%[addr]]\n" :: [addr] "r" (ADDR) : ); #else // by default no explicit prefetching #define EIGEN_ARM_PREFETCH(ADDR) @@ -83,7 +117,7 @@ template<> struct packet_traits : default_packet_traits HasSqrt = 0 }; }; -template<> struct packet_traits : default_packet_traits +template<> struct packet_traits : default_packet_traits { typedef Packet4i type; typedef Packet4i half; // Packet2i intrinsics not implemented yet @@ -105,19 +139,19 @@ EIGEN_STRONG_INLINE void vst1q_f32(float* to, float32x4_t from) { ::vst1q EIGEN_STRONG_INLINE void vst1_f32 (float* to, float32x2_t from) { ::vst1_f32 ((float32_t*)to,from); } #endif -template<> struct unpacket_traits { typedef float type; enum {size=4, alignment=Aligned16}; typedef Packet4f half; }; -template<> struct unpacket_traits { typedef int type; enum {size=4, alignment=Aligned16}; typedef Packet4i half; }; +template<> struct unpacket_traits { typedef float type; enum {size=4, alignment=Aligned16}; typedef Packet4f half; }; +template<> struct unpacket_traits { typedef int32_t type; enum {size=4, alignment=Aligned16}; typedef Packet4i half; }; template<> EIGEN_STRONG_INLINE Packet4f pset1(const float& from) { return vdupq_n_f32(from); } -template<> EIGEN_STRONG_INLINE Packet4i pset1(const int& from) { return vdupq_n_s32(from); } +template<> EIGEN_STRONG_INLINE Packet4i pset1(const int32_t& from) { return vdupq_n_s32(from); } template<> EIGEN_STRONG_INLINE Packet4f plset(const float& a) { - const float32_t f[] = {0, 1, 2, 3}; + const float f[] = {0, 1, 2, 3}; Packet4f countdown = vld1q_f32(f); return vaddq_f32(pset1(a), countdown); } -template<> EIGEN_STRONG_INLINE Packet4i plset(const int& a) +template<> EIGEN_STRONG_INLINE Packet4i plset(const int32_t& a) { const int32_t i[] = {0, 1, 2, 3}; Packet4i countdown = vld1q_s32(i); @@ -240,20 +274,20 @@ template<> EIGEN_STRONG_INLINE Packet4f pandnot(const Packet4f& a, con } template<> EIGEN_STRONG_INLINE Packet4i pandnot(const Packet4i& a, const Packet4i& b) { return vbicq_s32(a,b); } -template<> EIGEN_STRONG_INLINE Packet4f pload(const float* from) { EIGEN_DEBUG_ALIGNED_LOAD return vld1q_f32(from); } -template<> EIGEN_STRONG_INLINE Packet4i pload(const int* from) { EIGEN_DEBUG_ALIGNED_LOAD return vld1q_s32(from); } +template<> EIGEN_STRONG_INLINE Packet4f pload(const float* from) { EIGEN_DEBUG_ALIGNED_LOAD return vld1q_f32(from); } +template<> EIGEN_STRONG_INLINE Packet4i pload(const int32_t* from) { EIGEN_DEBUG_ALIGNED_LOAD return vld1q_s32(from); } -template<> EIGEN_STRONG_INLINE Packet4f ploadu(const float* from) { EIGEN_DEBUG_UNALIGNED_LOAD return vld1q_f32(from); } -template<> EIGEN_STRONG_INLINE Packet4i ploadu(const int* from) { EIGEN_DEBUG_UNALIGNED_LOAD return vld1q_s32(from); } +template<> EIGEN_STRONG_INLINE Packet4f ploadu(const float* from) { EIGEN_DEBUG_UNALIGNED_LOAD return vld1q_f32(from); } +template<> EIGEN_STRONG_INLINE Packet4i ploadu(const int32_t* from) { EIGEN_DEBUG_UNALIGNED_LOAD return vld1q_s32(from); } -template<> EIGEN_STRONG_INLINE Packet4f ploaddup(const float* from) +template<> EIGEN_STRONG_INLINE Packet4f ploaddup(const float* from) { float32x2_t lo, hi; lo = vld1_dup_f32(from); hi = vld1_dup_f32(from+1); return vcombine_f32(lo, hi); } -template<> EIGEN_STRONG_INLINE Packet4i ploaddup(const int* from) +template<> EIGEN_STRONG_INLINE Packet4i ploaddup(const int32_t* from) { int32x2_t lo, hi; lo = vld1_dup_s32(from); @@ -261,11 +295,11 @@ template<> EIGEN_STRONG_INLINE Packet4i ploaddup(const int* from) return vcombine_s32(lo, hi); } -template<> EIGEN_STRONG_INLINE void pstore(float* to, const Packet4f& from) { EIGEN_DEBUG_ALIGNED_STORE vst1q_f32(to, from); } -template<> EIGEN_STRONG_INLINE void pstore(int* to, const Packet4i& from) { EIGEN_DEBUG_ALIGNED_STORE vst1q_s32(to, from); } +template<> EIGEN_STRONG_INLINE void pstore (float* to, const Packet4f& from) { EIGEN_DEBUG_ALIGNED_STORE vst1q_f32(to, from); } +template<> EIGEN_STRONG_INLINE void pstore(int32_t* to, const Packet4i& from) { EIGEN_DEBUG_ALIGNED_STORE vst1q_s32(to, from); } -template<> EIGEN_STRONG_INLINE void pstoreu(float* to, const Packet4f& from) { EIGEN_DEBUG_UNALIGNED_STORE vst1q_f32(to, from); } -template<> EIGEN_STRONG_INLINE void pstoreu(int* to, const Packet4i& from) { EIGEN_DEBUG_UNALIGNED_STORE vst1q_s32(to, from); } +template<> EIGEN_STRONG_INLINE void pstoreu (float* to, const Packet4f& from) { EIGEN_DEBUG_UNALIGNED_STORE vst1q_f32(to, from); } +template<> EIGEN_STRONG_INLINE void pstoreu(int32_t* to, const Packet4i& from) { EIGEN_DEBUG_UNALIGNED_STORE vst1q_s32(to, from); } template<> EIGEN_DEVICE_FUNC inline Packet4f pgather(const float* from, Index stride) { @@ -276,7 +310,7 @@ template<> EIGEN_DEVICE_FUNC inline Packet4f pgather(const floa res = vsetq_lane_f32(from[3*stride], res, 3); return res; } -template<> EIGEN_DEVICE_FUNC inline Packet4i pgather(const int* from, Index stride) +template<> EIGEN_DEVICE_FUNC inline Packet4i pgather(const int32_t* from, Index stride) { Packet4i res = pset1(0); res = vsetq_lane_s32(from[0*stride], res, 0); @@ -293,7 +327,7 @@ template<> EIGEN_DEVICE_FUNC inline void pscatter(float* to, co to[stride*2] = vgetq_lane_f32(from, 2); to[stride*3] = vgetq_lane_f32(from, 3); } -template<> EIGEN_DEVICE_FUNC inline void pscatter(int* to, const Packet4i& from, Index stride) +template<> EIGEN_DEVICE_FUNC inline void pscatter(int32_t* to, const Packet4i& from, Index stride) { to[stride*0] = vgetq_lane_s32(from, 0); to[stride*1] = vgetq_lane_s32(from, 1); @@ -301,12 +335,12 @@ template<> EIGEN_DEVICE_FUNC inline void pscatter(int* to, const to[stride*3] = vgetq_lane_s32(from, 3); } -template<> EIGEN_STRONG_INLINE void prefetch(const float* addr) { EIGEN_ARM_PREFETCH(addr); } -template<> EIGEN_STRONG_INLINE void prefetch(const int* addr) { EIGEN_ARM_PREFETCH(addr); } +template<> EIGEN_STRONG_INLINE void prefetch (const float* addr) { EIGEN_ARM_PREFETCH(addr); } +template<> EIGEN_STRONG_INLINE void prefetch(const int32_t* addr) { EIGEN_ARM_PREFETCH(addr); } // FIXME only store the 2 first elements ? -template<> EIGEN_STRONG_INLINE float pfirst(const Packet4f& a) { float EIGEN_ALIGN16 x[4]; vst1q_f32(x, a); return x[0]; } -template<> EIGEN_STRONG_INLINE int pfirst(const Packet4i& a) { int EIGEN_ALIGN16 x[4]; vst1q_s32(x, a); return x[0]; } +template<> EIGEN_STRONG_INLINE float pfirst(const Packet4f& a) { float EIGEN_ALIGN16 x[4]; vst1q_f32(x, a); return x[0]; } +template<> EIGEN_STRONG_INLINE int32_t pfirst(const Packet4i& a) { int32_t EIGEN_ALIGN16 x[4]; vst1q_s32(x, a); return x[0]; } template<> EIGEN_STRONG_INLINE Packet4f preverse(const Packet4f& a) { float32x2_t a_lo, a_hi; @@ -361,7 +395,7 @@ template<> EIGEN_STRONG_INLINE Packet4f preduxp(const Packet4f* vecs) return sum; } -template<> EIGEN_STRONG_INLINE int predux(const Packet4i& a) +template<> EIGEN_STRONG_INLINE int32_t predux(const Packet4i& a) { int32x2_t a_lo, a_hi, sum; @@ -408,7 +442,7 @@ template<> EIGEN_STRONG_INLINE float predux_mul(const Packet4f& a) return vget_lane_f32(prod, 0); } -template<> EIGEN_STRONG_INLINE int predux_mul(const Packet4i& a) +template<> EIGEN_STRONG_INLINE int32_t predux_mul(const Packet4i& a) { int32x2_t a_lo, a_hi, prod; @@ -436,7 +470,7 @@ template<> EIGEN_STRONG_INLINE float predux_min(const Packet4f& a) return vget_lane_f32(min, 0); } -template<> EIGEN_STRONG_INLINE int predux_min(const Packet4i& a) +template<> EIGEN_STRONG_INLINE int32_t predux_min(const Packet4i& a) { int32x2_t a_lo, a_hi, min; @@ -461,7 +495,7 @@ template<> EIGEN_STRONG_INLINE float predux_max(const Packet4f& a) return vget_lane_f32(max, 0); } -template<> EIGEN_STRONG_INLINE int predux_max(const Packet4i& a) +template<> EIGEN_STRONG_INLINE int32_t predux_max(const Packet4i& a) { int32x2_t a_lo, a_hi, max; diff --git a/eigenlib/Eigen/src/Core/arch/SSE/Complex.h b/eigenlib/Eigen/src/Core/arch/SSE/Complex.h index 5607fe0a..d075043c 100644 --- a/eigenlib/Eigen/src/Core/arch/SSE/Complex.h +++ b/eigenlib/Eigen/src/Core/arch/SSE/Complex.h @@ -128,7 +128,7 @@ template<> EIGEN_DEVICE_FUNC inline void pscatter, Packet2cf _mm_cvtss_f32(_mm_shuffle_ps(from.v, from.v, 3))); } -template<> EIGEN_STRONG_INLINE void prefetch >(const std::complex * addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); } +template<> EIGEN_STRONG_INLINE void prefetch >(const std::complex * addr) { _mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0); } template<> EIGEN_STRONG_INLINE std::complex pfirst(const Packet2cf& a) { @@ -229,23 +229,7 @@ template<> struct conj_helper } }; -template<> struct conj_helper -{ - EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet4f& x, const Packet2cf& y, const Packet2cf& c) const - { return padd(c, pmul(x,y)); } - - EIGEN_STRONG_INLINE Packet2cf pmul(const Packet4f& x, const Packet2cf& y) const - { return Packet2cf(Eigen::internal::pmul(x, y.v)); } -}; - -template<> struct conj_helper -{ - EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet4f& y, const Packet2cf& c) const - { return padd(c, pmul(x,y)); } - - EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& x, const Packet4f& y) const - { return Packet2cf(Eigen::internal::pmul(x.v, y)); } -}; +EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet2cf,Packet4f) template<> EIGEN_STRONG_INLINE Packet2cf pdiv(const Packet2cf& a, const Packet2cf& b) { @@ -340,7 +324,7 @@ template<> EIGEN_STRONG_INLINE Packet1cd ploaddup(const std::complex< template<> EIGEN_STRONG_INLINE void pstore >(std::complex * to, const Packet1cd& from) { EIGEN_DEBUG_ALIGNED_STORE pstore((double*)to, Packet2d(from.v)); } template<> EIGEN_STRONG_INLINE void pstoreu >(std::complex * to, const Packet1cd& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((double*)to, Packet2d(from.v)); } -template<> EIGEN_STRONG_INLINE void prefetch >(const std::complex * addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); } +template<> EIGEN_STRONG_INLINE void prefetch >(const std::complex * addr) { _mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0); } template<> EIGEN_STRONG_INLINE std::complex pfirst(const Packet1cd& a) { @@ -430,23 +414,7 @@ template<> struct conj_helper } }; -template<> struct conj_helper -{ - EIGEN_STRONG_INLINE Packet1cd pmadd(const Packet2d& x, const Packet1cd& y, const Packet1cd& c) const - { return padd(c, pmul(x,y)); } - - EIGEN_STRONG_INLINE Packet1cd pmul(const Packet2d& x, const Packet1cd& y) const - { return Packet1cd(Eigen::internal::pmul(x, y.v)); } -}; - -template<> struct conj_helper -{ - EIGEN_STRONG_INLINE Packet1cd pmadd(const Packet1cd& x, const Packet2d& y, const Packet1cd& c) const - { return padd(c, pmul(x,y)); } - - EIGEN_STRONG_INLINE Packet1cd pmul(const Packet1cd& x, const Packet2d& y) const - { return Packet1cd(Eigen::internal::pmul(x.v, y)); } -}; +EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet1cd,Packet2d) template<> EIGEN_STRONG_INLINE Packet1cd pdiv(const Packet1cd& a, const Packet1cd& b) { diff --git a/eigenlib/Eigen/src/Core/arch/SSE/PacketMath.h b/eigenlib/Eigen/src/Core/arch/SSE/PacketMath.h index 3832de14..60e2517e 100755 --- a/eigenlib/Eigen/src/Core/arch/SSE/PacketMath.h +++ b/eigenlib/Eigen/src/Core/arch/SSE/PacketMath.h @@ -28,7 +28,7 @@ namespace internal { #endif #endif -#if (defined EIGEN_VECTORIZE_AVX) && (EIGEN_COMP_GNUC_STRICT || EIGEN_COMP_MINGW) && (__GXX_ABI_VERSION < 1004) +#if ((defined EIGEN_VECTORIZE_AVX) && (EIGEN_COMP_GNUC_STRICT || EIGEN_COMP_MINGW) && (__GXX_ABI_VERSION < 1004)) || EIGEN_OS_QNX // With GCC's default ABI version, a __m128 or __m256 are the same types and therefore we cannot // have overloads for both types without linking error. // One solution is to increase ABI version using -fabi-version=4 (or greater). @@ -409,10 +409,16 @@ template<> EIGEN_STRONG_INLINE void pstore1(double* to, const double& pstore(to, Packet2d(vec2d_swizzle1(pa,0,0))); } +#if EIGEN_COMP_PGI +typedef const void * SsePrefetchPtrType; +#else +typedef const char * SsePrefetchPtrType; +#endif + #ifndef EIGEN_VECTORIZE_AVX -template<> EIGEN_STRONG_INLINE void prefetch(const float* addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); } -template<> EIGEN_STRONG_INLINE void prefetch(const double* addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); } -template<> EIGEN_STRONG_INLINE void prefetch(const int* addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); } +template<> EIGEN_STRONG_INLINE void prefetch(const float* addr) { _mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0); } +template<> EIGEN_STRONG_INLINE void prefetch(const double* addr) { _mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0); } +template<> EIGEN_STRONG_INLINE void prefetch(const int* addr) { _mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0); } #endif #if EIGEN_COMP_MSVC_STRICT && EIGEN_OS_WIN64 @@ -876,4 +882,14 @@ template<> EIGEN_STRONG_INLINE double pmadd(const double& a, const double& b, co } // end namespace Eigen +#if EIGEN_COMP_PGI +// PGI++ does not define the following intrinsics in C++ mode. +static inline __m128 _mm_castpd_ps (__m128d x) { return reinterpret_cast<__m128&>(x); } +static inline __m128i _mm_castpd_si128(__m128d x) { return reinterpret_cast<__m128i&>(x); } +static inline __m128d _mm_castps_pd (__m128 x) { return reinterpret_cast<__m128d&>(x); } +static inline __m128i _mm_castps_si128(__m128 x) { return reinterpret_cast<__m128i&>(x); } +static inline __m128 _mm_castsi128_ps(__m128i x) { return reinterpret_cast<__m128&>(x); } +static inline __m128d _mm_castsi128_pd(__m128i x) { return reinterpret_cast<__m128d&>(x); } +#endif + #endif // EIGEN_PACKET_MATH_SSE_H diff --git a/eigenlib/Eigen/src/Core/arch/SSE/TypeCasting.h b/eigenlib/Eigen/src/Core/arch/SSE/TypeCasting.h index c8489323..c6ca8c71 100644 --- a/eigenlib/Eigen/src/Core/arch/SSE/TypeCasting.h +++ b/eigenlib/Eigen/src/Core/arch/SSE/TypeCasting.h @@ -14,6 +14,7 @@ namespace Eigen { namespace internal { +#ifndef EIGEN_VECTORIZE_AVX template <> struct type_casting_traits { enum { @@ -23,11 +24,6 @@ struct type_casting_traits { }; }; -template<> EIGEN_STRONG_INLINE Packet4i pcast(const Packet4f& a) { - return _mm_cvttps_epi32(a); -} - - template <> struct type_casting_traits { enum { @@ -37,11 +33,6 @@ struct type_casting_traits { }; }; -template<> EIGEN_STRONG_INLINE Packet4f pcast(const Packet4i& a) { - return _mm_cvtepi32_ps(a); -} - - template <> struct type_casting_traits { enum { @@ -51,10 +42,6 @@ struct type_casting_traits { }; }; -template<> EIGEN_STRONG_INLINE Packet4f pcast(const Packet2d& a, const Packet2d& b) { - return _mm_shuffle_ps(_mm_cvtpd_ps(a), _mm_cvtpd_ps(b), (1 << 2) | (1 << 6)); -} - template <> struct type_casting_traits { enum { @@ -63,6 +50,19 @@ struct type_casting_traits { TgtCoeffRatio = 2 }; }; +#endif + +template<> EIGEN_STRONG_INLINE Packet4i pcast(const Packet4f& a) { + return _mm_cvttps_epi32(a); +} + +template<> EIGEN_STRONG_INLINE Packet4f pcast(const Packet4i& a) { + return _mm_cvtepi32_ps(a); +} + +template<> EIGEN_STRONG_INLINE Packet4f pcast(const Packet2d& a, const Packet2d& b) { + return _mm_shuffle_ps(_mm_cvtpd_ps(a), _mm_cvtpd_ps(b), (1 << 2) | (1 << 6)); +} template<> EIGEN_STRONG_INLINE Packet2d pcast(const Packet4f& a) { // Simply discard the second half of the input diff --git a/eigenlib/Eigen/src/Core/arch/ZVector/Complex.h b/eigenlib/Eigen/src/Core/arch/ZVector/Complex.h index d39d2d10..1bfb7339 100644 --- a/eigenlib/Eigen/src/Core/arch/ZVector/Complex.h +++ b/eigenlib/Eigen/src/Core/arch/ZVector/Complex.h @@ -336,6 +336,9 @@ template<> struct conj_helper } }; +EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet2cf,Packet4f) +EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet1cd,Packet2d) + template<> EIGEN_STRONG_INLINE Packet1cd pdiv(const Packet1cd& a, const Packet1cd& b) { // TODO optimize it for AltiVec diff --git a/eigenlib/Eigen/src/Core/arch/ZVector/PacketMath.h b/eigenlib/Eigen/src/Core/arch/ZVector/PacketMath.h index e2deb25c..57b01fc6 100755 --- a/eigenlib/Eigen/src/Core/arch/ZVector/PacketMath.h +++ b/eigenlib/Eigen/src/Core/arch/ZVector/PacketMath.h @@ -100,7 +100,7 @@ static Packet16uc p16uc_DUPLICATE32_HI = { 0,1,2,3, 0,1,2,3, 4,5,6,7, 4,5,6,7 }; // Mask alignment #define _EIGEN_MASK_ALIGNMENT 0xfffffffffffffff0 -#define _EIGEN_ALIGNED_PTR(x) ((ptrdiff_t)(x) & _EIGEN_MASK_ALIGNMENT) +#define _EIGEN_ALIGNED_PTR(x) ((std::ptrdiff_t)(x) & _EIGEN_MASK_ALIGNMENT) // Handle endianness properly while loading constants // Define global static constants: diff --git a/eigenlib/Eigen/src/Core/functors/AssignmentFunctors.h b/eigenlib/Eigen/src/Core/functors/AssignmentFunctors.h index 9b373c78..4153b877 100644 --- a/eigenlib/Eigen/src/Core/functors/AssignmentFunctors.h +++ b/eigenlib/Eigen/src/Core/functors/AssignmentFunctors.h @@ -28,7 +28,7 @@ template struct assign_op { { internal::pstoret(a,b); } }; -// Empty overload for void type (used by PermutationMatrix +// Empty overload for void type (used by PermutationMatrix) template struct assign_op {}; template diff --git a/eigenlib/Eigen/src/Core/functors/BinaryFunctors.h b/eigenlib/Eigen/src/Core/functors/BinaryFunctors.h index 96747bac..3eae6b8c 100644 --- a/eigenlib/Eigen/src/Core/functors/BinaryFunctors.h +++ b/eigenlib/Eigen/src/Core/functors/BinaryFunctors.h @@ -255,7 +255,7 @@ struct scalar_cmp_op : binary_op_base struct scalar_hypot_op : binary_op_base { EIGEN_EMPTY_STRUCT_CTOR(scalar_hypot_op) -// typedef typename NumTraits::Real result_type; - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& _x, const Scalar& _y) const + + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar &x, const Scalar &y) const { - EIGEN_USING_STD_MATH(sqrt) - Scalar p, qp; - if(_x>_y) - { - p = _x; - qp = _y / p; - } - else - { - p = _y; - qp = _x / p; - } - return p * sqrt(Scalar(1) + qp*qp); + // This functor is used by hypotNorm only for which it is faster to first apply abs + // on all coefficients prior to reduction through hypot. + // This way we avoid calling abs on positive and real entries, and this also permits + // to seamlessly handle complexes. Otherwise we would have to handle both real and complexes + // through the same functor... + return internal::positive_real_hypot(x,y); } }; template diff --git a/eigenlib/Eigen/src/Core/functors/NullaryFunctors.h b/eigenlib/Eigen/src/Core/functors/NullaryFunctors.h index 0311d903..b03be026 100644 --- a/eigenlib/Eigen/src/Core/functors/NullaryFunctors.h +++ b/eigenlib/Eigen/src/Core/functors/NullaryFunctors.h @@ -44,16 +44,16 @@ struct linspaced_op_impl { linspaced_op_impl(const Scalar& low, const Scalar& high, Index num_steps) : m_low(low), m_high(high), m_size1(num_steps==1 ? 1 : num_steps-1), m_step(num_steps==1 ? Scalar() : (high-low)/Scalar(num_steps-1)), - m_interPacket(plset(0)), m_flip(numext::abs(high) EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (IndexType i) const { + typedef typename NumTraits::Real RealScalar; if(m_flip) - return (i==0)? m_low : (m_high - (m_size1-i)*m_step); + return (i==0)? m_low : (m_high - RealScalar(m_size1-i)*m_step); else - return (i==m_size1)? m_high : (m_low + i*m_step); + return (i==m_size1)? m_high : (m_low + RealScalar(i)*m_step); } template @@ -63,7 +63,7 @@ struct linspaced_op_impl // [low, ..., low] + ( [step, ..., step] * ( [i, ..., i] + [0, ..., size] ) ) if(m_flip) { - Packet pi = padd(pset1(Scalar(i-m_size1)),m_interPacket); + Packet pi = plset(Scalar(i-m_size1)); Packet res = padd(pset1(m_high), pmul(pset1(m_step), pi)); if(i==0) res = pinsertfirst(res, m_low); @@ -71,7 +71,7 @@ struct linspaced_op_impl } else { - Packet pi = padd(pset1(Scalar(i)),m_interPacket); + Packet pi = plset(Scalar(i)); Packet res = padd(pset1(m_low), pmul(pset1(m_step), pi)); if(i==m_size1-unpacket_traits::size+1) res = pinsertlast(res, m_high); @@ -83,7 +83,6 @@ struct linspaced_op_impl const Scalar m_high; const Index m_size1; const Scalar m_step; - const Packet m_interPacket; const bool m_flip; }; @@ -93,8 +92,8 @@ struct linspaced_op_impl linspaced_op_impl(const Scalar& low, const Scalar& high, Index num_steps) : m_low(low), m_multiplier((high-low)/convert_index(num_steps<=1 ? 1 : num_steps-1)), - m_divisor(convert_index(num_steps+high-low)/(high-low+1)), - m_use_divisor((high+1)<(low+num_steps)) + m_divisor(convert_index((high>=low?num_steps:-num_steps)+(high-low))/((numext::abs(high-low)+1)==0?1:(numext::abs(high-low)+1))), + m_use_divisor(num_steps>1 && (numext::abs(high-low)+1) diff --git a/eigenlib/Eigen/src/Core/functors/StlFunctors.h b/eigenlib/Eigen/src/Core/functors/StlFunctors.h index 6df3fa50..9c1d7585 100644 --- a/eigenlib/Eigen/src/Core/functors/StlFunctors.h +++ b/eigenlib/Eigen/src/Core/functors/StlFunctors.h @@ -83,13 +83,17 @@ struct functor_traits > { enum { Cost = functor_traits::Cost, PacketAccess = false }; }; #endif +#if (__cplusplus < 201703L) && (EIGEN_COMP_MSVC < 1910) +// std::unary_negate is deprecated since c++17 and will be removed in c++20 template struct functor_traits > { enum { Cost = 1 + functor_traits::Cost, PacketAccess = false }; }; +// std::binary_negate is deprecated since c++17 and will be removed in c++20 template struct functor_traits > { enum { Cost = 1 + functor_traits::Cost, PacketAccess = false }; }; +#endif #ifdef EIGEN_STDEXT_SUPPORT diff --git a/eigenlib/Eigen/src/Core/functors/UnaryFunctors.h b/eigenlib/Eigen/src/Core/functors/UnaryFunctors.h index 2e6a00ff..b56e7afd 100644 --- a/eigenlib/Eigen/src/Core/functors/UnaryFunctors.h +++ b/eigenlib/Eigen/src/Core/functors/UnaryFunctors.h @@ -768,7 +768,7 @@ struct scalar_sign_op { if (aa==real_type(0)) return Scalar(0); aa = real_type(1)/aa; - return Scalar(real(a)*aa, imag(a)*aa ); + return Scalar(a.real()*aa, a.imag()*aa ); } //TODO //template diff --git a/eigenlib/Eigen/src/Core/products/GeneralBlockPanelKernel.h b/eigenlib/Eigen/src/Core/products/GeneralBlockPanelKernel.h index 45230bce..681451cc 100644 --- a/eigenlib/Eigen/src/Core/products/GeneralBlockPanelKernel.h +++ b/eigenlib/Eigen/src/Core/products/GeneralBlockPanelKernel.h @@ -115,7 +115,8 @@ void evaluateProductBlockingSizesHeuristic(Index& k, Index& m, Index& n, Index n // registers. However once the latency is hidden there is no point in // increasing the value of k, so we'll cap it at 320 (value determined // experimentally). - const Index k_cache = (numext::mini)((l1-ksub)/kdiv, 320); + // To avoid that k vanishes, we make k_cache at least as big as kr + const Index k_cache = numext::maxi(kr, (numext::mini)((l1-ksub)/kdiv, 320)); if (k_cache < k) { k = k_cache - (k_cache % kr); eigen_internal_assert(k > 0); @@ -648,8 +649,8 @@ public: // Vectorized path EIGEN_STRONG_INLINE void loadRhs(const RhsScalar* b, DoublePacketType& dest) const { - dest.first = pset1(real(*b)); - dest.second = pset1(imag(*b)); + dest.first = pset1(numext::real(*b)); + dest.second = pset1(numext::imag(*b)); } EIGEN_STRONG_INLINE void loadRhsQuad(const RhsScalar* b, ResPacket& dest) const @@ -1197,10 +1198,16 @@ void gebp_kernel=6 without FMA (bug 1637) + #if EIGEN_GNUC_AT_LEAST(6,0) && defined(EIGEN_VECTORIZE_SSE) + #define EIGEN_GEBP_2PX4_SPILLING_WORKAROUND __asm__ ("" : [a0] "+x,m" (A0),[a1] "+x,m" (A1)); + #else + #define EIGEN_GEBP_2PX4_SPILLING_WORKAROUND + #endif + #define EIGEN_GEBGP_ONESTEP(K) \ do { \ EIGEN_ASM_COMMENT("begin step of gebp micro kernel 2pX4"); \ - EIGEN_ASM_COMMENT("Note: these asm comments work around bug 935!"); \ traits.loadLhs(&blA[(0+2*K)*LhsProgress], A0); \ traits.loadLhs(&blA[(1+2*K)*LhsProgress], A1); \ traits.broadcastRhs(&blB[(0+4*K)*RhsProgress], B_0, B1, B2, B3); \ @@ -1212,6 +1219,7 @@ void gebp_kernel::half SResPacketHalf; + const int SResPacketHalfSize = unpacket_traits::half>::size; if ((SwappedTraits::LhsProgress % 4) == 0 && (SwappedTraits::LhsProgress <= 8) && - (SwappedTraits::LhsProgress!=8 || unpacket_traits::size==nr)) + (SwappedTraits::LhsProgress!=8 || SResPacketHalfSize==nr)) { SAccPacket C0, C1, C2, C3; straits.initAcc(C0); diff --git a/eigenlib/Eigen/src/Core/products/GeneralMatrixMatrix.h b/eigenlib/Eigen/src/Core/products/GeneralMatrixMatrix.h index 61df3be5..ed6234c3 100644 --- a/eigenlib/Eigen/src/Core/products/GeneralMatrixMatrix.h +++ b/eigenlib/Eigen/src/Core/products/GeneralMatrixMatrix.h @@ -20,8 +20,9 @@ template class level3_blocking; template< typename Index, typename LhsScalar, int LhsStorageOrder, bool ConjugateLhs, - typename RhsScalar, int RhsStorageOrder, bool ConjugateRhs> -struct general_matrix_matrix_product + typename RhsScalar, int RhsStorageOrder, bool ConjugateRhs, + int ResInnerStride> +struct general_matrix_matrix_product { typedef gebp_traits Traits; @@ -30,7 +31,7 @@ struct general_matrix_matrix_product& blocking, GemmParallelInfo* info = 0) @@ -39,8 +40,8 @@ struct general_matrix_matrix_product - ::run(cols,rows,depth,rhs,rhsStride,lhs,lhsStride,res,resStride,alpha,blocking,info); + ColMajor,ResInnerStride> + ::run(cols,rows,depth,rhs,rhsStride,lhs,lhsStride,res,resIncr,resStride,alpha,blocking,info); } }; @@ -49,8 +50,9 @@ struct general_matrix_matrix_product -struct general_matrix_matrix_product + typename RhsScalar, int RhsStorageOrder, bool ConjugateRhs, + int ResInnerStride> +struct general_matrix_matrix_product { typedef gebp_traits Traits; @@ -59,17 +61,17 @@ typedef typename ScalarBinaryOpTraits::ReturnType ResScala static void run(Index rows, Index cols, Index depth, const LhsScalar* _lhs, Index lhsStride, const RhsScalar* _rhs, Index rhsStride, - ResScalar* _res, Index resStride, + ResScalar* _res, Index resIncr, Index resStride, ResScalar alpha, level3_blocking& blocking, GemmParallelInfo* info = 0) { typedef const_blas_data_mapper LhsMapper; typedef const_blas_data_mapper RhsMapper; - typedef blas_data_mapper ResMapper; - LhsMapper lhs(_lhs,lhsStride); - RhsMapper rhs(_rhs,rhsStride); - ResMapper res(_res, resStride); + typedef blas_data_mapper ResMapper; + LhsMapper lhs(_lhs, lhsStride); + RhsMapper rhs(_rhs, rhsStride); + ResMapper res(_res, resStride, resIncr); Index kc = blocking.kc(); // cache block size along the K direction Index mc = (std::min)(rows,blocking.mc()); // cache block size along the M direction @@ -83,8 +85,8 @@ static void run(Index rows, Index cols, Index depth, if(info) { // this is the parallel version! - Index tid = omp_get_thread_num(); - Index threads = omp_get_num_threads(); + int tid = omp_get_thread_num(); + int threads = omp_get_num_threads(); LhsScalar* blockA = blocking.blockA(); eigen_internal_assert(blockA!=0); @@ -116,9 +118,9 @@ static void run(Index rows, Index cols, Index depth, info[tid].sync = k; // Computes C_i += A' * B' per A'_i - for(Index shift=0; shift static void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) { if((rhs.rows()+dst.rows()+dst.cols())<20 && rhs.rows()>0) - lazyproduct::evalTo(dst, lhs, rhs); + lazyproduct::eval_dynamic(dst, lhs, rhs, internal::assign_op()); else { dst.setZero(); @@ -440,7 +442,7 @@ struct generic_product_impl static void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) { if((rhs.rows()+dst.rows()+dst.cols())<20 && rhs.rows()>0) - lazyproduct::addTo(dst, lhs, rhs); + lazyproduct::eval_dynamic(dst, lhs, rhs, internal::add_assign_op()); else scaleAndAddTo(dst,lhs, rhs, Scalar(1)); } @@ -449,7 +451,7 @@ struct generic_product_impl static void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) { if((rhs.rows()+dst.rows()+dst.cols())<20 && rhs.rows()>0) - lazyproduct::subTo(dst, lhs, rhs); + lazyproduct::eval_dynamic(dst, lhs, rhs, internal::sub_assign_op()); else scaleAndAddTo(dst, lhs, rhs, Scalar(-1)); } @@ -476,7 +478,8 @@ struct generic_product_impl Index, LhsScalar, (ActualLhsTypeCleaned::Flags&RowMajorBit) ? RowMajor : ColMajor, bool(LhsBlasTraits::NeedToConjugate), RhsScalar, (ActualRhsTypeCleaned::Flags&RowMajorBit) ? RowMajor : ColMajor, bool(RhsBlasTraits::NeedToConjugate), - (Dest::Flags&RowMajorBit) ? RowMajor : ColMajor>, + (Dest::Flags&RowMajorBit) ? RowMajor : ColMajor, + Dest::InnerStrideAtCompileTime>, ActualLhsTypeCleaned, ActualRhsTypeCleaned, Dest, BlockingType> GemmFunctor; BlockingType blocking(dst.rows(), dst.cols(), lhs.cols(), 1, true); diff --git a/eigenlib/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h b/eigenlib/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h index 5cd2794a..d68d2f96 100644 --- a/eigenlib/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h +++ b/eigenlib/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h @@ -25,51 +25,54 @@ namespace internal { **********************************************************************/ // forward declarations (defined at the end of this file) -template +template struct tribb_kernel; /* Optimized matrix-matrix product evaluating only one triangular half */ template + int ResStorageOrder, int ResInnerStride, int UpLo, int Version = Specialized> struct general_matrix_matrix_triangular_product; // as usual if the result is row major => we transpose the product template -struct general_matrix_matrix_triangular_product + typename RhsScalar, int RhsStorageOrder, bool ConjugateRhs, + int ResInnerStride, int UpLo, int Version> +struct general_matrix_matrix_triangular_product { typedef typename ScalarBinaryOpTraits::ReturnType ResScalar; static EIGEN_STRONG_INLINE void run(Index size, Index depth,const LhsScalar* lhs, Index lhsStride, - const RhsScalar* rhs, Index rhsStride, ResScalar* res, Index resStride, + const RhsScalar* rhs, Index rhsStride, ResScalar* res, Index resIncr, Index resStride, const ResScalar& alpha, level3_blocking& blocking) { general_matrix_matrix_triangular_product - ::run(size,depth,rhs,rhsStride,lhs,lhsStride,res,resStride,alpha,blocking); + ColMajor, ResInnerStride, UpLo==Lower?Upper:Lower> + ::run(size,depth,rhs,rhsStride,lhs,lhsStride,res,resIncr,resStride,alpha,blocking); } }; template -struct general_matrix_matrix_triangular_product + typename RhsScalar, int RhsStorageOrder, bool ConjugateRhs, + int ResInnerStride, int UpLo, int Version> +struct general_matrix_matrix_triangular_product { typedef typename ScalarBinaryOpTraits::ReturnType ResScalar; static EIGEN_STRONG_INLINE void run(Index size, Index depth,const LhsScalar* _lhs, Index lhsStride, - const RhsScalar* _rhs, Index rhsStride, ResScalar* _res, Index resStride, + const RhsScalar* _rhs, Index rhsStride, + ResScalar* _res, Index resIncr, Index resStride, const ResScalar& alpha, level3_blocking& blocking) { typedef gebp_traits Traits; typedef const_blas_data_mapper LhsMapper; typedef const_blas_data_mapper RhsMapper; - typedef blas_data_mapper ResMapper; + typedef blas_data_mapper ResMapper; LhsMapper lhs(_lhs,lhsStride); RhsMapper rhs(_rhs,rhsStride); - ResMapper res(_res, resStride); + ResMapper res(_res, resStride, resIncr); Index kc = blocking.kc(); Index mc = (std::min)(size,blocking.mc()); @@ -87,7 +90,7 @@ struct general_matrix_matrix_triangular_product pack_lhs; gemm_pack_rhs pack_rhs; gebp_kernel gebp; - tribb_kernel sybb; + tribb_kernel sybb; for(Index k2=0; k2 +template struct tribb_kernel { typedef gebp_traits Traits; @@ -142,13 +144,15 @@ struct tribb_kernel enum { BlockSize = meta_least_common_multiple::ret }; - void operator()(ResScalar* _res, Index resStride, const LhsScalar* blockA, const RhsScalar* blockB, Index size, Index depth, const ResScalar& alpha) + void operator()(ResScalar* _res, Index resIncr, Index resStride, const LhsScalar* blockA, const RhsScalar* blockB, Index size, Index depth, const ResScalar& alpha) { - typedef blas_data_mapper ResMapper; - ResMapper res(_res, resStride); - gebp_kernel gebp_kernel; + typedef blas_data_mapper ResMapper; + typedef blas_data_mapper BufferMapper; + ResMapper res(_res, resStride, resIncr); + gebp_kernel gebp_kernel1; + gebp_kernel gebp_kernel2; - Matrix buffer; + Matrix buffer((internal::constructor_without_unaligned_array_assert())); // let's process the block per panel of actual_mc x BlockSize, // again, each is split into three parts, etc. @@ -158,31 +162,32 @@ struct tribb_kernel const RhsScalar* actual_b = blockB+j*depth; if(UpLo==Upper) - gebp_kernel(res.getSubMapper(0, j), blockA, actual_b, j, depth, actualBlockSize, alpha, - -1, -1, 0, 0); - + gebp_kernel1(res.getSubMapper(0, j), blockA, actual_b, j, depth, actualBlockSize, alpha, + -1, -1, 0, 0); + // selfadjoint micro block { Index i = j; buffer.setZero(); // 1 - apply the kernel on the temporary buffer - gebp_kernel(ResMapper(buffer.data(), BlockSize), blockA+depth*i, actual_b, actualBlockSize, depth, actualBlockSize, alpha, - -1, -1, 0, 0); + gebp_kernel2(BufferMapper(buffer.data(), BlockSize), blockA+depth*i, actual_b, actualBlockSize, depth, actualBlockSize, alpha, + -1, -1, 0, 0); + // 2 - triangular accumulation for(Index j1=0; j1 enum { IsRowMajor = (internal::traits::Flags&RowMajorBit) ? 1 : 0, LhsIsRowMajor = _ActualLhs::Flags&RowMajorBit ? 1 : 0, - RhsIsRowMajor = _ActualRhs::Flags&RowMajorBit ? 1 : 0 + RhsIsRowMajor = _ActualRhs::Flags&RowMajorBit ? 1 : 0, + SkipDiag = (UpLo&(UnitDiag|ZeroDiag))!=0 }; Index size = mat.cols(); + if(SkipDiag) + size--; Index depth = actualLhs.cols(); typedef internal::gemm_blocking_space internal::general_matrix_matrix_triangular_product + IsRowMajor ? RowMajor : ColMajor, MatrixType::InnerStrideAtCompileTime, UpLo&(Lower|Upper)> ::run(size, depth, - &actualLhs.coeffRef(0,0), actualLhs.outerStride(), &actualRhs.coeffRef(0,0), actualRhs.outerStride(), - mat.data(), mat.outerStride(), actualAlpha, blocking); + &actualLhs.coeffRef(SkipDiag&&(UpLo&Lower)==Lower ? 1 : 0,0), actualLhs.outerStride(), + &actualRhs.coeffRef(0,SkipDiag&&(UpLo&Upper)==Upper ? 1 : 0), actualRhs.outerStride(), + mat.data() + (SkipDiag ? (bool(IsRowMajor) != ((UpLo&Lower)==Lower) ? mat.innerStride() : mat.outerStride() ) : 0), + mat.innerStride(), mat.outerStride(), actualAlpha, blocking); } }; @@ -294,6 +304,7 @@ template template TriangularView& TriangularViewImpl::_assignProduct(const ProductType& prod, const Scalar& alpha, bool beta) { + EIGEN_STATIC_ASSERT((UpLo&UnitDiag)==0, WRITING_TO_TRIANGULAR_PART_WITH_UNIT_DIAGONAL_IS_NOT_SUPPORTED); eigen_assert(derived().nestedExpression().rows() == prod.rows() && derived().cols() == prod.cols()); general_product_to_triangular_selector::InnerSize==1>::run(derived().nestedExpression().const_cast_derived(), prod, alpha, beta); diff --git a/eigenlib/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h b/eigenlib/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h index 5b7c15cc..691f95d6 100644 --- a/eigenlib/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h +++ b/eigenlib/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h @@ -40,7 +40,7 @@ namespace internal { template struct general_matrix_matrix_rankupdate : general_matrix_matrix_triangular_product< - Index,Scalar,AStorageOrder,ConjugateA,Scalar,AStorageOrder,ConjugateA,ResStorageOrder,UpLo,BuiltIn> {}; + Index,Scalar,AStorageOrder,ConjugateA,Scalar,AStorageOrder,ConjugateA,ResStorageOrder,1,UpLo,BuiltIn> {}; // try to go to BLAS specialization @@ -48,19 +48,19 @@ struct general_matrix_matrix_rankupdate : template \ struct general_matrix_matrix_triangular_product { \ + Scalar,RhsStorageOrder,ConjugateRhs,ColMajor,1,UpLo,Specialized> { \ static EIGEN_STRONG_INLINE void run(Index size, Index depth,const Scalar* lhs, Index lhsStride, \ - const Scalar* rhs, Index rhsStride, Scalar* res, Index resStride, Scalar alpha, level3_blocking& blocking) \ + const Scalar* rhs, Index rhsStride, Scalar* res, Index resIncr, Index resStride, Scalar alpha, level3_blocking& blocking) \ { \ - if (lhs==rhs) { \ + if ( lhs==rhs && ((UpLo&(Lower|Upper))==UpLo) ) { \ general_matrix_matrix_rankupdate \ ::run(size,depth,lhs,lhsStride,rhs,rhsStride,res,resStride,alpha,blocking); \ } else { \ general_matrix_matrix_triangular_product \ - ::run(size,depth,lhs,lhsStride,rhs,rhsStride,res,resStride,alpha,blocking); \ + ColMajor, 1, UpLo, BuiltIn> \ + ::run(size,depth,lhs,lhsStride,rhs,rhsStride,res,resIncr,resStride,alpha,blocking); \ } \ } \ }; @@ -88,7 +88,7 @@ struct general_matrix_matrix_rankupdate(lhsStride), ldc=convert_index(resStride), n=convert_index(size), k=convert_index(depth); \ char uplo=((IsLower) ? 'L' : 'U'), trans=((AStorageOrder==RowMajor) ? 'T':'N'); \ EIGTYPE beta(1); \ - BLASFUNC(&uplo, &trans, &n, &k, &numext::real_ref(alpha), lhs, &lda, &numext::real_ref(beta), res, &ldc); \ + BLASFUNC(&uplo, &trans, &n, &k, (const BLASTYPE*)&numext::real_ref(alpha), lhs, &lda, (const BLASTYPE*)&numext::real_ref(beta), res, &ldc); \ } \ }; @@ -125,9 +125,13 @@ struct general_matrix_matrix_rankupdate \ -struct general_matrix_matrix_product \ +struct general_matrix_matrix_product \ { \ typedef gebp_traits Traits; \ \ static void run(Index rows, Index cols, Index depth, \ const EIGTYPE* _lhs, Index lhsStride, \ const EIGTYPE* _rhs, Index rhsStride, \ - EIGTYPE* res, Index resStride, \ + EIGTYPE* res, Index resIncr, Index resStride, \ EIGTYPE alpha, \ level3_blocking& /*blocking*/, \ GemmParallelInfo* /*info = 0*/) \ { \ using std::conj; \ \ + EIGEN_ONLY_USED_FOR_DEBUG(resIncr); \ + eigen_assert(resIncr == 1); \ char transa, transb; \ BlasIndex m, n, k, lda, ldb, ldc; \ const EIGTYPE *a, *b; \ @@ -100,13 +102,20 @@ static void run(Index rows, Index cols, Index depth, \ ldb = convert_index(b_tmp.outerStride()); \ } else b = _rhs; \ \ - BLASPREFIX##gemm_(&transa, &transb, &m, &n, &k, &numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (const BLASTYPE*)b, &ldb, &numext::real_ref(beta), (BLASTYPE*)res, &ldc); \ + BLASFUNC(&transa, &transb, &m, &n, &k, (const BLASTYPE*)&numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (const BLASTYPE*)b, &ldb, (const BLASTYPE*)&numext::real_ref(beta), (BLASTYPE*)res, &ldc); \ }}; -GEMM_SPECIALIZATION(double, d, double, d) -GEMM_SPECIALIZATION(float, f, float, s) -GEMM_SPECIALIZATION(dcomplex, cd, double, z) -GEMM_SPECIALIZATION(scomplex, cf, float, c) +#ifdef EIGEN_USE_MKL +GEMM_SPECIALIZATION(double, d, double, dgemm) +GEMM_SPECIALIZATION(float, f, float, sgemm) +GEMM_SPECIALIZATION(dcomplex, cd, MKL_Complex16, zgemm) +GEMM_SPECIALIZATION(scomplex, cf, MKL_Complex8, cgemm) +#else +GEMM_SPECIALIZATION(double, d, double, dgemm_) +GEMM_SPECIALIZATION(float, f, float, sgemm_) +GEMM_SPECIALIZATION(dcomplex, cd, double, zgemm_) +GEMM_SPECIALIZATION(scomplex, cf, float, cgemm_) +#endif } // end namespase internal diff --git a/eigenlib/Eigen/src/Core/products/GeneralMatrixVector.h b/eigenlib/Eigen/src/Core/products/GeneralMatrixVector.h index 3c1a7fc4..a597c1f4 100644 --- a/eigenlib/Eigen/src/Core/products/GeneralMatrixVector.h +++ b/eigenlib/Eigen/src/Core/products/GeneralMatrixVector.h @@ -183,8 +183,8 @@ EIGEN_DONT_INLINE void general_matrix_vector_product \ struct general_matrix_vector_product_gemv \ { \ @@ -113,14 +113,21 @@ static void run( \ x_ptr=x_tmp.data(); \ incx=1; \ } else x_ptr=rhs; \ - BLASPREFIX##gemv_(&trans, &m, &n, &numext::real_ref(alpha), (const BLASTYPE*)lhs, &lda, (const BLASTYPE*)x_ptr, &incx, &numext::real_ref(beta), (BLASTYPE*)res, &incy); \ + BLASFUNC(&trans, &m, &n, (const BLASTYPE*)&numext::real_ref(alpha), (const BLASTYPE*)lhs, &lda, (const BLASTYPE*)x_ptr, &incx, (const BLASTYPE*)&numext::real_ref(beta), (BLASTYPE*)res, &incy); \ }\ }; -EIGEN_BLAS_GEMV_SPECIALIZATION(double, double, d) -EIGEN_BLAS_GEMV_SPECIALIZATION(float, float, s) -EIGEN_BLAS_GEMV_SPECIALIZATION(dcomplex, double, z) -EIGEN_BLAS_GEMV_SPECIALIZATION(scomplex, float, c) +#ifdef EIGEN_USE_MKL +EIGEN_BLAS_GEMV_SPECIALIZATION(double, double, dgemv) +EIGEN_BLAS_GEMV_SPECIALIZATION(float, float, sgemv) +EIGEN_BLAS_GEMV_SPECIALIZATION(dcomplex, MKL_Complex16, zgemv) +EIGEN_BLAS_GEMV_SPECIALIZATION(scomplex, MKL_Complex8 , cgemv) +#else +EIGEN_BLAS_GEMV_SPECIALIZATION(double, double, dgemv_) +EIGEN_BLAS_GEMV_SPECIALIZATION(float, float, sgemv_) +EIGEN_BLAS_GEMV_SPECIALIZATION(dcomplex, double, zgemv_) +EIGEN_BLAS_GEMV_SPECIALIZATION(scomplex, float, cgemv_) +#endif } // end namespase internal diff --git a/eigenlib/Eigen/src/Core/products/Parallelizer.h b/eigenlib/Eigen/src/Core/products/Parallelizer.h index 2a31e4cb..a3cc05b7 100644 --- a/eigenlib/Eigen/src/Core/products/Parallelizer.h +++ b/eigenlib/Eigen/src/Core/products/Parallelizer.h @@ -17,7 +17,8 @@ namespace internal { /** \internal */ inline void manage_multi_threading(Action action, int* v) { - static EIGEN_UNUSED int m_maxThreads = -1; + static int m_maxThreads = -1; + EIGEN_UNUSED_VARIABLE(m_maxThreads); if(action==SetAction) { @@ -75,7 +76,7 @@ template struct GemmParallelInfo { GemmParallelInfo() : sync(-1), users(0), lhs_start(0), lhs_length(0) {} - int volatile sync; + Index volatile sync; int volatile users; Index lhs_start; @@ -104,13 +105,14 @@ void parallelize_gemm(const Functor& func, Index rows, Index cols, Index depth, // - the sizes are large enough // compute the maximal number of threads from the size of the product: - // FIXME this has to be fine tuned + // This first heuristic takes into account that the product kernel is fully optimized when working with nr columns at once. Index size = transpose ? rows : cols; - Index pb_max_threads = std::max(1,size / 32); + Index pb_max_threads = std::max(1,size / Functor::Traits::nr); + // compute the maximal number of threads from the total amount of work: double work = static_cast(rows) * static_cast(cols) * static_cast(depth); - double kMinTaskSize = 50000; // Heuristic. + double kMinTaskSize = 50000; // FIXME improve this heuristic. pb_max_threads = std::max(1, std::min(pb_max_threads, work / kMinTaskSize)); // compute the number of threads we are going to use @@ -149,8 +151,10 @@ void parallelize_gemm(const Functor& func, Index rows, Index cols, Index depth, info[i].lhs_start = r0; info[i].lhs_length = actualBlockRows; - if(transpose) func(c0, actualBlockCols, 0, rows, info); - else func(0, rows, c0, actualBlockCols, info); + if(transpose) + func(c0, actualBlockCols, 0, rows, info); + else + func(0, rows, c0, actualBlockCols, info); } #endif } diff --git a/eigenlib/Eigen/src/Core/products/SelfadjointMatrixMatrix.h b/eigenlib/Eigen/src/Core/products/SelfadjointMatrixMatrix.h index da6f82ab..04c93348 100644 --- a/eigenlib/Eigen/src/Core/products/SelfadjointMatrixMatrix.h +++ b/eigenlib/Eigen/src/Core/products/SelfadjointMatrixMatrix.h @@ -277,20 +277,21 @@ struct symm_pack_rhs template + int ResStorageOrder, int ResInnerStride> struct product_selfadjoint_matrix; template -struct product_selfadjoint_matrix + int RhsStorageOrder, bool RhsSelfAdjoint, bool ConjugateRhs, + int ResInnerStride> +struct product_selfadjoint_matrix { static EIGEN_STRONG_INLINE void run( Index rows, Index cols, const Scalar* lhs, Index lhsStride, const Scalar* rhs, Index rhsStride, - Scalar* res, Index resStride, + Scalar* res, Index resIncr, Index resStride, const Scalar& alpha, level3_blocking& blocking) { product_selfadjoint_matrix::IsComplex && EIGEN_LOGICAL_XOR(RhsSelfAdjoint,ConjugateRhs), EIGEN_LOGICAL_XOR(LhsSelfAdjoint,LhsStorageOrder==RowMajor) ? ColMajor : RowMajor, LhsSelfAdjoint, NumTraits::IsComplex && EIGEN_LOGICAL_XOR(LhsSelfAdjoint,ConjugateLhs), - ColMajor> - ::run(cols, rows, rhs, rhsStride, lhs, lhsStride, res, resStride, alpha, blocking); + ColMajor,ResInnerStride> + ::run(cols, rows, rhs, rhsStride, lhs, lhsStride, res, resIncr, resStride, alpha, blocking); } }; template -struct product_selfadjoint_matrix + int RhsStorageOrder, bool ConjugateRhs, + int ResInnerStride> +struct product_selfadjoint_matrix { static EIGEN_DONT_INLINE void run( Index rows, Index cols, const Scalar* _lhs, Index lhsStride, const Scalar* _rhs, Index rhsStride, - Scalar* res, Index resStride, + Scalar* res, Index resIncr, Index resStride, const Scalar& alpha, level3_blocking& blocking); }; template -EIGEN_DONT_INLINE void product_selfadjoint_matrix::run( + int RhsStorageOrder, bool ConjugateRhs, + int ResInnerStride> +EIGEN_DONT_INLINE void product_selfadjoint_matrix::run( Index rows, Index cols, const Scalar* _lhs, Index lhsStride, const Scalar* _rhs, Index rhsStride, - Scalar* _res, Index resStride, + Scalar* _res, Index resIncr, Index resStride, const Scalar& alpha, level3_blocking& blocking) { Index size = rows; @@ -334,11 +337,11 @@ EIGEN_DONT_INLINE void product_selfadjoint_matrix LhsMapper; typedef const_blas_data_mapper LhsTransposeMapper; typedef const_blas_data_mapper RhsMapper; - typedef blas_data_mapper ResMapper; + typedef blas_data_mapper ResMapper; LhsMapper lhs(_lhs,lhsStride); LhsTransposeMapper lhs_transpose(_lhs,lhsStride); RhsMapper rhs(_rhs,rhsStride); - ResMapper res(_res, resStride); + ResMapper res(_res, resStride, resIncr); Index kc = blocking.kc(); // cache block size along the K direction Index mc = (std::min)(rows,blocking.mc()); // cache block size along the M direction @@ -398,26 +401,28 @@ EIGEN_DONT_INLINE void product_selfadjoint_matrix -struct product_selfadjoint_matrix + int RhsStorageOrder, bool ConjugateRhs, + int ResInnerStride> +struct product_selfadjoint_matrix { static EIGEN_DONT_INLINE void run( Index rows, Index cols, const Scalar* _lhs, Index lhsStride, const Scalar* _rhs, Index rhsStride, - Scalar* res, Index resStride, + Scalar* res, Index resIncr, Index resStride, const Scalar& alpha, level3_blocking& blocking); }; template -EIGEN_DONT_INLINE void product_selfadjoint_matrix::run( + int RhsStorageOrder, bool ConjugateRhs, + int ResInnerStride> +EIGEN_DONT_INLINE void product_selfadjoint_matrix::run( Index rows, Index cols, const Scalar* _lhs, Index lhsStride, const Scalar* _rhs, Index rhsStride, - Scalar* _res, Index resStride, + Scalar* _res, Index resIncr, Index resStride, const Scalar& alpha, level3_blocking& blocking) { Index size = cols; @@ -425,9 +430,9 @@ EIGEN_DONT_INLINE void product_selfadjoint_matrix Traits; typedef const_blas_data_mapper LhsMapper; - typedef blas_data_mapper ResMapper; + typedef blas_data_mapper ResMapper; LhsMapper lhs(_lhs,lhsStride); - ResMapper res(_res,resStride); + ResMapper res(_res,resStride, resIncr); Index kc = blocking.kc(); // cache block size along the K direction Index mc = (std::min)(rows,blocking.mc()); // cache block size along the M direction @@ -503,12 +508,13 @@ struct selfadjoint_product_impl NumTraits::IsComplex && EIGEN_LOGICAL_XOR(LhsIsUpper,bool(LhsBlasTraits::NeedToConjugate)), EIGEN_LOGICAL_XOR(RhsIsUpper,internal::traits::Flags &RowMajorBit) ? RowMajor : ColMajor, RhsIsSelfAdjoint, NumTraits::IsComplex && EIGEN_LOGICAL_XOR(RhsIsUpper,bool(RhsBlasTraits::NeedToConjugate)), - internal::traits::Flags&RowMajorBit ? RowMajor : ColMajor> + internal::traits::Flags&RowMajorBit ? RowMajor : ColMajor, + Dest::InnerStrideAtCompileTime> ::run( lhs.rows(), rhs.cols(), // sizes &lhs.coeffRef(0,0), lhs.outerStride(), // lhs info &rhs.coeffRef(0,0), rhs.outerStride(), // rhs info - &dst.coeffRef(0,0), dst.outerStride(), // result info + &dst.coeffRef(0,0), dst.innerStride(), dst.outerStride(), // result info actualAlpha, blocking // alpha ); } diff --git a/eigenlib/Eigen/src/Core/products/SelfadjointMatrixMatrix_BLAS.h b/eigenlib/Eigen/src/Core/products/SelfadjointMatrixMatrix_BLAS.h index a45238d6..61396dbd 100644 --- a/eigenlib/Eigen/src/Core/products/SelfadjointMatrixMatrix_BLAS.h +++ b/eigenlib/Eigen/src/Core/products/SelfadjointMatrixMatrix_BLAS.h @@ -40,20 +40,22 @@ namespace internal { /* Optimized selfadjoint matrix * matrix (?SYMM/?HEMM) product */ -#define EIGEN_BLAS_SYMM_L(EIGTYPE, BLASTYPE, EIGPREFIX, BLASPREFIX) \ +#define EIGEN_BLAS_SYMM_L(EIGTYPE, BLASTYPE, EIGPREFIX, BLASFUNC) \ template \ -struct product_selfadjoint_matrix \ +struct product_selfadjoint_matrix \ {\ \ static void run( \ Index rows, Index cols, \ const EIGTYPE* _lhs, Index lhsStride, \ const EIGTYPE* _rhs, Index rhsStride, \ - EIGTYPE* res, Index resStride, \ + EIGTYPE* res, Index resIncr, Index resStride, \ EIGTYPE alpha, level3_blocking& /*blocking*/) \ { \ + EIGEN_ONLY_USED_FOR_DEBUG(resIncr); \ + eigen_assert(resIncr == 1); \ char side='L', uplo='L'; \ BlasIndex m, n, lda, ldb, ldc; \ const EIGTYPE *a, *b; \ @@ -81,25 +83,27 @@ struct product_selfadjoint_matrix(b_tmp.outerStride()); \ } else b = _rhs; \ \ - BLASPREFIX##symm_(&side, &uplo, &m, &n, &numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (const BLASTYPE*)b, &ldb, &numext::real_ref(beta), (BLASTYPE*)res, &ldc); \ + BLASFUNC(&side, &uplo, &m, &n, (const BLASTYPE*)&numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (const BLASTYPE*)b, &ldb, (const BLASTYPE*)&numext::real_ref(beta), (BLASTYPE*)res, &ldc); \ \ } \ }; -#define EIGEN_BLAS_HEMM_L(EIGTYPE, BLASTYPE, EIGPREFIX, BLASPREFIX) \ +#define EIGEN_BLAS_HEMM_L(EIGTYPE, BLASTYPE, EIGPREFIX, BLASFUNC) \ template \ -struct product_selfadjoint_matrix \ +struct product_selfadjoint_matrix \ {\ static void run( \ Index rows, Index cols, \ const EIGTYPE* _lhs, Index lhsStride, \ const EIGTYPE* _rhs, Index rhsStride, \ - EIGTYPE* res, Index resStride, \ + EIGTYPE* res, Index resIncr, Index resStride, \ EIGTYPE alpha, level3_blocking& /*blocking*/) \ { \ + EIGEN_ONLY_USED_FOR_DEBUG(resIncr); \ + eigen_assert(resIncr == 1); \ char side='L', uplo='L'; \ BlasIndex m, n, lda, ldb, ldc; \ const EIGTYPE *a, *b; \ @@ -144,33 +148,41 @@ struct product_selfadjoint_matrix(b_tmp.outerStride()); \ } \ \ - BLASPREFIX##hemm_(&side, &uplo, &m, &n, &numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (const BLASTYPE*)b, &ldb, &numext::real_ref(beta), (BLASTYPE*)res, &ldc); \ + BLASFUNC(&side, &uplo, &m, &n, (const BLASTYPE*)&numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (const BLASTYPE*)b, &ldb, (const BLASTYPE*)&numext::real_ref(beta), (BLASTYPE*)res, &ldc); \ \ } \ }; -EIGEN_BLAS_SYMM_L(double, double, d, d) -EIGEN_BLAS_SYMM_L(float, float, f, s) -EIGEN_BLAS_HEMM_L(dcomplex, double, cd, z) -EIGEN_BLAS_HEMM_L(scomplex, float, cf, c) - +#ifdef EIGEN_USE_MKL +EIGEN_BLAS_SYMM_L(double, double, d, dsymm) +EIGEN_BLAS_SYMM_L(float, float, f, ssymm) +EIGEN_BLAS_HEMM_L(dcomplex, MKL_Complex16, cd, zhemm) +EIGEN_BLAS_HEMM_L(scomplex, MKL_Complex8, cf, chemm) +#else +EIGEN_BLAS_SYMM_L(double, double, d, dsymm_) +EIGEN_BLAS_SYMM_L(float, float, f, ssymm_) +EIGEN_BLAS_HEMM_L(dcomplex, double, cd, zhemm_) +EIGEN_BLAS_HEMM_L(scomplex, float, cf, chemm_) +#endif /* Optimized matrix * selfadjoint matrix (?SYMM/?HEMM) product */ -#define EIGEN_BLAS_SYMM_R(EIGTYPE, BLASTYPE, EIGPREFIX, BLASPREFIX) \ +#define EIGEN_BLAS_SYMM_R(EIGTYPE, BLASTYPE, EIGPREFIX, BLASFUNC) \ template \ -struct product_selfadjoint_matrix \ +struct product_selfadjoint_matrix \ {\ \ static void run( \ Index rows, Index cols, \ const EIGTYPE* _lhs, Index lhsStride, \ const EIGTYPE* _rhs, Index rhsStride, \ - EIGTYPE* res, Index resStride, \ + EIGTYPE* res, Index resIncr, Index resStride, \ EIGTYPE alpha, level3_blocking& /*blocking*/) \ { \ + EIGEN_ONLY_USED_FOR_DEBUG(resIncr); \ + eigen_assert(resIncr == 1); \ char side='R', uplo='L'; \ BlasIndex m, n, lda, ldb, ldc; \ const EIGTYPE *a, *b; \ @@ -197,25 +209,27 @@ struct product_selfadjoint_matrix(b_tmp.outerStride()); \ } else b = _lhs; \ \ - BLASPREFIX##symm_(&side, &uplo, &m, &n, &numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (const BLASTYPE*)b, &ldb, &numext::real_ref(beta), (BLASTYPE*)res, &ldc); \ + BLASFUNC(&side, &uplo, &m, &n, (const BLASTYPE*)&numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (const BLASTYPE*)b, &ldb, (const BLASTYPE*)&numext::real_ref(beta), (BLASTYPE*)res, &ldc); \ \ } \ }; -#define EIGEN_BLAS_HEMM_R(EIGTYPE, BLASTYPE, EIGPREFIX, BLASPREFIX) \ +#define EIGEN_BLAS_HEMM_R(EIGTYPE, BLASTYPE, EIGPREFIX, BLASFUNC) \ template \ -struct product_selfadjoint_matrix \ +struct product_selfadjoint_matrix \ {\ static void run( \ Index rows, Index cols, \ const EIGTYPE* _lhs, Index lhsStride, \ const EIGTYPE* _rhs, Index rhsStride, \ - EIGTYPE* res, Index resStride, \ + EIGTYPE* res, Index resIncr, Index resStride, \ EIGTYPE alpha, level3_blocking& /*blocking*/) \ { \ + EIGEN_ONLY_USED_FOR_DEBUG(resIncr); \ + eigen_assert(resIncr == 1); \ char side='R', uplo='L'; \ BlasIndex m, n, lda, ldb, ldc; \ const EIGTYPE *a, *b; \ @@ -259,15 +273,21 @@ struct product_selfadjoint_matrix(b_tmp.outerStride()); \ } \ \ - BLASPREFIX##hemm_(&side, &uplo, &m, &n, &numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (const BLASTYPE*)b, &ldb, &numext::real_ref(beta), (BLASTYPE*)res, &ldc); \ + BLASFUNC(&side, &uplo, &m, &n, (const BLASTYPE*)&numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (const BLASTYPE*)b, &ldb, (const BLASTYPE*)&numext::real_ref(beta), (BLASTYPE*)res, &ldc); \ } \ }; -EIGEN_BLAS_SYMM_R(double, double, d, d) -EIGEN_BLAS_SYMM_R(float, float, f, s) -EIGEN_BLAS_HEMM_R(dcomplex, double, cd, z) -EIGEN_BLAS_HEMM_R(scomplex, float, cf, c) - +#ifdef EIGEN_USE_MKL +EIGEN_BLAS_SYMM_R(double, double, d, dsymm) +EIGEN_BLAS_SYMM_R(float, float, f, ssymm) +EIGEN_BLAS_HEMM_R(dcomplex, MKL_Complex16, cd, zhemm) +EIGEN_BLAS_HEMM_R(scomplex, MKL_Complex8, cf, chemm) +#else +EIGEN_BLAS_SYMM_R(double, double, d, dsymm_) +EIGEN_BLAS_SYMM_R(float, float, f, ssymm_) +EIGEN_BLAS_HEMM_R(dcomplex, double, cd, zhemm_) +EIGEN_BLAS_HEMM_R(scomplex, float, cf, chemm_) +#endif } // end namespace internal } // end namespace Eigen diff --git a/eigenlib/Eigen/src/Core/products/SelfadjointMatrixVector.h b/eigenlib/Eigen/src/Core/products/SelfadjointMatrixVector.h index d97f8caa..3fd180e6 100644 --- a/eigenlib/Eigen/src/Core/products/SelfadjointMatrixVector.h +++ b/eigenlib/Eigen/src/Core/products/SelfadjointMatrixVector.h @@ -83,10 +83,10 @@ EIGEN_DONT_INLINE void selfadjoint_matrix_vector_product(t3); - size_t starti = FirstTriangular ? 0 : j+2; - size_t endi = FirstTriangular ? j : size; - size_t alignedStart = (starti) + internal::first_default_aligned(&res[starti], endi-starti); - size_t alignedEnd = alignedStart + ((endi-alignedStart)/(PacketSize))*(PacketSize); + Index starti = FirstTriangular ? 0 : j+2; + Index endi = FirstTriangular ? j : size; + Index alignedStart = (starti) + internal::first_default_aligned(&res[starti], endi-starti); + Index alignedEnd = alignedStart + ((endi-alignedStart)/(PacketSize))*(PacketSize); res[j] += cjd.pmul(numext::real(A0[j]), t0); res[j+1] += cjd.pmul(numext::real(A1[j+1]), t1); @@ -101,7 +101,7 @@ EIGEN_DONT_INLINE void selfadjoint_matrix_vector_product(a0It); a0It += PacketSize; Packet A1i = ploadu(a1It); a1It += PacketSize; @@ -125,7 +125,7 @@ EIGEN_DONT_INLINE void selfadjoint_matrix_vector_product internal::general_matrix_matrix_triangular_product::IsComplex, Scalar, OtherIsRowMajor ? ColMajor : RowMajor, (!OtherBlasTraits::NeedToConjugate) && NumTraits::IsComplex, - IsRowMajor ? RowMajor : ColMajor, UpLo> + IsRowMajor ? RowMajor : ColMajor, MatrixType::InnerStrideAtCompileTime, UpLo> ::run(size, depth, &actualOther.coeffRef(0,0), actualOther.outerStride(), &actualOther.coeffRef(0,0), actualOther.outerStride(), - mat.data(), mat.outerStride(), actualAlpha, blocking); + mat.data(), mat.innerStride(), mat.outerStride(), actualAlpha, blocking); } }; diff --git a/eigenlib/Eigen/src/Core/products/TriangularMatrixMatrix.h b/eigenlib/Eigen/src/Core/products/TriangularMatrixMatrix.h index 8a2f7cd7..2fb408d1 100644 --- a/eigenlib/Eigen/src/Core/products/TriangularMatrixMatrix.h +++ b/eigenlib/Eigen/src/Core/products/TriangularMatrixMatrix.h @@ -45,22 +45,24 @@ template + int ResStorageOrder, int ResInnerStride, + int Version = Specialized> struct product_triangular_matrix_matrix; template + int RhsStorageOrder, bool ConjugateRhs, + int ResInnerStride, int Version> struct product_triangular_matrix_matrix + RhsStorageOrder,ConjugateRhs,RowMajor,ResInnerStride,Version> { static EIGEN_STRONG_INLINE void run( Index rows, Index cols, Index depth, const Scalar* lhs, Index lhsStride, const Scalar* rhs, Index rhsStride, - Scalar* res, Index resStride, + Scalar* res, Index resIncr, Index resStride, const Scalar& alpha, level3_blocking& blocking) { product_triangular_matrix_matrix - ::run(cols, rows, depth, rhs, rhsStride, lhs, lhsStride, res, resStride, alpha, blocking); + ColMajor, ResInnerStride> + ::run(cols, rows, depth, rhs, rhsStride, lhs, lhsStride, res, resIncr, resStride, alpha, blocking); } }; // implements col-major += alpha * op(triangular) * op(general) template + int RhsStorageOrder, bool ConjugateRhs, + int ResInnerStride, int Version> struct product_triangular_matrix_matrix + RhsStorageOrder,ConjugateRhs,ColMajor,ResInnerStride,Version> { typedef gebp_traits Traits; @@ -95,20 +98,21 @@ struct product_triangular_matrix_matrix& blocking); }; template + int RhsStorageOrder, bool ConjugateRhs, + int ResInnerStride, int Version> EIGEN_DONT_INLINE void product_triangular_matrix_matrix::run( + RhsStorageOrder,ConjugateRhs,ColMajor,ResInnerStride,Version>::run( Index _rows, Index _cols, Index _depth, const Scalar* _lhs, Index lhsStride, const Scalar* _rhs, Index rhsStride, - Scalar* _res, Index resStride, + Scalar* _res, Index resIncr, Index resStride, const Scalar& alpha, level3_blocking& blocking) { // strip zeros @@ -119,10 +123,10 @@ EIGEN_DONT_INLINE void product_triangular_matrix_matrix LhsMapper; typedef const_blas_data_mapper RhsMapper; - typedef blas_data_mapper ResMapper; + typedef blas_data_mapper ResMapper; LhsMapper lhs(_lhs,lhsStride); RhsMapper rhs(_rhs,rhsStride); - ResMapper res(_res, resStride); + ResMapper res(_res, resStride, resIncr); Index kc = blocking.kc(); // cache block size along the K direction Index mc = (std::min)(rows,blocking.mc()); // cache block size along the M direction @@ -137,7 +141,13 @@ EIGEN_DONT_INLINE void product_triangular_matrix_matrix triangularBuffer; + // To work around an "error: member reference base type 'Matrix<...> + // (Eigen::internal::constructor_without_unaligned_array_assert (*)())' is + // not a structure or union" compilation error in nvcc (tested V8.0.61), + // create a dummy internal::constructor_without_unaligned_array_assert + // object to pass to the Matrix constructor. + internal::constructor_without_unaligned_array_assert a; + Matrix triangularBuffer(a); triangularBuffer.setZero(); if((Mode&ZeroDiag)==ZeroDiag) triangularBuffer.diagonal().setZero(); @@ -229,10 +239,11 @@ EIGEN_DONT_INLINE void product_triangular_matrix_matrix + int RhsStorageOrder, bool ConjugateRhs, + int ResInnerStride, int Version> struct product_triangular_matrix_matrix + RhsStorageOrder,ConjugateRhs,ColMajor,ResInnerStride,Version> { typedef gebp_traits Traits; enum { @@ -245,20 +256,21 @@ struct product_triangular_matrix_matrix& blocking); }; template + int RhsStorageOrder, bool ConjugateRhs, + int ResInnerStride, int Version> EIGEN_DONT_INLINE void product_triangular_matrix_matrix::run( + RhsStorageOrder,ConjugateRhs,ColMajor,ResInnerStride,Version>::run( Index _rows, Index _cols, Index _depth, const Scalar* _lhs, Index lhsStride, const Scalar* _rhs, Index rhsStride, - Scalar* _res, Index resStride, + Scalar* _res, Index resIncr, Index resStride, const Scalar& alpha, level3_blocking& blocking) { const Index PacketBytes = packet_traits::size*sizeof(Scalar); @@ -270,10 +282,10 @@ EIGEN_DONT_INLINE void product_triangular_matrix_matrix LhsMapper; typedef const_blas_data_mapper RhsMapper; - typedef blas_data_mapper ResMapper; + typedef blas_data_mapper ResMapper; LhsMapper lhs(_lhs,lhsStride); RhsMapper rhs(_rhs,rhsStride); - ResMapper res(_res, resStride); + ResMapper res(_res, resStride, resIncr); Index kc = blocking.kc(); // cache block size along the K direction Index mc = (std::min)(rows,blocking.mc()); // cache block size along the M direction @@ -284,7 +296,8 @@ EIGEN_DONT_INLINE void product_triangular_matrix_matrix triangularBuffer; + internal::constructor_without_unaligned_array_assert a; + Matrix triangularBuffer(a); triangularBuffer.setZero(); if((Mode&ZeroDiag)==ZeroDiag) triangularBuffer.diagonal().setZero(); @@ -393,7 +406,9 @@ struct triangular_product_impl { template static void run(Dest& dst, const Lhs &a_lhs, const Rhs &a_rhs, const typename Dest::Scalar& alpha) { - typedef typename Dest::Scalar Scalar; + typedef typename Lhs::Scalar LhsScalar; + typedef typename Rhs::Scalar RhsScalar; + typedef typename Dest::Scalar Scalar; typedef internal::blas_traits LhsBlasTraits; typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhsType; @@ -405,8 +420,9 @@ struct triangular_product_impl typename internal::add_const_on_value_type::type lhs = LhsBlasTraits::extract(a_lhs); typename internal::add_const_on_value_type::type rhs = RhsBlasTraits::extract(a_rhs); - Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(a_lhs) - * RhsBlasTraits::extractScalarFactor(a_rhs); + LhsScalar lhs_alpha = LhsBlasTraits::extractScalarFactor(a_lhs); + RhsScalar rhs_alpha = RhsBlasTraits::extractScalarFactor(a_rhs); + Scalar actualAlpha = alpha * lhs_alpha * rhs_alpha; typedef internal::gemm_blocking_space<(Dest::Flags&RowMajorBit) ? RowMajor : ColMajor,Scalar,Scalar, Lhs::MaxRowsAtCompileTime, Rhs::MaxColsAtCompileTime, Lhs::MaxColsAtCompileTime,4> BlockingType; @@ -423,14 +439,29 @@ struct triangular_product_impl Mode, LhsIsTriangular, (internal::traits::Flags&RowMajorBit) ? RowMajor : ColMajor, LhsBlasTraits::NeedToConjugate, (internal::traits::Flags&RowMajorBit) ? RowMajor : ColMajor, RhsBlasTraits::NeedToConjugate, - (internal::traits::Flags&RowMajorBit) ? RowMajor : ColMajor> + (internal::traits::Flags&RowMajorBit) ? RowMajor : ColMajor, Dest::InnerStrideAtCompileTime> ::run( stripedRows, stripedCols, stripedDepth, // sizes &lhs.coeffRef(0,0), lhs.outerStride(), // lhs info &rhs.coeffRef(0,0), rhs.outerStride(), // rhs info - &dst.coeffRef(0,0), dst.outerStride(), // result info + &dst.coeffRef(0,0), dst.innerStride(), dst.outerStride(), // result info actualAlpha, blocking ); + + // Apply correction if the diagonal is unit and a scalar factor was nested: + if ((Mode&UnitDiag)==UnitDiag) + { + if (LhsIsTriangular && lhs_alpha!=LhsScalar(1)) + { + Index diagSize = (std::min)(lhs.rows(),lhs.cols()); + dst.topRows(diagSize) -= ((lhs_alpha-LhsScalar(1))*a_rhs).topRows(diagSize); + } + else if ((!LhsIsTriangular) && rhs_alpha!=RhsScalar(1)) + { + Index diagSize = (std::min)(rhs.rows(),rhs.cols()); + dst.leftCols(diagSize) -= (rhs_alpha-RhsScalar(1))*a_lhs.leftCols(diagSize); + } + } } }; diff --git a/eigenlib/Eigen/src/Core/products/TriangularMatrixMatrix_BLAS.h b/eigenlib/Eigen/src/Core/products/TriangularMatrixMatrix_BLAS.h index aecded6b..a98d12e4 100644 --- a/eigenlib/Eigen/src/Core/products/TriangularMatrixMatrix_BLAS.h +++ b/eigenlib/Eigen/src/Core/products/TriangularMatrixMatrix_BLAS.h @@ -46,7 +46,7 @@ template {}; + RhsStorageOrder, ConjugateRhs, ResStorageOrder, 1, BuiltIn> {}; // try to go to BLAS specialization @@ -55,13 +55,15 @@ template \ struct product_triangular_matrix_matrix { \ + LhsStorageOrder,ConjugateLhs, RhsStorageOrder,ConjugateRhs,ColMajor,1,Specialized> { \ static inline void run(Index _rows, Index _cols, Index _depth, const Scalar* _lhs, Index lhsStride,\ - const Scalar* _rhs, Index rhsStride, Scalar* res, Index resStride, Scalar alpha, level3_blocking& blocking) { \ + const Scalar* _rhs, Index rhsStride, Scalar* res, Index resIncr, Index resStride, Scalar alpha, level3_blocking& blocking) { \ + EIGEN_ONLY_USED_FOR_DEBUG(resIncr); \ + eigen_assert(resIncr == 1); \ product_triangular_matrix_matrix_trmm::run( \ - _rows, _cols, _depth, _lhs, lhsStride, _rhs, rhsStride, res, resStride, alpha, blocking); \ + _rows, _cols, _depth, _lhs, lhsStride, _rhs, rhsStride, res, resStride, alpha, blocking); \ } \ }; @@ -75,7 +77,7 @@ EIGEN_BLAS_TRMM_SPECIALIZE(scomplex, true) EIGEN_BLAS_TRMM_SPECIALIZE(scomplex, false) // implements col-major += alpha * op(triangular) * op(general) -#define EIGEN_BLAS_TRMM_L(EIGTYPE, BLASTYPE, EIGPREFIX, BLASPREFIX) \ +#define EIGEN_BLAS_TRMM_L(EIGTYPE, BLASTYPE, EIGPREFIX, BLASFUNC) \ template \ @@ -115,8 +117,8 @@ struct product_triangular_matrix_matrix_trmm::run( \ - _rows, _cols, _depth, _lhs, lhsStride, _rhs, rhsStride, res, resStride, alpha, blocking); \ + LhsStorageOrder,ConjugateLhs, RhsStorageOrder, ConjugateRhs, ColMajor, 1, BuiltIn>::run( \ + _rows, _cols, _depth, _lhs, lhsStride, _rhs, rhsStride, res, 1, resStride, alpha, blocking); \ /*std::cout << "TRMM_L: A is not square! Go to Eigen TRMM implementation!\n";*/ \ } else { \ /* Make sense to call GEMM */ \ @@ -124,8 +126,8 @@ struct product_triangular_matrix_matrix_trmm(); \ BlasIndex aStride = convert_index(aa_tmp.outerStride()); \ gemm_blocking_space gemm_blocking(_rows,_cols,_depth, 1, true); \ - general_matrix_matrix_product::run( \ - rows, cols, depth, aa_tmp.data(), aStride, _rhs, rhsStride, res, resStride, alpha, gemm_blocking, 0); \ + general_matrix_matrix_product::run( \ + rows, cols, depth, aa_tmp.data(), aStride, _rhs, rhsStride, res, 1, resStride, alpha, gemm_blocking, 0); \ \ /*std::cout << "TRMM_L: A is not square! Go to BLAS GEMM implementation! " << nthr<<" \n";*/ \ } \ @@ -172,7 +174,7 @@ struct product_triangular_matrix_matrix_trmm > res_tmp(res,rows,cols,OuterStride<>(resStride)); \ @@ -180,13 +182,20 @@ struct product_triangular_matrix_matrix_trmm \ @@ -225,8 +234,8 @@ struct product_triangular_matrix_matrix_trmm::run( \ - _rows, _cols, _depth, _lhs, lhsStride, _rhs, rhsStride, res, resStride, alpha, blocking); \ + LhsStorageOrder,ConjugateLhs, RhsStorageOrder, ConjugateRhs, ColMajor, 1, BuiltIn>::run( \ + _rows, _cols, _depth, _lhs, lhsStride, _rhs, rhsStride, res, 1, resStride, alpha, blocking); \ /*std::cout << "TRMM_R: A is not square! Go to Eigen TRMM implementation!\n";*/ \ } else { \ /* Make sense to call GEMM */ \ @@ -234,8 +243,8 @@ struct product_triangular_matrix_matrix_trmm(); \ BlasIndex aStride = convert_index(aa_tmp.outerStride()); \ gemm_blocking_space gemm_blocking(_rows,_cols,_depth, 1, true); \ - general_matrix_matrix_product::run( \ - rows, cols, depth, _lhs, lhsStride, aa_tmp.data(), aStride, res, resStride, alpha, gemm_blocking, 0); \ + general_matrix_matrix_product::run( \ + rows, cols, depth, _lhs, lhsStride, aa_tmp.data(), aStride, res, 1, resStride, alpha, gemm_blocking, 0); \ \ /*std::cout << "TRMM_R: A is not square! Go to BLAS GEMM implementation! " << nthr<<" \n";*/ \ } \ @@ -282,7 +291,7 @@ struct product_triangular_matrix_matrix_trmm > res_tmp(res,rows,cols,OuterStride<>(resStride)); \ @@ -290,11 +299,17 @@ struct product_triangular_matrix_matrix_trmm struct trmv_selector typename internal::add_const_on_value_type::type actualLhs = LhsBlasTraits::extract(lhs); typename internal::add_const_on_value_type::type actualRhs = RhsBlasTraits::extract(rhs); - ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(lhs) - * RhsBlasTraits::extractScalarFactor(rhs); + LhsScalar lhs_alpha = LhsBlasTraits::extractScalarFactor(lhs); + RhsScalar rhs_alpha = RhsBlasTraits::extractScalarFactor(rhs); + ResScalar actualAlpha = alpha * lhs_alpha * rhs_alpha; enum { // FIXME find a way to allow an inner stride on the result if packet_traits::size==1 @@ -274,6 +275,12 @@ template struct trmv_selector else dest = MappedDest(actualDestPtr, dest.size()); } + + if ( ((Mode&UnitDiag)==UnitDiag) && (lhs_alpha!=LhsScalar(1)) ) + { + Index diagSize = (std::min)(lhs.rows(),lhs.cols()); + dest.head(diagSize) -= (lhs_alpha-LhsScalar(1))*rhs.head(diagSize); + } } }; @@ -295,8 +302,9 @@ template struct trmv_selector typename add_const::type actualLhs = LhsBlasTraits::extract(lhs); typename add_const::type actualRhs = RhsBlasTraits::extract(rhs); - ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(lhs) - * RhsBlasTraits::extractScalarFactor(rhs); + LhsScalar lhs_alpha = LhsBlasTraits::extractScalarFactor(lhs); + RhsScalar rhs_alpha = RhsBlasTraits::extractScalarFactor(rhs); + ResScalar actualAlpha = alpha * lhs_alpha * rhs_alpha; enum { DirectlyUseRhs = ActualRhsTypeCleaned::InnerStrideAtCompileTime==1 @@ -326,6 +334,12 @@ template struct trmv_selector actualRhsPtr,1, dest.data(),dest.innerStride(), actualAlpha); + + if ( ((Mode&UnitDiag)==UnitDiag) && (lhs_alpha!=LhsScalar(1)) ) + { + Index diagSize = (std::min)(lhs.rows(),lhs.cols()); + dest.head(diagSize) -= (lhs_alpha-LhsScalar(1))*rhs.head(diagSize); + } } }; diff --git a/eigenlib/Eigen/src/Core/products/TriangularMatrixVector_BLAS.h b/eigenlib/Eigen/src/Core/products/TriangularMatrixVector_BLAS.h index 07bf26ce..3d47a2b9 100644 --- a/eigenlib/Eigen/src/Core/products/TriangularMatrixVector_BLAS.h +++ b/eigenlib/Eigen/src/Core/products/TriangularMatrixVector_BLAS.h @@ -71,7 +71,7 @@ EIGEN_BLAS_TRMV_SPECIALIZE(dcomplex) EIGEN_BLAS_TRMV_SPECIALIZE(scomplex) // implements col-major: res += alpha * op(triangular) * vector -#define EIGEN_BLAS_TRMV_CM(EIGTYPE, BLASTYPE, EIGPREFIX, BLASPREFIX) \ +#define EIGEN_BLAS_TRMV_CM(EIGTYPE, BLASTYPE, EIGPREFIX, BLASPREFIX, BLASPOSTFIX) \ template \ struct triangular_matrix_vector_product_trmv { \ enum { \ @@ -121,10 +121,10 @@ struct triangular_matrix_vector_product_trmv(size); \ n = convert_index(cols-size); \ } \ - BLASPREFIX##gemv_(&trans, &m, &n, &numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (const BLASTYPE*)x, &incx, &numext::real_ref(beta), (BLASTYPE*)y, &incy); \ + BLASPREFIX##gemv##BLASPOSTFIX(&trans, &m, &n, (const BLASTYPE*)&numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (const BLASTYPE*)x, &incx, (const BLASTYPE*)&numext::real_ref(beta), (BLASTYPE*)y, &incy); \ } \ } \ }; -EIGEN_BLAS_TRMV_CM(double, double, d, d) -EIGEN_BLAS_TRMV_CM(dcomplex, double, cd, z) -EIGEN_BLAS_TRMV_CM(float, float, f, s) -EIGEN_BLAS_TRMV_CM(scomplex, float, cf, c) +#ifdef EIGEN_USE_MKL +EIGEN_BLAS_TRMV_CM(double, double, d, d,) +EIGEN_BLAS_TRMV_CM(dcomplex, MKL_Complex16, cd, z,) +EIGEN_BLAS_TRMV_CM(float, float, f, s,) +EIGEN_BLAS_TRMV_CM(scomplex, MKL_Complex8, cf, c,) +#else +EIGEN_BLAS_TRMV_CM(double, double, d, d, _) +EIGEN_BLAS_TRMV_CM(dcomplex, double, cd, z, _) +EIGEN_BLAS_TRMV_CM(float, float, f, s, _) +EIGEN_BLAS_TRMV_CM(scomplex, float, cf, c, _) +#endif // implements row-major: res += alpha * op(triangular) * vector -#define EIGEN_BLAS_TRMV_RM(EIGTYPE, BLASTYPE, EIGPREFIX, BLASPREFIX) \ +#define EIGEN_BLAS_TRMV_RM(EIGTYPE, BLASTYPE, EIGPREFIX, BLASPREFIX, BLASPOSTFIX) \ template \ struct triangular_matrix_vector_product_trmv { \ enum { \ @@ -203,10 +210,10 @@ struct triangular_matrix_vector_product_trmv(size); \ n = convert_index(cols-size); \ } \ - BLASPREFIX##gemv_(&trans, &n, &m, &numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (const BLASTYPE*)x, &incx, &numext::real_ref(beta), (BLASTYPE*)y, &incy); \ + BLASPREFIX##gemv##BLASPOSTFIX(&trans, &n, &m, (const BLASTYPE*)&numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (const BLASTYPE*)x, &incx, (const BLASTYPE*)&numext::real_ref(beta), (BLASTYPE*)y, &incy); \ } \ } \ }; -EIGEN_BLAS_TRMV_RM(double, double, d, d) -EIGEN_BLAS_TRMV_RM(dcomplex, double, cd, z) -EIGEN_BLAS_TRMV_RM(float, float, f, s) -EIGEN_BLAS_TRMV_RM(scomplex, float, cf, c) +#ifdef EIGEN_USE_MKL +EIGEN_BLAS_TRMV_RM(double, double, d, d,) +EIGEN_BLAS_TRMV_RM(dcomplex, MKL_Complex16, cd, z,) +EIGEN_BLAS_TRMV_RM(float, float, f, s,) +EIGEN_BLAS_TRMV_RM(scomplex, MKL_Complex8, cf, c,) +#else +EIGEN_BLAS_TRMV_RM(double, double, d, d,_) +EIGEN_BLAS_TRMV_RM(dcomplex, double, cd, z,_) +EIGEN_BLAS_TRMV_RM(float, float, f, s,_) +EIGEN_BLAS_TRMV_RM(scomplex, float, cf, c,_) +#endif } // end namespase internal diff --git a/eigenlib/Eigen/src/Core/products/TriangularSolverMatrix.h b/eigenlib/Eigen/src/Core/products/TriangularSolverMatrix.h index 223c38b8..e3ed2cd1 100644 --- a/eigenlib/Eigen/src/Core/products/TriangularSolverMatrix.h +++ b/eigenlib/Eigen/src/Core/products/TriangularSolverMatrix.h @@ -15,48 +15,48 @@ namespace Eigen { namespace internal { // if the rhs is row major, let's transpose the product -template -struct triangular_solve_matrix +template +struct triangular_solve_matrix { static void run( Index size, Index cols, const Scalar* tri, Index triStride, - Scalar* _other, Index otherStride, + Scalar* _other, Index otherIncr, Index otherStride, level3_blocking& blocking) { triangular_solve_matrix< Scalar, Index, Side==OnTheLeft?OnTheRight:OnTheLeft, (Mode&UnitDiag) | ((Mode&Upper) ? Lower : Upper), NumTraits::IsComplex && Conjugate, - TriStorageOrder==RowMajor ? ColMajor : RowMajor, ColMajor> - ::run(size, cols, tri, triStride, _other, otherStride, blocking); + TriStorageOrder==RowMajor ? ColMajor : RowMajor, ColMajor, OtherInnerStride> + ::run(size, cols, tri, triStride, _other, otherIncr, otherStride, blocking); } }; /* Optimized triangular solver with multiple right hand side and the triangular matrix on the left */ -template -struct triangular_solve_matrix +template +struct triangular_solve_matrix { static EIGEN_DONT_INLINE void run( Index size, Index otherSize, const Scalar* _tri, Index triStride, - Scalar* _other, Index otherStride, + Scalar* _other, Index otherIncr, Index otherStride, level3_blocking& blocking); }; -template -EIGEN_DONT_INLINE void triangular_solve_matrix::run( +template +EIGEN_DONT_INLINE void triangular_solve_matrix::run( Index size, Index otherSize, const Scalar* _tri, Index triStride, - Scalar* _other, Index otherStride, + Scalar* _other, Index otherIncr, Index otherStride, level3_blocking& blocking) { Index cols = otherSize; typedef const_blas_data_mapper TriMapper; - typedef blas_data_mapper OtherMapper; + typedef blas_data_mapper OtherMapper; TriMapper tri(_tri, triStride); - OtherMapper other(_other, otherStride); + OtherMapper other(_other, otherStride, otherIncr); typedef gebp_traits Traits; @@ -128,19 +128,19 @@ EIGEN_DONT_INLINE void triangular_solve_matrix -struct triangular_solve_matrix +template +struct triangular_solve_matrix { static EIGEN_DONT_INLINE void run( Index size, Index otherSize, const Scalar* _tri, Index triStride, - Scalar* _other, Index otherStride, + Scalar* _other, Index otherIncr, Index otherStride, level3_blocking& blocking); }; -template -EIGEN_DONT_INLINE void triangular_solve_matrix::run( +template +EIGEN_DONT_INLINE void triangular_solve_matrix::run( Index size, Index otherSize, const Scalar* _tri, Index triStride, - Scalar* _other, Index otherStride, + Scalar* _other, Index otherIncr, Index otherStride, level3_blocking& blocking) { Index rows = otherSize; typedef typename NumTraits::Real RealScalar; - typedef blas_data_mapper LhsMapper; + typedef blas_data_mapper LhsMapper; typedef const_blas_data_mapper RhsMapper; - LhsMapper lhs(_other, otherStride); + LhsMapper lhs(_other, otherStride, otherIncr); RhsMapper rhs(_tri, triStride); typedef gebp_traits Traits; @@ -297,24 +297,24 @@ EIGEN_DONT_INLINE void triangular_solve_matrix \ -struct triangular_solve_matrix \ +struct triangular_solve_matrix \ { \ enum { \ IsLower = (Mode&Lower) == Lower, \ @@ -51,8 +51,10 @@ struct triangular_solve_matrix& /*blocking*/) \ + EIGTYPE* _other, Index otherIncr, Index otherStride, level3_blocking& /*blocking*/) \ { \ + EIGEN_ONLY_USED_FOR_DEBUG(otherIncr); \ + eigen_assert(otherIncr == 1); \ BlasIndex m = convert_index(size), n = convert_index(otherSize), lda, ldb; \ char side = 'L', uplo, diag='N', transa; \ /* Set alpha_ */ \ @@ -80,20 +82,26 @@ struct triangular_solve_matrix \ -struct triangular_solve_matrix \ +struct triangular_solve_matrix \ { \ enum { \ IsLower = (Mode&Lower) == Lower, \ @@ -104,8 +112,10 @@ struct triangular_solve_matrix& /*blocking*/) \ + EIGTYPE* _other, Index otherIncr, Index otherStride, level3_blocking& /*blocking*/) \ { \ + EIGEN_ONLY_USED_FOR_DEBUG(otherIncr); \ + eigen_assert(otherIncr == 1); \ BlasIndex m = convert_index(otherSize), n = convert_index(size), lda, ldb; \ char side = 'R', uplo, diag='N', transa; \ /* Set alpha_ */ \ @@ -133,16 +143,22 @@ struct triangular_solve_matrix + int ResStorageOrder, int ResInnerStride> struct general_matrix_matrix_product; template +class BlasLinearMapper; + template -class BlasLinearMapper { +class BlasLinearMapper { public: typedef typename packet_traits::type Packet; typedef typename packet_traits::half HalfPacket; - EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE BlasLinearMapper(Scalar *data) : m_data(data) {} + EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE BlasLinearMapper(Scalar *data, Index incr=1) + : m_data(data) + { + EIGEN_ONLY_USED_FOR_DEBUG(incr); + eigen_assert(incr==1); + } EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void prefetch(int i) const { internal::prefetch(&operator()(i)); @@ -188,16 +196,25 @@ class BlasLinearMapper { }; // Lightweight helper class to access matrix coefficients. -template -class blas_data_mapper { - public: +template +class blas_data_mapper; + +template +class blas_data_mapper +{ +public: typedef typename packet_traits::type Packet; typedef typename packet_traits::half HalfPacket; typedef BlasLinearMapper LinearMapper; typedef BlasVectorMapper VectorMapper; - EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE blas_data_mapper(Scalar* data, Index stride) : m_data(data), m_stride(stride) {} + EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE blas_data_mapper(Scalar* data, Index stride, Index incr=1) + : m_data(data), m_stride(stride) + { + EIGEN_ONLY_USED_FOR_DEBUG(incr); + eigen_assert(incr==1); + } EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE blas_data_mapper getSubMapper(Index i, Index j) const { @@ -251,6 +268,90 @@ class blas_data_mapper { const Index m_stride; }; +// Implementation of non-natural increment (i.e. inner-stride != 1) +// The exposed API is not complete yet compared to the Incr==1 case +// because some features makes less sense in this case. +template +class BlasLinearMapper +{ +public: + typedef typename packet_traits::type Packet; + typedef typename packet_traits::half HalfPacket; + + EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE BlasLinearMapper(Scalar *data,Index incr) : m_data(data), m_incr(incr) {} + + EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void prefetch(int i) const { + internal::prefetch(&operator()(i)); + } + + EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Scalar& operator()(Index i) const { + return m_data[i*m_incr.value()]; + } + + EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet loadPacket(Index i) const { + return pgather(m_data + i*m_incr.value(), m_incr.value()); + } + + template + EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void storePacket(Index i, const PacketType &p) const { + pscatter(m_data + i*m_incr.value(), p, m_incr.value()); + } + +protected: + Scalar *m_data; + const internal::variable_if_dynamic m_incr; +}; + +template +class blas_data_mapper +{ +public: + typedef typename packet_traits::type Packet; + typedef typename packet_traits::half HalfPacket; + + typedef BlasLinearMapper LinearMapper; + + EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE blas_data_mapper(Scalar* data, Index stride, Index incr) : m_data(data), m_stride(stride), m_incr(incr) {} + + EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE blas_data_mapper + getSubMapper(Index i, Index j) const { + return blas_data_mapper(&operator()(i, j), m_stride, m_incr.value()); + } + + EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE LinearMapper getLinearMapper(Index i, Index j) const { + return LinearMapper(&operator()(i, j), m_incr.value()); + } + + EIGEN_DEVICE_FUNC + EIGEN_ALWAYS_INLINE Scalar& operator()(Index i, Index j) const { + return m_data[StorageOrder==RowMajor ? j*m_incr.value() + i*m_stride : i*m_incr.value() + j*m_stride]; + } + + EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet loadPacket(Index i, Index j) const { + return pgather(&operator()(i, j),m_incr.value()); + } + + template + EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE PacketT load(Index i, Index j) const { + return pgather(&operator()(i, j),m_incr.value()); + } + + template + EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void scatterPacket(Index i, Index j, const SubPacket &p) const { + pscatter(&operator()(i, j), p, m_stride); + } + + template + EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE SubPacket gatherPacket(Index i, Index j) const { + return pgather(&operator()(i, j), m_stride); + } + +protected: + Scalar* EIGEN_RESTRICT m_data; + const Index m_stride; + const internal::variable_if_dynamic m_incr; +}; + // lightweight helper class to access matrix coefficients (const version) template class const_blas_data_mapper : public blas_data_mapper { diff --git a/eigenlib/Eigen/src/Core/util/DisableStupidWarnings.h b/eigenlib/Eigen/src/Core/util/DisableStupidWarnings.h index 7559e129..74f74cc4 100755 --- a/eigenlib/Eigen/src/Core/util/DisableStupidWarnings.h +++ b/eigenlib/Eigen/src/Core/util/DisableStupidWarnings.h @@ -43,13 +43,24 @@ #endif #pragma clang diagnostic ignored "-Wconstant-logical-operand" -#elif defined __GNUC__ && __GNUC__>=6 +#elif defined __GNUC__ - #ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS + #if (!defined(EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS)) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) #pragma GCC diagnostic push #endif - #pragma GCC diagnostic ignored "-Wignored-attributes" - + // g++ warns about local variables shadowing member functions, which is too strict + #pragma GCC diagnostic ignored "-Wshadow" + #if __GNUC__ == 4 && __GNUC_MINOR__ < 8 + // Until g++-4.7 there are warnings when comparing unsigned int vs 0, even in templated functions: + #pragma GCC diagnostic ignored "-Wtype-limits" + #endif + #if __GNUC__>=6 + #pragma GCC diagnostic ignored "-Wignored-attributes" + #endif + #if __GNUC__==7 + // See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89325 + #pragma GCC diagnostic ignored "-Wattributes" + #endif #endif #if defined __NVCC__ @@ -72,4 +83,12 @@ #pragma diag_suppress 2737 #endif +#else +// warnings already disabled: +# ifndef EIGEN_WARNINGS_DISABLED_2 +# define EIGEN_WARNINGS_DISABLED_2 +# elif defined(EIGEN_INTERNAL_DEBUGGING) +# error "Do not include \"DisableStupidWarnings.h\" recursively more than twice!" +# endif + #endif // not EIGEN_WARNINGS_DISABLED diff --git a/eigenlib/Eigen/src/Core/util/ForwardDeclarations.h b/eigenlib/Eigen/src/Core/util/ForwardDeclarations.h index ea107393..134544f9 100644 --- a/eigenlib/Eigen/src/Core/util/ForwardDeclarations.h +++ b/eigenlib/Eigen/src/Core/util/ForwardDeclarations.h @@ -47,11 +47,7 @@ template struct NumTraits; template struct EigenBase; template class DenseBase; template class PlainObjectBase; - - -template::value > -class DenseCoeffsBase; +template class DenseCoeffsBase; template /*Check IMKL version for compatibility: < 10.3 is not usable with Eigen*/ @@ -108,6 +109,10 @@ #endif #endif +#if defined(EIGEN_USE_BLAS) && !defined(EIGEN_USE_MKL) +#include "../../misc/blas.h" +#endif + namespace Eigen { typedef std::complex dcomplex; @@ -121,8 +126,5 @@ typedef int BlasIndex; } // end namespace Eigen -#if defined(EIGEN_USE_BLAS) -#include "../../misc/blas.h" -#endif #endif // EIGEN_MKL_SUPPORT_H diff --git a/eigenlib/Eigen/src/Core/util/Macros.h b/eigenlib/Eigen/src/Core/util/Macros.h index ace330b3..6b0399eb 100644 --- a/eigenlib/Eigen/src/Core/util/Macros.h +++ b/eigenlib/Eigen/src/Core/util/Macros.h @@ -13,7 +13,7 @@ #define EIGEN_WORLD_VERSION 3 #define EIGEN_MAJOR_VERSION 3 -#define EIGEN_MINOR_VERSION 2 +#define EIGEN_MINOR_VERSION 9 #define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \ (EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \ @@ -80,8 +80,8 @@ // 2015 14 1900 // "15" 15 1900 -/// \internal EIGEN_COMP_MSVC_STRICT set to 1 if the compiler is really Microsoft Visual C++ and not ,e.g., ICC -#if EIGEN_COMP_MSVC && !(EIGEN_COMP_ICC) +/// \internal EIGEN_COMP_MSVC_STRICT set to 1 if the compiler is really Microsoft Visual C++ and not ,e.g., ICC or clang-cl +#if EIGEN_COMP_MSVC && !(EIGEN_COMP_ICC || EIGEN_COMP_LLVM || EIGEN_COMP_CLANG) #define EIGEN_COMP_MSVC_STRICT _MSC_VER #else #define EIGEN_COMP_MSVC_STRICT 0 @@ -380,7 +380,8 @@ #if EIGEN_MAX_CPP_VER>=11 && \ ((defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)) \ || (defined(__GNUC__) && defined(_GLIBCXX_USE_C99)) \ - || (defined(_LIBCPP_VERSION) && !defined(_MSC_VER))) + || (defined(_LIBCPP_VERSION) && !defined(_MSC_VER)) \ + || (EIGEN_COMP_MSVC >= 1900) ) #define EIGEN_HAS_C99_MATH 1 #else #define EIGEN_HAS_C99_MATH 0 @@ -396,10 +397,24 @@ #endif #endif +// Does the compiler support type_traits? +// - full support of type traits was added only to GCC 5.1.0. +// - 20150626 corresponds to the last release of 4.x libstdc++ +#ifndef EIGEN_HAS_TYPE_TRAITS +#if EIGEN_MAX_CPP_VER>=11 && (EIGEN_HAS_CXX11 || EIGEN_COMP_MSVC >= 1700) \ + && ((!EIGEN_COMP_GNUC_STRICT) || EIGEN_GNUC_AT_LEAST(5, 1)) \ + && ((!defined(__GLIBCXX__)) || __GLIBCXX__ > 20150626) +#define EIGEN_HAS_TYPE_TRAITS 1 +#define EIGEN_INCLUDE_TYPE_TRAITS +#else +#define EIGEN_HAS_TYPE_TRAITS 0 +#endif +#endif + // Does the compiler support variadic templates? #ifndef EIGEN_HAS_VARIADIC_TEMPLATES #if EIGEN_MAX_CPP_VER>=11 && (__cplusplus > 199711L || EIGEN_COMP_MSVC >= 1900) \ - && ( !defined(__NVCC__) || !EIGEN_ARCH_ARM_OR_ARM64 || (defined __CUDACC_VER__ && __CUDACC_VER__ >= 80000) ) + && (!defined(__NVCC__) || !EIGEN_ARCH_ARM_OR_ARM64 || (EIGEN_CUDACC_VER >= 80000) ) // ^^ Disable the use of variadic templates when compiling with versions of nvcc older than 8.0 on ARM devices: // this prevents nvcc from crashing when compiling Eigen on Tegra X1 #define EIGEN_HAS_VARIADIC_TEMPLATES 1 @@ -413,7 +428,7 @@ #ifdef __CUDACC__ // Const expressions are supported provided that c++11 is enabled and we're using either clang or nvcc 7.5 or above -#if EIGEN_MAX_CPP_VER>=14 && (__cplusplus > 199711L && defined(__CUDACC_VER__) && (EIGEN_COMP_CLANG || __CUDACC_VER__ >= 70500)) +#if EIGEN_MAX_CPP_VER>=14 && (__cplusplus > 199711L && (EIGEN_COMP_CLANG || EIGEN_CUDACC_VER >= 70500)) #define EIGEN_HAS_CONSTEXPR 1 #endif #elif EIGEN_MAX_CPP_VER>=14 && (__has_feature(cxx_relaxed_constexpr) || (defined(__cplusplus) && __cplusplus >= 201402L) || \ @@ -487,11 +502,13 @@ // EIGEN_STRONG_INLINE is a stronger version of the inline, using __forceinline on MSVC, // but it still doesn't use GCC's always_inline. This is useful in (common) situations where MSVC needs forceinline // but GCC is still doing fine with just inline. +#ifndef EIGEN_STRONG_INLINE #if EIGEN_COMP_MSVC || EIGEN_COMP_ICC #define EIGEN_STRONG_INLINE __forceinline #else #define EIGEN_STRONG_INLINE inline #endif +#endif // EIGEN_ALWAYS_INLINE is the stronget, it has the effect of making the function inline and adding every possible // attribute to maximize inlining. This should only be used when really necessary: in particular, @@ -812,7 +829,8 @@ namespace Eigen { // just an empty macro ! #define EIGEN_EMPTY -#if EIGEN_COMP_MSVC_STRICT && (EIGEN_COMP_MSVC < 1900 || __CUDACC_VER__) // for older MSVC versions, as well as 1900 && CUDA 8, using the base operator is sufficient (cf Bugs 1000, 1324) +#if EIGEN_COMP_MSVC_STRICT && (EIGEN_COMP_MSVC < 1900 || EIGEN_CUDACC_VER>0) + // for older MSVC versions, as well as 1900 && CUDA 8, using the base operator is sufficient (cf Bugs 1000, 1324) #define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \ using Base::operator =; #elif EIGEN_COMP_CLANG // workaround clang bug (see http://forum.kde.org/viewtopic.php?f=74&t=102653) @@ -832,11 +850,48 @@ namespace Eigen { #endif +/** + * \internal + * \brief Macro to explicitly define the default copy constructor. + * This is necessary, because the implicit definition is deprecated if the copy-assignment is overridden. + */ +#if EIGEN_HAS_CXX11 +#define EIGEN_DEFAULT_COPY_CONSTRUCTOR(CLASS) EIGEN_DEVICE_FUNC CLASS(const CLASS&) = default; +#else +#define EIGEN_DEFAULT_COPY_CONSTRUCTOR(CLASS) +#endif + + + /** \internal * \brief Macro to manually inherit assignment operators. * This is necessary, because the implicitly defined assignment operator gets deleted when a custom operator= is defined. + * With C++11 or later this also default-implements the copy-constructor */ -#define EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Derived) EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) +#define EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Derived) \ + EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \ + EIGEN_DEFAULT_COPY_CONSTRUCTOR(Derived) + +/** \internal + * \brief Macro to manually define default constructors and destructors. + * This is necessary when the copy constructor is re-defined. + * For empty helper classes this should usually be protected, to avoid accidentally creating empty objects. + * + * Hiding the default destructor lead to problems in C++03 mode together with boost::multiprecision + */ +#if EIGEN_HAS_CXX11 +#define EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(Derived) \ + EIGEN_DEVICE_FUNC Derived() = default; \ + EIGEN_DEVICE_FUNC ~Derived() = default; +#else +#define EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(Derived) \ + EIGEN_DEVICE_FUNC Derived() {}; \ + /* EIGEN_DEVICE_FUNC ~Derived() {}; */ +#endif + + + + /** * Just a side note. Commenting within defines works only by documenting @@ -986,7 +1041,13 @@ namespace Eigen { # define EIGEN_NOEXCEPT # define EIGEN_NOEXCEPT_IF(x) # define EIGEN_NO_THROW throw() -# define EIGEN_EXCEPTION_SPEC(X) throw(X) +# if EIGEN_COMP_MSVC + // MSVC does not support exception specifications (warning C4290), + // and they are deprecated in c++11 anyway. +# define EIGEN_EXCEPTION_SPEC(X) throw() +# else +# define EIGEN_EXCEPTION_SPEC(X) throw(X) +# endif #endif #endif // EIGEN_MACROS_H diff --git a/eigenlib/Eigen/src/Core/util/Memory.h b/eigenlib/Eigen/src/Core/util/Memory.h index 67053db6..291383c5 100644 --- a/eigenlib/Eigen/src/Core/util/Memory.h +++ b/eigenlib/Eigen/src/Core/util/Memory.h @@ -70,7 +70,7 @@ inline void throw_std_bad_alloc() throw std::bad_alloc(); #else std::size_t huge = static_cast(-1); - new int[huge]; + ::operator new(huge); #endif } @@ -150,7 +150,7 @@ EIGEN_DEVICE_FUNC inline void check_that_malloc_is_allowed() /** \internal Allocates \a size bytes. The returned pointer is guaranteed to have 16 or 32 bytes alignment depending on the requirements. * On allocation error, the returned pointer is null, and std::bad_alloc is thrown. */ -EIGEN_DEVICE_FUNC inline void* aligned_malloc(size_t size) +EIGEN_DEVICE_FUNC inline void* aligned_malloc(std::size_t size) { check_that_malloc_is_allowed(); @@ -185,7 +185,7 @@ EIGEN_DEVICE_FUNC inline void aligned_free(void *ptr) * \brief Reallocates an aligned block of memory. * \throws std::bad_alloc on allocation failure */ -inline void* aligned_realloc(void *ptr, size_t new_size, size_t old_size) +inline void* aligned_realloc(void *ptr, std::size_t new_size, std::size_t old_size) { EIGEN_UNUSED_VARIABLE(old_size); @@ -209,12 +209,12 @@ inline void* aligned_realloc(void *ptr, size_t new_size, size_t old_size) /** \internal Allocates \a size bytes. If Align is true, then the returned ptr is 16-byte-aligned. * On allocation error, the returned pointer is null, and a std::bad_alloc is thrown. */ -template EIGEN_DEVICE_FUNC inline void* conditional_aligned_malloc(size_t size) +template EIGEN_DEVICE_FUNC inline void* conditional_aligned_malloc(std::size_t size) { return aligned_malloc(size); } -template<> EIGEN_DEVICE_FUNC inline void* conditional_aligned_malloc(size_t size) +template<> EIGEN_DEVICE_FUNC inline void* conditional_aligned_malloc(std::size_t size) { check_that_malloc_is_allowed(); @@ -235,12 +235,12 @@ template<> EIGEN_DEVICE_FUNC inline void conditional_aligned_free(void *p std::free(ptr); } -template inline void* conditional_aligned_realloc(void* ptr, size_t new_size, size_t old_size) +template inline void* conditional_aligned_realloc(void* ptr, std::size_t new_size, std::size_t old_size) { return aligned_realloc(ptr, new_size, old_size); } -template<> inline void* conditional_aligned_realloc(void* ptr, size_t new_size, size_t) +template<> inline void* conditional_aligned_realloc(void* ptr, std::size_t new_size, std::size_t) { return std::realloc(ptr, new_size); } @@ -252,7 +252,7 @@ template<> inline void* conditional_aligned_realloc(void* ptr, size_t new /** \internal Destructs the elements of an array. * The \a size parameters tells on how many objects to call the destructor of T. */ -template EIGEN_DEVICE_FUNC inline void destruct_elements_of_array(T *ptr, size_t size) +template EIGEN_DEVICE_FUNC inline void destruct_elements_of_array(T *ptr, std::size_t size) { // always destruct an array starting from the end. if(ptr) @@ -262,9 +262,9 @@ template EIGEN_DEVICE_FUNC inline void destruct_elements_of_array(T /** \internal Constructs the elements of an array. * The \a size parameter tells on how many objects to call the constructor of T. */ -template EIGEN_DEVICE_FUNC inline T* construct_elements_of_array(T *ptr, size_t size) +template EIGEN_DEVICE_FUNC inline T* construct_elements_of_array(T *ptr, std::size_t size) { - size_t i; + std::size_t i; EIGEN_TRY { for (i = 0; i < size; ++i) ::new (ptr + i) T; @@ -283,9 +283,9 @@ template EIGEN_DEVICE_FUNC inline T* construct_elements_of_array(T * *****************************************************************************/ template -EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void check_size_for_overflow(size_t size) +EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void check_size_for_overflow(std::size_t size) { - if(size > size_t(-1) / sizeof(T)) + if(size > std::size_t(-1) / sizeof(T)) throw_std_bad_alloc(); } @@ -293,7 +293,7 @@ EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void check_size_for_overflow(size_t size) * On allocation error, the returned pointer is undefined, but a std::bad_alloc is thrown. * The default constructor of T is called. */ -template EIGEN_DEVICE_FUNC inline T* aligned_new(size_t size) +template EIGEN_DEVICE_FUNC inline T* aligned_new(std::size_t size) { check_size_for_overflow(size); T *result = reinterpret_cast(aligned_malloc(sizeof(T)*size)); @@ -309,7 +309,7 @@ template EIGEN_DEVICE_FUNC inline T* aligned_new(size_t size) return result; } -template EIGEN_DEVICE_FUNC inline T* conditional_aligned_new(size_t size) +template EIGEN_DEVICE_FUNC inline T* conditional_aligned_new(std::size_t size) { check_size_for_overflow(size); T *result = reinterpret_cast(conditional_aligned_malloc(sizeof(T)*size)); @@ -328,7 +328,7 @@ template EIGEN_DEVICE_FUNC inline T* conditional_aligned /** \internal Deletes objects constructed with aligned_new * The \a size parameters tells on how many objects to call the destructor of T. */ -template EIGEN_DEVICE_FUNC inline void aligned_delete(T *ptr, size_t size) +template EIGEN_DEVICE_FUNC inline void aligned_delete(T *ptr, std::size_t size) { destruct_elements_of_array(ptr, size); aligned_free(ptr); @@ -337,13 +337,13 @@ template EIGEN_DEVICE_FUNC inline void aligned_delete(T *ptr, size_t /** \internal Deletes objects constructed with conditional_aligned_new * The \a size parameters tells on how many objects to call the destructor of T. */ -template EIGEN_DEVICE_FUNC inline void conditional_aligned_delete(T *ptr, size_t size) +template EIGEN_DEVICE_FUNC inline void conditional_aligned_delete(T *ptr, std::size_t size) { destruct_elements_of_array(ptr, size); conditional_aligned_free(ptr); } -template EIGEN_DEVICE_FUNC inline T* conditional_aligned_realloc_new(T* pts, size_t new_size, size_t old_size) +template EIGEN_DEVICE_FUNC inline T* conditional_aligned_realloc_new(T* pts, std::size_t new_size, std::size_t old_size) { check_size_for_overflow(new_size); check_size_for_overflow(old_size); @@ -366,7 +366,7 @@ template EIGEN_DEVICE_FUNC inline T* conditional_aligned } -template EIGEN_DEVICE_FUNC inline T* conditional_aligned_new_auto(size_t size) +template EIGEN_DEVICE_FUNC inline T* conditional_aligned_new_auto(std::size_t size) { if(size==0) return 0; // short-cut. Also fixes Bug 884 @@ -387,7 +387,7 @@ template EIGEN_DEVICE_FUNC inline T* conditional_aligned return result; } -template inline T* conditional_aligned_realloc_new_auto(T* pts, size_t new_size, size_t old_size) +template inline T* conditional_aligned_realloc_new_auto(T* pts, std::size_t new_size, std::size_t old_size) { check_size_for_overflow(new_size); check_size_for_overflow(old_size); @@ -409,7 +409,7 @@ template inline T* conditional_aligned_realloc_new_auto( return result; } -template EIGEN_DEVICE_FUNC inline void conditional_aligned_delete_auto(T *ptr, size_t size) +template EIGEN_DEVICE_FUNC inline void conditional_aligned_delete_auto(T *ptr, std::size_t size) { if(NumTraits::RequireInitialization) destruct_elements_of_array(ptr, size); @@ -493,7 +493,7 @@ template struct smart_copy_helper { IntPtr size = IntPtr(end)-IntPtr(start); if(size==0) return; eigen_internal_assert(start!=0 && end!=0 && target!=0); - memcpy(target, start, size); + std::memcpy(target, start, size); } }; @@ -561,7 +561,7 @@ template class aligned_stack_memory_handler : noncopyable * In this case, the buffer elements will also be destructed when this handler will be destructed. * Finally, if \a dealloc is true, then the pointer \a ptr is freed. **/ - aligned_stack_memory_handler(T* ptr, size_t size, bool dealloc) + aligned_stack_memory_handler(T* ptr, std::size_t size, bool dealloc) : m_ptr(ptr), m_size(size), m_deallocate(dealloc) { if(NumTraits::RequireInitialization && m_ptr) @@ -576,7 +576,7 @@ template class aligned_stack_memory_handler : noncopyable } protected: T* m_ptr; - size_t m_size; + std::size_t m_size; bool m_deallocate; }; @@ -655,15 +655,15 @@ template void swap(scoped_array &a,scoped_array &b) #if EIGEN_MAX_ALIGN_BYTES!=0 #define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \ - void* operator new(size_t size, const std::nothrow_t&) EIGEN_NO_THROW { \ + void* operator new(std::size_t size, const std::nothrow_t&) EIGEN_NO_THROW { \ EIGEN_TRY { return Eigen::internal::conditional_aligned_malloc(size); } \ EIGEN_CATCH (...) { return 0; } \ } #define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign) \ - void *operator new(size_t size) { \ + void *operator new(std::size_t size) { \ return Eigen::internal::conditional_aligned_malloc(size); \ } \ - void *operator new[](size_t size) { \ + void *operator new[](std::size_t size) { \ return Eigen::internal::conditional_aligned_malloc(size); \ } \ void operator delete(void * ptr) EIGEN_NO_THROW { Eigen::internal::conditional_aligned_free(ptr); } \ @@ -673,8 +673,8 @@ template void swap(scoped_array &a,scoped_array &b) /* in-place new and delete. since (at least afaik) there is no actual */ \ /* memory allocated we can safely let the default implementation handle */ \ /* this particular case. */ \ - static void *operator new(size_t size, void *ptr) { return ::operator new(size,ptr); } \ - static void *operator new[](size_t size, void* ptr) { return ::operator new[](size,ptr); } \ + static void *operator new(std::size_t size, void *ptr) { return ::operator new(size,ptr); } \ + static void *operator new[](std::size_t size, void* ptr) { return ::operator new[](size,ptr); } \ void operator delete(void * memory, void *ptr) EIGEN_NO_THROW { return ::operator delete(memory,ptr); } \ void operator delete[](void * memory, void *ptr) EIGEN_NO_THROW { return ::operator delete[](memory,ptr); } \ /* nothrow-new (returns zero instead of std::bad_alloc) */ \ @@ -696,7 +696,15 @@ template void swap(scoped_array &a,scoped_array &b) /** \class aligned_allocator * \ingroup Core_Module * -* \brief STL compatible allocator to use with with 16 byte aligned types +* \brief STL compatible allocator to use with types requiring a non standrad alignment. +* +* The memory is aligned as for dynamically aligned matrix/array types such as MatrixXd. +* By default, it will thus provide at least 16 bytes alignment and more in following cases: +* - 32 bytes alignment if AVX is enabled. +* - 64 bytes alignment if AVX512 is enabled. +* +* This can be controled using the \c EIGEN_MAX_ALIGN_BYTES macro as documented +* \link TopicPreprocessorDirectivesPerformance there \endlink. * * Example: * \code @@ -713,7 +721,7 @@ template class aligned_allocator : public std::allocator { public: - typedef size_t size_type; + typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; typedef T* pointer; typedef const T* const_pointer; @@ -739,7 +747,15 @@ public: pointer allocate(size_type num, const void* /*hint*/ = 0) { internal::check_size_for_overflow(num); - return static_cast( internal::aligned_malloc(num * sizeof(T)) ); + size_type size = num * sizeof(T); +#if EIGEN_COMP_GNUC_STRICT && EIGEN_GNUC_AT_LEAST(7,0) + // workaround gcc bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87544 + // It triggered eigen/Eigen/src/Core/util/Memory.h:189:12: warning: argument 1 value '18446744073709551612' exceeds maximum object size 9223372036854775807 + if(size>=std::size_t((std::numeric_limits::max)())) + return 0; + else +#endif + return static_cast( internal::aligned_malloc(size) ); } void deallocate(pointer p, size_type /*num*/) diff --git a/eigenlib/Eigen/src/Core/util/Meta.h b/eigenlib/Eigen/src/Core/util/Meta.h index 7f637075..9b61ff03 100755 --- a/eigenlib/Eigen/src/Core/util/Meta.h +++ b/eigenlib/Eigen/src/Core/util/Meta.h @@ -97,6 +97,9 @@ template<> struct is_arithmetic { enum { value = true }; }; template<> struct is_arithmetic { enum { value = true }; }; template<> struct is_arithmetic { enum { value = true }; }; +#if EIGEN_HAS_CXX11 +using std::is_integral; +#else template struct is_integral { enum { value = false }; }; template<> struct is_integral { enum { value = true }; }; template<> struct is_integral { enum { value = true }; }; @@ -108,6 +111,33 @@ template<> struct is_integral { enum { value = true }; }; template<> struct is_integral { enum { value = true }; }; template<> struct is_integral { enum { value = true }; }; template<> struct is_integral { enum { value = true }; }; +#if EIGEN_COMP_MSVC +template<> struct is_integral { enum { value = true }; }; +template<> struct is_integral{ enum { value = true }; }; +#endif +#endif + +#if EIGEN_HAS_CXX11 +using std::make_unsigned; +#else +// TODO: Possibly improve this implementation of make_unsigned. +// It is currently used only by +// template struct random_default_impl. +template struct make_unsigned; +template<> struct make_unsigned { typedef unsigned char type; }; +template<> struct make_unsigned { typedef unsigned char type; }; +template<> struct make_unsigned { typedef unsigned char type; }; +template<> struct make_unsigned { typedef unsigned short type; }; +template<> struct make_unsigned { typedef unsigned short type; }; +template<> struct make_unsigned { typedef unsigned int type; }; +template<> struct make_unsigned { typedef unsigned int type; }; +template<> struct make_unsigned { typedef unsigned long type; }; +template<> struct make_unsigned { typedef unsigned long type; }; +#if EIGEN_COMP_MSVC +template<> struct make_unsigned { typedef unsigned __int64 type; }; +template<> struct make_unsigned { typedef unsigned __int64 type; }; +#endif +#endif template struct add_const { typedef const T type; }; template struct add_const { typedef T& type; }; @@ -485,8 +515,54 @@ T div_ceil(const T &a, const T &b) return (a+b-1) / b; } +// The aim of the following functions is to bypass -Wfloat-equal warnings +// when we really want a strict equality comparison on floating points. +template EIGEN_STRONG_INLINE +bool equal_strict(const X& x,const Y& y) { return x == y; } + +template<> EIGEN_STRONG_INLINE +bool equal_strict(const float& x,const float& y) { return std::equal_to()(x,y); } + +template<> EIGEN_STRONG_INLINE +bool equal_strict(const double& x,const double& y) { return std::equal_to()(x,y); } + +template EIGEN_STRONG_INLINE +bool not_equal_strict(const X& x,const Y& y) { return x != y; } + +template<> EIGEN_STRONG_INLINE +bool not_equal_strict(const float& x,const float& y) { return std::not_equal_to()(x,y); } + +template<> EIGEN_STRONG_INLINE +bool not_equal_strict(const double& x,const double& y) { return std::not_equal_to()(x,y); } + } // end namespace numext } // end namespace Eigen +// Define portable (u)int{32,64} types +#if EIGEN_HAS_CXX11 +#include +namespace Eigen { +namespace numext { +typedef std::uint32_t uint32_t; +typedef std::int32_t int32_t; +typedef std::uint64_t uint64_t; +typedef std::int64_t int64_t; +} +} +#else +// Without c++11, all compilers able to compile Eigen also +// provides the C99 stdint.h header file. +#include +namespace Eigen { +namespace numext { +typedef ::uint32_t uint32_t; +typedef ::int32_t int32_t; +typedef ::uint64_t uint64_t; +typedef ::int64_t int64_t; +} +} +#endif + + #endif // EIGEN_META_H diff --git a/eigenlib/Eigen/src/Core/util/ReenableStupidWarnings.h b/eigenlib/Eigen/src/Core/util/ReenableStupidWarnings.h index 86b60f52..1ce6fd1b 100644 --- a/eigenlib/Eigen/src/Core/util/ReenableStupidWarnings.h +++ b/eigenlib/Eigen/src/Core/util/ReenableStupidWarnings.h @@ -1,4 +1,8 @@ -#ifdef EIGEN_WARNINGS_DISABLED +#ifdef EIGEN_WARNINGS_DISABLED_2 +// "DisableStupidWarnings.h" was included twice recursively: Do not reenable warnings yet! +# undef EIGEN_WARNINGS_DISABLED_2 + +#elif defined(EIGEN_WARNINGS_DISABLED) #undef EIGEN_WARNINGS_DISABLED #ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS @@ -8,7 +12,7 @@ #pragma warning pop #elif defined __clang__ #pragma clang diagnostic pop - #elif defined __GNUC__ && __GNUC__>=6 + #elif defined __GNUC__ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) #pragma GCC diagnostic pop #endif diff --git a/eigenlib/Eigen/src/Core/util/StaticAssert.h b/eigenlib/Eigen/src/Core/util/StaticAssert.h index 983361a4..500e4779 100644 --- a/eigenlib/Eigen/src/Core/util/StaticAssert.h +++ b/eigenlib/Eigen/src/Core/util/StaticAssert.h @@ -24,6 +24,7 @@ * */ +#ifndef EIGEN_STATIC_ASSERT #ifndef EIGEN_NO_STATIC_ASSERT #if EIGEN_MAX_CPP_VER>=11 && (__has_feature(cxx_static_assert) || (defined(__cplusplus) && __cplusplus >= 201103L) || (EIGEN_COMP_MSVC >= 1600)) @@ -44,64 +45,65 @@ struct static_assertion { enum { - YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX, - YOU_MIXED_VECTORS_OF_DIFFERENT_SIZES, - YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES, - THIS_METHOD_IS_ONLY_FOR_VECTORS_OF_A_SPECIFIC_SIZE, - THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE, - THIS_METHOD_IS_ONLY_FOR_OBJECTS_OF_A_SPECIFIC_SIZE, - OUT_OF_RANGE_ACCESS, - YOU_MADE_A_PROGRAMMING_MISTAKE, - EIGEN_INTERNAL_ERROR_PLEASE_FILE_A_BUG_REPORT, - EIGEN_INTERNAL_COMPILATION_ERROR_OR_YOU_MADE_A_PROGRAMMING_MISTAKE, - YOU_CALLED_A_FIXED_SIZE_METHOD_ON_A_DYNAMIC_SIZE_MATRIX_OR_VECTOR, - YOU_CALLED_A_DYNAMIC_SIZE_METHOD_ON_A_FIXED_SIZE_MATRIX_OR_VECTOR, - UNALIGNED_LOAD_AND_STORE_OPERATIONS_UNIMPLEMENTED_ON_ALTIVEC, - THIS_FUNCTION_IS_NOT_FOR_INTEGER_NUMERIC_TYPES, - FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED, - NUMERIC_TYPE_MUST_BE_REAL, - COEFFICIENT_WRITE_ACCESS_TO_SELFADJOINT_NOT_SUPPORTED, - WRITING_TO_TRIANGULAR_PART_WITH_UNIT_DIAGONAL_IS_NOT_SUPPORTED, - THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE, - INVALID_MATRIX_PRODUCT, - INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS, - INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION, - YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY, - THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES, - THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES, - INVALID_MATRIX_TEMPLATE_PARAMETERS, - INVALID_MATRIXBASE_TEMPLATE_PARAMETERS, - BOTH_MATRICES_MUST_HAVE_THE_SAME_STORAGE_ORDER, - THIS_METHOD_IS_ONLY_FOR_DIAGONAL_MATRIX, - THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE, - THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_WITH_DIRECT_MEMORY_ACCESS_SUCH_AS_MAP_OR_PLAIN_MATRICES, - YOU_ALREADY_SPECIFIED_THIS_STRIDE, - INVALID_STORAGE_ORDER_FOR_THIS_VECTOR_EXPRESSION, - THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD, - PACKET_ACCESS_REQUIRES_TO_HAVE_INNER_STRIDE_FIXED_TO_1, - THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS, - YOU_CANNOT_MIX_ARRAYS_AND_MATRICES, - YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION, - THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY, - YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT, - THIS_METHOD_IS_ONLY_FOR_1x1_EXPRESSIONS, - THIS_METHOD_IS_ONLY_FOR_INNER_OR_LAZY_PRODUCTS, - THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_OF_BOOL, - THIS_METHOD_IS_ONLY_FOR_ARRAYS_NOT_MATRICES, - YOU_PASSED_A_ROW_VECTOR_BUT_A_COLUMN_VECTOR_WAS_EXPECTED, - YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED, - THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE, - THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH, - OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG, - IMPLICIT_CONVERSION_TO_SCALAR_IS_FOR_INNER_PRODUCT_ONLY, - STORAGE_LAYOUT_DOES_NOT_MATCH, - EIGEN_INTERNAL_ERROR_PLEASE_FILE_A_BUG_REPORT__INVALID_COST_VALUE, - THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS, - MATRIX_FREE_CONJUGATE_GRADIENT_IS_COMPATIBLE_WITH_UPPER_UNION_LOWER_MODE_ONLY, - THIS_TYPE_IS_NOT_SUPPORTED, - STORAGE_KIND_MUST_MATCH, - STORAGE_INDEX_MUST_MATCH, - CHOLMOD_SUPPORTS_DOUBLE_PRECISION_ONLY + YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX=1, + YOU_MIXED_VECTORS_OF_DIFFERENT_SIZES=1, + YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES=1, + THIS_METHOD_IS_ONLY_FOR_VECTORS_OF_A_SPECIFIC_SIZE=1, + THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE=1, + THIS_METHOD_IS_ONLY_FOR_OBJECTS_OF_A_SPECIFIC_SIZE=1, + OUT_OF_RANGE_ACCESS=1, + YOU_MADE_A_PROGRAMMING_MISTAKE=1, + EIGEN_INTERNAL_ERROR_PLEASE_FILE_A_BUG_REPORT=1, + EIGEN_INTERNAL_COMPILATION_ERROR_OR_YOU_MADE_A_PROGRAMMING_MISTAKE=1, + YOU_CALLED_A_FIXED_SIZE_METHOD_ON_A_DYNAMIC_SIZE_MATRIX_OR_VECTOR=1, + YOU_CALLED_A_DYNAMIC_SIZE_METHOD_ON_A_FIXED_SIZE_MATRIX_OR_VECTOR=1, + UNALIGNED_LOAD_AND_STORE_OPERATIONS_UNIMPLEMENTED_ON_ALTIVEC=1, + THIS_FUNCTION_IS_NOT_FOR_INTEGER_NUMERIC_TYPES=1, + FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED=1, + NUMERIC_TYPE_MUST_BE_REAL=1, + COEFFICIENT_WRITE_ACCESS_TO_SELFADJOINT_NOT_SUPPORTED=1, + WRITING_TO_TRIANGULAR_PART_WITH_UNIT_DIAGONAL_IS_NOT_SUPPORTED=1, + THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE=1, + INVALID_MATRIX_PRODUCT=1, + INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS=1, + INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION=1, + YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY=1, + THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES=1, + THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES=1, + INVALID_MATRIX_TEMPLATE_PARAMETERS=1, + INVALID_MATRIXBASE_TEMPLATE_PARAMETERS=1, + BOTH_MATRICES_MUST_HAVE_THE_SAME_STORAGE_ORDER=1, + THIS_METHOD_IS_ONLY_FOR_DIAGONAL_MATRIX=1, + THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE=1, + THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_WITH_DIRECT_MEMORY_ACCESS_SUCH_AS_MAP_OR_PLAIN_MATRICES=1, + YOU_ALREADY_SPECIFIED_THIS_STRIDE=1, + INVALID_STORAGE_ORDER_FOR_THIS_VECTOR_EXPRESSION=1, + THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD=1, + PACKET_ACCESS_REQUIRES_TO_HAVE_INNER_STRIDE_FIXED_TO_1=1, + THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS=1, + YOU_CANNOT_MIX_ARRAYS_AND_MATRICES=1, + YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION=1, + THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY=1, + YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT=1, + THIS_METHOD_IS_ONLY_FOR_1x1_EXPRESSIONS=1, + THIS_METHOD_IS_ONLY_FOR_INNER_OR_LAZY_PRODUCTS=1, + THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_OF_BOOL=1, + THIS_METHOD_IS_ONLY_FOR_ARRAYS_NOT_MATRICES=1, + YOU_PASSED_A_ROW_VECTOR_BUT_A_COLUMN_VECTOR_WAS_EXPECTED=1, + YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED=1, + THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE=1, + THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH=1, + OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG=1, + IMPLICIT_CONVERSION_TO_SCALAR_IS_FOR_INNER_PRODUCT_ONLY=1, + STORAGE_LAYOUT_DOES_NOT_MATCH=1, + EIGEN_INTERNAL_ERROR_PLEASE_FILE_A_BUG_REPORT__INVALID_COST_VALUE=1, + THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS=1, + MATRIX_FREE_CONJUGATE_GRADIENT_IS_COMPATIBLE_WITH_UPPER_UNION_LOWER_MODE_ONLY=1, + THIS_TYPE_IS_NOT_SUPPORTED=1, + STORAGE_KIND_MUST_MATCH=1, + STORAGE_INDEX_MUST_MATCH=1, + CHOLMOD_SUPPORTS_DOUBLE_PRECISION_ONLY=1, + SELFADJOINTVIEW_ACCEPTS_UPPER_AND_LOWER_MODE_ONLY=1 }; }; @@ -131,7 +133,7 @@ #define EIGEN_STATIC_ASSERT(CONDITION,MSG) eigen_assert((CONDITION) && #MSG); #endif // EIGEN_NO_STATIC_ASSERT - +#endif // EIGEN_STATIC_ASSERT // static assertion failing if the type \a TYPE is not a vector type #define EIGEN_STATIC_ASSERT_VECTOR_ONLY(TYPE) \ diff --git a/eigenlib/Eigen/src/Core/util/XprHelper.h b/eigenlib/Eigen/src/Core/util/XprHelper.h index e88510dc..6bb49708 100644 --- a/eigenlib/Eigen/src/Core/util/XprHelper.h +++ b/eigenlib/Eigen/src/Core/util/XprHelper.h @@ -34,6 +34,20 @@ inline IndexDest convert_index(const IndexSrc& idx) { return IndexDest(idx); } +// true if T can be considered as an integral index (i.e., and integral type or enum) +template struct is_valid_index_type +{ + enum { value = +#if EIGEN_HAS_TYPE_TRAITS + internal::is_integral::value || std::is_enum::value +#elif EIGEN_COMP_MSVC + internal::is_integral::value || __is_enum(T) +#else + // without C++11, we use is_convertible to Index instead of is_integral in order to treat enums as Index. + internal::is_convertible::value && !internal::is_same::value && !is_same::value +#endif + }; +}; // promote_scalar_arg is an helper used in operation between an expression and a scalar, like: // expression * scalar @@ -90,6 +104,9 @@ class no_assignment_operator { private: no_assignment_operator& operator=(const no_assignment_operator&); + protected: + EIGEN_DEFAULT_COPY_CONSTRUCTOR(no_assignment_operator) + EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(no_assignment_operator) }; /** \internal return the index type with the largest number of bits */ @@ -638,7 +655,7 @@ struct plain_constant_type template struct is_lvalue { - enum { value = !bool(is_const::value) && + enum { value = (!bool(is_const::value)) && bool(traits::Flags & LvalueBit) }; }; diff --git a/eigenlib/Eigen/src/Eigenvalues/ComplexEigenSolver.h b/eigenlib/Eigen/src/Eigenvalues/ComplexEigenSolver.h index ec3b1633..dc5fae06 100644 --- a/eigenlib/Eigen/src/Eigenvalues/ComplexEigenSolver.h +++ b/eigenlib/Eigen/src/Eigenvalues/ComplexEigenSolver.h @@ -250,7 +250,7 @@ template class ComplexEigenSolver EigenvectorType m_matX; private: - void doComputeEigenvectors(const RealScalar& matrixnorm); + void doComputeEigenvectors(RealScalar matrixnorm); void sortEigenvalues(bool computeEigenvectors); }; @@ -284,10 +284,12 @@ ComplexEigenSolver::compute(const EigenBase& matrix, bool template -void ComplexEigenSolver::doComputeEigenvectors(const RealScalar& matrixnorm) +void ComplexEigenSolver::doComputeEigenvectors(RealScalar matrixnorm) { const Index n = m_eivalues.size(); + matrixnorm = numext::maxi(matrixnorm,(std::numeric_limits::min)()); + // Compute X such that T = X D X^(-1), where D is the diagonal of T. // The matrix X is unit triangular. m_matX = EigenvectorType::Zero(n, n); diff --git a/eigenlib/Eigen/src/Eigenvalues/ComplexSchur.h b/eigenlib/Eigen/src/Eigenvalues/ComplexSchur.h index 7f38919f..4354e401 100644 --- a/eigenlib/Eigen/src/Eigenvalues/ComplexSchur.h +++ b/eigenlib/Eigen/src/Eigenvalues/ComplexSchur.h @@ -300,10 +300,13 @@ typename ComplexSchur::ComplexScalar ComplexSchur::compu ComplexScalar trace = t.coeff(0,0) + t.coeff(1,1); ComplexScalar eival1 = (trace + disc) / RealScalar(2); ComplexScalar eival2 = (trace - disc) / RealScalar(2); - - if(numext::norm1(eival1) > numext::norm1(eival2)) + RealScalar eival1_norm = numext::norm1(eival1); + RealScalar eival2_norm = numext::norm1(eival2); + // A division by zero can only occur if eival1==eival2==0. + // In this case, det==0, and all we have to do is checking that eival2_norm!=0 + if(eival1_norm > eival2_norm) eival2 = det / eival1; - else + else if(eival2_norm!=RealScalar(0)) eival1 = det / eival2; // choose the eigenvalue closest to the bottom entry of the diagonal diff --git a/eigenlib/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h b/eigenlib/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h index 36a91dff..87d789b3 100644 --- a/eigenlib/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h +++ b/eigenlib/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h @@ -311,7 +311,6 @@ GeneralizedEigenSolver::compute(const MatrixType& A, const MatrixTyp // Aliases: Map v(reinterpret_cast(m_tmp.data()), size); ComplexVectorType &cv = m_tmp; - const MatrixType &mZ = m_realQZ.matrixZ(); const MatrixType &mS = m_realQZ.matrixS(); const MatrixType &mT = m_realQZ.matrixT(); @@ -351,7 +350,7 @@ GeneralizedEigenSolver::compute(const MatrixType& A, const MatrixTyp } } } - m_eivec.col(i).real().noalias() = mZ.transpose() * v; + m_eivec.col(i).real().noalias() = m_realQZ.matrixZ().transpose() * v; m_eivec.col(i).real().normalize(); m_eivec.col(i).imag().setConstant(0); } @@ -400,7 +399,7 @@ GeneralizedEigenSolver::compute(const MatrixType& A, const MatrixTyp / (alpha*mT.coeffRef(j,j) - static_cast(beta*mS.coeffRef(j,j))); } } - m_eivec.col(i+1).noalias() = (mZ.transpose() * cv); + m_eivec.col(i+1).noalias() = (m_realQZ.matrixZ().transpose() * cv); m_eivec.col(i+1).normalize(); m_eivec.col(i) = m_eivec.col(i+1).conjugate(); } diff --git a/eigenlib/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h b/eigenlib/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h index 4fec8af0..e4e42607 100644 --- a/eigenlib/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h +++ b/eigenlib/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h @@ -66,7 +66,6 @@ template inline typename MatrixBase::EigenvaluesReturnType MatrixBase::eigenvalues() const { - typedef typename internal::traits::Scalar Scalar; return internal::eigenvalues_selector::IsComplex>::run(derived()); } @@ -88,7 +87,6 @@ template inline typename SelfAdjointView::EigenvaluesReturnType SelfAdjointView::eigenvalues() const { - typedef typename SelfAdjointView::PlainObject PlainObject; PlainObject thisAsMatrix(*this); return SelfAdjointEigenSolver(thisAsMatrix, false).eigenvalues(); } diff --git a/eigenlib/Eigen/src/Eigenvalues/RealSchur.h b/eigenlib/Eigen/src/Eigenvalues/RealSchur.h index d6a339f0..9191519a 100644 --- a/eigenlib/Eigen/src/Eigenvalues/RealSchur.h +++ b/eigenlib/Eigen/src/Eigenvalues/RealSchur.h @@ -236,7 +236,7 @@ template class RealSchur typedef Matrix Vector3s; Scalar computeNormOfT(); - Index findSmallSubdiagEntry(Index iu); + Index findSmallSubdiagEntry(Index iu, const Scalar& considerAsZero); void splitOffTwoRows(Index iu, bool computeU, const Scalar& exshift); void computeShift(Index iu, Index iter, Scalar& exshift, Vector3s& shiftInfo); void initFrancisQRStep(Index il, Index iu, const Vector3s& shiftInfo, Index& im, Vector3s& firstHouseholderVector); @@ -248,12 +248,24 @@ template template RealSchur& RealSchur::compute(const EigenBase& matrix, bool computeU) { + const Scalar considerAsZero = (std::numeric_limits::min)(); + eigen_assert(matrix.cols() == matrix.rows()); Index maxIters = m_maxIters; if (maxIters == -1) maxIters = m_maxIterationsPerRow * matrix.rows(); Scalar scale = matrix.derived().cwiseAbs().maxCoeff(); + if(scale& RealSchur::computeFromHessenberg(const HessMa Index totalIter = 0; // iteration count for whole matrix Scalar exshift(0); // sum of exceptional shifts Scalar norm = computeNormOfT(); + // sub-diagonal entries smaller than considerAsZero will be treated as zero. + // We use eps^2 to enable more precision in small eigenvalues. + Scalar considerAsZero = numext::maxi( norm * numext::abs2(NumTraits::epsilon()), + (std::numeric_limits::min)() ); - if(norm!=0) + if(norm!=Scalar(0)) { while (iu >= 0) { - Index il = findSmallSubdiagEntry(iu); + Index il = findSmallSubdiagEntry(iu,considerAsZero); // Check for convergence if (il == iu) // One root found @@ -315,7 +331,7 @@ RealSchur& RealSchur::computeFromHessenberg(const HessMa else // No convergence yet { // The firstHouseholderVector vector has to be initialized to something to get rid of a silly GCC warning (-O1 -Wall -DNDEBUG ) - Vector3s firstHouseholderVector(0,0,0), shiftInfo; + Vector3s firstHouseholderVector = Vector3s::Zero(), shiftInfo; computeShift(iu, iter, exshift, shiftInfo); iter = iter + 1; totalIter = totalIter + 1; @@ -352,14 +368,17 @@ inline typename MatrixType::Scalar RealSchur::computeNormOfT() /** \internal Look for single small sub-diagonal element and returns its index */ template -inline Index RealSchur::findSmallSubdiagEntry(Index iu) +inline Index RealSchur::findSmallSubdiagEntry(Index iu, const Scalar& considerAsZero) { using std::abs; Index res = iu; while (res > 0) { Scalar s = abs(m_matT.coeff(res-1,res-1)) + abs(m_matT.coeff(res,res)); - if (abs(m_matT.coeff(res,res-1)) <= NumTraits::epsilon() * s) + + s = numext::maxi(s * NumTraits::epsilon(), considerAsZero); + + if (abs(m_matT.coeff(res,res-1)) <= s) break; res--; } diff --git a/eigenlib/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h b/eigenlib/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h index a9f56c4f..d37656fa 100644 --- a/eigenlib/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h +++ b/eigenlib/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h @@ -414,7 +414,8 @@ SelfAdjointEigenSolver& SelfAdjointEigenSolver if(n==1) { - m_eivalues.coeffRef(0,0) = numext::real(matrix.diagonal()[0]); + m_eivec = matrix; + m_eivalues.coeffRef(0,0) = numext::real(m_eivec.coeff(0,0)); if(computeEigenvectors) m_eivec.setOnes(n,n); m_info = Success; @@ -604,7 +605,8 @@ template struct direct_selfadjoint_eigenvalues res, Ref representative) { - using std::abs; + EIGEN_USING_STD_MATH(sqrt) + EIGEN_USING_STD_MATH(abs) Index i0; // Find non-zero column i0 (by construction, there must exist a non zero coefficient on the diagonal): mat.diagonal().cwiseAbs().maxCoeff(&i0); @@ -615,8 +617,8 @@ template struct direct_selfadjoint_eigenvaluesn1) res = c0/std::sqrt(n0); - else res = c1/std::sqrt(n1); + if(n0>n1) res = c0/sqrt(n0); + else res = c1/sqrt(n1); return true; } diff --git a/eigenlib/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h b/eigenlib/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h index 3891cf88..b0c947dc 100644 --- a/eigenlib/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h +++ b/eigenlib/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h @@ -37,7 +37,7 @@ namespace Eigen { /** \internal Specialization for the data types supported by LAPACKe */ -#define EIGEN_LAPACKE_EIG_SELFADJ(EIGTYPE, LAPACKE_TYPE, LAPACKE_RTYPE, LAPACKE_NAME, EIGCOLROW, LAPACKE_COLROW ) \ +#define EIGEN_LAPACKE_EIG_SELFADJ_2(EIGTYPE, LAPACKE_TYPE, LAPACKE_RTYPE, LAPACKE_NAME, EIGCOLROW ) \ template<> template inline \ SelfAdjointEigenSolver >& \ SelfAdjointEigenSolver >::compute(const EigenBase& matrix, int options) \ @@ -47,7 +47,7 @@ SelfAdjointEigenSolver >::compute(c && (options&EigVecMask)!=EigVecMask \ && "invalid option parameter"); \ bool computeEigenvectors = (options&ComputeEigenvectors)==ComputeEigenvectors; \ - lapack_int n = internal::convert_index(matrix.cols()), lda, matrix_order, info; \ + lapack_int n = internal::convert_index(matrix.cols()), lda, info; \ m_eivalues.resize(n,1); \ m_subdiag.resize(n-1); \ m_eivec = matrix; \ @@ -63,27 +63,24 @@ SelfAdjointEigenSolver >::compute(c } \ \ lda = internal::convert_index(m_eivec.outerStride()); \ - matrix_order=LAPACKE_COLROW; \ char jobz, uplo='L'/*, range='A'*/; \ jobz = computeEigenvectors ? 'V' : 'N'; \ \ - info = LAPACKE_##LAPACKE_NAME( matrix_order, jobz, uplo, n, (LAPACKE_TYPE*)m_eivec.data(), lda, (LAPACKE_RTYPE*)m_eivalues.data() ); \ + info = LAPACKE_##LAPACKE_NAME( LAPACK_COL_MAJOR, jobz, uplo, n, (LAPACKE_TYPE*)m_eivec.data(), lda, (LAPACKE_RTYPE*)m_eivalues.data() ); \ m_info = (info==0) ? Success : NoConvergence; \ m_isInitialized = true; \ m_eigenvectorsOk = computeEigenvectors; \ return *this; \ } +#define EIGEN_LAPACKE_EIG_SELFADJ(EIGTYPE, LAPACKE_TYPE, LAPACKE_RTYPE, LAPACKE_NAME ) \ + EIGEN_LAPACKE_EIG_SELFADJ_2(EIGTYPE, LAPACKE_TYPE, LAPACKE_RTYPE, LAPACKE_NAME, ColMajor ) \ + EIGEN_LAPACKE_EIG_SELFADJ_2(EIGTYPE, LAPACKE_TYPE, LAPACKE_RTYPE, LAPACKE_NAME, RowMajor ) -EIGEN_LAPACKE_EIG_SELFADJ(double, double, double, dsyev, ColMajor, LAPACK_COL_MAJOR) -EIGEN_LAPACKE_EIG_SELFADJ(float, float, float, ssyev, ColMajor, LAPACK_COL_MAJOR) -EIGEN_LAPACKE_EIG_SELFADJ(dcomplex, lapack_complex_double, double, zheev, ColMajor, LAPACK_COL_MAJOR) -EIGEN_LAPACKE_EIG_SELFADJ(scomplex, lapack_complex_float, float, cheev, ColMajor, LAPACK_COL_MAJOR) - -EIGEN_LAPACKE_EIG_SELFADJ(double, double, double, dsyev, RowMajor, LAPACK_ROW_MAJOR) -EIGEN_LAPACKE_EIG_SELFADJ(float, float, float, ssyev, RowMajor, LAPACK_ROW_MAJOR) -EIGEN_LAPACKE_EIG_SELFADJ(dcomplex, lapack_complex_double, double, zheev, RowMajor, LAPACK_ROW_MAJOR) -EIGEN_LAPACKE_EIG_SELFADJ(scomplex, lapack_complex_float, float, cheev, RowMajor, LAPACK_ROW_MAJOR) +EIGEN_LAPACKE_EIG_SELFADJ(double, double, double, dsyev) +EIGEN_LAPACKE_EIG_SELFADJ(float, float, float, ssyev) +EIGEN_LAPACKE_EIG_SELFADJ(dcomplex, lapack_complex_double, double, zheev) +EIGEN_LAPACKE_EIG_SELFADJ(scomplex, lapack_complex_float, float, cheev) } // end namespace Eigen diff --git a/eigenlib/Eigen/src/Geometry/AngleAxis.h b/eigenlib/Eigen/src/Geometry/AngleAxis.h index 0af3c1b0..83ee1be4 100644 --- a/eigenlib/Eigen/src/Geometry/AngleAxis.h +++ b/eigenlib/Eigen/src/Geometry/AngleAxis.h @@ -178,7 +178,7 @@ EIGEN_DEVICE_FUNC AngleAxis& AngleAxis::operator=(const Quaterni if (n != Scalar(0)) { m_angle = Scalar(2)*atan2(n, abs(q.w())); - if(q.w() < 0) + if(q.w() < Scalar(0)) n = -n; m_axis = q.vec() / n; } diff --git a/eigenlib/Eigen/src/Geometry/Quaternion.h b/eigenlib/Eigen/src/Geometry/Quaternion.h index f6ef1bcf..b8182065 100644 --- a/eigenlib/Eigen/src/Geometry/Quaternion.h +++ b/eigenlib/Eigen/src/Geometry/Quaternion.h @@ -43,6 +43,11 @@ class QuaternionBase : public RotationBase typedef typename internal::traits::Scalar Scalar; typedef typename NumTraits::Real RealScalar; typedef typename internal::traits::Coefficients Coefficients; + typedef typename Coefficients::CoeffReturnType CoeffReturnType; + typedef typename internal::conditional::Flags&LvalueBit), + Scalar&, CoeffReturnType>::type NonConstCoeffReturnType; + + enum { Flags = Eigen::internal::traits::Flags }; @@ -58,22 +63,22 @@ class QuaternionBase : public RotationBase /** \returns the \c x coefficient */ - EIGEN_DEVICE_FUNC inline Scalar x() const { return this->derived().coeffs().coeff(0); } + EIGEN_DEVICE_FUNC inline CoeffReturnType x() const { return this->derived().coeffs().coeff(0); } /** \returns the \c y coefficient */ - EIGEN_DEVICE_FUNC inline Scalar y() const { return this->derived().coeffs().coeff(1); } + EIGEN_DEVICE_FUNC inline CoeffReturnType y() const { return this->derived().coeffs().coeff(1); } /** \returns the \c z coefficient */ - EIGEN_DEVICE_FUNC inline Scalar z() const { return this->derived().coeffs().coeff(2); } + EIGEN_DEVICE_FUNC inline CoeffReturnType z() const { return this->derived().coeffs().coeff(2); } /** \returns the \c w coefficient */ - EIGEN_DEVICE_FUNC inline Scalar w() const { return this->derived().coeffs().coeff(3); } + EIGEN_DEVICE_FUNC inline CoeffReturnType w() const { return this->derived().coeffs().coeff(3); } - /** \returns a reference to the \c x coefficient */ - EIGEN_DEVICE_FUNC inline Scalar& x() { return this->derived().coeffs().coeffRef(0); } - /** \returns a reference to the \c y coefficient */ - EIGEN_DEVICE_FUNC inline Scalar& y() { return this->derived().coeffs().coeffRef(1); } - /** \returns a reference to the \c z coefficient */ - EIGEN_DEVICE_FUNC inline Scalar& z() { return this->derived().coeffs().coeffRef(2); } - /** \returns a reference to the \c w coefficient */ - EIGEN_DEVICE_FUNC inline Scalar& w() { return this->derived().coeffs().coeffRef(3); } + /** \returns a reference to the \c x coefficient (if Derived is a non-const lvalue) */ + EIGEN_DEVICE_FUNC inline NonConstCoeffReturnType x() { return this->derived().coeffs().x(); } + /** \returns a reference to the \c y coefficient (if Derived is a non-const lvalue) */ + EIGEN_DEVICE_FUNC inline NonConstCoeffReturnType y() { return this->derived().coeffs().y(); } + /** \returns a reference to the \c z coefficient (if Derived is a non-const lvalue) */ + EIGEN_DEVICE_FUNC inline NonConstCoeffReturnType z() { return this->derived().coeffs().z(); } + /** \returns a reference to the \c w coefficient (if Derived is a non-const lvalue) */ + EIGEN_DEVICE_FUNC inline NonConstCoeffReturnType w() { return this->derived().coeffs().w(); } /** \returns a read-only vector expression of the imaginary part (x,y,z) */ EIGEN_DEVICE_FUNC inline const VectorBlock vec() const { return coeffs().template head<3>(); } @@ -164,20 +169,38 @@ class QuaternionBase : public RotationBase /** return the result vector of \a v through the rotation*/ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Vector3 _transformVector(const Vector3& v) const; + #ifdef EIGEN_PARSED_BY_DOXYGEN /** \returns \c *this with scalar type casted to \a NewScalarType * * Note that if \a NewScalarType is equal to the current scalar type of \c *this * then this function smartly returns a const reference to \c *this. */ template - EIGEN_DEVICE_FUNC inline typename internal::cast_return_type >::type cast() const + EIGEN_DEVICE_FUNC inline typename internal::cast_return_type >::type cast() const; + + #else + + template + EIGEN_DEVICE_FUNC inline + typename internal::enable_if::value,const Derived&>::type cast() const { - return typename internal::cast_return_type >::type(derived()); + return derived(); } + template + EIGEN_DEVICE_FUNC inline + typename internal::enable_if::value,Quaternion >::type cast() const + { + return Quaternion(coeffs().template cast()); + } + #endif + #ifdef EIGEN_QUATERNIONBASE_PLUGIN # include EIGEN_QUATERNIONBASE_PLUGIN #endif +protected: + EIGEN_DEFAULT_COPY_CONSTRUCTOR(QuaternionBase) + EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(QuaternionBase) }; /*************************************************************************** @@ -423,7 +446,7 @@ typedef Map, Aligned> QuaternionMapAlignedd; // Generic Quaternion * Quaternion product // This product can be specialized for a given architecture via the Arch template argument. namespace internal { -template struct quat_product +template struct quat_product { EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Quaternion run(const QuaternionBase& a, const QuaternionBase& b){ return Quaternion @@ -446,8 +469,7 @@ QuaternionBase::operator* (const QuaternionBase& other) c EIGEN_STATIC_ASSERT((internal::is_same::value), YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) return internal::quat_product::Scalar, - EIGEN_PLAIN_ENUM_MIN(internal::traits::Alignment, internal::traits::Alignment)>::run(*this, other); + typename internal::traits::Scalar>::run(*this, other); } /** \sa operator*(Quaternion) */ @@ -672,7 +694,7 @@ EIGEN_DEVICE_FUNC inline Quaternion::Scalar> // Generic conjugate of a Quaternion namespace internal { -template struct quat_conj +template struct quat_conj { EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Quaternion run(const QuaternionBase& q){ return Quaternion(q.w(),-q.x(),-q.y(),-q.z()); @@ -691,8 +713,7 @@ EIGEN_DEVICE_FUNC inline Quaternion::Scalar> QuaternionBase::conjugate() const { return internal::quat_conj::Scalar, - internal::traits::Alignment>::run(*this); + typename internal::traits::Scalar>::run(*this); } diff --git a/eigenlib/Eigen/src/Geometry/Scaling.h b/eigenlib/Eigen/src/Geometry/Scaling.h old mode 100755 new mode 100644 index f58ca03d..33eabd81 --- a/eigenlib/Eigen/src/Geometry/Scaling.h +++ b/eigenlib/Eigen/src/Geometry/Scaling.h @@ -14,7 +14,7 @@ namespace Eigen { /** \geometry_module \ingroup Geometry_Module * - * \class Scaling + * \class UniformScaling * * \brief Represents a generic uniform scaling transformation * diff --git a/eigenlib/Eigen/src/Geometry/Transform.h b/eigenlib/Eigen/src/Geometry/Transform.h index 3f31ee45..c21d9e55 100644 --- a/eigenlib/Eigen/src/Geometry/Transform.h +++ b/eigenlib/Eigen/src/Geometry/Transform.h @@ -252,11 +252,11 @@ protected: public: /** Default constructor without initialization of the meaningful coefficients. - * If Mode==Affine, then the last row is set to [0 ... 0 1] */ + * If Mode==Affine or Mode==Isometry, then the last row is set to [0 ... 0 1] */ EIGEN_DEVICE_FUNC inline Transform() { check_template_params(); - internal::transform_make_affine<(int(Mode)==Affine) ? Affine : AffineCompact>::run(m_matrix); + internal::transform_make_affine<(int(Mode)==Affine || int(Mode)==Isometry) ? Affine : AffineCompact>::run(m_matrix); } EIGEN_DEVICE_FUNC inline Transform(const Transform& other) diff --git a/eigenlib/Eigen/src/Geometry/Translation.h b/eigenlib/Eigen/src/Geometry/Translation.h index 51d9a82e..0e99ce68 100644 --- a/eigenlib/Eigen/src/Geometry/Translation.h +++ b/eigenlib/Eigen/src/Geometry/Translation.h @@ -138,12 +138,6 @@ public: /** \returns the inverse translation (opposite) */ Translation inverse() const { return Translation(-m_coeffs); } - Translation& operator=(const Translation& other) - { - m_coeffs = other.m_coeffs; - return *this; - } - static const Translation Identity() { return Translation(VectorType::Zero()); } /** \returns \c *this with scalar type casted to \a NewScalarType diff --git a/eigenlib/Eigen/src/Geometry/Umeyama.h b/eigenlib/Eigen/src/Geometry/Umeyama.h index 7e933fca..6b755008 100644 --- a/eigenlib/Eigen/src/Geometry/Umeyama.h +++ b/eigenlib/Eigen/src/Geometry/Umeyama.h @@ -87,7 +87,7 @@ struct umeyama_transform_matrix_type * \f{align*} * T = \begin{bmatrix} c\mathbf{R} & \mathbf{t} \\ \mathbf{0} & 1 \end{bmatrix} * \f} -* minimizing the resudiual above. This transformation is always returned as an +* minimizing the residual above. This transformation is always returned as an * Eigen::Matrix. */ template diff --git a/eigenlib/Eigen/src/Geometry/arch/Geometry_SSE.h b/eigenlib/Eigen/src/Geometry/arch/Geometry_SSE.h index 1a86ff83..f68cab58 100644 --- a/eigenlib/Eigen/src/Geometry/arch/Geometry_SSE.h +++ b/eigenlib/Eigen/src/Geometry/arch/Geometry_SSE.h @@ -16,17 +16,23 @@ namespace Eigen { namespace internal { template -struct quat_product +struct quat_product { + enum { + AAlignment = traits::Alignment, + BAlignment = traits::Alignment, + ResAlignment = traits >::Alignment + }; static inline Quaternion run(const QuaternionBase& _a, const QuaternionBase& _b) { Quaternion res; const __m128 mask = _mm_setr_ps(0.f,0.f,0.f,-0.f); - __m128 a = _a.coeffs().template packet(0); - __m128 b = _b.coeffs().template packet(0); + __m128 a = _a.coeffs().template packet(0); + __m128 b = _b.coeffs().template packet(0); __m128 s1 = _mm_mul_ps(vec4f_swizzle1(a,1,2,0,2),vec4f_swizzle1(b,2,0,1,2)); __m128 s2 = _mm_mul_ps(vec4f_swizzle1(a,3,3,3,1),vec4f_swizzle1(b,0,1,2,1)); - pstore(&res.x(), + pstoret( + &res.x(), _mm_add_ps(_mm_sub_ps(_mm_mul_ps(a,vec4f_swizzle1(b,3,3,3,3)), _mm_mul_ps(vec4f_swizzle1(a,2,0,1,0), vec4f_swizzle1(b,1,2,0,0))), @@ -36,14 +42,17 @@ struct quat_product } }; -template -struct quat_conj +template +struct quat_conj { + enum { + ResAlignment = traits >::Alignment + }; static inline Quaternion run(const QuaternionBase& q) { Quaternion res; const __m128 mask = _mm_setr_ps(-0.f,-0.f,-0.f,0.f); - pstore(&res.x(), _mm_xor_ps(mask, q.coeffs().template packet(0))); + pstoret(&res.x(), _mm_xor_ps(mask, q.coeffs().template packet::Alignment>(0))); return res; } }; @@ -52,6 +61,9 @@ struct quat_conj template struct cross3_impl { + enum { + ResAlignment = traits::type>::Alignment + }; static inline typename plain_matrix_type::type run(const VectorLhs& lhs, const VectorRhs& rhs) { @@ -60,7 +72,7 @@ struct cross3_impl __m128 mul1=_mm_mul_ps(vec4f_swizzle1(a,1,2,0,3),vec4f_swizzle1(b,2,0,1,3)); __m128 mul2=_mm_mul_ps(vec4f_swizzle1(a,2,0,1,3),vec4f_swizzle1(b,1,2,0,3)); typename plain_matrix_type::type res; - pstore(&res.x(),_mm_sub_ps(mul1,mul2)); + pstoret(&res.x(),_mm_sub_ps(mul1,mul2)); return res; } }; @@ -68,9 +80,14 @@ struct cross3_impl -template -struct quat_product +template +struct quat_product { + enum { + BAlignment = traits::Alignment, + ResAlignment = traits >::Alignment + }; + static inline Quaternion run(const QuaternionBase& _a, const QuaternionBase& _b) { const Packet2d mask = _mm_castsi128_pd(_mm_set_epi32(0x0,0x0,0x80000000,0x0)); @@ -78,8 +95,8 @@ struct quat_product Quaternion res; const double* a = _a.coeffs().data(); - Packet2d b_xy = _b.coeffs().template packet(0); - Packet2d b_zw = _b.coeffs().template packet(2); + Packet2d b_xy = _b.coeffs().template packet(0); + Packet2d b_zw = _b.coeffs().template packet(2); Packet2d a_xx = pset1(a[0]); Packet2d a_yy = pset1(a[1]); Packet2d a_zz = pset1(a[2]); @@ -97,9 +114,9 @@ struct quat_product t2 = psub(pmul(a_zz, b_xy), pmul(a_xx, b_zw)); #ifdef EIGEN_VECTORIZE_SSE3 EIGEN_UNUSED_VARIABLE(mask) - pstore(&res.x(), _mm_addsub_pd(t1, preverse(t2))); + pstoret(&res.x(), _mm_addsub_pd(t1, preverse(t2))); #else - pstore(&res.x(), padd(t1, pxor(mask,preverse(t2)))); + pstoret(&res.x(), padd(t1, pxor(mask,preverse(t2)))); #endif /* @@ -111,25 +128,28 @@ struct quat_product t2 = padd(pmul(a_zz, b_zw), pmul(a_xx, b_xy)); #ifdef EIGEN_VECTORIZE_SSE3 EIGEN_UNUSED_VARIABLE(mask) - pstore(&res.z(), preverse(_mm_addsub_pd(preverse(t1), t2))); + pstoret(&res.z(), preverse(_mm_addsub_pd(preverse(t1), t2))); #else - pstore(&res.z(), psub(t1, pxor(mask,preverse(t2)))); + pstoret(&res.z(), psub(t1, pxor(mask,preverse(t2)))); #endif return res; } }; -template -struct quat_conj +template +struct quat_conj { + enum { + ResAlignment = traits >::Alignment + }; static inline Quaternion run(const QuaternionBase& q) { Quaternion res; const __m128d mask0 = _mm_setr_pd(-0.,-0.); const __m128d mask2 = _mm_setr_pd(-0.,0.); - pstore(&res.x(), _mm_xor_pd(mask0, q.coeffs().template packet(0))); - pstore(&res.z(), _mm_xor_pd(mask2, q.coeffs().template packet(2))); + pstoret(&res.x(), _mm_xor_pd(mask0, q.coeffs().template packet::Alignment>(0))); + pstoret(&res.z(), _mm_xor_pd(mask2, q.coeffs().template packet::Alignment>(2))); return res; } }; diff --git a/eigenlib/Eigen/src/Householder/BlockHouseholder.h b/eigenlib/Eigen/src/Householder/BlockHouseholder.h index 39bf8c83..01a7ed18 100644 --- a/eigenlib/Eigen/src/Householder/BlockHouseholder.h +++ b/eigenlib/Eigen/src/Householder/BlockHouseholder.h @@ -87,7 +87,8 @@ void apply_block_householder_on_the_left(MatrixType& mat, const VectorsType& vec const TriangularView V(vectors); // A -= V T V^* A - Matrix tmp = V.adjoint() * mat; // FIXME add .noalias() once the triangular product can work inplace if(forward) tmp = T.template triangularView() * tmp; diff --git a/eigenlib/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h b/eigenlib/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h index 358444af..f66c846e 100644 --- a/eigenlib/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h +++ b/eigenlib/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h @@ -152,13 +152,28 @@ class LeastSquareDiagonalPreconditioner : public DiagonalPreconditioner<_Scalar> { // Compute the inverse squared-norm of each column of mat m_invdiag.resize(mat.cols()); - for(Index j=0; j0) - m_invdiag(j) = RealScalar(1)/sum; - else - m_invdiag(j) = RealScalar(1); + m_invdiag.setZero(); + for(Index j=0; jRealScalar(0)) + m_invdiag(j) = RealScalar(1)/numext::real(m_invdiag(j)); + } + else + { + for(Index j=0; jRealScalar(0)) + m_invdiag(j) = RealScalar(1)/sum; + else + m_invdiag(j) = RealScalar(1); + } } Base::m_isInitialized = true; return *this; diff --git a/eigenlib/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h b/eigenlib/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h index 395daa8e..f7ce4713 100644 --- a/eigenlib/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h +++ b/eigenlib/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h @@ -50,7 +50,8 @@ void conjugate_gradient(const MatrixType& mat, const Rhs& rhs, Dest& x, tol_error = 0; return; } - RealScalar threshold = tol*tol*rhsNorm2; + const RealScalar considerAsZero = (std::numeric_limits::min)(); + RealScalar threshold = numext::maxi(tol*tol*rhsNorm2,considerAsZero); RealScalar residualNorm2 = residual.squaredNorm(); if (residualNorm2 < threshold) { @@ -58,7 +59,7 @@ void conjugate_gradient(const MatrixType& mat, const Rhs& rhs, Dest& x, tol_error = sqrt(residualNorm2 / rhsNorm2); return; } - + VectorType p(n); p = precond.solve(residual); // initial search direction diff --git a/eigenlib/Eigen/src/Jacobi/Jacobi.h b/eigenlib/Eigen/src/Jacobi/Jacobi.h index d25af8e9..1998c632 100644 --- a/eigenlib/Eigen/src/Jacobi/Jacobi.h +++ b/eigenlib/Eigen/src/Jacobi/Jacobi.h @@ -65,11 +65,11 @@ template class JacobiRotation bool makeJacobi(const MatrixBase&, Index p, Index q); bool makeJacobi(const RealScalar& x, const Scalar& y, const RealScalar& z); - void makeGivens(const Scalar& p, const Scalar& q, Scalar* z=0); + void makeGivens(const Scalar& p, const Scalar& q, Scalar* r=0); protected: - void makeGivens(const Scalar& p, const Scalar& q, Scalar* z, internal::true_type); - void makeGivens(const Scalar& p, const Scalar& q, Scalar* z, internal::false_type); + void makeGivens(const Scalar& p, const Scalar& q, Scalar* r, internal::true_type); + void makeGivens(const Scalar& p, const Scalar& q, Scalar* r, internal::false_type); Scalar m_c, m_s; }; @@ -84,7 +84,6 @@ bool JacobiRotation::makeJacobi(const RealScalar& x, const Scalar& y, co { using std::sqrt; using std::abs; - typedef typename NumTraits::Real RealScalar; RealScalar deno = RealScalar(2)*abs(y); if(deno < (std::numeric_limits::min)()) { @@ -133,7 +132,7 @@ inline bool JacobiRotation::makeJacobi(const MatrixBase& m, Ind * \f$ V = \left ( \begin{array}{c} p \\ q \end{array} \right )\f$ yields: * \f$ G^* V = \left ( \begin{array}{c} r \\ 0 \end{array} \right )\f$. * - * The value of \a z is returned if \a z is not null (the default is null). + * The value of \a r is returned if \a r is not null (the default is null). * Also note that G is built such that the cosine is always real. * * Example: \include Jacobi_makeGivens.cpp @@ -146,9 +145,9 @@ inline bool JacobiRotation::makeJacobi(const MatrixBase& m, Ind * \sa MatrixBase::applyOnTheLeft(), MatrixBase::applyOnTheRight() */ template -void JacobiRotation::makeGivens(const Scalar& p, const Scalar& q, Scalar* z) +void JacobiRotation::makeGivens(const Scalar& p, const Scalar& q, Scalar* r) { - makeGivens(p, q, z, typename internal::conditional::IsComplex, internal::true_type, internal::false_type>::type()); + makeGivens(p, q, r, typename internal::conditional::IsComplex, internal::true_type, internal::false_type>::type()); } @@ -298,12 +297,144 @@ inline void MatrixBase::applyOnTheRight(Index p, Index q, const JacobiR } namespace internal { + +template +struct apply_rotation_in_the_plane_selector +{ + static inline void run(Scalar *x, Index incrx, Scalar *y, Index incry, Index size, OtherScalar c, OtherScalar s) + { + for(Index i=0; i +struct apply_rotation_in_the_plane_selector +{ + static inline void run(Scalar *x, Index incrx, Scalar *y, Index incry, Index size, OtherScalar c, OtherScalar s) + { + enum { + PacketSize = packet_traits::size, + OtherPacketSize = packet_traits::size + }; + typedef typename packet_traits::type Packet; + typedef typename packet_traits::type OtherPacket; + + /*** dynamic-size vectorized paths ***/ + if(SizeAtCompileTime == Dynamic && ((incrx==1 && incry==1) || PacketSize == 1)) + { + // both vectors are sequentially stored in memory => vectorization + enum { Peeling = 2 }; + + Index alignedStart = internal::first_default_aligned(y, size); + Index alignedEnd = alignedStart + ((size-alignedStart)/PacketSize)*PacketSize; + + const OtherPacket pc = pset1(c); + const OtherPacket ps = pset1(s); + conj_helper::IsComplex,false> pcj; + conj_helper pm; + + for(Index i=0; i(px); + Packet yi = pload(py); + pstore(px, padd(pm.pmul(pc,xi),pcj.pmul(ps,yi))); + pstore(py, psub(pcj.pmul(pc,yi),pm.pmul(ps,xi))); + px += PacketSize; + py += PacketSize; + } + } + else + { + Index peelingEnd = alignedStart + ((size-alignedStart)/(Peeling*PacketSize))*(Peeling*PacketSize); + for(Index i=alignedStart; i(px); + Packet xi1 = ploadu(px+PacketSize); + Packet yi = pload (py); + Packet yi1 = pload (py+PacketSize); + pstoreu(px, padd(pm.pmul(pc,xi),pcj.pmul(ps,yi))); + pstoreu(px+PacketSize, padd(pm.pmul(pc,xi1),pcj.pmul(ps,yi1))); + pstore (py, psub(pcj.pmul(pc,yi),pm.pmul(ps,xi))); + pstore (py+PacketSize, psub(pcj.pmul(pc,yi1),pm.pmul(ps,xi1))); + px += Peeling*PacketSize; + py += Peeling*PacketSize; + } + if(alignedEnd!=peelingEnd) + { + Packet xi = ploadu(x+peelingEnd); + Packet yi = pload (y+peelingEnd); + pstoreu(x+peelingEnd, padd(pm.pmul(pc,xi),pcj.pmul(ps,yi))); + pstore (y+peelingEnd, psub(pcj.pmul(pc,yi),pm.pmul(ps,xi))); + } + } + + for(Index i=alignedEnd; i0) // FIXME should be compared to the required alignment + { + const OtherPacket pc = pset1(c); + const OtherPacket ps = pset1(s); + conj_helper::IsComplex,false> pcj; + conj_helper pm; + Scalar* EIGEN_RESTRICT px = x; + Scalar* EIGEN_RESTRICT py = y; + for(Index i=0; i(px); + Packet yi = pload(py); + pstore(px, padd(pm.pmul(pc,xi),pcj.pmul(ps,yi))); + pstore(py, psub(pcj.pmul(pc,yi),pm.pmul(ps,xi))); + px += PacketSize; + py += PacketSize; + } + } + + /*** non-vectorized path ***/ + else + { + apply_rotation_in_the_plane_selector::run(x,incrx,y,incry,size,c,s); + } + } +}; + template void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(DenseBase& xpr_x, DenseBase& xpr_y, const JacobiRotation& j) { typedef typename VectorX::Scalar Scalar; - enum { PacketSize = packet_traits::size }; - typedef typename packet_traits::type Packet; + const bool Vectorizable = (VectorX::Flags & VectorY::Flags & PacketAccessBit) + && (int(packet_traits::size) == int(packet_traits::size)); + eigen_assert(xpr_x.size() == xpr_y.size()); Index size = xpr_x.size(); Index incrx = xpr_x.derived().innerStride(); @@ -317,113 +448,11 @@ void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(DenseBase& xpr_x if (c==OtherScalar(1) && s==OtherScalar(0)) return; - /*** dynamic-size vectorized paths ***/ - - if(VectorX::SizeAtCompileTime == Dynamic && - (VectorX::Flags & VectorY::Flags & PacketAccessBit) && - ((incrx==1 && incry==1) || PacketSize == 1)) - { - // both vectors are sequentially stored in memory => vectorization - enum { Peeling = 2 }; - - Index alignedStart = internal::first_default_aligned(y, size); - Index alignedEnd = alignedStart + ((size-alignedStart)/PacketSize)*PacketSize; - - const Packet pc = pset1(c); - const Packet ps = pset1(s); - conj_helper::IsComplex,false> pcj; - - for(Index i=0; i(px); - Packet yi = pload(py); - pstore(px, padd(pmul(pc,xi),pcj.pmul(ps,yi))); - pstore(py, psub(pcj.pmul(pc,yi),pmul(ps,xi))); - px += PacketSize; - py += PacketSize; - } - } - else - { - Index peelingEnd = alignedStart + ((size-alignedStart)/(Peeling*PacketSize))*(Peeling*PacketSize); - for(Index i=alignedStart; i(px); - Packet xi1 = ploadu(px+PacketSize); - Packet yi = pload (py); - Packet yi1 = pload (py+PacketSize); - pstoreu(px, padd(pmul(pc,xi),pcj.pmul(ps,yi))); - pstoreu(px+PacketSize, padd(pmul(pc,xi1),pcj.pmul(ps,yi1))); - pstore (py, psub(pcj.pmul(pc,yi),pmul(ps,xi))); - pstore (py+PacketSize, psub(pcj.pmul(pc,yi1),pmul(ps,xi1))); - px += Peeling*PacketSize; - py += Peeling*PacketSize; - } - if(alignedEnd!=peelingEnd) - { - Packet xi = ploadu(x+peelingEnd); - Packet yi = pload (y+peelingEnd); - pstoreu(x+peelingEnd, padd(pmul(pc,xi),pcj.pmul(ps,yi))); - pstore (y+peelingEnd, psub(pcj.pmul(pc,yi),pmul(ps,xi))); - } - } - - for(Index i=alignedEnd; i::Alignment, evaluator::Alignment)>0)) // FIXME should be compared to the required alignment - { - const Packet pc = pset1(c); - const Packet ps = pset1(s); - conj_helper::IsComplex,false> pcj; - Scalar* EIGEN_RESTRICT px = x; - Scalar* EIGEN_RESTRICT py = y; - for(Index i=0; i(px); - Packet yi = pload(py); - pstore(px, padd(pmul(pc,xi),pcj.pmul(ps,yi))); - pstore(py, psub(pcj.pmul(pc,yi),pmul(ps,xi))); - px += PacketSize; - py += PacketSize; - } - } - - /*** non-vectorized path ***/ - else - { - for(Index i=0; i::Alignment, evaluator::Alignment), + Vectorizable>::run(x,incrx,y,incry,size,c,s); } } // end namespace internal diff --git a/eigenlib/Eigen/src/LU/InverseImpl.h b/eigenlib/Eigen/src/LU/InverseImpl.h index 018f99b5..f49f2336 100644 --- a/eigenlib/Eigen/src/LU/InverseImpl.h +++ b/eigenlib/Eigen/src/LU/InverseImpl.h @@ -404,7 +404,7 @@ inline void MatrixBase::computeInverseWithCheck( const RealScalar& absDeterminantThreshold ) const { - RealScalar determinant; + Scalar determinant; // i'd love to put some static assertions there, but SFINAE means that they have no effect... eigen_assert(rows() == cols()); computeInverseAndDetWithCheck(inverse,determinant,invertible,absDeterminantThreshold); diff --git a/eigenlib/Eigen/src/LU/PartialPivLU.h b/eigenlib/Eigen/src/LU/PartialPivLU.h index d4396188..6b10f39f 100644 --- a/eigenlib/Eigen/src/LU/PartialPivLU.h +++ b/eigenlib/Eigen/src/LU/PartialPivLU.h @@ -519,7 +519,10 @@ void PartialPivLU::compute() // the row permutation is stored as int indices, so just to be sure: eigen_assert(m_lu.rows()::highest()); - m_l1_norm = m_lu.cwiseAbs().colwise().sum().maxCoeff(); + if(m_lu.cols()>0) + m_l1_norm = m_lu.cwiseAbs().colwise().sum().maxCoeff(); + else + m_l1_norm = RealScalar(0); eigen_assert(m_lu.rows() == m_lu.cols() && "PartialPivLU is only for square (and moreover invertible) matrices"); const Index size = m_lu.rows(); diff --git a/eigenlib/Eigen/src/LU/arch/Inverse_SSE.h b/eigenlib/Eigen/src/LU/arch/Inverse_SSE.h index ebb64a62..4dce2ef2 100644 --- a/eigenlib/Eigen/src/LU/arch/Inverse_SSE.h +++ b/eigenlib/Eigen/src/LU/arch/Inverse_SSE.h @@ -44,7 +44,7 @@ struct compute_inverse_size4 static void run(const MatrixType& mat, ResultType& result) { ActualMatrixType matrix(mat); - EIGEN_ALIGN16 const unsigned int _Sign_PNNP[4] = { 0x00000000, 0x80000000, 0x80000000, 0x00000000 }; + const Packet4f p4f_sign_PNNP = _mm_castsi128_ps(_mm_set_epi32(0x00000000, 0x80000000, 0x80000000, 0x00000000)); // Load the full matrix into registers __m128 _L1 = matrix.template packet( 0); @@ -139,7 +139,7 @@ struct compute_inverse_size4 iC = _mm_sub_ps(iC, _mm_mul_ps(_mm_shuffle_ps(A,A,0xB1), _mm_shuffle_ps(DC,DC,0x66))); rd = _mm_shuffle_ps(rd,rd,0); - rd = _mm_xor_ps(rd, _mm_load_ps((float*)_Sign_PNNP)); + rd = _mm_xor_ps(rd, p4f_sign_PNNP); // iB = C*|B| - D*B#*A iB = _mm_sub_ps(_mm_mul_ps(C,_mm_shuffle_ps(dB,dB,0)), iB); diff --git a/eigenlib/Eigen/src/OrderingMethods/Eigen_Colamd.h b/eigenlib/Eigen/src/OrderingMethods/Eigen_Colamd.h index 933cd564..da85b4d6 100644 --- a/eigenlib/Eigen/src/OrderingMethods/Eigen_Colamd.h +++ b/eigenlib/Eigen/src/OrderingMethods/Eigen_Colamd.h @@ -1004,7 +1004,7 @@ static IndexType find_ordering /* return the number of garbage collections */ COLAMD_ASSERT (head [min_score] >= COLAMD_EMPTY) ; /* get pivot column from head of minimum degree list */ - while (head [min_score] == COLAMD_EMPTY && min_score < n_col) + while (min_score < n_col && head [min_score] == COLAMD_EMPTY) { min_score++ ; } diff --git a/eigenlib/Eigen/src/PaStiXSupport/PaStiXSupport.h b/eigenlib/Eigen/src/PaStiXSupport/PaStiXSupport.h index d2ebfd7b..160d8a52 100644 --- a/eigenlib/Eigen/src/PaStiXSupport/PaStiXSupport.h +++ b/eigenlib/Eigen/src/PaStiXSupport/PaStiXSupport.h @@ -64,28 +64,28 @@ namespace internal typedef typename _MatrixType::StorageIndex StorageIndex; }; - void eigen_pastix(pastix_data_t **pastix_data, int pastix_comm, int n, int *ptr, int *idx, float *vals, int *perm, int * invp, float *x, int nbrhs, int *iparm, double *dparm) + inline void eigen_pastix(pastix_data_t **pastix_data, int pastix_comm, int n, int *ptr, int *idx, float *vals, int *perm, int * invp, float *x, int nbrhs, int *iparm, double *dparm) { if (n == 0) { ptr = NULL; idx = NULL; vals = NULL; } if (nbrhs == 0) {x = NULL; nbrhs=1;} s_pastix(pastix_data, pastix_comm, n, ptr, idx, vals, perm, invp, x, nbrhs, iparm, dparm); } - void eigen_pastix(pastix_data_t **pastix_data, int pastix_comm, int n, int *ptr, int *idx, double *vals, int *perm, int * invp, double *x, int nbrhs, int *iparm, double *dparm) + inline void eigen_pastix(pastix_data_t **pastix_data, int pastix_comm, int n, int *ptr, int *idx, double *vals, int *perm, int * invp, double *x, int nbrhs, int *iparm, double *dparm) { if (n == 0) { ptr = NULL; idx = NULL; vals = NULL; } if (nbrhs == 0) {x = NULL; nbrhs=1;} d_pastix(pastix_data, pastix_comm, n, ptr, idx, vals, perm, invp, x, nbrhs, iparm, dparm); } - void eigen_pastix(pastix_data_t **pastix_data, int pastix_comm, int n, int *ptr, int *idx, std::complex *vals, int *perm, int * invp, std::complex *x, int nbrhs, int *iparm, double *dparm) + inline void eigen_pastix(pastix_data_t **pastix_data, int pastix_comm, int n, int *ptr, int *idx, std::complex *vals, int *perm, int * invp, std::complex *x, int nbrhs, int *iparm, double *dparm) { if (n == 0) { ptr = NULL; idx = NULL; vals = NULL; } if (nbrhs == 0) {x = NULL; nbrhs=1;} c_pastix(pastix_data, pastix_comm, n, ptr, idx, reinterpret_cast(vals), perm, invp, reinterpret_cast(x), nbrhs, iparm, dparm); } - void eigen_pastix(pastix_data_t **pastix_data, int pastix_comm, int n, int *ptr, int *idx, std::complex *vals, int *perm, int * invp, std::complex *x, int nbrhs, int *iparm, double *dparm) + inline void eigen_pastix(pastix_data_t **pastix_data, int pastix_comm, int n, int *ptr, int *idx, std::complex *vals, int *perm, int * invp, std::complex *x, int nbrhs, int *iparm, double *dparm) { if (n == 0) { ptr = NULL; idx = NULL; vals = NULL; } if (nbrhs == 0) {x = NULL; nbrhs=1;} diff --git a/eigenlib/Eigen/src/PardisoSupport/PardisoSupport.h b/eigenlib/Eigen/src/PardisoSupport/PardisoSupport.h index 091c3970..98d0e3f2 100644 --- a/eigenlib/Eigen/src/PardisoSupport/PardisoSupport.h +++ b/eigenlib/Eigen/src/PardisoSupport/PardisoSupport.h @@ -192,7 +192,8 @@ class PardisoImpl : public SparseSolverBase void pardisoInit(int type) { m_type = type; - bool symmetric = std::abs(m_type) < 10; + EIGEN_USING_STD_MATH(abs); + bool symmetric = abs(m_type) < 10; m_iparm[0] = 1; // No solver default m_iparm[1] = 2; // use Metis for the ordering m_iparm[2] = 0; // Reserved. Set to zero. (??Numbers of processors, value of OMP_NUM_THREADS??) diff --git a/eigenlib/Eigen/src/QR/ColPivHouseholderQR.h b/eigenlib/Eigen/src/QR/ColPivHouseholderQR.h index 0e47c833..a7b47d55 100644 --- a/eigenlib/Eigen/src/QR/ColPivHouseholderQR.h +++ b/eigenlib/Eigen/src/QR/ColPivHouseholderQR.h @@ -506,8 +506,8 @@ void ColPivHouseholderQR::computeInPlace() m_colNormsUpdated.coeffRef(k) = m_colNormsDirect.coeffRef(k); } - RealScalar threshold_helper = numext::abs2(m_colNormsUpdated.maxCoeff() * NumTraits::epsilon()) / RealScalar(rows); - RealScalar norm_downdate_threshold = numext::sqrt(NumTraits::epsilon()); + RealScalar threshold_helper = numext::abs2(m_colNormsUpdated.maxCoeff() * NumTraits::epsilon()) / RealScalar(rows); + RealScalar norm_downdate_threshold = numext::sqrt(NumTraits::epsilon()); m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case) m_maxpivot = RealScalar(0); @@ -553,12 +553,12 @@ void ColPivHouseholderQR::computeInPlace() // http://www.netlib.org/lapack/lawnspdf/lawn176.pdf // and used in LAPACK routines xGEQPF and xGEQP3. // See lines 278-297 in http://www.netlib.org/lapack/explore-html/dc/df4/sgeqpf_8f_source.html - if (m_colNormsUpdated.coeffRef(j) != 0) { + if (m_colNormsUpdated.coeffRef(j) != RealScalar(0)) { RealScalar temp = abs(m_qr.coeffRef(k, j)) / m_colNormsUpdated.coeffRef(j); temp = (RealScalar(1) + temp) * (RealScalar(1) - temp); - temp = temp < 0 ? 0 : temp; - RealScalar temp2 = temp * numext::abs2(m_colNormsUpdated.coeffRef(j) / - m_colNormsDirect.coeffRef(j)); + temp = temp < RealScalar(0) ? RealScalar(0) : temp; + RealScalar temp2 = temp * numext::abs2(m_colNormsUpdated.coeffRef(j) / + m_colNormsDirect.coeffRef(j)); if (temp2 <= norm_downdate_threshold) { // The updated norm has become too inaccurate so re-compute the column // norm directly. diff --git a/eigenlib/Eigen/src/SVD/BDCSVD.h b/eigenlib/Eigen/src/SVD/BDCSVD.h index 25fca6f4..a5b73f8f 100644 --- a/eigenlib/Eigen/src/SVD/BDCSVD.h +++ b/eigenlib/Eigen/src/SVD/BDCSVD.h @@ -11,7 +11,7 @@ // Copyright (C) 2013 Jean Ceccato // Copyright (C) 2013 Pierre Zoppitelli // Copyright (C) 2013 Jitse Niesen -// Copyright (C) 2014-2016 Gael Guennebaud +// Copyright (C) 2014-2017 Gael Guennebaud // // Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed @@ -77,6 +77,7 @@ public: typedef _MatrixType MatrixType; typedef typename MatrixType::Scalar Scalar; typedef typename NumTraits::Real RealScalar; + typedef typename NumTraits::Literal Literal; enum { RowsAtCompileTime = MatrixType::RowsAtCompileTime, ColsAtCompileTime = MatrixType::ColsAtCompileTime, @@ -259,7 +260,7 @@ BDCSVD& BDCSVD::compute(const MatrixType& matrix, unsign //**** step 0 - Copy the input matrix and apply scaling to reduce over/under-flows RealScalar scale = matrix.cwiseAbs().maxCoeff(); - if(scale==RealScalar(0)) scale = RealScalar(1); + if(scale==Literal(0)) scale = Literal(1); MatrixX copy; if (m_isTranspose) copy = matrix.adjoint()/scale; else copy = matrix/scale; @@ -351,13 +352,13 @@ void BDCSVD::structured_update(Block A, co Index k1=0, k2=0; for(Index j=0; j::divide (Index firstCol, Index lastCol, Index firstRowW, l = m_naiveU.row(1).segment(firstCol, k); f = m_naiveU.row(0).segment(firstCol + k + 1, n - k - 1); } - if (m_compV) m_naiveV(firstRowW+k, firstColW) = 1; + if (m_compV) m_naiveV(firstRowW+k, firstColW) = Literal(1); if (r0::computeSVDofM(Index firstCol, Index n, MatrixXr& U, Vec ArrayRef col0 = m_computed.col(firstCol).segment(firstCol, n); m_workspace.head(n) = m_computed.block(firstCol, firstCol, n, n).diagonal(); ArrayRef diag = m_workspace.head(n); - diag(0) = 0; + diag(0) = Literal(0); // Allocate space for singular values and vectors singVals.resize(n); @@ -590,7 +591,7 @@ void BDCSVD::computeSVDofM(Index firstCol, Index n, MatrixXr& U, Vec // but others are interleaved and we must ignore them at this stage. // To this end, let's compute a permutation skipping them: Index actual_n = n; - while(actual_n>1 && diag(actual_n-1)==0) --actual_n; + while(actual_n>1 && diag(actual_n-1)==Literal(0)) --actual_n; Index m = 0; // size of the deflated problem for(Index k=0;kconsiderZero) @@ -691,11 +692,13 @@ template typename BDCSVD::RealScalar BDCSVD::secularEq(RealScalar mu, const ArrayRef& col0, const ArrayRef& diag, const IndicesRef &perm, const ArrayRef& diagShifted, RealScalar shift) { Index m = perm.size(); - RealScalar res = 1; + RealScalar res = Literal(1); for(Index i=0; i::computeSingVals(const ArrayRef& col0, const ArrayRef& d { using std::abs; using std::swap; + using std::sqrt; Index n = col0.size(); Index actual_n = n; - while(actual_n>1 && col0(actual_n-1)==0) --actual_n; + // Note that here actual_n is computed based on col0(i)==0 instead of diag(i)==0 as above + // because 1) we have diag(i)==0 => col0(i)==0 and 2) if col0(i)==0, then diag(i) is already a singular value. + while(actual_n>1 && col0(actual_n-1)==Literal(0)) --actual_n; for (Index k = 0; k < n; ++k) { - if (col0(k) == 0 || actual_n==1) + if (col0(k) == Literal(0) || actual_n==1) { // if col0(k) == 0, then entry is deflated, so singular value is on diagonal // if actual_n==1, then the deflated problem is already diagonalized singVals(k) = k==0 ? col0(0) : diag(k); - mus(k) = 0; + mus(k) = Literal(0); shifts(k) = k==0 ? col0(0) : diag(k); continue; } @@ -731,15 +737,17 @@ void BDCSVD::computeSingVals(const ArrayRef& col0, const ArrayRef& d right = (diag(actual_n-1) + col0.matrix().norm()); else { - // Skip deflated singular values + // Skip deflated singular values, + // recall that at this stage we assume that z[j]!=0 and all entries for which z[j]==0 have been put aside. + // This should be equivalent to using perm[] Index l = k+1; - while(col0(l)==0) { ++l; eigen_internal_assert(l::computeSingVals(const ArrayRef& col0, const ArrayRef& d << " " << secularEq(0.8*(left+right), col0, diag, perm, diag, 0) << " " << secularEq(0.9*(left+right), col0, diag, perm, diag, 0) << "\n"; #endif - RealScalar shift = (k == actual_n-1 || fMid > 0) ? left : right; + RealScalar shift = (k == actual_n-1 || fMid > Literal(0)) ? left : right; // measure everything relative to shift Map diagShifted(m_workspace.data()+4*n, n); diagShifted = diag - shift; + + if(k!=actual_n-1) + { + // check that after the shift, f(mid) is still negative: + RealScalar midShifted = (right - left) / RealScalar(2); + if(shift==right) + midShifted = -midShifted; + RealScalar fMidShifted = secularEq(midShifted, col0, diag, perm, diagShifted, shift); + if(fMidShifted>0) + { + // fMid was erroneous, fix it: + shift = fMidShifted > Literal(0) ? left : right; + diagShifted = diag - shift; + } + } // initial guess RealScalar muPrev, muCur; @@ -785,13 +808,13 @@ void BDCSVD::computeSingVals(const ArrayRef& col0, const ArrayRef& d // rational interpolation: fit a function of the form a / mu + b through the two previous // iterates and use its zero to compute the next iterate - bool useBisection = fPrev*fCur>0; - while (fCur!=0 && abs(muCur - muPrev) > 8 * NumTraits::epsilon() * numext::maxi(abs(muCur), abs(muPrev)) && abs(fCur - fPrev)>NumTraits::epsilon() && !useBisection) + bool useBisection = fPrev*fCur>Literal(0); + while (fCur!=Literal(0) && abs(muCur - muPrev) > Literal(8) * NumTraits::epsilon() * numext::maxi(abs(muCur), abs(muPrev)) && abs(fCur - fPrev)>NumTraits::epsilon() && !useBisection) { ++m_numIters; // Find a and b such that the function f(mu) = a / mu + b matches the current and previous samples. - RealScalar a = (fCur - fPrev) / (1/muCur - 1/muPrev); + RealScalar a = (fCur - fPrev) / (Literal(1)/muCur - Literal(1)/muPrev); RealScalar b = fCur - a / muCur; // And find mu such that f(mu)==0: RealScalar muZero = -a/b; @@ -803,8 +826,8 @@ void BDCSVD::computeSingVals(const ArrayRef& col0, const ArrayRef& d fCur = fZero; - if (shift == left && (muCur < 0 || muCur > right - left)) useBisection = true; - if (shift == right && (muCur < -(right - left) || muCur > 0)) useBisection = true; + if (shift == left && (muCur < Literal(0) || muCur > right - left)) useBisection = true; + if (shift == right && (muCur < -(right - left) || muCur > Literal(0))) useBisection = true; if (abs(fCur)>abs(fPrev)) useBisection = true; } @@ -817,23 +840,33 @@ void BDCSVD::computeSingVals(const ArrayRef& col0, const ArrayRef& d RealScalar leftShifted, rightShifted; if (shift == left) { - leftShifted = (std::numeric_limits::min)(); + // to avoid overflow, we must have mu > max(real_min, |z(k)|/sqrt(real_max)), + // the factor 2 is to be more conservative + leftShifted = numext::maxi( (std::numeric_limits::min)(), Literal(2) * abs(col0(k)) / sqrt((std::numeric_limits::max)()) ); + + // check that we did it right: + eigen_internal_assert( (numext::isfinite)( (col0(k)/leftShifted)*(col0(k)/(diag(k)+shift+leftShifted)) ) ); // I don't understand why the case k==0 would be special there: - // if (k == 0) rightShifted = right - left; else - rightShifted = (k==actual_n-1) ? right : ((right - left) * RealScalar(0.6)); // theoretically we can take 0.5, but let's be safe + // if (k == 0) rightShifted = right - left; else + rightShifted = (k==actual_n-1) ? right : ((right - left) * RealScalar(0.51)); // theoretically we can take 0.5, but let's be safe } else { - leftShifted = -(right - left) * RealScalar(0.6); - rightShifted = -(std::numeric_limits::min)(); + leftShifted = -(right - left) * RealScalar(0.51); + if(k+1( (std::numeric_limits::min)(), abs(col0(k+1)) / sqrt((std::numeric_limits::max)()) ); + else + rightShifted = -(std::numeric_limits::min)(); } RealScalar fLeft = secularEq(leftShifted, col0, diag, perm, diagShifted, shift); + eigen_internal_assert(fLeft::computeSingVals(const ArrayRef& col0, const ArrayRef& d std::cout << k << " : " << fLeft << " * " << fRight << " == " << fLeft * fRight << " ; " << left << " - " << right << " -> " << leftShifted << " " << rightShifted << " shift=" << shift << "\n"; } #endif - eigen_internal_assert(fLeft * fRight < 0); - - while (rightShifted - leftShifted > 2 * NumTraits::epsilon() * numext::maxi(abs(leftShifted), abs(rightShifted))) - { - RealScalar midShifted = (leftShifted + rightShifted) / 2; - fMid = secularEq(midShifted, col0, diag, perm, diagShifted, shift); - if (fLeft * fMid < 0) - { - rightShifted = midShifted; - } - else - { - leftShifted = midShifted; - fLeft = fMid; - } - } + eigen_internal_assert(fLeft * fRight < Literal(0)); - muCur = (leftShifted + rightShifted) / 2; + if(fLeft Literal(2) * NumTraits::epsilon() * numext::maxi(abs(leftShifted), abs(rightShifted))) + { + RealScalar midShifted = (leftShifted + rightShifted) / Literal(2); + fMid = secularEq(midShifted, col0, diag, perm, diagShifted, shift); + eigen_internal_assert((numext::isfinite)(fMid)); + + if (fLeft * fMid < Literal(0)) + { + rightShifted = midShifted; + } + else + { + leftShifted = midShifted; + fLeft = fMid; + } + } + muCur = (leftShifted + rightShifted) / Literal(2); + } + else + { + // We have a problem as shifting on the left or right give either a positive or negative value + // at the middle of [left,right]... + // Instead fo abbording or entering an infinite loop, + // let's just use the middle as the estimated zero-crossing: + muCur = (right - left) * RealScalar(0.5); + if(shift == right) + muCur = -muCur; + } } singVals[k] = shift + muCur; @@ -892,8 +939,8 @@ void BDCSVD::perturbCol0 // The offset permits to skip deflated entries while computing zhat for (Index k = 0; k < n; ++k) { - if (col0(k) == 0) // deflated - zhat(k) = 0; + if (col0(k) == Literal(0)) // deflated + zhat(k) = Literal(0); else { // see equation (3.6) @@ -908,7 +955,7 @@ void BDCSVD::perturbCol0 Index j = i 0.9 ) + if(i!=k && numext::abs(((singVals(j)+dk)*(mus(j)+(shifts(j)-dk)))/((diag(i)+dk)*(diag(i)-dk)) - 1) > 0.9 ) std::cout << " " << ((singVals(j)+dk)*(mus(j)+(shifts(j)-dk)))/((diag(i)+dk)*(diag(i)-dk)) << " == (" << (singVals(j)+dk) << " * " << (mus(j)+(shifts(j)-dk)) << ") / (" << (diag(i)+dk) << " * " << (diag(i)-dk) << ")\n"; #endif @@ -918,7 +965,7 @@ void BDCSVD::perturbCol0 std::cout << "zhat(" << k << ") = sqrt( " << prod << ") ; " << (singVals(last) + dk) << " * " << mus(last) + shifts(last) << " - " << dk << "\n"; #endif RealScalar tmp = sqrt(prod); - zhat(k) = col0(k) > 0 ? tmp : -tmp; + zhat(k) = col0(k) > Literal(0) ? RealScalar(tmp) : RealScalar(-tmp); } } } @@ -934,7 +981,7 @@ void BDCSVD::computeSingVecs for (Index k = 0; k < n; ++k) { - if (zhat(k) == 0) + if (zhat(k) == Literal(0)) { U.col(k) = VectorType::Unit(n+1, k); if (m_compV) V.col(k) = VectorType::Unit(n, k); @@ -947,7 +994,7 @@ void BDCSVD::computeSingVecs Index i = perm(l); U(i,k) = zhat(i)/(((diag(i) - shifts(k)) - mus(k)) )/( (diag(i) + singVals[k])); } - U(n,k) = 0; + U(n,k) = Literal(0); U.col(k).normalize(); if (m_compV) @@ -958,7 +1005,7 @@ void BDCSVD::computeSingVecs Index i = perm(l); V(i,k) = diag(i) * zhat(i) / (((diag(i) - shifts(k)) - mus(k)) )/( (diag(i) + singVals[k])); } - V(0,k) = -1; + V(0,k) = Literal(-1); V.col(k).normalize(); } } @@ -979,15 +1026,15 @@ void BDCSVD::deflation43(Index firstCol, Index shift, Index i, Index Index start = firstCol + shift; RealScalar c = m_computed(start, start); RealScalar s = m_computed(start+i, start); - RealScalar r = sqrt(numext::abs2(c) + numext::abs2(s)); - if (r == 0) + RealScalar r = numext::hypot(c,s); + if (r == Literal(0)) { - m_computed(start+i, start+i) = 0; + m_computed(start+i, start+i) = Literal(0); return; } m_computed(start,start) = r; - m_computed(start+i, start) = 0; - m_computed(start+i, start+i) = 0; + m_computed(start+i, start) = Literal(0); + m_computed(start+i, start+i) = Literal(0); JacobiRotation J(c/r,-s/r); if (m_compU) m_naiveU.middleRows(firstCol, size+1).applyOnTheRight(firstCol, firstCol+i, J); @@ -1020,7 +1067,7 @@ void BDCSVD::deflation44(Index firstColu , Index firstColm, Index fi << m_computed(firstColm + i+1, firstColm+i+1) << " " << m_computed(firstColm + i+2, firstColm+i+2) << "\n"; #endif - if (r==0) + if (r==Literal(0)) { m_computed(firstColm + i, firstColm + i) = m_computed(firstColm + j, firstColm + j); return; @@ -1029,7 +1076,7 @@ void BDCSVD::deflation44(Index firstColu , Index firstColm, Index fi s/=r; m_computed(firstColm + i, firstColm) = r; m_computed(firstColm + j, firstColm + j) = m_computed(firstColm + i, firstColm + i); - m_computed(firstColm + j, firstColm) = 0; + m_computed(firstColm + j, firstColm) = Literal(0); JacobiRotation J(c,-s); if (m_compU) m_naiveU.middleRows(firstColu, size+1).applyOnTheRight(firstColu + i, firstColu + j, J); @@ -1053,7 +1100,7 @@ void BDCSVD::deflation(Index firstCol, Index lastCol, Index k, Index const RealScalar considerZero = (std::numeric_limits::min)(); RealScalar maxDiag = diag.tail((std::max)(Index(1),length-1)).cwiseAbs().maxCoeff(); RealScalar epsilon_strict = numext::maxi(considerZero,NumTraits::epsilon() * maxDiag); - RealScalar epsilon_coarse = 8 * NumTraits::epsilon() * numext::maxi(col0.cwiseAbs().maxCoeff(), maxDiag); + RealScalar epsilon_coarse = Literal(8) * NumTraits::epsilon() * numext::maxi(col0.cwiseAbs().maxCoeff(), maxDiag); #ifdef EIGEN_BDCSVD_SANITY_CHECKS assert(m_naiveU.allFinite()); @@ -1081,7 +1128,7 @@ void BDCSVD::deflation(Index firstCol, Index lastCol, Index k, Index #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE std::cout << "deflation 4.2, set z(" << i << ") to zero because " << abs(col0(i)) << " < " << epsilon_strict << " (diag(" << i << ")=" << diag(i) << ")\n"; #endif - col0(i) = 0; + col0(i) = Literal(0); } //condition 4.3 diff --git a/eigenlib/Eigen/src/SVD/JacobiSVD.h b/eigenlib/Eigen/src/SVD/JacobiSVD.h index e0cfb628..43488b1e 100644 --- a/eigenlib/Eigen/src/SVD/JacobiSVD.h +++ b/eigenlib/Eigen/src/SVD/JacobiSVD.h @@ -112,9 +112,11 @@ public: ColsAtCompileTime = MatrixType::ColsAtCompileTime, MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime, - Options = MatrixType::Options + TrOptions = RowsAtCompileTime==1 ? (MatrixType::Options & ~(RowMajor)) + : ColsAtCompileTime==1 ? (MatrixType::Options | RowMajor) + : MatrixType::Options }; - typedef Matrix + typedef Matrix TransposeTypeWithSameStorageOrder; void allocate(const JacobiSVD& svd) @@ -200,10 +202,12 @@ public: ColsAtCompileTime = MatrixType::ColsAtCompileTime, MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime, - Options = MatrixType::Options + TrOptions = RowsAtCompileTime==1 ? (MatrixType::Options & ~(RowMajor)) + : ColsAtCompileTime==1 ? (MatrixType::Options | RowMajor) + : MatrixType::Options }; - typedef Matrix + typedef Matrix TransposeTypeWithSameStorageOrder; void allocate(const JacobiSVD& svd) diff --git a/eigenlib/Eigen/src/SVD/JacobiSVD_LAPACKE.h b/eigenlib/Eigen/src/SVD/JacobiSVD_LAPACKE.h index 50272154..ff0516f6 100644 --- a/eigenlib/Eigen/src/SVD/JacobiSVD_LAPACKE.h +++ b/eigenlib/Eigen/src/SVD/JacobiSVD_LAPACKE.h @@ -61,9 +61,10 @@ JacobiSVD, ColPiv u = (LAPACKE_TYPE*)m_matrixU.data(); \ } else { ldu=1; u=&dummy; }\ MatrixType localV; \ - ldvt = (m_computeFullV) ? internal::convert_index(m_cols) : (m_computeThinV) ? internal::convert_index(m_diagSize) : 1; \ + lapack_int vt_rows = (m_computeFullV) ? internal::convert_index(m_cols) : (m_computeThinV) ? internal::convert_index(m_diagSize) : 1; \ if (computeV()) { \ - localV.resize(ldvt, m_cols); \ + localV.resize(vt_rows, m_cols); \ + ldvt = internal::convert_index(localV.outerStride()); \ vt = (LAPACKE_TYPE*)localV.data(); \ } else { ldvt=1; vt=&dummy; }\ Matrix superb; superb.resize(m_diagSize, 1); \ diff --git a/eigenlib/Eigen/src/SVD/SVDBase.h b/eigenlib/Eigen/src/SVD/SVDBase.h index cc90a3b7..53da2848 100644 --- a/eigenlib/Eigen/src/SVD/SVDBase.h +++ b/eigenlib/Eigen/src/SVD/SVDBase.h @@ -180,8 +180,10 @@ public: RealScalar threshold() const { eigen_assert(m_isInitialized || m_usePrescribedThreshold); + // this temporary is needed to workaround a MSVC issue + Index diagSize = (std::max)(1,m_diagSize); return m_usePrescribedThreshold ? m_prescribedThreshold - : (std::max)(1,m_diagSize)*NumTraits::epsilon(); + : RealScalar(diagSize)*NumTraits::epsilon(); } /** \returns true if \a U (full or thin) is asked for in this SVD decomposition */ diff --git a/eigenlib/Eigen/src/SVD/UpperBidiagonalization.h b/eigenlib/Eigen/src/SVD/UpperBidiagonalization.h index 0b146089..11ac847e 100644 --- a/eigenlib/Eigen/src/SVD/UpperBidiagonalization.h +++ b/eigenlib/Eigen/src/SVD/UpperBidiagonalization.h @@ -159,6 +159,8 @@ void upperbidiagonalization_blocked_helper(MatrixType& A, traits::Flags & RowMajorBit> > Y) { typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::RealScalar RealScalar; + typedef typename NumTraits::Literal Literal; enum { StorageOrder = traits::Flags & RowMajorBit }; typedef InnerStride ColInnerStride; typedef InnerStride RowInnerStride; @@ -263,7 +265,7 @@ void upperbidiagonalization_blocked_helper(MatrixType& A, SubMatType A10( A.block(bs,0, brows-bs,bs) ); SubMatType A01( A.block(0,bs, bs,bcols-bs) ); Scalar tmp = A01(bs-1,0); - A01(bs-1,0) = 1; + A01(bs-1,0) = Literal(1); A11.noalias() -= A10 * Y.topLeftCorner(bcols,bs).bottomRows(bcols-bs).adjoint(); A11.noalias() -= X.topLeftCorner(brows,bs).bottomRows(brows-bs) * A01; A01(bs-1,0) = tmp; diff --git a/eigenlib/Eigen/src/SparseCholesky/SimplicialCholesky.h b/eigenlib/Eigen/src/SparseCholesky/SimplicialCholesky.h index 2907f652..369e6804 100644 --- a/eigenlib/Eigen/src/SparseCholesky/SimplicialCholesky.h +++ b/eigenlib/Eigen/src/SparseCholesky/SimplicialCholesky.h @@ -608,7 +608,7 @@ public: } if(Base::m_diag.size()>0) - dest = Base::m_diag.asDiagonal().inverse() * dest; + dest = Base::m_diag.real().asDiagonal().inverse() * dest; if (Base::m_matrix.nonZeros()>0) // otherwise I==I { diff --git a/eigenlib/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h b/eigenlib/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h index 31e06995..7b6183d0 100644 --- a/eigenlib/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h +++ b/eigenlib/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h @@ -156,7 +156,7 @@ void SimplicialCholeskyBase::factorize_preordered(const CholMatrixType& /* the nonzero entry L(k,i) */ Scalar l_ki; if(DoLDLT) - l_ki = yi / m_diag[i]; + l_ki = yi / numext::real(m_diag[i]); else yi = l_ki = yi / Lx[Lp[i]]; diff --git a/eigenlib/Eigen/src/SparseCore/AmbiVector.h b/eigenlib/Eigen/src/SparseCore/AmbiVector.h index 1233e164..2cb7747c 100644 --- a/eigenlib/Eigen/src/SparseCore/AmbiVector.h +++ b/eigenlib/Eigen/src/SparseCore/AmbiVector.h @@ -28,7 +28,7 @@ class AmbiVector typedef typename NumTraits::Real RealScalar; explicit AmbiVector(Index size) - : m_buffer(0), m_zero(0), m_size(0), m_allocatedSize(0), m_allocatedElements(0), m_mode(-1) + : m_buffer(0), m_zero(0), m_size(0), m_end(0), m_allocatedSize(0), m_allocatedElements(0), m_mode(-1) { resize(size); } @@ -94,7 +94,7 @@ class AmbiVector Index allocSize = m_allocatedElements * sizeof(ListEl); allocSize = (allocSize + sizeof(Scalar) - 1)/sizeof(Scalar); Scalar* newBuffer = new Scalar[allocSize]; - memcpy(newBuffer, m_buffer, copyElements * sizeof(ListEl)); + std::memcpy(newBuffer, m_buffer, copyElements * sizeof(ListEl)); delete[] m_buffer; m_buffer = newBuffer; } @@ -147,7 +147,8 @@ template void AmbiVector<_Scalar,_StorageIndex>::init(int mode) { m_mode = mode; - if (m_mode==IsSparse) + // This is only necessary in sparse mode, but we set these unconditionally to avoid some maybe-uninitialized warnings + // if (m_mode==IsSparse) { m_llSize = 0; m_llStart = -1; @@ -336,7 +337,7 @@ class AmbiVector<_Scalar,_StorageIndex>::Iterator { do { ++m_cachedIndex; - } while (m_cachedIndex::Iterator ListEl* EIGEN_RESTRICT llElements = reinterpret_cast(m_vector.m_buffer); do { m_currentEl = llElements[m_currentEl].next; - } while (m_currentEl>=0 && abs(llElements[m_currentEl].value)=0 && abs(llElements[m_currentEl].value)<=m_epsilon); if (m_currentEl<0) { m_cachedIndex = -1; @@ -363,9 +364,9 @@ class AmbiVector<_Scalar,_StorageIndex>::Iterator protected: const AmbiVector& m_vector; // the target vector - StorageIndex m_currentEl; // the current element in sparse/linked-list mode + StorageIndex m_currentEl; // the current element in sparse/linked-list mode RealScalar m_epsilon; // epsilon used to prune zero coefficients - StorageIndex m_cachedIndex; // current coordinate + StorageIndex m_cachedIndex; // current coordinate Scalar m_cachedValue; // current value bool m_isDense; // mode of the vector }; diff --git a/eigenlib/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h b/eigenlib/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h index 492eb0a2..9db119b6 100644 --- a/eigenlib/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h +++ b/eigenlib/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h @@ -17,7 +17,9 @@ namespace internal { template static void conservative_sparse_sparse_product_impl(const Lhs& lhs, const Rhs& rhs, ResultType& res, bool sortedInsertion = false) { - typedef typename remove_all::type::Scalar Scalar; + typedef typename remove_all::type::Scalar LhsScalar; + typedef typename remove_all::type::Scalar RhsScalar; + typedef typename remove_all::type::Scalar ResScalar; // make sure to call innerSize/outerSize since we fake the storage order. Index rows = lhs.innerSize(); @@ -25,7 +27,7 @@ static void conservative_sparse_sparse_product_impl(const Lhs& lhs, const Rhs& r eigen_assert(lhs.outerSize() == rhs.innerSize()); ei_declare_aligned_stack_constructed_variable(bool, mask, rows, 0); - ei_declare_aligned_stack_constructed_variable(Scalar, values, rows, 0); + ei_declare_aligned_stack_constructed_variable(ResScalar, values, rows, 0); ei_declare_aligned_stack_constructed_variable(Index, indices, rows, 0); std::memset(mask,0,sizeof(bool)*rows); @@ -51,12 +53,12 @@ static void conservative_sparse_sparse_product_impl(const Lhs& lhs, const Rhs& r Index nnz = 0; for (typename evaluator::InnerIterator rhsIt(rhsEval, j); rhsIt; ++rhsIt) { - Scalar y = rhsIt.value(); + RhsScalar y = rhsIt.value(); Index k = rhsIt.index(); for (typename evaluator::InnerIterator lhsIt(lhsEval, k); lhsIt; ++lhsIt) { Index i = lhsIt.index(); - Scalar x = lhsIt.value(); + LhsScalar x = lhsIt.value(); if(!mask[i]) { mask[i] = true; @@ -166,11 +168,12 @@ struct conservative_sparse_sparse_product_selector RowMajorMatrix; - RowMajorMatrix rhsRow = rhs; - RowMajorMatrix resRow(lhs.rows(), rhs.cols()); - internal::conservative_sparse_sparse_product_impl(rhsRow, lhs, resRow); - res = resRow; + typedef SparseMatrix RowMajorRhs; + typedef SparseMatrix RowMajorRes; + RowMajorRhs rhsRow = rhs; + RowMajorRes resRow(lhs.rows(), rhs.cols()); + internal::conservative_sparse_sparse_product_impl(rhsRow, lhs, resRow); + res = resRow; } }; @@ -179,10 +182,11 @@ struct conservative_sparse_sparse_product_selector RowMajorMatrix; - RowMajorMatrix lhsRow = lhs; - RowMajorMatrix resRow(lhs.rows(), rhs.cols()); - internal::conservative_sparse_sparse_product_impl(rhs, lhsRow, resRow); + typedef SparseMatrix RowMajorLhs; + typedef SparseMatrix RowMajorRes; + RowMajorLhs lhsRow = lhs; + RowMajorRes resRow(lhs.rows(), rhs.cols()); + internal::conservative_sparse_sparse_product_impl(rhs, lhsRow, resRow); res = resRow; } }; @@ -219,10 +223,11 @@ struct conservative_sparse_sparse_product_selector ColMajorMatrix; - ColMajorMatrix lhsCol = lhs; - ColMajorMatrix resCol(lhs.rows(), rhs.cols()); - internal::conservative_sparse_sparse_product_impl(lhsCol, rhs, resCol); + typedef SparseMatrix ColMajorLhs; + typedef SparseMatrix ColMajorRes; + ColMajorLhs lhsCol = lhs; + ColMajorRes resCol(lhs.rows(), rhs.cols()); + internal::conservative_sparse_sparse_product_impl(lhsCol, rhs, resCol); res = resCol; } }; @@ -232,10 +237,11 @@ struct conservative_sparse_sparse_product_selector ColMajorMatrix; - ColMajorMatrix rhsCol = rhs; - ColMajorMatrix resCol(lhs.rows(), rhs.cols()); - internal::conservative_sparse_sparse_product_impl(lhs, rhsCol, resCol); + typedef SparseMatrix ColMajorRhs; + typedef SparseMatrix ColMajorRes; + ColMajorRhs rhsCol = rhs; + ColMajorRes resCol(lhs.rows(), rhs.cols()); + internal::conservative_sparse_sparse_product_impl(lhs, rhsCol, resCol); res = resCol; } }; @@ -263,7 +269,8 @@ namespace internal { template static void sparse_sparse_to_dense_product_impl(const Lhs& lhs, const Rhs& rhs, ResultType& res) { - typedef typename remove_all::type::Scalar Scalar; + typedef typename remove_all::type::Scalar LhsScalar; + typedef typename remove_all::type::Scalar RhsScalar; Index cols = rhs.outerSize(); eigen_assert(lhs.outerSize() == rhs.innerSize()); @@ -274,12 +281,12 @@ static void sparse_sparse_to_dense_product_impl(const Lhs& lhs, const Rhs& rhs, { for (typename evaluator::InnerIterator rhsIt(rhsEval, j); rhsIt; ++rhsIt) { - Scalar y = rhsIt.value(); + RhsScalar y = rhsIt.value(); Index k = rhsIt.index(); for (typename evaluator::InnerIterator lhsIt(lhsEval, k); lhsIt; ++lhsIt) { Index i = lhsIt.index(); - Scalar x = lhsIt.value(); + LhsScalar x = lhsIt.value(); res.coeffRef(i,j) += x * y; } } @@ -310,9 +317,9 @@ struct sparse_sparse_to_dense_product_selector ColMajorMatrix; - ColMajorMatrix lhsCol(lhs); - internal::sparse_sparse_to_dense_product_impl(lhsCol, rhs, res); + typedef SparseMatrix ColMajorLhs; + ColMajorLhs lhsCol(lhs); + internal::sparse_sparse_to_dense_product_impl(lhsCol, rhs, res); } }; @@ -321,9 +328,9 @@ struct sparse_sparse_to_dense_product_selector ColMajorMatrix; - ColMajorMatrix rhsCol(rhs); - internal::sparse_sparse_to_dense_product_impl(lhs, rhsCol, res); + typedef SparseMatrix ColMajorRhs; + ColMajorRhs rhsCol(rhs); + internal::sparse_sparse_to_dense_product_impl(lhs, rhsCol, res); } }; diff --git a/eigenlib/Eigen/src/SparseCore/SparseAssign.h b/eigenlib/Eigen/src/SparseCore/SparseAssign.h index 83776645..18352a84 100644 --- a/eigenlib/Eigen/src/SparseCore/SparseAssign.h +++ b/eigenlib/Eigen/src/SparseCore/SparseAssign.h @@ -143,10 +143,7 @@ struct Assignment dst.setZero(); internal::evaluator srcEval(src); - Index dstRows = src.rows(); - Index dstCols = src.cols(); - if((dst.rows()!=dstRows) || (dst.cols()!=dstCols)) - dst.resize(dstRows, dstCols); + resize_if_allowed(dst, src, func); internal::evaluator dstEval(dst); const Index outerEvaluationSize = (internal::evaluator::Flags&RowMajorBit) ? src.rows() : src.cols(); diff --git a/eigenlib/Eigen/src/SparseCore/SparseCompressedBase.h b/eigenlib/Eigen/src/SparseCore/SparseCompressedBase.h index e0850795..5ccb4665 100644 --- a/eigenlib/Eigen/src/SparseCore/SparseCompressedBase.h +++ b/eigenlib/Eigen/src/SparseCore/SparseCompressedBase.h @@ -279,11 +279,11 @@ struct evaluator > Flags = Derived::Flags }; - evaluator() : m_matrix(0) + evaluator() : m_matrix(0), m_zero(0) { EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost); } - explicit evaluator(const Derived &mat) : m_matrix(&mat) + explicit evaluator(const Derived &mat) : m_matrix(&mat), m_zero(0) { EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost); } @@ -296,26 +296,42 @@ struct evaluator > operator const Derived&() const { return *m_matrix; } typedef typename DenseCoeffsBase::CoeffReturnType CoeffReturnType; - Scalar coeff(Index row, Index col) const - { return m_matrix->coeff(row,col); } - + const Scalar& coeff(Index row, Index col) const + { + Index p = find(row,col); + + if(p==Dynamic) + return m_zero; + else + return m_matrix->const_cast_derived().valuePtr()[p]; + } + Scalar& coeffRef(Index row, Index col) + { + Index p = find(row,col); + eigen_assert(p!=Dynamic && "written coefficient does not exist"); + return m_matrix->const_cast_derived().valuePtr()[p]; + } + +protected: + + Index find(Index row, Index col) const { eigen_internal_assert(row>=0 && rowrows() && col>=0 && colcols()); - + const Index outer = Derived::IsRowMajor ? row : col; const Index inner = Derived::IsRowMajor ? col : row; Index start = m_matrix->outerIndexPtr()[outer]; Index end = m_matrix->isCompressed() ? m_matrix->outerIndexPtr()[outer+1] : m_matrix->outerIndexPtr()[outer] + m_matrix->innerNonZeroPtr()[outer]; - eigen_assert(end>start && "you are using a non finalized sparse matrix or written coefficient does not exist"); - const Index p = std::lower_bound(m_matrix->innerIndexPtr()+start, m_matrix->innerIndexPtr()+end,inner) - - m_matrix->innerIndexPtr(); - eigen_assert((pinnerIndexPtr()[p]==inner) && "written coefficient does not exist"); - return m_matrix->const_cast_derived().valuePtr()[p]; + eigen_assert(end>=start && "you are using a non finalized sparse matrix or written coefficient does not exist"); + const Index p = std::lower_bound(m_matrix->innerIndexPtr()+start, m_matrix->innerIndexPtr()+end,inner) - m_matrix->innerIndexPtr(); + + return ((pinnerIndexPtr()[p]==inner)) ? p : Dynamic; } const Derived *m_matrix; + const Scalar m_zero; }; } diff --git a/eigenlib/Eigen/src/SparseCore/SparseCwiseBinaryOp.h b/eigenlib/Eigen/src/SparseCore/SparseCwiseBinaryOp.h index 526c7121..e315e355 100644 --- a/eigenlib/Eigen/src/SparseCore/SparseCwiseBinaryOp.h +++ b/eigenlib/Eigen/src/SparseCore/SparseCwiseBinaryOp.h @@ -359,6 +359,16 @@ struct binary_evaluator, Lhs, Rhs>, Itera explicit binary_evaluator(const XprType& xpr) : Base(xpr) {} }; +// "sparse ./ dense" +template +struct binary_evaluator, Lhs, Rhs>, IteratorBased, IndexBased> + : sparse_conjunction_evaluator, Lhs, Rhs> > +{ + typedef CwiseBinaryOp, Lhs, Rhs> XprType; + typedef sparse_conjunction_evaluator Base; + explicit binary_evaluator(const XprType& xpr) : Base(xpr) {} +}; + // "sparse && sparse" template struct binary_evaluator, IteratorBased, IteratorBased> diff --git a/eigenlib/Eigen/src/SparseCore/SparseCwiseUnaryOp.h b/eigenlib/Eigen/src/SparseCore/SparseCwiseUnaryOp.h index ea797379..df6c28d2 100644 --- a/eigenlib/Eigen/src/SparseCore/SparseCwiseUnaryOp.h +++ b/eigenlib/Eigen/src/SparseCore/SparseCwiseUnaryOp.h @@ -49,6 +49,7 @@ template class unary_evaluator, IteratorBased>::InnerIterator : public unary_evaluator, IteratorBased>::EvalIterator { + protected: typedef typename XprType::Scalar Scalar; typedef typename unary_evaluator, IteratorBased>::EvalIterator Base; public: @@ -99,6 +100,7 @@ template class unary_evaluator, IteratorBased>::InnerIterator : public unary_evaluator, IteratorBased>::EvalIterator { + protected: typedef typename XprType::Scalar Scalar; typedef typename unary_evaluator, IteratorBased>::EvalIterator Base; public: diff --git a/eigenlib/Eigen/src/SparseCore/SparseDiagonalProduct.h b/eigenlib/Eigen/src/SparseCore/SparseDiagonalProduct.h index e4af49e0..941c03be 100644 --- a/eigenlib/Eigen/src/SparseCore/SparseDiagonalProduct.h +++ b/eigenlib/Eigen/src/SparseCore/SparseDiagonalProduct.h @@ -80,6 +80,8 @@ public: sparse_diagonal_product_evaluator(const SparseXprType &sparseXpr, const DiagonalCoeffType &diagCoeff) : m_sparseXprImpl(sparseXpr), m_diagCoeffImpl(diagCoeff) {} + + Index nonZerosEstimate() const { return m_sparseXprImpl.nonZerosEstimate(); } protected: evaluator m_sparseXprImpl; @@ -121,6 +123,8 @@ struct sparse_diagonal_product_evaluator m_sparseXprEval; diff --git a/eigenlib/Eigen/src/SparseCore/SparseMatrix.h b/eigenlib/Eigen/src/SparseCore/SparseMatrix.h index 529c7a0a..a5396538 100644 --- a/eigenlib/Eigen/src/SparseCore/SparseMatrix.h +++ b/eigenlib/Eigen/src/SparseCore/SparseMatrix.h @@ -327,7 +327,8 @@ class SparseMatrix m_outerIndex[j] = newOuterIndex[j]; m_innerNonZeros[j] = innerNNZ; } - m_outerIndex[m_outerSize] = m_outerIndex[m_outerSize-1] + m_innerNonZeros[m_outerSize-1] + reserveSizes[m_outerSize-1]; + if(m_outerSize>0) + m_outerIndex[m_outerSize] = m_outerIndex[m_outerSize-1] + m_innerNonZeros[m_outerSize-1] + reserveSizes[m_outerSize-1]; m_data.resize(m_outerIndex[m_outerSize]); } @@ -893,7 +894,7 @@ public: Index p = m_outerIndex[outer] + m_innerNonZeros[outer]++; m_data.index(p) = convert_index(inner); - return (m_data.value(p) = 0); + return (m_data.value(p) = Scalar(0)); } private: @@ -1274,7 +1275,7 @@ EIGEN_DONT_INLINE typename SparseMatrix<_Scalar,_Options,_StorageIndex>::Scalar& m_innerNonZeros[outer]++; m_data.index(p) = inner; - return (m_data.value(p) = 0); + return (m_data.value(p) = Scalar(0)); } template @@ -1301,11 +1302,11 @@ EIGEN_DONT_INLINE typename SparseMatrix<_Scalar,_Options,_StorageIndex>::Scalar& // starts with: [ 0 0 0 0 0 1 ...] and we are inserted in, e.g., // the 2nd inner vector... bool isLastVec = (!(previousOuter==-1 && m_data.size()!=0)) - && (size_t(m_outerIndex[outer+1]) == m_data.size()); + && (std::size_t(m_outerIndex[outer+1]) == m_data.size()); - size_t startId = m_outerIndex[outer]; - // FIXME let's make sure sizeof(long int) == sizeof(size_t) - size_t p = m_outerIndex[outer+1]; + std::size_t startId = m_outerIndex[outer]; + // FIXME let's make sure sizeof(long int) == sizeof(std::size_t) + std::size_t p = m_outerIndex[outer+1]; ++m_outerIndex[outer+1]; double reallocRatio = 1; @@ -1381,7 +1382,7 @@ EIGEN_DONT_INLINE typename SparseMatrix<_Scalar,_Options,_StorageIndex>::Scalar& } m_data.index(p) = inner; - return (m_data.value(p) = 0); + return (m_data.value(p) = Scalar(0)); } namespace internal { diff --git a/eigenlib/Eigen/src/SparseCore/SparseSelfAdjointView.h b/eigenlib/Eigen/src/SparseCore/SparseSelfAdjointView.h index 9e39be73..76117a01 100644 --- a/eigenlib/Eigen/src/SparseCore/SparseSelfAdjointView.h +++ b/eigenlib/Eigen/src/SparseCore/SparseSelfAdjointView.h @@ -47,6 +47,7 @@ template class SparseSelfAdjointView enum { Mode = _Mode, + TransposeMode = ((Mode & Upper) ? Lower : 0) | ((Mode & Lower) ? Upper : 0), RowsAtCompileTime = internal::traits::RowsAtCompileTime, ColsAtCompileTime = internal::traits::ColsAtCompileTime }; @@ -310,7 +311,7 @@ inline void sparse_selfadjoint_time_dense_product(const SparseLhsType& lhs, cons while (i && i.index() dstT(dst); - internal::sparse_selfadjoint_time_dense_product(rhsNested.transpose(), lhsNested.transpose(), dstT, alpha); + internal::sparse_selfadjoint_time_dense_product(rhsNested.transpose(), lhsNested.transpose(), dstT, alpha); } }; @@ -452,7 +453,7 @@ void permute_symm_to_fullsymm(const MatrixType& mat, SparseMatrix::type::Scalar Scalar; + typedef typename remove_all::type::Scalar RhsScalar; + typedef typename remove_all::type::Scalar ResScalar; typedef typename remove_all::type::StorageIndex StorageIndex; // make sure to call innerSize/outerSize since we fake the storage order. @@ -31,7 +32,7 @@ static void sparse_sparse_product_with_pruning_impl(const Lhs& lhs, const Rhs& r eigen_assert(lhs.outerSize() == rhs.innerSize()); // allocate a temporary buffer - AmbiVector tempVector(rows); + AmbiVector tempVector(rows); // mimics a resizeByInnerOuter: if(ResultType::IsRowMajor) @@ -63,14 +64,14 @@ static void sparse_sparse_product_with_pruning_impl(const Lhs& lhs, const Rhs& r { // FIXME should be written like this: tmp += rhsIt.value() * lhs.col(rhsIt.index()) tempVector.restart(); - Scalar x = rhsIt.value(); + RhsScalar x = rhsIt.value(); for (typename evaluator::InnerIterator lhsIt(lhsEval, rhsIt.index()); lhsIt; ++lhsIt) { tempVector.coeffRef(lhsIt.index()) += lhsIt.value() * x; } } res.startVec(j); - for (typename AmbiVector::Iterator it(tempVector,tolerance); it; ++it) + for (typename AmbiVector::Iterator it(tempVector,tolerance); it; ++it) res.insertBackByOuterInner(j,it.index()) = it.value(); } res.finalize(); @@ -85,7 +86,6 @@ struct sparse_sparse_product_with_pruning_selector; template struct sparse_sparse_product_with_pruning_selector { - typedef typename traits::type>::Scalar Scalar; typedef typename ResultType::RealScalar RealScalar; static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res, const RealScalar& tolerance) @@ -129,8 +129,8 @@ struct sparse_sparse_product_with_pruning_selector ColMajorMatrixLhs; - typedef SparseMatrix ColMajorMatrixRhs; + typedef SparseMatrix ColMajorMatrixLhs; + typedef SparseMatrix ColMajorMatrixRhs; ColMajorMatrixLhs colLhs(lhs); ColMajorMatrixRhs colRhs(rhs); internal::sparse_sparse_product_with_pruning_impl(colLhs, colRhs, res, tolerance); @@ -149,7 +149,7 @@ struct sparse_sparse_product_with_pruning_selector RowMajorMatrixLhs; + typedef SparseMatrix RowMajorMatrixLhs; RowMajorMatrixLhs rowLhs(lhs); sparse_sparse_product_with_pruning_selector(rowLhs,rhs,res,tolerance); } @@ -161,7 +161,7 @@ struct sparse_sparse_product_with_pruning_selector RowMajorMatrixRhs; + typedef SparseMatrix RowMajorMatrixRhs; RowMajorMatrixRhs rowRhs(rhs); sparse_sparse_product_with_pruning_selector(lhs,rowRhs,res,tolerance); } @@ -173,7 +173,7 @@ struct sparse_sparse_product_with_pruning_selector ColMajorMatrixRhs; + typedef SparseMatrix ColMajorMatrixRhs; ColMajorMatrixRhs colRhs(rhs); internal::sparse_sparse_product_with_pruning_impl(lhs, colRhs, res, tolerance); } @@ -185,7 +185,7 @@ struct sparse_sparse_product_with_pruning_selector ColMajorMatrixLhs; + typedef SparseMatrix ColMajorMatrixLhs; ColMajorMatrixLhs colLhs(lhs); internal::sparse_sparse_product_with_pruning_impl(colLhs, rhs, res, tolerance); } diff --git a/eigenlib/Eigen/src/SparseCore/SparseView.h b/eigenlib/Eigen/src/SparseCore/SparseView.h index 7c4aea74..92b3d1f7 100644 --- a/eigenlib/Eigen/src/SparseCore/SparseView.h +++ b/eigenlib/Eigen/src/SparseCore/SparseView.h @@ -90,6 +90,7 @@ struct unary_evaluator, IteratorBased> class InnerIterator : public EvalIterator { + protected: typedef typename XprType::Scalar Scalar; public: diff --git a/eigenlib/Eigen/src/SparseLU/SparseLU.h b/eigenlib/Eigen/src/SparseLU/SparseLU.h index f883ab38..87f0efe3 100644 --- a/eigenlib/Eigen/src/SparseLU/SparseLU.h +++ b/eigenlib/Eigen/src/SparseLU/SparseLU.h @@ -43,8 +43,8 @@ template struct SparseLUMatrixURetu * Simple example with key steps * \code * VectorXd x(n), b(n); - * SparseMatrix A; - * SparseLU, COLAMDOrdering > solver; + * SparseMatrix A; + * SparseLU, COLAMDOrdering > solver; * // fill A and b; * // Compute the ordering permutation vector from the structural pattern of A * solver.analyzePattern(A); @@ -499,8 +499,6 @@ void SparseLU::factorize(const MatrixType& matrix) eigen_assert(m_analysisIsOk && "analyzePattern() should be called first"); eigen_assert((matrix.rows() == matrix.cols()) && "Only for squared matrices"); - typedef typename IndexVector::Scalar StorageIndex; - m_isInitialized = true; diff --git a/eigenlib/Eigen/src/SparseQR/SparseQR.h b/eigenlib/Eigen/src/SparseQR/SparseQR.h index 2d4498b0..7409fcae 100644 --- a/eigenlib/Eigen/src/SparseQR/SparseQR.h +++ b/eigenlib/Eigen/src/SparseQR/SparseQR.h @@ -52,7 +52,7 @@ namespace internal { * rank-revealing permutations. Use colsPermutation() to get it. * * Q is the orthogonal matrix represented as products of Householder reflectors. - * Use matrixQ() to get an expression and matrixQ().transpose() to get the transpose. + * Use matrixQ() to get an expression and matrixQ().adjoint() to get the adjoint. * You can then apply it to a vector. * * R is the sparse triangular or trapezoidal matrix. The later occurs when A is rank-deficient. @@ -65,6 +65,7 @@ namespace internal { * \implsparsesolverconcept * * \warning The input sparse matrix A must be in compressed mode (see SparseMatrix::makeCompressed()). + * \warning For complex matrices matrixQ().transpose() will actually return the adjoint matrix. * */ template @@ -196,9 +197,9 @@ class SparseQR : public SparseSolverBase > Index rank = this->rank(); - // Compute Q^T * b; + // Compute Q^* * b; typename Dest::PlainObject y, b; - y = this->matrixQ().transpose() * B; + y = this->matrixQ().adjoint() * B; b = y; // Solve with the triangular matrix R @@ -604,7 +605,7 @@ struct SparseQR_QProduct : ReturnByValue @@ -668,13 +672,14 @@ struct SparseQRMatrixQReturnType : public EigenBase(m_qr,other.derived(),false); } + // To use for operations with the adjoint of Q SparseQRMatrixQTransposeReturnType adjoint() const { return SparseQRMatrixQTransposeReturnType(m_qr); } inline Index rows() const { return m_qr.rows(); } - inline Index cols() const { return (std::min)(m_qr.rows(),m_qr.cols()); } - // To use for operations with the transpose of Q + inline Index cols() const { return m_qr.rows(); } + // To use for operations with the transpose of Q FIXME this is the same as adjoint at the moment SparseQRMatrixQTransposeReturnType transpose() const { return SparseQRMatrixQTransposeReturnType(m_qr); @@ -682,6 +687,7 @@ struct SparseQRMatrixQReturnType : public EigenBase struct SparseQRMatrixQTransposeReturnType { @@ -712,7 +718,7 @@ struct Assignment, internal: typedef typename DstXprType::StorageIndex StorageIndex; static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op &/*func*/) { - typename DstXprType::PlainObject idMat(src.m_qr.rows(), src.m_qr.rows()); + typename DstXprType::PlainObject idMat(src.rows(), src.cols()); idMat.setIdentity(); // Sort the sparse householder reflectors if needed const_cast(&src.m_qr)->_sort_matrix_Q(); diff --git a/eigenlib/Eigen/src/StlSupport/StdDeque.h b/eigenlib/Eigen/src/StlSupport/StdDeque.h index cf1fedf9..af158f42 100644 --- a/eigenlib/Eigen/src/StlSupport/StdDeque.h +++ b/eigenlib/Eigen/src/StlSupport/StdDeque.h @@ -98,8 +98,10 @@ namespace std { { return deque_base::insert(position,x); } void insert(const_iterator position, size_type new_size, const value_type& x) { deque_base::insert(position, new_size, x); } -#elif defined(_GLIBCXX_DEQUE) && EIGEN_GNUC_AT_LEAST(4,2) +#elif defined(_GLIBCXX_DEQUE) && EIGEN_GNUC_AT_LEAST(4,2) && !EIGEN_GNUC_AT_LEAST(10, 1) // workaround GCC std::deque implementation + // GCC 10.1 doesn't let us access _Deque_impl _M_impl anymore and we have to + // fall-back to the default case void resize(size_type new_size, const value_type& x) { if (new_size < deque_base::size()) @@ -108,7 +110,7 @@ namespace std { deque_base::insert(deque_base::end(), new_size - deque_base::size(), x); } #else - // either GCC 4.1 or non-GCC + // either non-GCC or GCC between 4.1 and 10.1 // default implementation which should always work. void resize(size_type new_size, const value_type& x) { diff --git a/eigenlib/Eigen/src/StlSupport/details.h b/eigenlib/Eigen/src/StlSupport/details.h index e42ec024..2cfd13e0 100644 --- a/eigenlib/Eigen/src/StlSupport/details.h +++ b/eigenlib/Eigen/src/StlSupport/details.h @@ -22,13 +22,13 @@ namespace Eigen { class aligned_allocator_indirection : public EIGEN_ALIGNED_ALLOCATOR { public: - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef T* pointer; - typedef const T* const_pointer; - typedef T& reference; - typedef const T& const_reference; - typedef T value_type; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef T* pointer; + typedef const T* const_pointer; + typedef T& reference; + typedef const T& const_reference; + typedef T value_type; template struct rebind diff --git a/eigenlib/Eigen/src/SuperLUSupport/SuperLUSupport.h b/eigenlib/Eigen/src/SuperLUSupport/SuperLUSupport.h index 50a69f30..7261c7d0 100644 --- a/eigenlib/Eigen/src/SuperLUSupport/SuperLUSupport.h +++ b/eigenlib/Eigen/src/SuperLUSupport/SuperLUSupport.h @@ -297,8 +297,8 @@ SluMatrix asSluMatrix(MatrixType& mat) template MappedSparseMatrix map_superlu(SluMatrix& sluMat) { - eigen_assert((Flags&RowMajor)==RowMajor && sluMat.Stype == SLU_NR - || (Flags&ColMajor)==ColMajor && sluMat.Stype == SLU_NC); + eigen_assert(((Flags&RowMajor)==RowMajor && sluMat.Stype == SLU_NR) + || ((Flags&ColMajor)==ColMajor && sluMat.Stype == SLU_NC)); Index outerSize = (Flags&RowMajor)==RowMajor ? sluMat.ncol : sluMat.nrow; diff --git a/eigenlib/Eigen/src/UmfPackSupport/UmfPackSupport.h b/eigenlib/Eigen/src/UmfPackSupport/UmfPackSupport.h index dc74de93..91c09ab1 100644 --- a/eigenlib/Eigen/src/UmfPackSupport/UmfPackSupport.h +++ b/eigenlib/Eigen/src/UmfPackSupport/UmfPackSupport.h @@ -10,19 +10,37 @@ #ifndef EIGEN_UMFPACKSUPPORT_H #define EIGEN_UMFPACKSUPPORT_H -namespace Eigen { +namespace Eigen { /* TODO extract L, extract U, compute det, etc... */ // generic double/complex wrapper functions: -inline void umfpack_defaults(double control[UMFPACK_CONTROL], double) +inline void umfpack_defaults(double control[UMFPACK_CONTROL], double) { umfpack_di_defaults(control); } -inline void umfpack_defaults(double control[UMFPACK_CONTROL], std::complex) +inline void umfpack_defaults(double control[UMFPACK_CONTROL], std::complex) { umfpack_zi_defaults(control); } +inline void umfpack_report_info(double control[UMFPACK_CONTROL], double info[UMFPACK_INFO], double) +{ umfpack_di_report_info(control, info);} + +inline void umfpack_report_info(double control[UMFPACK_CONTROL], double info[UMFPACK_INFO], std::complex) +{ umfpack_zi_report_info(control, info);} + +inline void umfpack_report_status(double control[UMFPACK_CONTROL], int status, double) +{ umfpack_di_report_status(control, status);} + +inline void umfpack_report_status(double control[UMFPACK_CONTROL], int status, std::complex) +{ umfpack_zi_report_status(control, status);} + +inline void umfpack_report_control(double control[UMFPACK_CONTROL], double) +{ umfpack_di_report_control(control);} + +inline void umfpack_report_control(double control[UMFPACK_CONTROL], std::complex) +{ umfpack_zi_report_control(control);} + inline void umfpack_free_numeric(void **Numeric, double) { umfpack_di_free_numeric(Numeric); *Numeric = 0; } @@ -156,6 +174,7 @@ class UmfPackLU : public SparseSolverBase > public: typedef Array UmfpackControl; + typedef Array UmfpackInfo; UmfPackLU() : m_dummy(0,0), mp_matrix(m_dummy) @@ -215,7 +234,7 @@ class UmfPackLU : public SparseSolverBase > return m_q; } - /** Computes the sparse Cholesky decomposition of \a matrix + /** Computes the sparse Cholesky decomposition of \a matrix * Note that the matrix should be column-major, and in compressed format for best performance. * \sa SparseMatrix::makeCompressed(). */ @@ -240,7 +259,7 @@ class UmfPackLU : public SparseSolverBase > { if(m_symbolic) umfpack_free_symbolic(&m_symbolic,Scalar()); if(m_numeric) umfpack_free_numeric(&m_numeric,Scalar()); - + grab(matrix.derived()); analyzePattern_impl(); @@ -267,7 +286,7 @@ class UmfPackLU : public SparseSolverBase > { return m_control; } - + /** Provides access to the control settings array used by UmfPack. * * If this array contains NaN's, the default values are used. @@ -278,7 +297,7 @@ class UmfPackLU : public SparseSolverBase > { return m_control; } - + /** Performs a numeric decomposition of \a matrix * * The given matrix must has the same sparcity than the matrix on which the pattern anylysis has been performed. @@ -293,10 +312,38 @@ class UmfPackLU : public SparseSolverBase > umfpack_free_numeric(&m_numeric,Scalar()); grab(matrix.derived()); - + factorize_impl(); } + /** Prints the current UmfPack control settings. + * + * \sa umfpackControl() + */ + void umfpackReportControl() + { + umfpack_report_control(m_control.data(), Scalar()); + } + + /** Prints statistics collected by UmfPack. + * + * \sa analyzePattern(), compute() + */ + void umfpackReportInfo() + { + eigen_assert(m_analysisIsOk && "UmfPackLU: you must first call analyzePattern()"); + umfpack_report_info(m_control.data(), m_umfpackInfo.data(), Scalar()); + } + + /** Prints the status of the previous factorization operation performed by UmfPack (symbolic or numerical factorization). + * + * \sa analyzePattern(), compute() + */ + void umfpackReportStatus() { + eigen_assert(m_analysisIsOk && "UmfPackLU: you must first call analyzePattern()"); + umfpack_report_status(m_control.data(), m_fact_errorCode, Scalar()); + } + /** \internal */ template bool _solve_impl(const MatrixBase &b, MatrixBase &x) const; @@ -314,41 +361,42 @@ class UmfPackLU : public SparseSolverBase > m_numeric = 0; m_symbolic = 0; m_extractedDataAreDirty = true; + + umfpack_defaults(m_control.data(), Scalar()); } - + void analyzePattern_impl() { - umfpack_defaults(m_control.data(), Scalar()); - int errorCode = 0; - errorCode = umfpack_symbolic(internal::convert_index(mp_matrix.rows()), - internal::convert_index(mp_matrix.cols()), - mp_matrix.outerIndexPtr(), mp_matrix.innerIndexPtr(), mp_matrix.valuePtr(), - &m_symbolic, m_control.data(), 0); + m_fact_errorCode = umfpack_symbolic(internal::convert_index(mp_matrix.rows()), + internal::convert_index(mp_matrix.cols()), + mp_matrix.outerIndexPtr(), mp_matrix.innerIndexPtr(), mp_matrix.valuePtr(), + &m_symbolic, m_control.data(), m_umfpackInfo.data()); m_isInitialized = true; - m_info = errorCode ? InvalidInput : Success; + m_info = m_fact_errorCode ? InvalidInput : Success; m_analysisIsOk = true; m_factorizationIsOk = false; m_extractedDataAreDirty = true; } - + void factorize_impl() { + m_fact_errorCode = umfpack_numeric(mp_matrix.outerIndexPtr(), mp_matrix.innerIndexPtr(), mp_matrix.valuePtr(), - m_symbolic, &m_numeric, m_control.data(), 0); + m_symbolic, &m_numeric, m_control.data(), m_umfpackInfo.data()); m_info = m_fact_errorCode == UMFPACK_OK ? Success : NumericalIssue; m_factorizationIsOk = true; m_extractedDataAreDirty = true; } - + template void grab(const EigenBase &A) { mp_matrix.~UmfpackMatrixRef(); ::new (&mp_matrix) UmfpackMatrixRef(A.derived()); } - + void grab(const UmfpackMatrixRef &A) { if(&(A.derived()) != &mp_matrix) @@ -357,19 +405,20 @@ class UmfPackLU : public SparseSolverBase > ::new (&mp_matrix) UmfpackMatrixRef(A); } } - + // cached data to reduce reallocation, etc. mutable LUMatrixType m_l; int m_fact_errorCode; UmfpackControl m_control; - + mutable UmfpackInfo m_umfpackInfo; + mutable LUMatrixType m_u; mutable IntColVectorType m_p; mutable IntRowVectorType m_q; UmfpackMatrixType m_dummy; UmfpackMatrixRef mp_matrix; - + void* m_numeric; void* m_symbolic; @@ -377,7 +426,7 @@ class UmfPackLU : public SparseSolverBase > int m_factorizationIsOk; int m_analysisIsOk; mutable bool m_extractedDataAreDirty; - + private: UmfPackLU(const UmfPackLU& ) { } }; @@ -427,7 +476,7 @@ bool UmfPackLU::_solve_impl(const MatrixBase &b, MatrixBas eigen_assert((BDerived::Flags&RowMajorBit)==0 && "UmfPackLU backend does not support non col-major rhs yet"); eigen_assert((XDerived::Flags&RowMajorBit)==0 && "UmfPackLU backend does not support non col-major result yet"); eigen_assert(b.derived().data() != x.derived().data() && " Umfpack does not support inplace solve"); - + int errorCode; Scalar* x_ptr = 0; Matrix x_tmp; @@ -442,7 +491,7 @@ bool UmfPackLU::_solve_impl(const MatrixBase &b, MatrixBas x_ptr = &x.col(j).coeffRef(0); errorCode = umfpack_solve(UMFPACK_A, mp_matrix.outerIndexPtr(), mp_matrix.innerIndexPtr(), mp_matrix.valuePtr(), - x_ptr, &b.const_cast_derived().col(j).coeffRef(0), m_numeric, m_control.data(), 0); + x_ptr, &b.const_cast_derived().col(j).coeffRef(0), m_numeric, m_control.data(), m_umfpackInfo.data()); if(x.innerStride()!=1) x.col(j) = x_tmp; if (errorCode!=0) diff --git a/eigenlib/Eigen/src/plugins/ArrayCwiseBinaryOps.h b/eigenlib/Eigen/src/plugins/ArrayCwiseBinaryOps.h index 1f8a531a..05a7449b 100644 --- a/eigenlib/Eigen/src/plugins/ArrayCwiseBinaryOps.h +++ b/eigenlib/Eigen/src/plugins/ArrayCwiseBinaryOps.h @@ -119,7 +119,7 @@ OP(const Scalar& s) const { \ return this->OP(Derived::PlainObject::Constant(rows(), cols(), s)); \ } \ EIGEN_DEVICE_FUNC friend EIGEN_STRONG_INLINE const RCmp ## COMPARATOR ## ReturnType \ -OP(const Scalar& s, const Derived& d) { \ +OP(const Scalar& s, const EIGEN_CURRENT_STORAGE_BASE_CLASS& d) { \ return Derived::PlainObject::Constant(d.rows(), d.cols(), s).OP(d); \ } diff --git a/eigenlib/howto.txt b/eigenlib/howto.txt index 5f893409..99b20682 100644 --- a/eigenlib/howto.txt +++ b/eigenlib/howto.txt @@ -3,11 +3,12 @@ Current Eigen Version 3.2.1 (26.02.2014) updated on 14/05/2014 Current Eigen Version 3.2.2 (04.08.2014) updated on 21/10/2014 Current Eigen Version 3.2.5 (16.06.2015) updated on 24/09/2015 Current Eigen Version 3.3.2 (18.01.2017) updated on 24/01/2017 +Current Eigen Version 3.3.9 (04.12.2020) updated on 15/06/2021 To update the lib: - download Eigen - unzip it somewhere -- delete (in the filesystem) the content of the folder eigenlib/Eigen - copy the folders 'Eigen' there +- delete (in the filesystem) the content of the folder eigenlib/Eigen - copy the folders 'Eigen' there - check the git status. - update this file - commit everything From 721dace0c5882c7c70ff3ea55fe0cb8aabd9553e Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Thu, 17 Jun 2021 12:49:42 +0200 Subject: [PATCH 025/117] update cmake to be sure vcg is included just one time --- CMakeLists.txt | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 663c74cf..acc67cd0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -279,14 +279,18 @@ set(SOURCES ) if (VCG_HEADER_ONLY) - add_library(vcglib INTERFACE) - target_include_directories( - vcglib INTERFACE - ${CMAKE_CURRENT_LIST_DIR} - ${EIGEN_INCLUDE_DIRS}) + if (NOT TARGET vcglib) # to be sure that vcglib target is created just one time + add_library(vcglib INTERFACE) + target_include_directories( + vcglib INTERFACE + ${CMAKE_CURRENT_LIST_DIR} + ${EIGEN_INCLUDE_DIRS}) - #just to show headers in ide - add_custom_target(vcglib_ide SOURCES ${VCG_HEADERS}) + #just to show headers in ide + add_custom_target(vcglib_ide SOURCES ${VCG_HEADERS}) + else() + message(STATUS "- VCGLib - jumped - already included") + endif() else() #TODO make vcglib that includes all the wrap sources, checking everytime # if the the required targets (e.g. qt, gl, glew...) exists From ab3b3b3c5a38c298c716c60afbfe16e53eb6f251 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Mon, 21 Jun 2021 11:25:51 +0200 Subject: [PATCH 026/117] code cleanups - remove unneeded semicolons --- vcg/complex/algorithms/create/platonic.h | 4 ++-- vcg/complex/used_types.h | 2 +- vcg/space/intersection3.h | 4 ++-- vcg/space/tetra3.h | 4 ++-- wrap/gl/deprecated_space.h | 6 +++--- wrap/system/memory_info.h | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/vcg/complex/algorithms/create/platonic.h b/vcg/complex/algorithms/create/platonic.h index 8b4d906e..386bcff1 100644 --- a/vcg/complex/algorithms/create/platonic.h +++ b/vcg/complex/algorithms/create/platonic.h @@ -639,11 +639,11 @@ void Torus(MeshType &m, float hRingRadius, float vRingRadius, int hRingDiv=24, i template static ScalarType _SQfnC(ScalarType a, ScalarType b){ return math::Sgn(cos(a))*pow(fabs(cos(a)),b); -}; +} template static ScalarType _SQfnS(ScalarType a, ScalarType b){ return math::Sgn(sin(a))*pow(fabs(sin(a)),b); -}; +} /** diff --git a/vcg/complex/used_types.h b/vcg/complex/used_types.h index 570dd1ce..61060a2b 100755 --- a/vcg/complex/used_types.h +++ b/vcg/complex/used_types.h @@ -119,6 +119,6 @@ struct _Face : public Face<_UsedTypes>{}; struct _Tetra : public TetraSimp<_UsedTypes>{}; struct _HEdge : public HEdge<_UsedTypes>{}; -}; +} #endif // USED_TYPES_H diff --git a/vcg/space/intersection3.h b/vcg/space/intersection3.h index e6cc96ae..e0fcadd2 100644 --- a/vcg/space/intersection3.h +++ b/vcg/space/intersection3.h @@ -121,7 +121,7 @@ namespace vcg { solution_count++; } return solution_count; - }; // end of IntersectionSegmentSphere + } // end of IntersectionSegmentSphere /*! @@ -214,7 +214,7 @@ namespace vcg { penetration_detected = (witness.SquaredNorm() <= (radius*radius)); witness += center; return penetration_detected; - }; //end of IntersectionSphereTriangle + } //end of IntersectionSphereTriangle /// intersection between line and plane template diff --git a/vcg/space/tetra3.h b/vcg/space/tetra3.h index cd702b31..4f07b145 100644 --- a/vcg/space/tetra3.h +++ b/vcg/space/tetra3.h @@ -379,7 +379,7 @@ class Tetra CoordType n1 = ((p2 - p0) ^ (p1 - p0)).normalized(); return M_PI - double(acos(n0 * n1)); - }; + } template static typename TetraType::ScalarType SolidAngle(const TetraType &t, const size_t vidx) @@ -390,7 +390,7 @@ class Tetra ScalarType a2 = DihedralAngle(t, Tetra::EofV(vidx, 2)); return (a0 + a1 + a2) - M_PI; - }; + } template static typename TetraType::ScalarType AspectRatio(const TetraType &t) diff --git a/wrap/gl/deprecated_space.h b/wrap/gl/deprecated_space.h index 563032cc..7478b859 100644 --- a/wrap/gl/deprecated_space.h +++ b/wrap/gl/deprecated_space.h @@ -152,7 +152,7 @@ namespace vcg { glVertex3f((float)b.min[0],(float)b.max[1],(float)b.max[2]); glEnd(); glPopAttrib(); -}; +} template /// Funzione di utilita' per la visualizzazione in OpenGL (flat shaded) inline void glBoxFlat(Box3 const & b) @@ -190,7 +190,7 @@ inline void glBoxFlat(Box3 const & b) glVertex3f(b.min[0], b.min[1], b.max[2]); glEnd(); glPopAttrib(); -}; +} template @@ -228,7 +228,7 @@ inline void glBoxClip(const Box3 & b) glEnd(); glPopAttrib(); -}; +} template inline void glPlane3( Plane3 p, Point3 c, T size ) { Point3 w = p.Direction(); diff --git a/wrap/system/memory_info.h b/wrap/system/memory_info.h index 517f49e7..884ccc31 100644 --- a/wrap/system/memory_info.h +++ b/wrap/system/memory_info.h @@ -112,6 +112,6 @@ namespace vcg return (_currentfreememory >= mem); } }; -}; +} -#endif \ No newline at end of file +#endif From b2727b1394fc242079ca819d1858ad4de774d662 Mon Sep 17 00:00:00 2001 From: Luigi Malomo Date: Fri, 25 Jun 2021 19:29:46 +0200 Subject: [PATCH 027/117] warnings fixed --- vcg/complex/append.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vcg/complex/append.h b/vcg/complex/append.h index 2d342038..1f064611 100644 --- a/vcg/complex/append.h +++ b/vcg/complex/append.h @@ -410,7 +410,7 @@ static void MeshAppendConst( if(adjFlag) ImportVertexAdj(ml,mr,vl,v,remap); if (vertTexFlag){ - if (v.T().n() < mappingTextures.size()) { + if (size_t(v.T().n()) < mappingTextures.size()) { //standard case: the texture is contained in the mesh vl.T().n() = mappingTextures[v.T().n()]; } @@ -452,7 +452,7 @@ static void MeshAppendConst( fl.ImportData(f); if(wedgeTexFlag) { for(int i = 0; i < fl.VN(); ++i){ - if (f.WT(i).n() < mappingTextures.size()){ + if (size_t(f.WT(i).n()) < mappingTextures.size()){ //standard case: the texture is contained in the mesh fl.WT(i).n() = mappingTextures[f.WT(i).n()]; } From 094918662bb7819332f2d2b3f7986a7ec62ecdf7 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Mon, 5 Jul 2021 13:02:13 +0200 Subject: [PATCH 028/117] fix append texcoords --- vcg/complex/append.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/vcg/complex/append.h b/vcg/complex/append.h index 1f064611..bba38581 100644 --- a/vcg/complex/append.h +++ b/vcg/complex/append.h @@ -400,8 +400,10 @@ static void MeshAppendConst( // phase 2. // copy data from mr to its corresponding elements in ml and adjacencies + //vtexcoords - can copy only if they are enabled both on l and r + bool vertTexFlag = HasPerVertexTexCoord(ml) && HasPerVertexTexCoord(mr); + // vertex - bool vertTexFlag = HasPerVertexTexCoord(mr); ForEachVertex(mr, [&](const VertexRight& v) { if(!selected || v.IsS()){ @@ -437,8 +439,10 @@ static void MeshAppendConst( } }); + //ftexcoords - can copy only if they are enabled both on l and r + bool wedgeTexFlag = HasPerWedgeTexCoord(ml) && HasPerWedgeTexCoord(mr); + // face - bool wedgeTexFlag = HasPerWedgeTexCoord(mr); ForEachFace(mr, [&](const FaceRight& f) { if(!selected || f.IsS()) From 0f320aa6710d60e2940432d07757ef91d835e19c Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Tue, 6 Jul 2021 16:43:22 +0200 Subject: [PATCH 029/117] fix off polygon export --- vcg/complex/algorithms/polygon_support.h | 7 +++++-- wrap/io_trimesh/export_off.h | 9 ++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/vcg/complex/algorithms/polygon_support.h b/vcg/complex/algorithms/polygon_support.h index bce0d219..801a35bb 100644 --- a/vcg/complex/algorithms/polygon_support.h +++ b/vcg/complex/algorithms/polygon_support.h @@ -24,6 +24,9 @@ #ifndef __VCGLIB_POLYGON_SUPPORT #define __VCGLIB_POLYGON_SUPPORT +#include +#include +#include #include #include @@ -141,8 +144,8 @@ namespace tri { { std::vector vs;// vertices of the polygon ExtractPolygon(&*tfi,vs); - if (vs.size() > 3) - std::reverse(vs.begin(), vs.end()); + if (vs.size() > 3) + std::reverse(vs.begin(), vs.end()); //now vs contains all the vertices of the polygon (still in the trimesh) if (vs.size()==0)continue; typename PolyMeshType::FaceIterator pfi = tri::Allocator::AddFaces(pm,1); diff --git a/wrap/io_trimesh/export_off.h b/wrap/io_trimesh/export_off.h index 3a9fec97..d4b8435b 100644 --- a/wrap/io_trimesh/export_off.h +++ b/wrap/io_trimesh/export_off.h @@ -104,10 +104,17 @@ public: tri::UpdateFlags::FaceClearV(m); for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi) if (!fi->IsD()) if (!fi->IsV()) { vcg::tri::PolygonSupport::ExtractPolygon(&*fi,polygon); + //not sure why this std::reverse is needed. ExtractPolygon is used in + //many other functions, and nobody complained. however, this list is + //clockwise wrt fi normal. + std::reverse(polygon.begin(), polygon.end()); if(!polygon.empty()) { fprintf(fpout,"%d ", int(polygon.size()) ); - for (size_t i=0; iFlags() ); + for (size_t i=0; iC()[0],fi->C()[1],fi->C()[2] ); fprintf(fpout,"\n"); } } From a282947a724a9aa251f80b57a01b65d62eef5777 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Wed, 7 Jul 2021 16:45:15 +0200 Subject: [PATCH 030/117] get birth faces indices in ImportFromPolyMesh function --- vcg/complex/algorithms/polygon_support.h | 91 ++++++++++++++---------- 1 file changed, 54 insertions(+), 37 deletions(-) diff --git a/vcg/complex/algorithms/polygon_support.h b/vcg/complex/algorithms/polygon_support.h index 801a35bb..84429259 100644 --- a/vcg/complex/algorithms/polygon_support.h +++ b/vcg/complex/algorithms/polygon_support.h @@ -74,46 +74,63 @@ namespace tri { } } - /** - Import a trianglemesh from a polygon mesh - **/ - static void ImportFromPolyMesh(TriMeshType & tm, PolyMeshType & pm) - { - tri::RequirePolygonalMesh(pm); - std::vector points; + /** + * @brief Import a trianglemesh from a polygon mesh + * @param tm: output triangle mesh + * @param pm: input polygonal mesh + * @param birthFaces: a mapping that tells, for each face of the triangle mesh, + * which one is its birth face in the polygonal mesh. + */ + static void ImportFromPolyMesh(TriMeshType& tm, PolyMeshType& pm, std::vector& birthFaces) + { + birthFaces.clear(); + birthFaces.reserve(pm.FN()); //at least the same face number of the polymesh + tri::RequirePolygonalMesh(pm); + std::vector points; - // the vertices are the same, simply import them - PolyVertexIterator vi; - TriVertexIterator tvi = Allocator::AddVertices(tm,pm.vert.size()); - int cnt = 0; - for(tvi = tm.vert.begin(),vi = pm.vert.begin(); tvi != tm.vert.end(); ++tvi,++vi,++cnt) - if(!(*vi).IsD()) (*tvi).ImportData(*vi); else tri::Allocator::DeleteVertex(tm,(*tvi)); + // the vertices are the same, simply import them + PolyVertexIterator vi; + TriVertexIterator tvi = Allocator::AddVertices(tm,pm.vert.size()); + int cnt = 0; + for(tvi = tm.vert.begin(),vi = pm.vert.begin(); tvi != tm.vert.end(); ++tvi,++vi,++cnt) + if(!(*vi).IsD()) (*tvi).ImportData(*vi); else tri::Allocator::DeleteVertex(tm,(*tvi)); - for(PolyFaceIterator fi = pm.face.begin(); fi != pm.face.end(); ++fi) - { - if(!((*fi).IsD())){ - points.clear(); - for(int i = 0; i < (*fi).VN(); ++i) { - typename PolyMeshType::VertexType * v = (*fi).V(i); - points.push_back(v->P()); - } - std::vector faces; - TessellatePlanarPolygon3(points,faces); - for(size_t i = 0; i::AddFace(tm, - tri::Index(pm,(*fi).V( faces[i+0] )), - tri::Index(pm,(*fi).V( faces[i+1] )), - tri::Index(pm,(*fi).V( faces[i+2] )) ); + for(PolyFaceIterator fi = pm.face.begin(); fi != pm.face.end(); ++fi) + { + if(!((*fi).IsD())){ + points.clear(); + for(int i = 0; i < (*fi).VN(); ++i) { + typename PolyMeshType::VertexType * v = (*fi).V(i); + points.push_back(v->P()); + } + std::vector faces; + TessellatePlanarPolygon3(points,faces); - tfi->ImportData(*fi); - // set the F flags - if( (faces[i ]+1)%points.size() != size_t(faces[i+1])) (*tfi).SetF(0); - if( (faces[i+1]+1)%points.size() != size_t(faces[i+2])) (*tfi).SetF(1); - if( (faces[i+2]+1)%points.size() != size_t(faces[i ])) (*tfi).SetF(2); - } - } - } - } + //all the faces we add in tm have as a birth face fi + birthFaces.insert(birthFaces.end(), faces.size()/3, tri::Index(pm, *fi)); + + for(size_t i = 0; i::AddFace( + tm, + tri::Index(pm,(*fi).V( faces[i+0] )), + tri::Index(pm,(*fi).V( faces[i+1] )), + tri::Index(pm,(*fi).V( faces[i+2] )) ); + + tfi->ImportData(*fi); + // set the F flags + if( (faces[i ]+1)%points.size() != size_t(faces[i+1])) (*tfi).SetF(0); + if( (faces[i+1]+1)%points.size() != size_t(faces[i+2])) (*tfi).SetF(1); + if( (faces[i+2]+1)%points.size() != size_t(faces[i ])) (*tfi).SetF(2); + } + } + } + } + + static void ImportFromPolyMesh(TriMeshType & tm, PolyMeshType & pm) + { + std::vector dummyVector; + ImportFromPolyMesh(tm, pm, dummyVector); + } /** From 735f93c256f960aa50ce3a0559c10b8eb1f2782a Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Thu, 8 Jul 2021 12:56:06 +0200 Subject: [PATCH 031/117] fix load obj texture filename when has any option --- wrap/io_trimesh/import_obj.h | 260 +++++++++++++++++------------------ 1 file changed, 130 insertions(+), 130 deletions(-) diff --git a/wrap/io_trimesh/import_obj.h b/wrap/io_trimesh/import_obj.h index 66ce8526..0a3a6347 100644 --- a/wrap/io_trimesh/import_obj.h +++ b/wrap/io_trimesh/import_obj.h @@ -960,136 +960,136 @@ public: return ret; } - static bool LoadMaterials(const char * filename, std::vector &materials, std::vector &textures) - { - // assumes we are in the right directory - - std::ifstream stream(filename); - if (stream.fail()) - return false; - - std::vector< std::string > tokens; - std::string line; - std::string header; - - materials.clear(); - Material currentMaterial; - - // Fill in some default values for the material - currentMaterial.index = (unsigned int)(-1); - currentMaterial.Ka = Point3f(0.2, 0.2, 0.2); - currentMaterial.Kd = Point3f(1, 1, 1); - currentMaterial.Ks = Point3f(1, 1, 1); - currentMaterial.Tr = 1; - currentMaterial.Ns = 0; - currentMaterial.illum = 2; - - bool first = true; - while (!stream.eof()) - { - tokens.clear(); - TokenizeNextLine(stream, tokens, line, 0); - - if (tokens.size() > 0) - { - header.clear(); - header = tokens[0]; - - if (header.compare("newmtl")==0) - { - if (!first) - { - materials.push_back(currentMaterial); - currentMaterial = Material(); - currentMaterial.index = (unsigned int)(-1); - } - else - first = false; - //strcpy(currentMaterial.name, tokens[1].c_str()); - if(tokens.size() < 2) - return false; - else if (tokens.size() == 2) - currentMaterial.materialName = tokens[1]; //play it safe - else - currentMaterial.materialName = line.substr(7); //space in the name, get everything after "newmtl " - } - else if (header.compare("Ka")==0) - { - if (tokens.size() < 4) return false; - currentMaterial.Ka = Point3fFrom3Tokens(tokens,1); - } - else if (header.compare("Kd")==0) - { - if (tokens.size() < 4) return false; - currentMaterial.Kd = Point3fFrom3Tokens(tokens,1); - } - else if (header.compare("Ks")==0) - { - if (tokens.size() < 4) return false; - currentMaterial.Ks = Point3fFrom3Tokens(tokens,1); - } - else if ( (header.compare("d")==0) || - (header.compare("Tr")==0) ) // alpha - { - if (tokens.size() < 2) return false; - currentMaterial.Tr = (float) atof(tokens[1].c_str()); - } - else if (header.compare("Ns")==0) // shininess - { - if (tokens.size() < 2) return false; - currentMaterial.Ns = float(atoi(tokens[1].c_str())); - } - else if (header.compare("illum")==0) // specular illumination on/off - { - if (tokens.size() < 2) return false; - currentMaterial.illum = atoi(tokens[1].c_str());; - } - else if(header.compare("map_Kd")==0) // texture name - { - std::string textureName; - if (tokens.size() < 2) - return false; - else if (tokens.size() == 2) - textureName = tokens[1]; //play it safe - else - textureName = line.substr(7); //get everything after "map_Kd " - - currentMaterial.map_Kd=textureName; - - // adding texture name into textures vector (if not already present) - // avoid adding the same name twice - auto it = std::find(textures.begin(), textures.end(), textureName); - if(it==textures.end()) { - currentMaterial.index = textures.size(); - textures.push_back(textureName); - } else { - currentMaterial.index = std::distance(textures.begin(),it); - } - } - // we simply ignore other situations - } - } - materials.push_back(currentMaterial); // add last read material - - stream.close(); - // Sometimes some materials have texture and no texture - // in this case for sake of uniformity we just use the first texture. - if(!textures.empty()) - { - for(size_t i=0;i &materials, std::vector &textures) + { + // assumes we are in the right directory + + std::ifstream stream(filename); + if (stream.fail()) + return false; + + std::vector< std::string > tokens; + std::string line; + std::string header; + + materials.clear(); + Material currentMaterial; + + // Fill in some default values for the material + currentMaterial.index = (unsigned int)(-1); + currentMaterial.Ka = Point3f(0.2, 0.2, 0.2); + currentMaterial.Kd = Point3f(1, 1, 1); + currentMaterial.Ks = Point3f(1, 1, 1); + currentMaterial.Tr = 1; + currentMaterial.Ns = 0; + currentMaterial.illum = 2; + + bool first = true; + while (!stream.eof()) + { + tokens.clear(); + TokenizeNextLine(stream, tokens, line, 0); + + if (tokens.size() > 0) + { + header.clear(); + header = tokens[0]; + + if (header.compare("newmtl")==0) + { + if (!first) + { + materials.push_back(currentMaterial); + currentMaterial = Material(); + currentMaterial.index = (unsigned int)(-1); + } + else + first = false; + //strcpy(currentMaterial.name, tokens[1].c_str()); + if(tokens.size() < 2) + return false; + else if (tokens.size() == 2) + currentMaterial.materialName = tokens[1]; //play it safe + else + currentMaterial.materialName = line.substr(7); //space in the name, get everything after "newmtl " + } + else if (header.compare("Ka")==0) + { + if (tokens.size() < 4) return false; + currentMaterial.Ka = Point3fFrom3Tokens(tokens,1); + } + else if (header.compare("Kd")==0) + { + if (tokens.size() < 4) return false; + currentMaterial.Kd = Point3fFrom3Tokens(tokens,1); + } + else if (header.compare("Ks")==0) + { + if (tokens.size() < 4) return false; + currentMaterial.Ks = Point3fFrom3Tokens(tokens,1); + } + else if ( (header.compare("d")==0) || + (header.compare("Tr")==0) ) // alpha + { + if (tokens.size() < 2) return false; + currentMaterial.Tr = (float) atof(tokens[1].c_str()); + } + else if (header.compare("Ns")==0) // shininess + { + if (tokens.size() < 2) return false; + currentMaterial.Ns = float(atoi(tokens[1].c_str())); + } + else if (header.compare("illum")==0) // specular illumination on/off + { + if (tokens.size() < 2) return false; + currentMaterial.illum = atoi(tokens[1].c_str());; + } + else if(header.compare("map_Kd")==0) // texture name + { + std::string textureName; + if (tokens.size() < 2) + return false; + else { + //the tex name is the last one (after any option) + textureName = tokens[tokens.size()-1]; + } + + currentMaterial.map_Kd=textureName; + + // adding texture name into textures vector (if not already present) + // avoid adding the same name twice + auto it = std::find(textures.begin(), textures.end(), textureName); + if(it==textures.end()) { + currentMaterial.index = textures.size(); + textures.push_back(textureName); + } else { + currentMaterial.index = std::distance(textures.begin(),it); + } + } + // we simply ignore other situations + } + } + materials.push_back(currentMaterial); // add last read material + + stream.close(); + // Sometimes some materials have texture and no texture + // in this case for sake of uniformity we just use the first texture. + if(!textures.empty()) + { + for(size_t i=0;i Date: Fri, 9 Jul 2021 12:23:05 +0200 Subject: [PATCH 032/117] TriMesh virtual destructor and fix TriMesh clean --- vcg/complex/base.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/vcg/complex/base.h b/vcg/complex/base.h index 88de7028..2656a318 100644 --- a/vcg/complex/base.h +++ b/vcg/complex/base.h @@ -443,7 +443,7 @@ public: } /// destructor - ~TriMesh() + virtual ~TriMesh() { // ClearAttributes(); Clear(); @@ -481,13 +481,14 @@ public: face.clear(); edge.clear(); tetra.clear(); - // textures.clear(); - // normalmaps.clear(); + textures.clear(); + normalmaps.clear(); vn = 0; en = 0; fn = 0; hn = 0; tn = 0; + attrn = 0; imark = 0; C()=Color4b::Gray; } From cfe0511f35a994967ac19501484b47b6d05b0fdc Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Tue, 13 Jul 2021 12:36:04 +0200 Subject: [PATCH 033/117] const getFovFromFocal in shot.h --- vcg/math/shot.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vcg/math/shot.h b/vcg/math/shot.h index 0eeda9cf..6ab6def0 100644 --- a/vcg/math/shot.h +++ b/vcg/math/shot.h @@ -127,7 +127,7 @@ public: void SetViewPoint(const vcg::Point3 & viewpoint); /// GET fov from focal - float GetFovFromFocal(); + float GetFovFromFocal() const; /// look at (point+up) void LookAt(const vcg::Point3 & point,const vcg::Point3 & up); @@ -256,7 +256,7 @@ void Shot::SetViewPoint(const vcg::Point3 & viewpoint) /// GET fov from focal template -float Shot::GetFovFromFocal() +float Shot::GetFovFromFocal() const { double viewportYMm= Intrinsics.PixelSizeMm[1]* Intrinsics.ViewportPx[1]; return 2*(vcg::math::ToDeg(atanf(viewportYMm/(2*Intrinsics.FocalMm)))); From f1530c585b953b05869b42de3bf3a1b7918a284b Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Tue, 13 Jul 2021 16:46:02 +0200 Subject: [PATCH 034/117] wrap/gl camera and shot const correctness --- wrap/gl/camera.h | 30 +++++++++++++++--------------- wrap/gl/shot.h | 8 ++++---- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/wrap/gl/camera.h b/wrap/gl/camera.h index a72d15d4..debf7252 100644 --- a/wrap/gl/camera.h +++ b/wrap/gl/camera.h @@ -139,35 +139,35 @@ static void SetGLIsometricProj(float x1, float x2, float y1, float y2, float z1, } /// get OpenGL-like frustum from a vcg camera (intrinsics) -static void GetFrustum(vcg::Camera & intrinsics, S & sx,S & dx,S & bt,S & tp,S & f) +static void GetFrustum(const vcg::Camera & intrinsics, S & sx,S & dx,S & bt,S & tp,S & f) { intrinsics.GetFrustum(sx,dx,bt,tp,f); } /// set the OpenGL PROJECTION matrix to match the camera (intrinsics). requires near and far plane -static void TransformGL(vcg::Camera & camera, S nearDist, S farDist ) +static void TransformGL(const vcg::Camera & camera, S nearDist, S farDist ) { S sx,dx,bt,tp,nr; camera.GetFrustum(sx,dx,bt,tp,nr); - if(camera.cameraType == CameraType::PERSPECTIVE) { - S ratio = nearDist/nr; - sx *= ratio; - dx *= ratio; - bt *= ratio; - tp *= ratio; - } + if(camera.cameraType == CameraType::PERSPECTIVE) { + S ratio = nearDist/nr; + sx *= ratio; + dx *= ratio; + bt *= ratio; + tp *= ratio; + } assert(glGetError()==0); - switch(camera.cameraType) + switch(camera.cameraType) { - case CameraType::PERSPECTIVE: glFrustum(sx,dx,bt,tp,nearDist,farDist); break; - case CameraType::ORTHO: glOrtho(sx,dx,bt,tp,nearDist,farDist); break; - case CameraType::ISOMETRIC: SetGLIsometricProj(sx,dx,bt,tp,nearDist,farDist); break; - case CameraType::CAVALIERI: SetGLCavalieriProj(sx,dx,bt,tp,nearDist,farDist); break; + case CameraType::PERSPECTIVE: glFrustum(sx,dx,bt,tp,nearDist,farDist); break; + case CameraType::ORTHO: glOrtho(sx,dx,bt,tp,nearDist,farDist); break; + case CameraType::ISOMETRIC: SetGLIsometricProj(sx,dx,bt,tp,nearDist,farDist); break; + case CameraType::CAVALIERI: SetGLCavalieriProj(sx,dx,bt,tp,nearDist,farDist); break; } - + assert(glGetError()==0); }; diff --git a/wrap/gl/shot.h b/wrap/gl/shot.h index b175c3d6..4f4baade 100644 --- a/wrap/gl/shot.h +++ b/wrap/gl/shot.h @@ -95,13 +95,13 @@ struct GlShot { typedef GlCamera GlCameraType; /// returns the OpenGL 4x4 MODELVIEW matrix that describes the shot position and orientation (extrinsics) -static void MatrixGL(ShotType & shot,vcg::Matrix44 & m) +static void MatrixGL(const ShotType & shot,vcg::Matrix44 & m) { m = shot.GetWorldToExtrinsicsMatrix(); } /// set the OpenGL MODELVIEW matrix to match the shot (extrinsics) -static void TransformGL(vcg::Shot & shot) +static void TransformGL(const vcg::Shot & shot) { vcg::Matrix44 m; MatrixGL(shot,m); @@ -109,7 +109,7 @@ static void TransformGL(vcg::Shot & shot) } /// set the OpenGL PROJECTION and MODELVIEW matrix to match camera+shot. requires near and far plane -static void SetView(vcg::Shot & shot, ScalarType nearDist, ScalarType farDist) +static void SetView(const vcg::Shot & shot, ScalarType nearDist, ScalarType farDist) { assert(glGetError() == 0); glMatrixMode(GL_PROJECTION); @@ -170,7 +170,7 @@ static ScalarType GetFarPlane(vcg::Shot & shot, vcg::Box3 & shot, vcg::Box3 bbox, ScalarType &nr, ScalarType &fr) +static void GetNearFarPlanes(const vcg::Shot & shot, vcg::Box3 bbox, ScalarType &nr, ScalarType &fr) { vcg::Point3 zaxis = shot.Axis(2); ScalarType offset = zaxis * shot.GetViewPoint(); From bc07a00def027222f6a78ddb7e95dc964c583e1c Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Thu, 15 Jul 2021 18:52:45 +0200 Subject: [PATCH 035/117] bugfix on edge rendering bo manager --- ..._mesh_attributes_multi_viewer_bo_manager.h | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/wrap/gl/gl_mesh_attributes_multi_viewer_bo_manager.h b/wrap/gl/gl_mesh_attributes_multi_viewer_bo_manager.h index 30feb0ef..e0fd053e 100644 --- a/wrap/gl/gl_mesh_attributes_multi_viewer_bo_manager.h +++ b/wrap/gl/gl_mesh_attributes_multi_viewer_bo_manager.h @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include @@ -1158,25 +1158,27 @@ namespace vcg triangles += cit->second - cit->first + 1; } - if ((attributestobeupdated[INT_ATT_NAMES::ATT_EDGEINDICES]) && (_edge.size() > 0)) - { - for (typename std::vector::iterator it = _edge.begin(); it != _edge.end(); ++it) - { - it->_v[0] = vpatlas[it->_v[0]]; - it->_v[1] = vpatlas[it->_v[1]]; - } - - GLBufferObject* buffobj = _bo[INT_ATT_NAMES::ATT_EDGEINDICES]; - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffobj->_bohandle); - glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, buffobj->_components * buffobj->getSizeOfGLType() * _edge.size(), &_edge[0]); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - } - if (attributestobeupdated[INT_ATT_NAMES::ATT_WEDGETEXTURE] || attributestobeupdated[INT_ATT_NAMES::ATT_VERTTEXTURE]) _texindnumtriangles[t] = std::make_pair(mit->first, triangles); ++t; } + if ((attributestobeupdated[INT_ATT_NAMES::ATT_EDGEINDICES]) && (_edge.size() > 0)) + { + unsigned int i = 0; + for (EdgeVertInd& e : _edge) + { + e._v[0] = vpatlas[e._v[0]]; + e._v[1] = vpatlas[e._v[1]]; + ++i; + } + + GLBufferObject* buffobj = _bo[INT_ATT_NAMES::ATT_EDGEINDICES]; + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffobj->_bohandle); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, buffobj->_components * buffobj->getSizeOfGLType() * _edge.size(), &_edge[0]); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } + //return (k != tn) // throw MeshLabException("Mesh has not been properly partitioned"); return true; From eca8c51255118cd729caddd51d2c979e0a2b4282 Mon Sep 17 00:00:00 2001 From: Luigi Malomo Date: Mon, 16 Aug 2021 17:36:01 +0200 Subject: [PATCH 036/117] another const access fix --- vcg/simplex/edge/component.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/vcg/simplex/edge/component.h b/vcg/simplex/edge/component.h index 4e922ae3..8c27bcec 100644 --- a/vcg/simplex/edge/component.h +++ b/vcg/simplex/edge/component.h @@ -128,9 +128,10 @@ public: inline typename T::VertexType * const & V( const int j ) const { assert(j>=0 && j<2); return v[j]; } inline typename T::VertexType * cV( const int j ) const { assert(j>=0 && j<2); return v[j]; } - // Shortcut per accedere ai punti delle facce - inline CoordType & P( const int j ) { assert(j>=0 && j<2); return v[j]->P(); } - inline const CoordType &cP( const int j ) const { assert(j>=0 && j<2); return v[j]->P(); } + /// Shortcuts to access points + inline CoordType & P( const int j ) { assert(j>=0 && j<2); return v[j]->P();} + inline const CoordType & P( const int j ) const { assert(j>=0 && j<2); return v[j]->P();} + inline const CoordType & cP( const int j ) const { assert(j>=0 && j<2); return v[j]->P();} /** Return the pointer to the ((j+1)%3)-th vertex of the face. @param j Index of the face vertex. @@ -142,7 +143,7 @@ public: inline const typename T::VertexType * const & cV0( const int j ) const { return cV(j);} inline const typename T::VertexType * const & cV1( const int j ) const { return cV((j+1)%2);} - /// Shortcut per accedere ai punti delle facce + /// Shortcuts to access points inline CoordType & P0( const int j ) { return V(j)->P();} inline CoordType & P1( const int j ) { return V((j+1)%2)->P();} inline const CoordType & P0( const int j ) const { return V(j)->P();} From 95b376b64829639bbff1573cccb4f01b7755819b Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Mon, 23 Aug 2021 11:07:40 +0200 Subject: [PATCH 037/117] apply #19, #78, #84, #157, #159 --- README.md | 36 +++++++++---------- docs/Doxygen/basic_concepts.dxy | 25 +++++++------ .../algorithms/parametrization/uv_utils.h | 17 ++++----- wrap/gl/camera.h | 3 -- 4 files changed, 39 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index d98ee6ec..28469735 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,37 @@ -The **_Visualization and Computer Graphics Library_** (VCGlib for short) is a open source, portable, C++, templated, no dependency, library for manipulation, processing, cleaning, simplifying triangle meshes. +The **_Visualization and Computer Graphics Library_** (VCGlib for short) is an open source, portable, and templated library written in C++, with no external dependencies, for manipulation, processing, cleaning, and simplifying triangle meshes. ![BuildExamplesLinux](https://github.com/cnr-isti-vclab/vcglib/workflows/BuildExamplesLinux/badge.svg) ![BuildExamplesMacOS](https://github.com/cnr-isti-vclab/vcglib/workflows/BuildExamplesMacOS/badge.svg) ![BuildExamplesWindows](https://github.com/cnr-isti-vclab/vcglib/workflows/BuildExamplesWindows/badge.svg) -The library, composed by more than 100k lines of code, is released under the GPL license, and it is the base of most of the software tools of the [Visual Computing Lab](http://vcg.isti.cnr.it) of the Italian National Research Council Institute ISTI, like MeshLab, metro and many others. +The library, composed by more than 100k lines of code, is released under the GPL license, and it is the base of most of the software tools of the [Visual Computing Lab](http://vcg.isti.cnr.it) of the Italian National Research Council Institute - ISTI, like [MeshLab](http://www.meshlab.net/), [Metro](http://vcg.isti.cnr.it/vcglib/metro.html) and many others. -The VCG library is tailored to mostly manage triangular meshes: The library is fairly large and offers many state of the art functionalities for processing meshes, like: +The VCG library is tailored to mostly manage triangular meshes: The library is fairly large and offers many state-of-the-art capabilities for processing meshes, such as: -- high quality quadric-error edge-collapse based simplfication, -- efficient spatial query structures (uniform grids, hashed grids, kdtree, ...) , -- advanced smoothing and fairing algorithms, -- computation of curvature, -- optimization of texture coordinates, -- Hausdorff distance computation, -- geodesic paths, -- mesh repairing capabilities, -- isosurface extraction and advancing front meshing algorithms, -- Poisson Disk sampling and other tools to sample point distributions over meshes, +- high quality quadric-error edge-collapse based simplfication +- efficient spatial query structures (uniform grids, hashed grids, kdtree, etc) +- advanced smoothing and fairing algorithms +- computation of curvature +- optimization of texture coordinates +- Hausdorff distance computation +- geodesic paths +- mesh repairing capabilities +- isosurface extraction and advancing front meshing algorithms +- Poisson Disk sampling and other tools to sample point distributions over meshes - subdivision surfaces ## Notable Applications -A number of applications have been developed using the vcglib: +A number of applications have been developed using the VCGlib: -- MeshLab: the renowed open source mesh processing is based on this library. +- MeshLab: the renowed open source mesh processing software - Metro, the tool for measuring differences between meshes - The first high quality out-of-core mesh simplifier that was used by the Stanford Digital Michelangelo project to process their huge 3D scanned models. ## Contacts -For any info about licensing (portion of) the library please contact us: -Paolo Cignoni (p.cignoni@isti.cnr.it) +For any info about licensing (portions of) the library please contact us: +Paolo Cignoni (p.cignoni@isti.cnr.it) Visual Computing Lab of the Italian National Research Council - ISTI -In case of bugs please report them [here](https://github.com/cnr-isti-vclab/vcglib/issues) . +In case of bugs please report them [here](https://github.com/cnr-isti-vclab/vcglib/issues). diff --git a/docs/Doxygen/basic_concepts.dxy b/docs/Doxygen/basic_concepts.dxy index b0ab1ff8..5514636e 100644 --- a/docs/Doxygen/basic_concepts.dxy +++ b/docs/Doxygen/basic_concepts.dxy @@ -28,13 +28,13 @@ The face, the edge and the vertex type are the crucial bits to understand in ord \until Qualityf \c vcg::Vertex is the VCG base class for a vertex. -\c vcg::UsedTypes declares which are the types invoved in the definition of the mesh. It is a mapping between the names of your entity types (MyVertex,MyEdge,MyFace... and the role they play in the mesh definition). The mapping is established passing the template parameters with the syntax +\c vcg::UsedTypes declares which are the types involved in the definition of the mesh. It is a mapping between the names of your entity types (MyVertex,MyEdge,MyFace... and the role they play in the mesh definition). The mapping is established passing the template parameters with the syntax It can be annoying when you see it but it is useful that every entity involved knows the type of the others and this is the way VCG Lib does it. As you can see the three definitions of MyVertex0,1,2 differ for the remaining template parameters (the components). These specify which values will be stored with the vertex type: - MyVertex0 is a type storing coordinates as a triple of doubles and normal as a triple of floats, - MyVertex1 also store a color value specified as 4 bytes - MyVertex2 store a long list of different components. -Many other compenents are implemented in the library for the simplexes, the complete list can be found +Many other components are implemented in the library for the simplexes, the complete list can be found in the \ref VertexComponentGroup, \ref EdgeComponentGroup and \ref FaceComponentGroup pages. You can place any combination of them as a template parameters of your vertex/edge/face type (note that order is rather unimportant). Now we have all it takes for a working definition of MyMesh type: @@ -54,15 +54,15 @@ One more comment: \c vcg::face::VertexRef is an attribute that stores 3 pointers How to create a mesh -------------------- -Once you declared your mesh type, you may want to instance an object and to fill it with vertices and triangles. The typical approach is just to open some file like in the above example. It may cross your mind that you could just make some push_back on the vertexes and faces container (data member vert and face of class vcg::tri::Trimesh). In fact this is the wrong way since there can be side effects by adding element to a container. We describe this issue and the correct way of adding mesh element in the \ref allocation page. +Once you declared your mesh type, you may want to instance an object and to fill it with vertices and triangles. The typical approach is just to open some file like in the above example. It may cross your mind that you could just make some push_back on the vertexes and faces container (data member vert and face of class vcg::tri::Trimesh). In fact this is the wrong way since there can be side effects by adding an element to a container. We describe this issue and the correct way of adding mesh element in the \ref allocation page. The flags of the mesh elements ----------- -Usually to each element of the mesh we associate a small bit vector containing useful single-bit information about vertices and faces. For example the deletion of vertex simply mark a the Deletion bit in thsi vector (more details on the various deletion/allocation issues in the \ref allocation page. More details on the various kind of flags that can be associated are in the \ref flags page. +Usually to each element of the mesh we associate a small bit vector containing useful single-bit information about vertices and faces. For example the deletion of vertex simply mark a the Deletion bit in this vector (more details on the various deletion/allocation issues in the \ref allocation page. More details on the various kind of flags that can be associated are in the \ref flags page. How to process a mesh ------------- -The algorithms that do something on a mesh are generally written as static member functions of a class templated on the mesh type. For example the code snipped below is part of the class UpdateNormals, which contains the several algorithms to compute the value of the normal +The algorithms that do something on a mesh are generally written as a static member functions of a templated class on the mesh type. For example the code snipped below is part of the class UpdateNormals, which contains the several algorithms to compute the value of the normal \code ... @@ -73,16 +73,16 @@ class UpdateNormals{ static void PerFace(ComputeMeshType &m) // Calculates the vertex normal. Without exploiting or touching face normals -// The normal of a vertex v is the weigthed average of the normals of the faces incident on v. +// The normal of a vertex v is the weighted average of the normals of the faces incident on v. static void PerVertex(ComputeMeshType &m) // Calculates both vertex and face normals. -// The normal of a vertex v is the weigthed average of the normals of the faces incident on v. +// The normal of a vertex v is the weighted average of the normals of the faces incident on v. static void PerVertexPerFace(ComputeMeshType &m) ... }; \endcode -This class is part of a kernel of classes with name UpdateValue that compute the value of the vertex or face attributes and that can be found altogether in the folder vcg/complex/trimesh/update. For example, the following example show how to compute the value of the normal and the mean and gaussian curvature per vertex: +This class is part of a kernel of classes with name UpdateValue that compute the value of the vertex or face attributes and that can be found altogether in the folder vcg/complex/trimesh/update. For example, the following example shows how to compute the value of the normal and the mean and gaussian curvature per vertex: \code #include @@ -92,9 +92,9 @@ This class is part of a kernel of classes with name UpdateValue that compute the #include #include -#include -#include //class UpdateNormals -#include //class UpdateCurvature +#include +#include //class UpdateNormals +#include //class UpdateCurvature class MyVertex; class MyFace; @@ -120,6 +120,5 @@ int main() } \endcode -Other than algorithms that update values of the mesh attributes, VCG Lib provides algorithms to create a mesh from another source, for example from point sets (by means of the Ball Pivoting approach) or as isosurfaces from a volumetric dataset (by means of Marching Cubes algorithm). Those algorithm can be found in vcg/complex/trimesh/create/. +Other than algorithms that update values of the mesh attributes, VCG Lib provides algorithms to create a mesh from another source, for example from point sets (by means of the Ball Pivoting approach) or as isosurfaces from a volumetric dataset (by means of Marching Cubes algorithm). Those algorithms can be found in vcg/complex/trimesh/create/. Finally, you can find algorithms for refinement (midpoint, Loop, Butterfly...), for smoothing, for closing holes and other that are not currently classified under any specific heading and that you can find under /vcg/complex/trimesh.*/ - diff --git a/vcg/complex/algorithms/parametrization/uv_utils.h b/vcg/complex/algorithms/parametrization/uv_utils.h index e93bcedf..82b2e8ec 100644 --- a/vcg/complex/algorithms/parametrization/uv_utils.h +++ b/vcg/complex/algorithms/parametrization/uv_utils.h @@ -8,7 +8,7 @@ * \ * * All rights reserved. * * * -* This program is free software; you can redistribute it and/or modify * +* This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * @@ -21,8 +21,8 @@ * * ****************************************************************************/ -#ifndef VCG_UV_UTILS -#define VCG_UV_UTILS +#ifndef VCG_COMPLEX_ALGORITHMS_PARAMETRIZATION_UV_UTILS_H +#define VCG_COMPLEX_ALGORITHMS_PARAMETRIZATION_UV_UTILS_H #include #include @@ -30,7 +30,7 @@ #include namespace vcg { -namespace tri{ +namespace tri { template class UV_Utils { @@ -44,7 +44,7 @@ class UV_Utils public: - ///calculate the area in UV space + /// calculate the area in UV space static ScalarType PerVertUVArea(MeshType &m) { FaceIterator fi; @@ -242,6 +242,7 @@ public: } } }; -} //End Namespace Tri -} // End Namespace vcg -#endif + +} // end Namespace tri +} // end Namespace vcg +#endif // VCG_COMPLEX_ALGORITHMS_PARAMETRIZATION_UV_UTILS_H diff --git a/wrap/gl/camera.h b/wrap/gl/camera.h index debf7252..b6a8dc77 100644 --- a/wrap/gl/camera.h +++ b/wrap/gl/camera.h @@ -79,9 +79,6 @@ creation // VCG #include -// opengl -#include - template struct GlCamera{ From aec8880e851a7eedc2669eb3254e52f471264d26 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Mon, 23 Aug 2021 16:24:23 +0200 Subject: [PATCH 038/117] restore deterministic poisson sampling --- vcg/complex/algorithms/point_sampling.h | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/vcg/complex/algorithms/point_sampling.h b/vcg/complex/algorithms/point_sampling.h index d5e711f8..1647e782 100644 --- a/vcg/complex/algorithms/point_sampling.h +++ b/vcg/complex/algorithms/point_sampling.h @@ -502,6 +502,18 @@ static unsigned int RandomInt(unsigned int i) return (SamplingRandomGenerator().generate(i)); } +class MarsenneTwisterURBG +{ +public: + typedef unsigned int result_type; + MarsenneTwisterURBG(result_type max) : _max(max) {} + result_type min() const {return 0;} + result_type max() const {return _max;} + result_type operator()() {return SamplingRandomGenerator().generate(_max);} +private: + result_type _max; +}; + // Returns a random number in the [0,1) real interval using the improved Marsenne-Twister method. static double RandomDouble01() { @@ -714,8 +726,9 @@ static void FillAndShuffleFacePointerVector(MeshType & m, std::vector &vertVec) @@ -726,8 +739,9 @@ static void FillAndShuffleVertexPointerVector(MeshType & m, std::vector Date: Mon, 23 Aug 2021 16:29:36 +0200 Subject: [PATCH 039/117] using ninja instead of jom for windows build examples --- .github/workflows/BuildExamplesWindows.yml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/.github/workflows/BuildExamplesWindows.yml b/.github/workflows/BuildExamplesWindows.yml index f92285cc..193024c0 100644 --- a/.github/workflows/BuildExamplesWindows.yml +++ b/.github/workflows/BuildExamplesWindows.yml @@ -9,12 +9,6 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Download Jom - run: | - Invoke-WebRequest -Uri "http://mirrors.ukfast.co.uk/sites/qt.io/official_releases/jom/jom_1_1_3.zip" -OutFile "jom_1_1_3.zip" - New-Item -Name "jom" -ItemType "directory" - Expand-Archive -Path jom_1_1_3.zip -DestinationPath .\jom - echo "$(Get-Location)\jom" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - name: Setup env variables id: envs run: | @@ -27,5 +21,5 @@ jobs: run: | mkdir build cd build - cmake -G "NMake Makefiles" -DVCG_BUILD_EXAMPLES=ON .. - jom -j4 + cmake -GNinja -DVCG_BUILD_EXAMPLES=ON .. + ninja From e3731ec7f52902f5f2fee4cda9141f50eb786c5a Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Mon, 23 Aug 2021 17:26:28 +0200 Subject: [PATCH 040/117] fix MarsenneTwisterURBG class --- vcg/complex/algorithms/point_sampling.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vcg/complex/algorithms/point_sampling.h b/vcg/complex/algorithms/point_sampling.h index 1647e782..5436042c 100644 --- a/vcg/complex/algorithms/point_sampling.h +++ b/vcg/complex/algorithms/point_sampling.h @@ -506,9 +506,9 @@ class MarsenneTwisterURBG { public: typedef unsigned int result_type; - MarsenneTwisterURBG(result_type max) : _max(max) {} - result_type min() const {return 0;} - result_type max() const {return _max;} + MarsenneTwisterURBG(result_type max){_max = max;} + static result_type min() {return 0;} + static result_type max() {return std::numeric_limits::max();} result_type operator()() {return SamplingRandomGenerator().generate(_max);} private: result_type _max; From b1c1d03215ee6968adf4ebdbab225daf933f07eb Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Mon, 23 Aug 2021 17:35:50 +0200 Subject: [PATCH 041/117] fix MarsenneTwisterURBG class --- vcg/complex/algorithms/point_sampling.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vcg/complex/algorithms/point_sampling.h b/vcg/complex/algorithms/point_sampling.h index 5436042c..1ef40d61 100644 --- a/vcg/complex/algorithms/point_sampling.h +++ b/vcg/complex/algorithms/point_sampling.h @@ -507,8 +507,8 @@ class MarsenneTwisterURBG public: typedef unsigned int result_type; MarsenneTwisterURBG(result_type max){_max = max;} - static result_type min() {return 0;} - static result_type max() {return std::numeric_limits::max();} + static constexpr result_type min() {return 0;} + static constexpr result_type max() {return std::numeric_limits::max();} result_type operator()() {return SamplingRandomGenerator().generate(_max);} private: result_type _max; From 78d98b25770e5f9f1c5bb93e15f90a0642aafab5 Mon Sep 17 00:00:00 2001 From: nico Date: Tue, 24 Aug 2021 09:26:28 +1000 Subject: [PATCH 042/117] Fixed 2 more instances of the Marsienne Twister --- vcg/complex/algorithms/point_sampling.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/vcg/complex/algorithms/point_sampling.h b/vcg/complex/algorithms/point_sampling.h index 1ef40d61..4bd163c0 100644 --- a/vcg/complex/algorithms/point_sampling.h +++ b/vcg/complex/algorithms/point_sampling.h @@ -1948,8 +1948,10 @@ static void PoissonDiskPruning(VertexSampler &ps, MeshType &montecarloMesh, InitRadiusHandleFromQuality(montecarloMesh, rH, diskRadius, pp.radiusVariance, pp.invertQuality); //unsigned int (*p_myrandom)(unsigned int) = RandomInt; - std::random_device rd; - std::mt19937 g(rd()); +// std::random_device rd; +// std::mt19937 g(rd()); +// std::shuffle(montecarloSHT.AllocatedCells.begin(),montecarloSHT.AllocatedCells.end(), g); + MarsenneTwisterURBG g(montecarloSHT.AllocatedCells.size()); std::shuffle(montecarloSHT.AllocatedCells.begin(),montecarloSHT.AllocatedCells.end(), g); int t1 = clock(); pp.pds.montecarloSampleNum = montecarloMesh.vn; @@ -2085,7 +2087,9 @@ static void HierarchicalPoissonDisk(MeshType &origMesh, VertexSampler &ps, MeshT // shuffle active cells //unsigned int (*p_myrandom)(unsigned int) = RandomInt; std::random_device rd; - std::mt19937 g(rd()); +// std::mt19937 g(rd()); +// std::shuffle(montecarloSHT.AllocatedCells.begin(),montecarloSHT.AllocatedCells.end(), g); + MarsenneTwisterURBG g(montecarloSHT.AllocatedCells.size()); std::shuffle(montecarloSHT.AllocatedCells.begin(),montecarloSHT.AllocatedCells.end(), g); // generate a sample inside C by choosing one of the contained pre-generated samples From bd05cf0932cb1b1c5721e5ba58498a3da5e1c005 Mon Sep 17 00:00:00 2001 From: nico Date: Tue, 24 Aug 2021 09:28:03 +1000 Subject: [PATCH 043/117] Checked to not collapse triangular faces in Function RemoveValence2Vertices --- vcg/complex/algorithms/polygonal_algorithms.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vcg/complex/algorithms/polygonal_algorithms.h b/vcg/complex/algorithms/polygonal_algorithms.h index 7154278c..a8988afd 100644 --- a/vcg/complex/algorithms/polygonal_algorithms.h +++ b/vcg/complex/algorithms/polygonal_algorithms.h @@ -23,8 +23,8 @@ #ifndef __VCGLIB_POLY_MESH_ALGORITHM #define __VCGLIB_POLY_MESH_ALGORITHM -#include #include +#include #include #include #include From 4e3f08e134e922d0c4b50c002f3c4ff535f0b95f Mon Sep 17 00:00:00 2001 From: nico Date: Tue, 31 Aug 2021 21:38:59 +1000 Subject: [PATCH 044/117] corrected some simple warning and avoided collapse of edges of triangular faces for polygons --- .../algorithms/parametrization/tangent_field_operators.h | 2 +- vcg/complex/algorithms/polygonal_algorithms.h | 8 ++++++++ vcg/container/simple_temporary_data.h | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/vcg/complex/algorithms/parametrization/tangent_field_operators.h b/vcg/complex/algorithms/parametrization/tangent_field_operators.h index 4dfb3963..6e2d3087 100644 --- a/vcg/complex/algorithms/parametrization/tangent_field_operators.h +++ b/vcg/complex/algorithms/parametrization/tangent_field_operators.h @@ -624,7 +624,7 @@ public: do { std::vector new_queue; - for (int i=0; iIsD()); diff --git a/vcg/complex/algorithms/polygonal_algorithms.h b/vcg/complex/algorithms/polygonal_algorithms.h index a8988afd..6d1807de 100644 --- a/vcg/complex/algorithms/polygonal_algorithms.h +++ b/vcg/complex/algorithms/polygonal_algorithms.h @@ -1181,6 +1181,14 @@ public: for (int j=0;j3)continue; + for (int j=0;j datareserve) reserve(sz); From fea0a33575356a7b00517aa45b9b06f804262827 Mon Sep 17 00:00:00 2001 From: nico Date: Tue, 31 Aug 2021 21:40:01 +1000 Subject: [PATCH 045/117] added std namespace for max function on line 281 --- vcg/complex/algorithms/mesh_to_matrix.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vcg/complex/algorithms/mesh_to_matrix.h b/vcg/complex/algorithms/mesh_to_matrix.h index c85edf8b..89ac2afd 100644 --- a/vcg/complex/algorithms/mesh_to_matrix.h +++ b/vcg/complex/algorithms/mesh_to_matrix.h @@ -278,7 +278,7 @@ public: } ScalarType maxA=0; for(int i=0;i Date: Tue, 31 Aug 2021 21:40:46 +1000 Subject: [PATCH 046/117] set to void parameters when not using Miq Field smoothing to avoid warnings --- wrap/igl/smooth_field.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/wrap/igl/smooth_field.h b/wrap/igl/smooth_field.h index bc3ad19f..9629a883 100644 --- a/wrap/igl/smooth_field.h +++ b/wrap/igl/smooth_field.h @@ -264,6 +264,14 @@ class FieldSmoother mesh.face[i].PD2()=dir2*Norm2; } #else + (void)mesh; + (void)HardI; + (void)HardD; + (void)SoftI; + (void)SoftD; + (void)SoftW; + (void)alpha_soft; + (void)Ndir; assert(0); #endif } From 02c4e32a1fa47b56788e904032d0f61f7b710b11 Mon Sep 17 00:00:00 2001 From: gabryon99 Date: Mon, 13 Sep 2021 19:29:54 +0200 Subject: [PATCH 047/117] add OccupancyGrid class --- CMakeLists.txt | 1 + vcg/complex/algorithms/occupancy_grid.h | 435 ++++++++++++++++++++++++ 2 files changed, 436 insertions(+) create mode 100644 vcg/complex/algorithms/occupancy_grid.h diff --git a/CMakeLists.txt b/CMakeLists.txt index acc67cd0..60fc296a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,6 +72,7 @@ set(VCG_HEADERS vcg/complex/algorithms/polygonal_algorithms.h vcg/complex/algorithms/inertia.h vcg/complex/algorithms/mesh_assert.h + vcg/complex/algorithms/occupancy_grid.h vcg/complex/algorithms/cut_tree.h vcg/complex/algorithms/nring.h vcg/complex/algorithms/tetra/tetfuse_collapse.h diff --git a/vcg/complex/algorithms/occupancy_grid.h b/vcg/complex/algorithms/occupancy_grid.h new file mode 100644 index 00000000..bcd6148c --- /dev/null +++ b/vcg/complex/algorithms/occupancy_grid.h @@ -0,0 +1,435 @@ +#include + +#include +#include + +#ifndef VCGLIB_OCCUPANCY_GRID_H +#define VCGLIB_OCCUPANCY_GRID_H + +#define OG_MAX_MCB_SIZE 2048 +#define OG_MESH_INFO_MAX_STAT 64 + +namespace vcg { + namespace tri { + + template + class OccupancyGrid { + + private: + + GridStaticObj G; + + int mn; + int TotalArea; + /** + * Maximum number of meshes that cross a cell + */ + int MaxCount; + + /** + * SortedVisual Arcs + */ + std::vector SVA; // SortedVirtual Arcs; + /** + * High level information for each mesh. Mapped by mesh id + */ + std::map VM; + + public: + + /** + * Class to keep for each voxel the id of the mesh passing through it. + * based on bitset + */ + class MeshCounter { + + private: + std::bitset cnt; + + public: + + static constexpr int MaxVal() { + return OG_MAX_MCB_SIZE; + } + + bool Empty() const { + return cnt.none(); + } + + void Clear() { + cnt.reset(); + } + + bool IsSet(size_t i) const { + return cnt.test(i); + } + + void Set(size_t i) { + cnt.set(i); + } + + void UnSet(size_t i) { + cnt.reset(i); + } + + size_t Count() const { + return cnt.count(); + } + + /** + * Return a vector with all the id of the meshes + */ + void Pack(std::vector &v) const { + + v.clear(); + + for (size_t i = 0; i < MeshCounter::MaxVal(); ++i) { + if (cnt.test(i) { + v.push_back(i); + } + } + } + + bool operator < (const MeshCounter &c) const { + + if (cnt==c.cnt) return false; + + size_t ii = 0; + + while (ii < MeshCounter::MaxVal()){ + if (cnt[ii]!=c.cnt[ii]) { + return cnt[ii] < c.cnt[ii]; + } + ++ii; + } + return false; + } + }; + + /** + * Class for collecting cumulative information about each mesh in the OG. + * This info are collected in the Compute() by scanning the OG after we filled it with all the meshes. + */ + class OGMeshInfo { + + public: + + int id; // the id of the mesh + int area; // number of voxels in the OG touched by this mesh + int coverage; // quanto e' ricoperta da altre mesh eccetto se stessa (eg: se ho due mesh di 1000 con overlap al 30% la covrg e' 300) + + bool used = false; + + std::vector densityDistribution; // Distribution of the of the density of the voxels touched by this mesh: + // densityDistribution[i] says how many voxel (among the ones coverd by this mesh) + // are covered by othermeshes. Sum(densityDistribution) == area; + // if densityDistribution[1] > 0 means that this mesh is the unique to cover some portion of the space. + + OGMeshInfo() { + Init(-1); + } + + void Init(int _id) { + coverage=0;area=0; id=_id; + } + + bool operator < (OGMeshInfo &o) const { + return area < o.area; + } + + static constexpr int MaxStat() { + return OG_MESH_INFO_MAX_STAT; + } + }; + + /** + * Classe con informazioni su un arco plausibile + */ + class OGArcInfo { + public: + + enum sort { + AREA, + NORM_AREA, + DEGREE + }; + + int s,t; // source and target (come indici nel gruppo corrente) + int area; // + float norm_area; + + OGArcInfo(int _s, int _t, int _area, float _n) : s{_s}, t{_t}, area{_area}, norm_area{_n} {} + OGArcInfo(int _s, int _t, int _area) s{_s}, t{_t}, area{_area} {} + + bool operator < (const OGArcInfo &p) const { + return norm_area < p.norm_area; + } + }; + + bool Init(int _mn, Box3d bb, int size) { + + // the number of meshes (including all the unused ones; eg it is the range of the possible id) + mn = _mn; + if (mn > MeshCounter::MaxVal()) return false; + + MeshCounter MC; + + MC.Clear(); + G.Create(bb,size,MC); + VM.clear(); + + return true; + } + + void Add(const char *MeshName, Matrix44d &Tr, int id) { + + AlignPair::A2Mesh M; + + vcg::tri::io::Importer::Open(M,MeshName); + vcg::tri::Clean::RemoveUnreferencedVertex(M); + + AddMesh(M,Tr,id); + } + + void AddMeshes(std::vector &names, std::vector &trv,int size) { + + Box3d bb, totalbb; + + bb.SetNull(); + totalbb.SetNull(); + + std::fprintf(stdout, "OG::AddMesh:Scanning BBoxex\n"); + + for (std::size_t i = 0; i < names.size(); ++i) { + ply::ScanBBox(names[i].c_str(),bb); + totalbb.Add(trv[i], bb); + } + + Init(names.size(),totalbb,size); + + for (std::size_t i = 0; i < names.size(); ++i) { + std::fprintf(stdout, "OG::AddMesh:Adding Mesh %i '%s'\n", i, names[i].c_str()); + Add(names[i].c_str(),trv[i],i); + } + } + + void AddMesh(MeshType &mesh, const Matrix44d &Tr, int ind) { + + Matrix44f Trf; + Trf.Import(Tr); + + for (auto vi = std::begin(M.vert); vi != std::end(M.vert); ++vi) { + + if (!(*vi).IsD()) { + G.Grid( Trf * Point3f::Construct((*vi).P()) ).Set(ind); + } + } + + VM[ind].Init(ind); + VM[ind].used = true; + } + + void RemoveMesh(int id) { + + MeshCounter *GridEnd = G.grid+G.size(); + + for (MeshCounter* ig = G.grid; ig != GridEnd; ++ig) { + ig->UnSet(id); + } + } + + /** + * This function is called after we have all the mesh to the OG + * to collect the information about the interferences between the various meshes. + */ + void Compute() { + + // Analisi della griglia + // Si deve trovare l'insieme degli archi piu'plausibili + // un arco ha "senso" in una cella se entrambe le mesh compaiono in quell'arco + // Si considera tutti gli archi possibili e si conta in quante celle ha senso un arco + + std::vector VA; // virtual arcs + VA.resize(mn * mn, 0); + + std::map, int> VAMap; + + // First Loop: + // Scan the grid and update possible arc count + for (int i = 0; i < G.siz[0]; ++i) { + + for (int j = 0; j < G.siz[1]; ++j) { + + for (int k = 0; k < G.siz[2]; ++k) { + + std::vector vv; + G.Grid(i, j, k).Pack(vv); + std::size_t meshInCell = vv.size(); + + for (std::size_t ii = 0; ii < vv.size(); ++ii) { + + OccupancyGrid::OGMeshInfo &omi_ii = VM[vv[ii]]; + + ++omi_ii.area; // compute mesh area + if (meshInCell > omi_ii.densityDistribution.size()) { + omi_ii.densityDistribution.resize(meshInCell); + } + + ++(omi_ii.densityDistribution[meshInCell - 1]); + } + + for (std::size_t ii = 0; ii < vv.size(); ++ii) { + for (std::size_t jj = ii + 1; jj < vv.size(); ++jj) { + // count intersections of all mesh pairs + ++VAMap[std::make_pair(vv[ii], vv[jj])]; + } + } + } + } + } + + // Find all the arcs, e.g. all the pair of meshes + SVA.clear(); + for (auto vi = std::begin(VAMap); vi != std::end(VAMap); ++vi) { + if (vi->second > 0) { + int m_s = vi->first.first; + int m_t = vi->first.second; + int area = vi->second; + SVA.push_back( OGArcInfo (m_s,m_t,area,float(area)/float(min(VM[m_s].area,VM[m_t].area)) )); + } + } + + // Compute Mesh Coverage + for (std::size_t i = 0; i < SVA.size(); ++i) { + VM[SVA[i].s].coverage += SVA[i].area; + VM[SVA[i].t].coverage += SVA[i].area; + } + + std::sort(std::begin(SVA), std::end(SVA)); + std::reverse(std::begin(SVA), std::end(SVA)); + } + + void ComputeUsefulMesh(FILE *elfp) { + + int mcnt = 0; + std::vector UpdArea(mn); + std::vector UpdCovg(mn); + + for (std::size_t m = 0; m < mn; ++m) { + + if (VM[m].used && VM[m].area > 0) { + mcnt++; + UpdCovg[m]=VM[m].coverage; + UpdArea[m]=VM[m].area; + } + } + + int sz = G.size(); + if (elfp) { + std::fprintf(elfp, "\n\nComputing Usefulness of Meshes of %i(on %i) meshes\n Og with %i / %i fill ratio %i max mesh per cell\n\n", mcnt, mn, TotalArea, sz, MaxCount); + std::fprintf(elfp, "\n"); + } + + int CumArea = 0; + + for (std::size_t m = 0; m < mn-1; ++m) { + + int best = max_element(std::begin(UpdArea), std::end(UpdArea)) - std::begin(UpdArea); + + CumArea += UpdArea[best]; + if (UpdCovg[best] < 0) break; + + // se era una mesh fuori del working group si salta tutto. + if (VM[best].area == 0) continue; + + if (elfp) { + fprintf(elfp, "%3i %3i %7i (%7i) %7i %5.2f %7i(%7i)\n", + m, best, UpdArea[best], VM[best].area, TotalArea - CumArea, + 100.0 - 100 * float(CumArea) / TotalArea, UpdCovg[best], VM[best].coverage); + } + + UpdArea[best] = -1; + UpdCovg[best] = -1; + + for (std::size_t i = 0; i < sz; ++i) { + + MeshCounter &mc = G.grid[i]; + + if (mc.IsSet(best)) { + + mc.UnSet(best); + + for (std::size_t j = 0; j < mn; ++j) { + if (mc.IsSet(j)) { + --UpdArea[j]; + UpdCovg[j]-=mc.Count(); + } + } + + mc.Clear(); + } + } + } + } + + void Dump(FILE *fp) { + + std::fprintf(fp, "Occupancy Grid\n"); + std::fprintf(fp, "grid of ~%i kcells: %d x %d x %d\n", G.size(), G.siz[0], G.siz[1], G.siz[2]); + std::fprintf(fp, "grid voxel size of %f %f %f\n", G.voxel[0], G.voxel[1], G.voxel[2]); + + std::fprintf(fp,"Computed %lu arcs for %i meshes\n", SVA.size(), mn); + + for (std::size_t i=0;i(8), VM[i].densityDistribution.size()); ++j) { + std::fprintf(fp," %3i ", VM[i].densityDistribution[j]); + } + + std::fprintf(fp,"\n"); + } + else { + std::fprintf(fp, "mesh %3lu ---- UNUSED\n", i); + } + } + + std::fprintf(fp, "Computed %lu Arcs :\n", SVA.size()); + + for (std::size_t i = 0; i .1; ++i) { + std::fprintf(fp, "%4i -> %4i Area:%5i NormArea:%5.3f\n", SVA[i].s, SVA[i].t, SVA[i].area, SVA[i].norm_area); + } + + std::fprintf(fp, "End OG Dump\n"); + } + + void ComputeTotalArea() { + + using uint = unsigned int; + + int ccnt = 0; + MaxCount = 0; + + int sz=G.size(); + + for (int i = 0; i < sz; ++i) + + if (!G.grid[i].Empty()) { + + ccnt++; + if (G.grid[i].Count() > static_cast(MaxCount)) { + MaxCount = G.grid[i].Count(); + } + } + + TotalArea = ccnt; + } + + }; + } +} + +#endif //VCGLIB_OCCUPANCY_GRID_H From 6f38a1adc6a23aab4c128c8f79e75bd49324810d Mon Sep 17 00:00:00 2001 From: gabryon99 Date: Mon, 13 Sep 2021 19:34:50 +0200 Subject: [PATCH 048/117] removed tri namespace from OccupancyGrid --- vcg/complex/algorithms/occupancy_grid.h | 771 ++++++++++++------------ 1 file changed, 384 insertions(+), 387 deletions(-) diff --git a/vcg/complex/algorithms/occupancy_grid.h b/vcg/complex/algorithms/occupancy_grid.h index bcd6148c..5272f946 100644 --- a/vcg/complex/algorithms/occupancy_grid.h +++ b/vcg/complex/algorithms/occupancy_grid.h @@ -10,426 +10,423 @@ #define OG_MESH_INFO_MAX_STAT 64 namespace vcg { - namespace tri { + template + class OccupancyGrid { - template - class OccupancyGrid { + private: + + GridStaticObj G; + + int mn; + int TotalArea; + /** + * Maximum number of meshes that cross a cell + */ + int MaxCount; + + /** + * SortedVisual Arcs + */ + std::vector SVA; // SortedVirtual Arcs; + /** + * High level information for each mesh. Mapped by mesh id + */ + std::map VM; + + public: + + /** + * Class to keep for each voxel the id of the mesh passing through it. + * based on bitset + */ + class MeshCounter { private: - - GridStaticObj G; - - int mn; - int TotalArea; - /** - * Maximum number of meshes that cross a cell - */ - int MaxCount; - - /** - * SortedVisual Arcs - */ - std::vector SVA; // SortedVirtual Arcs; - /** - * High level information for each mesh. Mapped by mesh id - */ - std::map VM; + std::bitset cnt; public: - /** - * Class to keep for each voxel the id of the mesh passing through it. - * based on bitset - */ - class MeshCounter { - - private: - std::bitset cnt; - - public: - - static constexpr int MaxVal() { - return OG_MAX_MCB_SIZE; - } - - bool Empty() const { - return cnt.none(); - } - - void Clear() { - cnt.reset(); - } - - bool IsSet(size_t i) const { - return cnt.test(i); - } - - void Set(size_t i) { - cnt.set(i); - } - - void UnSet(size_t i) { - cnt.reset(i); - } - - size_t Count() const { - return cnt.count(); - } - - /** - * Return a vector with all the id of the meshes - */ - void Pack(std::vector &v) const { - - v.clear(); - - for (size_t i = 0; i < MeshCounter::MaxVal(); ++i) { - if (cnt.test(i) { - v.push_back(i); - } - } - } - - bool operator < (const MeshCounter &c) const { - - if (cnt==c.cnt) return false; - - size_t ii = 0; - - while (ii < MeshCounter::MaxVal()){ - if (cnt[ii]!=c.cnt[ii]) { - return cnt[ii] < c.cnt[ii]; - } - ++ii; - } - return false; - } - }; - - /** - * Class for collecting cumulative information about each mesh in the OG. - * This info are collected in the Compute() by scanning the OG after we filled it with all the meshes. - */ - class OGMeshInfo { - - public: - - int id; // the id of the mesh - int area; // number of voxels in the OG touched by this mesh - int coverage; // quanto e' ricoperta da altre mesh eccetto se stessa (eg: se ho due mesh di 1000 con overlap al 30% la covrg e' 300) - - bool used = false; - - std::vector densityDistribution; // Distribution of the of the density of the voxels touched by this mesh: - // densityDistribution[i] says how many voxel (among the ones coverd by this mesh) - // are covered by othermeshes. Sum(densityDistribution) == area; - // if densityDistribution[1] > 0 means that this mesh is the unique to cover some portion of the space. - - OGMeshInfo() { - Init(-1); - } - - void Init(int _id) { - coverage=0;area=0; id=_id; - } - - bool operator < (OGMeshInfo &o) const { - return area < o.area; - } - - static constexpr int MaxStat() { - return OG_MESH_INFO_MAX_STAT; - } - }; - - /** - * Classe con informazioni su un arco plausibile - */ - class OGArcInfo { - public: - - enum sort { - AREA, - NORM_AREA, - DEGREE - }; - - int s,t; // source and target (come indici nel gruppo corrente) - int area; // - float norm_area; - - OGArcInfo(int _s, int _t, int _area, float _n) : s{_s}, t{_t}, area{_area}, norm_area{_n} {} - OGArcInfo(int _s, int _t, int _area) s{_s}, t{_t}, area{_area} {} - - bool operator < (const OGArcInfo &p) const { - return norm_area < p.norm_area; - } - }; - - bool Init(int _mn, Box3d bb, int size) { - - // the number of meshes (including all the unused ones; eg it is the range of the possible id) - mn = _mn; - if (mn > MeshCounter::MaxVal()) return false; - - MeshCounter MC; - - MC.Clear(); - G.Create(bb,size,MC); - VM.clear(); - - return true; + static constexpr int MaxVal() { + return OG_MAX_MCB_SIZE; } - void Add(const char *MeshName, Matrix44d &Tr, int id) { - - AlignPair::A2Mesh M; - - vcg::tri::io::Importer::Open(M,MeshName); - vcg::tri::Clean::RemoveUnreferencedVertex(M); - - AddMesh(M,Tr,id); + bool Empty() const { + return cnt.none(); } - void AddMeshes(std::vector &names, std::vector &trv,int size) { - - Box3d bb, totalbb; - - bb.SetNull(); - totalbb.SetNull(); - - std::fprintf(stdout, "OG::AddMesh:Scanning BBoxex\n"); - - for (std::size_t i = 0; i < names.size(); ++i) { - ply::ScanBBox(names[i].c_str(),bb); - totalbb.Add(trv[i], bb); - } - - Init(names.size(),totalbb,size); - - for (std::size_t i = 0; i < names.size(); ++i) { - std::fprintf(stdout, "OG::AddMesh:Adding Mesh %i '%s'\n", i, names[i].c_str()); - Add(names[i].c_str(),trv[i],i); - } + void Clear() { + cnt.reset(); } - void AddMesh(MeshType &mesh, const Matrix44d &Tr, int ind) { - - Matrix44f Trf; - Trf.Import(Tr); - - for (auto vi = std::begin(M.vert); vi != std::end(M.vert); ++vi) { - - if (!(*vi).IsD()) { - G.Grid( Trf * Point3f::Construct((*vi).P()) ).Set(ind); - } - } - - VM[ind].Init(ind); - VM[ind].used = true; + bool IsSet(size_t i) const { + return cnt.test(i); } - void RemoveMesh(int id) { + void Set(size_t i) { + cnt.set(i); + } - MeshCounter *GridEnd = G.grid+G.size(); + void UnSet(size_t i) { + cnt.reset(i); + } - for (MeshCounter* ig = G.grid; ig != GridEnd; ++ig) { - ig->UnSet(id); - } + size_t Count() const { + return cnt.count(); } /** - * This function is called after we have all the mesh to the OG - * to collect the information about the interferences between the various meshes. + * Return a vector with all the id of the meshes */ - void Compute() { + void Pack(std::vector &v) const { - // Analisi della griglia - // Si deve trovare l'insieme degli archi piu'plausibili - // un arco ha "senso" in una cella se entrambe le mesh compaiono in quell'arco - // Si considera tutti gli archi possibili e si conta in quante celle ha senso un arco + v.clear(); - std::vector VA; // virtual arcs - VA.resize(mn * mn, 0); - - std::map, int> VAMap; - - // First Loop: - // Scan the grid and update possible arc count - for (int i = 0; i < G.siz[0]; ++i) { - - for (int j = 0; j < G.siz[1]; ++j) { - - for (int k = 0; k < G.siz[2]; ++k) { - - std::vector vv; - G.Grid(i, j, k).Pack(vv); - std::size_t meshInCell = vv.size(); - - for (std::size_t ii = 0; ii < vv.size(); ++ii) { - - OccupancyGrid::OGMeshInfo &omi_ii = VM[vv[ii]]; - - ++omi_ii.area; // compute mesh area - if (meshInCell > omi_ii.densityDistribution.size()) { - omi_ii.densityDistribution.resize(meshInCell); - } - - ++(omi_ii.densityDistribution[meshInCell - 1]); - } - - for (std::size_t ii = 0; ii < vv.size(); ++ii) { - for (std::size_t jj = ii + 1; jj < vv.size(); ++jj) { - // count intersections of all mesh pairs - ++VAMap[std::make_pair(vv[ii], vv[jj])]; - } - } - } - } - } - - // Find all the arcs, e.g. all the pair of meshes - SVA.clear(); - for (auto vi = std::begin(VAMap); vi != std::end(VAMap); ++vi) { - if (vi->second > 0) { - int m_s = vi->first.first; - int m_t = vi->first.second; - int area = vi->second; - SVA.push_back( OGArcInfo (m_s,m_t,area,float(area)/float(min(VM[m_s].area,VM[m_t].area)) )); - } - } - - // Compute Mesh Coverage - for (std::size_t i = 0; i < SVA.size(); ++i) { - VM[SVA[i].s].coverage += SVA[i].area; - VM[SVA[i].t].coverage += SVA[i].area; - } - - std::sort(std::begin(SVA), std::end(SVA)); - std::reverse(std::begin(SVA), std::end(SVA)); - } - - void ComputeUsefulMesh(FILE *elfp) { - - int mcnt = 0; - std::vector UpdArea(mn); - std::vector UpdCovg(mn); - - for (std::size_t m = 0; m < mn; ++m) { - - if (VM[m].used && VM[m].area > 0) { - mcnt++; - UpdCovg[m]=VM[m].coverage; - UpdArea[m]=VM[m].area; - } - } - - int sz = G.size(); - if (elfp) { - std::fprintf(elfp, "\n\nComputing Usefulness of Meshes of %i(on %i) meshes\n Og with %i / %i fill ratio %i max mesh per cell\n\n", mcnt, mn, TotalArea, sz, MaxCount); - std::fprintf(elfp, "\n"); - } - - int CumArea = 0; - - for (std::size_t m = 0; m < mn-1; ++m) { - - int best = max_element(std::begin(UpdArea), std::end(UpdArea)) - std::begin(UpdArea); - - CumArea += UpdArea[best]; - if (UpdCovg[best] < 0) break; - - // se era una mesh fuori del working group si salta tutto. - if (VM[best].area == 0) continue; - - if (elfp) { - fprintf(elfp, "%3i %3i %7i (%7i) %7i %5.2f %7i(%7i)\n", - m, best, UpdArea[best], VM[best].area, TotalArea - CumArea, - 100.0 - 100 * float(CumArea) / TotalArea, UpdCovg[best], VM[best].coverage); - } - - UpdArea[best] = -1; - UpdCovg[best] = -1; - - for (std::size_t i = 0; i < sz; ++i) { - - MeshCounter &mc = G.grid[i]; - - if (mc.IsSet(best)) { - - mc.UnSet(best); - - for (std::size_t j = 0; j < mn; ++j) { - if (mc.IsSet(j)) { - --UpdArea[j]; - UpdCovg[j]-=mc.Count(); - } - } - - mc.Clear(); - } + for (size_t i = 0; i < MeshCounter::MaxVal(); ++i) { + if (cnt.test(i) { + v.push_back(i); } } } - void Dump(FILE *fp) { + bool operator < (const MeshCounter &c) const { - std::fprintf(fp, "Occupancy Grid\n"); - std::fprintf(fp, "grid of ~%i kcells: %d x %d x %d\n", G.size(), G.siz[0], G.siz[1], G.siz[2]); - std::fprintf(fp, "grid voxel size of %f %f %f\n", G.voxel[0], G.voxel[1], G.voxel[2]); + if (cnt==c.cnt) return false; - std::fprintf(fp,"Computed %lu arcs for %i meshes\n", SVA.size(), mn); + size_t ii = 0; - for (std::size_t i=0;i(8), VM[i].densityDistribution.size()); ++j) { - std::fprintf(fp," %3i ", VM[i].densityDistribution[j]); - } - - std::fprintf(fp,"\n"); - } - else { - std::fprintf(fp, "mesh %3lu ---- UNUSED\n", i); + while (ii < MeshCounter::MaxVal()){ + if (cnt[ii]!=c.cnt[ii]) { + return cnt[ii] < c.cnt[ii]; } + ++ii; } - - std::fprintf(fp, "Computed %lu Arcs :\n", SVA.size()); - - for (std::size_t i = 0; i .1; ++i) { - std::fprintf(fp, "%4i -> %4i Area:%5i NormArea:%5.3f\n", SVA[i].s, SVA[i].t, SVA[i].area, SVA[i].norm_area); - } - - std::fprintf(fp, "End OG Dump\n"); + return false; } - - void ComputeTotalArea() { - - using uint = unsigned int; - - int ccnt = 0; - MaxCount = 0; - - int sz=G.size(); - - for (int i = 0; i < sz; ++i) - - if (!G.grid[i].Empty()) { - - ccnt++; - if (G.grid[i].Count() > static_cast(MaxCount)) { - MaxCount = G.grid[i].Count(); - } - } - - TotalArea = ccnt; - } - }; - } + + /** + * Class for collecting cumulative information about each mesh in the OG. + * This info are collected in the Compute() by scanning the OG after we filled it with all the meshes. + */ + class OGMeshInfo { + + public: + + int id; // the id of the mesh + int area; // number of voxels in the OG touched by this mesh + int coverage; // quanto e' ricoperta da altre mesh eccetto se stessa (eg: se ho due mesh di 1000 con overlap al 30% la covrg e' 300) + + bool used = false; + + std::vector densityDistribution; // Distribution of the of the density of the voxels touched by this mesh: + // densityDistribution[i] says how many voxel (among the ones coverd by this mesh) + // are covered by othermeshes. Sum(densityDistribution) == area; + // if densityDistribution[1] > 0 means that this mesh is the unique to cover some portion of the space. + + OGMeshInfo() { + Init(-1); + } + + void Init(int _id) { + coverage=0;area=0; id=_id; + } + + bool operator < (OGMeshInfo &o) const { + return area < o.area; + } + + static constexpr int MaxStat() { + return OG_MESH_INFO_MAX_STAT; + } + }; + + /** + * Classe con informazioni su un arco plausibile + */ + class OGArcInfo { + public: + + enum sort { + AREA, + NORM_AREA, + DEGREE + }; + + int s,t; // source and target (come indici nel gruppo corrente) + int area; // + float norm_area; + + OGArcInfo(int _s, int _t, int _area, float _n) : s{_s}, t{_t}, area{_area}, norm_area{_n} {} + OGArcInfo(int _s, int _t, int _area) s{_s}, t{_t}, area{_area} {} + + bool operator < (const OGArcInfo &p) const { + return norm_area < p.norm_area; + } + }; + + bool Init(int _mn, Box3d bb, int size) { + + // the number of meshes (including all the unused ones; eg it is the range of the possible id) + mn = _mn; + if (mn > MeshCounter::MaxVal()) return false; + + MeshCounter MC; + + MC.Clear(); + G.Create(bb,size,MC); + VM.clear(); + + return true; + } + + void Add(const char *MeshName, Matrix44d &Tr, int id) { + + AlignPair::A2Mesh M; + + vcg::tri::io::Importer::Open(M,MeshName); + vcg::tri::Clean::RemoveUnreferencedVertex(M); + + AddMesh(M,Tr,id); + } + + void AddMeshes(std::vector &names, std::vector &trv,int size) { + + Box3d bb, totalbb; + + bb.SetNull(); + totalbb.SetNull(); + + std::fprintf(stdout, "OG::AddMesh:Scanning BBoxex\n"); + + for (std::size_t i = 0; i < names.size(); ++i) { + ply::ScanBBox(names[i].c_str(),bb); + totalbb.Add(trv[i], bb); + } + + Init(names.size(),totalbb,size); + + for (std::size_t i = 0; i < names.size(); ++i) { + std::fprintf(stdout, "OG::AddMesh:Adding Mesh %i '%s'\n", i, names[i].c_str()); + Add(names[i].c_str(),trv[i],i); + } + } + + void AddMesh(MeshType &mesh, const Matrix44d &Tr, int ind) { + + Matrix44f Trf; + Trf.Import(Tr); + + for (auto vi = std::begin(M.vert); vi != std::end(M.vert); ++vi) { + + if (!(*vi).IsD()) { + G.Grid( Trf * Point3f::Construct((*vi).P()) ).Set(ind); + } + } + + VM[ind].Init(ind); + VM[ind].used = true; + } + + void RemoveMesh(int id) { + + MeshCounter *GridEnd = G.grid+G.size(); + + for (MeshCounter* ig = G.grid; ig != GridEnd; ++ig) { + ig->UnSet(id); + } + } + + /** + * This function is called after we have all the mesh to the OG + * to collect the information about the interferences between the various meshes. + */ + void Compute() { + + // Analisi della griglia + // Si deve trovare l'insieme degli archi piu'plausibili + // un arco ha "senso" in una cella se entrambe le mesh compaiono in quell'arco + // Si considera tutti gli archi possibili e si conta in quante celle ha senso un arco + + std::vector VA; // virtual arcs + VA.resize(mn * mn, 0); + + std::map, int> VAMap; + + // First Loop: + // Scan the grid and update possible arc count + for (int i = 0; i < G.siz[0]; ++i) { + + for (int j = 0; j < G.siz[1]; ++j) { + + for (int k = 0; k < G.siz[2]; ++k) { + + std::vector vv; + G.Grid(i, j, k).Pack(vv); + std::size_t meshInCell = vv.size(); + + for (std::size_t ii = 0; ii < vv.size(); ++ii) { + + OccupancyGrid::OGMeshInfo &omi_ii = VM[vv[ii]]; + + ++omi_ii.area; // compute mesh area + if (meshInCell > omi_ii.densityDistribution.size()) { + omi_ii.densityDistribution.resize(meshInCell); + } + + ++(omi_ii.densityDistribution[meshInCell - 1]); + } + + for (std::size_t ii = 0; ii < vv.size(); ++ii) { + for (std::size_t jj = ii + 1; jj < vv.size(); ++jj) { + // count intersections of all mesh pairs + ++VAMap[std::make_pair(vv[ii], vv[jj])]; + } + } + } + } + } + + // Find all the arcs, e.g. all the pair of meshes + SVA.clear(); + for (auto vi = std::begin(VAMap); vi != std::end(VAMap); ++vi) { + if (vi->second > 0) { + int m_s = vi->first.first; + int m_t = vi->first.second; + int area = vi->second; + SVA.push_back( OGArcInfo (m_s,m_t,area,float(area)/float(min(VM[m_s].area,VM[m_t].area)) )); + } + } + + // Compute Mesh Coverage + for (std::size_t i = 0; i < SVA.size(); ++i) { + VM[SVA[i].s].coverage += SVA[i].area; + VM[SVA[i].t].coverage += SVA[i].area; + } + + std::sort(std::begin(SVA), std::end(SVA)); + std::reverse(std::begin(SVA), std::end(SVA)); + } + + void ComputeUsefulMesh(FILE *elfp) { + + int mcnt = 0; + std::vector UpdArea(mn); + std::vector UpdCovg(mn); + + for (std::size_t m = 0; m < mn; ++m) { + + if (VM[m].used && VM[m].area > 0) { + mcnt++; + UpdCovg[m]=VM[m].coverage; + UpdArea[m]=VM[m].area; + } + } + + int sz = G.size(); + if (elfp) { + std::fprintf(elfp, "\n\nComputing Usefulness of Meshes of %i(on %i) meshes\n Og with %i / %i fill ratio %i max mesh per cell\n\n", mcnt, mn, TotalArea, sz, MaxCount); + std::fprintf(elfp, "\n"); + } + + int CumArea = 0; + + for (std::size_t m = 0; m < mn-1; ++m) { + + int best = max_element(std::begin(UpdArea), std::end(UpdArea)) - std::begin(UpdArea); + + CumArea += UpdArea[best]; + if (UpdCovg[best] < 0) break; + + // se era una mesh fuori del working group si salta tutto. + if (VM[best].area == 0) continue; + + if (elfp) { + fprintf(elfp, "%3i %3i %7i (%7i) %7i %5.2f %7i(%7i)\n", + m, best, UpdArea[best], VM[best].area, TotalArea - CumArea, + 100.0 - 100 * float(CumArea) / TotalArea, UpdCovg[best], VM[best].coverage); + } + + UpdArea[best] = -1; + UpdCovg[best] = -1; + + for (std::size_t i = 0; i < sz; ++i) { + + MeshCounter &mc = G.grid[i]; + + if (mc.IsSet(best)) { + + mc.UnSet(best); + + for (std::size_t j = 0; j < mn; ++j) { + if (mc.IsSet(j)) { + --UpdArea[j]; + UpdCovg[j]-=mc.Count(); + } + } + + mc.Clear(); + } + } + } + } + + void Dump(FILE *fp) { + + std::fprintf(fp, "Occupancy Grid\n"); + std::fprintf(fp, "grid of ~%i kcells: %d x %d x %d\n", G.size(), G.siz[0], G.siz[1], G.siz[2]); + std::fprintf(fp, "grid voxel size of %f %f %f\n", G.voxel[0], G.voxel[1], G.voxel[2]); + + std::fprintf(fp,"Computed %lu arcs for %i meshes\n", SVA.size(), mn); + + for (std::size_t i=0;i(8), VM[i].densityDistribution.size()); ++j) { + std::fprintf(fp," %3i ", VM[i].densityDistribution[j]); + } + + std::fprintf(fp,"\n"); + } + else { + std::fprintf(fp, "mesh %3lu ---- UNUSED\n", i); + } + } + + std::fprintf(fp, "Computed %lu Arcs :\n", SVA.size()); + + for (std::size_t i = 0; i .1; ++i) { + std::fprintf(fp, "%4i -> %4i Area:%5i NormArea:%5.3f\n", SVA[i].s, SVA[i].t, SVA[i].area, SVA[i].norm_area); + } + + std::fprintf(fp, "End OG Dump\n"); + } + + void ComputeTotalArea() { + + using uint = unsigned int; + + int ccnt = 0; + MaxCount = 0; + + int sz=G.size(); + + for (int i = 0; i < sz; ++i) + + if (!G.grid[i].Empty()) { + + ccnt++; + if (G.grid[i].Count() > static_cast(MaxCount)) { + MaxCount = G.grid[i].Count(); + } + } + + TotalArea = ccnt; + } + + }; } #endif //VCGLIB_OCCUPANCY_GRID_H From 8928fbbe6bfcc9b15b45a86e427ce765bdd09eac Mon Sep 17 00:00:00 2001 From: gabryon99 Date: Mon, 13 Sep 2021 19:37:26 +0200 Subject: [PATCH 049/117] fixes --- vcg/complex/algorithms/occupancy_grid.h | 40 ++++++++++++------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/vcg/complex/algorithms/occupancy_grid.h b/vcg/complex/algorithms/occupancy_grid.h index 5272f946..6bb15067 100644 --- a/vcg/complex/algorithms/occupancy_grid.h +++ b/vcg/complex/algorithms/occupancy_grid.h @@ -13,26 +13,6 @@ namespace vcg { template class OccupancyGrid { - private: - - GridStaticObj G; - - int mn; - int TotalArea; - /** - * Maximum number of meshes that cross a cell - */ - int MaxCount; - - /** - * SortedVisual Arcs - */ - std::vector SVA; // SortedVirtual Arcs; - /** - * High level information for each mesh. Mapped by mesh id - */ - std::map VM; - public: /** @@ -426,6 +406,26 @@ namespace vcg { TotalArea = ccnt; } + private: + + GridStaticObj G; + + int mn; + int TotalArea; + /** + * Maximum number of meshes that cross a cell + */ + int MaxCount; + + /** + * SortedVisual Arcs + */ + std::vector SVA; // SortedVirtual Arcs; + /** + * High level information for each mesh. Mapped by mesh id + */ + std::map VM; + }; } From 2a5c9bfb6177bf24707fd90b299f2da8f2e60643 Mon Sep 17 00:00:00 2001 From: gabryon99 Date: Mon, 13 Sep 2021 20:28:45 +0200 Subject: [PATCH 050/117] fix typos --- vcg/complex/algorithms/occupancy_grid.h | 55 +++++++++++++------------ 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/vcg/complex/algorithms/occupancy_grid.h b/vcg/complex/algorithms/occupancy_grid.h index 6bb15067..e3742246 100644 --- a/vcg/complex/algorithms/occupancy_grid.h +++ b/vcg/complex/algorithms/occupancy_grid.h @@ -3,6 +3,9 @@ #include #include +#include +#include + #ifndef VCGLIB_OCCUPANCY_GRID_H #define VCGLIB_OCCUPANCY_GRID_H @@ -62,7 +65,7 @@ namespace vcg { v.clear(); for (size_t i = 0; i < MeshCounter::MaxVal(); ++i) { - if (cnt.test(i) { + if (cnt.test(i)) { v.push_back(i); } } @@ -132,18 +135,36 @@ namespace vcg { DEGREE }; - int s,t; // source and target (come indici nel gruppo corrente) + int s, t; // source and target (come indici nel gruppo corrente) int area; // float norm_area; OGArcInfo(int _s, int _t, int _area, float _n) : s{_s}, t{_t}, area{_area}, norm_area{_n} {} - OGArcInfo(int _s, int _t, int _area) s{_s}, t{_t}, area{_area} {} + OGArcInfo(int _s, int _t, int _area) : s{_s}, t{_t}, area{_area} {} bool operator < (const OGArcInfo &p) const { return norm_area < p.norm_area; } }; + GridStaticObj G; + + int mn; + int TotalArea; + /** + * Maximum number of meshes that cross a cell + */ + int MaxCount; + + /** + * SortedVisual Arcs + */ + std::vector SVA; // SortedVirtual Arcs; + /** + * High level information for each mesh. Mapped by mesh id + */ + std::map VM; + bool Init(int _mn, Box3d bb, int size) { // the number of meshes (including all the unused ones; eg it is the range of the possible id) @@ -163,8 +184,8 @@ namespace vcg { AlignPair::A2Mesh M; - vcg::tri::io::Importer::Open(M,MeshName); - vcg::tri::Clean::RemoveUnreferencedVertex(M); + vcg::tri::io::Importer::Open(M, MeshName); + vcg::tri::Clean::RemoveUnreferencedVertex(M); AddMesh(M,Tr,id); } @@ -179,7 +200,7 @@ namespace vcg { std::fprintf(stdout, "OG::AddMesh:Scanning BBoxex\n"); for (std::size_t i = 0; i < names.size(); ++i) { - ply::ScanBBox(names[i].c_str(),bb); + vcg::ply::ScanBBox(names[i].c_str(),bb); totalbb.Add(trv[i], bb); } @@ -196,7 +217,7 @@ namespace vcg { Matrix44f Trf; Trf.Import(Tr); - for (auto vi = std::begin(M.vert); vi != std::end(M.vert); ++vi) { + for (auto vi = std::begin(mesh.vert); vi != std::end(mesh.vert); ++vi) { if (!(*vi).IsD()) { G.Grid( Trf * Point3f::Construct((*vi).P()) ).Set(ind); @@ -406,26 +427,6 @@ namespace vcg { TotalArea = ccnt; } - private: - - GridStaticObj G; - - int mn; - int TotalArea; - /** - * Maximum number of meshes that cross a cell - */ - int MaxCount; - - /** - * SortedVisual Arcs - */ - std::vector SVA; // SortedVirtual Arcs; - /** - * High level information for each mesh. Mapped by mesh id - */ - std::map VM; - }; } From 4595f3220251412b64911383f61ff027a208519c Mon Sep 17 00:00:00 2001 From: gabryon99 Date: Mon, 13 Sep 2021 21:05:08 +0200 Subject: [PATCH 051/117] uncommented the include of plystuff to avoid duplicate symbols --- vcg/complex/algorithms/occupancy_grid.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/vcg/complex/algorithms/occupancy_grid.h b/vcg/complex/algorithms/occupancy_grid.h index e3742246..1c74ae6f 100644 --- a/vcg/complex/algorithms/occupancy_grid.h +++ b/vcg/complex/algorithms/occupancy_grid.h @@ -1,11 +1,11 @@ #include +// #include +#include + #include #include -#include -#include - #ifndef VCGLIB_OCCUPANCY_GRID_H #define VCGLIB_OCCUPANCY_GRID_H @@ -78,7 +78,7 @@ namespace vcg { size_t ii = 0; while (ii < MeshCounter::MaxVal()){ - if (cnt[ii]!=c.cnt[ii]) { + if (cnt[ii] != c.cnt[ii]) { return cnt[ii] < c.cnt[ii]; } ++ii; @@ -197,10 +197,10 @@ namespace vcg { bb.SetNull(); totalbb.SetNull(); - std::fprintf(stdout, "OG::AddMesh:Scanning BBoxex\n"); + std::fprintf(stdout, "OG::AddMesh:Scanning BBoxes\n"); for (std::size_t i = 0; i < names.size(); ++i) { - vcg::ply::ScanBBox(names[i].c_str(),bb); + // vcg::ply::ScanBBox(names[i].c_str(), bb, true); totalbb.Add(trv[i], bb); } @@ -208,7 +208,7 @@ namespace vcg { for (std::size_t i = 0; i < names.size(); ++i) { std::fprintf(stdout, "OG::AddMesh:Adding Mesh %i '%s'\n", i, names[i].c_str()); - Add(names[i].c_str(),trv[i],i); + Add(names[i].c_str(), trv[i], i); } } @@ -220,7 +220,7 @@ namespace vcg { for (auto vi = std::begin(mesh.vert); vi != std::end(mesh.vert); ++vi) { if (!(*vi).IsD()) { - G.Grid( Trf * Point3f::Construct((*vi).P()) ).Set(ind); + G.Grid(Trf * Point3f::Construct((*vi).P())).Set(ind); } } @@ -230,7 +230,7 @@ namespace vcg { void RemoveMesh(int id) { - MeshCounter *GridEnd = G.grid+G.size(); + MeshCounter *GridEnd = G.grid + G.size(); for (MeshCounter* ig = G.grid; ig != GridEnd; ++ig) { ig->UnSet(id); @@ -294,7 +294,7 @@ namespace vcg { int m_s = vi->first.first; int m_t = vi->first.second; int area = vi->second; - SVA.push_back( OGArcInfo (m_s,m_t,area,float(area)/float(min(VM[m_s].area,VM[m_t].area)) )); + SVA.push_back( OGArcInfo (m_s,m_t,area,float(area)/float(std::min(VM[m_s].area,VM[m_t].area)) )); } } @@ -398,7 +398,7 @@ namespace vcg { std::fprintf(fp, "Computed %lu Arcs :\n", SVA.size()); - for (std::size_t i = 0; i .1; ++i) { + for (std::size_t i = 0; i < SVA.size() && SVA[i].norm_area > .1; ++i) { std::fprintf(fp, "%4i -> %4i Area:%5i NormArea:%5.3f\n", SVA[i].s, SVA[i].t, SVA[i].area, SVA[i].norm_area); } From 16de5d341c07e02e27888c590f1509d6950a8921 Mon Sep 17 00:00:00 2001 From: gabryon99 Date: Mon, 13 Sep 2021 21:34:08 +0200 Subject: [PATCH 052/117] add meshtree.h --- CMakeLists.txt | 1 + vcg/complex/algorithms/meshtree.h | 352 ++++++++++++++++++++++++++++++ 2 files changed, 353 insertions(+) create mode 100644 vcg/complex/algorithms/meshtree.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 60fc296a..e671ab53 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,6 +73,7 @@ set(VCG_HEADERS vcg/complex/algorithms/inertia.h vcg/complex/algorithms/mesh_assert.h vcg/complex/algorithms/occupancy_grid.h + vcg/complex/algorithms/meshtree.h.h vcg/complex/algorithms/cut_tree.h vcg/complex/algorithms/nring.h vcg/complex/algorithms/tetra/tetfuse_collapse.h diff --git a/vcg/complex/algorithms/meshtree.h b/vcg/complex/algorithms/meshtree.h new file mode 100644 index 00000000..c66fadc7 --- /dev/null +++ b/vcg/complex/algorithms/meshtree.h @@ -0,0 +1,352 @@ +#ifndef VCGLIB_MESHTREE_H +#define VCGLIB_MESHTREE_H + +namespace vcg { + + template + class MeshTree { + + public: + + class MeshNode { + + public: + bool glued; + MeshType *m; + + MeshNode(MeshType *_m) : m{_m}, glued{false} {} + + vcg::Matrix44 &tr() { + return m->cm.Tr; + } + + const vcg::Box3 &bbox() const { + return m->cm.bbox; + } + + int Id() { + return m->id(); + } + }; + + class Param { + public: + int OGSize = 5000; + float arcThreshold = 0.3f; + float recalcThreshold = 0.1f; + }; + + std::map nodeMap; + std::list resultList; + + vcg::OccupancyGrid OG; + vcg::CallBackPos * cb; + + MeshType *MM(unsigned int i) { + return nodeMap[i]->m; + } + + MeshTree(); + + void clear() { + + for (auto ni = std::begin(nodeMap); ni != std::end(nodeMap); ++ni) { + delete ni->second; + } + + nodeMap.clear(); + resultList.clear(); + } + + void deleteResult(MeshTree::MeshNode *mp) { + + auto li = std::begin(resultList); + while (li != resultList.end()) { + + if (li->MovName==mp->Id() || li->FixName==mp->Id()) { + li=resultList.erase(li); + } + else { + ++li; + } + } + } + + vcg::AlignPair::Result* findResult(int id1, int id2) { + + for (auto li = std::begin(resultList); li != std::end(resultList); ++li) { + if ((li->MovName==id1 && li->FixName==id2) || (li->MovName==id2 && li->FixName==id1) ) { + return &*li; + } + } + + return 0; + } + + MeshTree::MeshNode *find(int id) { + + MeshTree::MeshNode *mp = nodeMap[id]; + + if (mp==0 || mp->Id()!=id) { + assert("You are trying to find an unexistent mesh"==0); + } + + return mp; + } + + MeshTree::MeshNode *find(MeshType *m) { + + for (auto ni = std::begin(nodeMap); ni != std::end(nodeMap); ++ni) { + if (ni->second->m==m) return ni->second; + } + + assert("You are trying to find an unexistent mesh" ==0); + return 0; + } + + int gluedNum() { + + int cnt = 0; + + for (auto ni = std::begin(nodeMap); ni != std::end(nodeMap); ++ni) { + MeshTree::MeshNode *mn=ni->second; + if (mn->glued) ++cnt; + } + + return cnt; + } + + void Process(vcg::AlignPair::Param &ap, Param &mtp) { + + // QString buf; + // cb(0,qUtf8Printable(buf.sprintf("Starting Processing of %i glued meshes out of %zu meshes\n",gluedNum(),nodeMap.size()))); + + /******* Occupancy Grid Computation *************/ + // cb(0,qUtf8Printable(buf.sprintf("Computing Overlaps %i glued meshes...\n",gluedNum() ))); + + OG.Init(static_cast(nodeMap.size()), vcg::Box3d::Construct(gluedBBox()), mtp.OGSize); + + for(auto ni = std::begin(nodeMap); ni != std::end(nodeMap); ++ni) { + MeshTree::MeshNode *mn = ni->second; + if (mn->glued) { + OG.AddMesh(mn->m->cm, vcg::Matrix44d::Construct(mn->tr()), mn->Id()); + } + } + + OG.Compute(); + OG.Dump(stdout); + // Note: the s and t of the OG translate into fix and mov, respectively. + + /*************** The long loop of arc computing **************/ + + // count existing arcs within current error threshold + float percentileThr = 0f; + if (resultList.size() > 0) { + + vcg::Distribution H; + for (auto li = std::begin(resultList); li != std::end(resultList); ++li) { + H.Add(li->err); + } + + percentileThr = H.Percentile(1.0f - mtp.recalcThreshold); + } + + std::size_t totalArcNum = 0; + int preservedArcNum = 0, recalcArcNum = 0; + + while(totalArcNum mtp.arcThreshold) + { + AlignPair::Result *curResult = findResult(OG.SVA[totalArcNum].s, OG.SVA[totalArcNum].t); + if (curResult) { + if (curResult->err < percentileThr) { + ++preservedArcNum; + } + else { + ++recalcArcNum; + } + } + else { + resultList.push_back(AlignPair::Result()); + resultList.back().FixName = OG.SVA[totalArcNum].s; + resultList.back().MovName = OG.SVA[totalArcNum].t; + resultList.back().err = std::numeric_limits::max(); + } + ++totalArcNum; + } + + //if there are no arcs at all complain and return + if (totalArcNum == 0) { + // cb(0, qUtf8Printable(buf.sprintf("\n Failure. There are no overlapping meshes?\n No candidate alignment arcs. Nothing Done.\n"))); + return; + } + + int num_max_thread = 1; + #ifdef _OPENMP + if (totalArcNum > 32) num_max_thread = omp_get_max_threads(); + #endif + // cb(0,qUtf8Printable(buf.sprintf("Arc with good overlap %6zu (on %6zu)\n",totalArcNum,OG.SVA.size()))); + // cb(0,qUtf8Printable(buf.sprintf(" %6i preserved %i Recalc \n",preservedArcNum,recalcArcNum))); + + bool hasValidAlign = false; + + #pragma omp parallel for schedule(dynamic, 1) num_threads(num_max_thread) + + // on windows, omp does not support unsigned types for indices on cycles + for (int i = 0 ;i < static_cast(totalArcNum); ++i) { + + std::fprintf(stdout,"%4i -> %4i Area:%5i NormArea:%5.3f\n",OG.SVA[i].s,OG.SVA[i].t,OG.SVA[i].area,OG.SVA[i].norm_area); + AlignPair::Result *curResult = findResult(OG.SVA[i].s,OG.SVA[i].t); + + // // missing arc and arc with great error must be recomputed. + if (curResult->err >= percentileThr) { + + ProcessArc(OG.SVA[i].s, OG.SVA[i].t, *curResult, ap); + curResult->area = OG.SVA[i].norm_area; + + if (curResult->isValid()) { + hasValidAlign = true; + std::pair dd = curResult->computeAvgErr(); + #pragma omp critical + //cb(0,qUtf8Printable(buf.sprintf("(%3i/%3zu) %2i -> %2i Aligned AvgErr dd=%f -> dd=%f \n",i+1,totalArcNum,OG.SVA[i].s,OG.SVA[i].t,dd.first,dd.second))); + } + else { + #pragma omp critical + //cb(0,qUtf8Printable(buf.sprintf( "(%3i/%3zu) %2i -> %2i Failed Alignment of one arc %s\n",i+1,totalArcNum,OG.SVA[i].s,OG.SVA[i].t,vcg::AlignPair::errorMsg(curResult->status)))); + } + } + } + + //if there are no valid arcs complain and return + if (!hasValidAlign) { + // cb(0,qUtf8Printable(buf.sprintf("\n Failure. No successful arc among candidate Alignment arcs. Nothing Done.\n"))); + return; + } + + vcg::Distribution H; // stat for printing + for (auto li = std::begin(resultList); li != std::end(resultList); ++li) { + if ((*li).isValid()) { + H.Add(li->err); + } + } + + //cb(0,qUtf8Printable(buf.sprintf("Completed Mesh-Mesh Alignment: Avg Err %5.3f; Median %5.3f; 90%% %5.3f\n", H.Avg(), H.Percentile(0.5f), H.Percentile(0.9f)))); + + ProcessGlobal(ap); + } + + void ProcessGlobal(vcg::AlignPair::Param &ap) { + + /************** Preparing Matrices for global alignment *************/ + std::vector GluedIdVec; + std::vector GluedTrVec; + + std::map names; + + for (auto ni = std::begin(nodeMap); ni != std::end(nodeMap); ++ni) { + MeshTree::MeshNode *mn=ni->second; + if (mn->glued) { + GluedIdVec.push_back(mn->Id()); + GluedTrVec.push_back(vcg::Matrix44d::Construct(mn->tr())); + names[mn->Id()]=qUtf8Printable(mn->m->label()); + } + } + + vcg::AlignGlobal AG; + std::vector ResVecPtr; + for (auto li = std::begin(resultList); li != std::end(resultList); ++li) { + if ((*li).isValid()) { + ResVecPtr.push_back(&*li); + } + } + + AG.BuildGraph(ResVecPtr, GluedTrVec, GluedIdVec); + + float StartGlobErr = 0.001f; + while (!AG.GlobalAlign(names, StartGlobErr, 100, ap.MatchMode==vcg::AlignPair::Param::MMRigid, stdout)){ + StartGlobErr *= 2; + AG.BuildGraph(ResVecPtr,GluedTrVec, GluedIdVec); + } + + std::vector GluedTrVecOut(GluedTrVec.size()); + AG.GetMatrixVector(GluedTrVecOut,GluedIdVec); + + // Now get back the results! + for (std::size_t ii = 0; ii < GluedTrVecOut.size(); ++ii) { + MM(GluedIdVec[ii])->cm.Tr.Import(GluedTrVecOut[ii]); + } + + } + + void ProcessArc(int fixId, int movId, vcg::AlignPair::Result &result, vcg::AlignPair::Param ap) { + + // l'allineatore globale cambia le varie matrici di posizione di base delle mesh + // per questo motivo si aspetta i punti nel sistema di riferimento locale della mesh fix + // Si fanno tutti i conti rispetto al sistema di riferimento locale della mesh fix + vcg::Matrix44d FixM = vcg::Matrix44d::Construct(find(fixId)->tr()); + vcg::Matrix44d MovM = vcg::Matrix44d::Construct(find(movId)->tr()); + vcg::Matrix44d MovToFix = Inverse(FixM) * MovM; + + ProcessArc(fixId,movId,MovToFix,result,ap); + } + + void ProcessArc(int fixId, int movId, vcg::Matrix44d &MovToFix, vcg::AlignPair::Result &result, vcg::AlignPair::Param ap) { + + vcg::AlignPair::A2Mesh Fix; + vcg::AlignPair aa; + + // 1) Convert fixed mesh and put it into the grid. + MM(fixId)->updateDataMask(MeshModel::MM_FACEMARK); + aa.convertMesh(MM(fixId)->cm,Fix); + + vcg::AlignPair::A2Grid UG; + vcg::AlignPair::A2GridVert VG; + + if (MM(fixId)->cm.fn==0 || ap.UseVertexOnly) { + Fix.initVert(vcg::Matrix44d::Identity()); + vcg::AlignPair::InitFixVert(&Fix,ap,VG); + } + else { + Fix.init(vcg::Matrix44d::Identity()); + vcg::AlignPair::initFix(&Fix, ap, UG); + } + + // 2) Convert the second mesh and sample a points on it. + MM(movId)->updateDataMask(MeshModel::MM_FACEMARK); + std::vector tmpmv; + aa.convertVertex(MM(movId)->cm.vert,tmpmv); + aa.sampleMovVert(tmpmv, ap.SampleNum, ap.SampleMode); + + aa.mov=&tmpmv; + aa.fix=&Fix; + aa.ap = ap; + + vcg::Matrix44d In=MovM; + // Perform the ICP algorithm + aa.align(In,UG,VG,result); + + result.FixName=fixId; + result.MovName=movId; + } + + inline Box3m bbox() { + Box3m FullBBox; + for (auto ni = std::begin(nodeMap); ni != std::end(nodeMap); ++ni) { + FullBBox.Add(Matrix44m::Construct(ni->second->tr()),ni->second->bbox()); + } + return FullBBox; + } + + inline Box3m gluedBBox() { + Box3m FullBBox; + for (auto ni = std::begin(nodeMap); ni != std::end(nodeMap); ++ni) { + if (ni->second->glued) { + FullBBox.Add(Matrix44m::Construct(ni->second->tr()), ni->second->bbox()); + } + } + return FullBBox; + } + + }; +} + +#endif //VCGLIB_MESHTREE_H From 76d2649a5eba6f30124a1fb7950475f7f6effa52 Mon Sep 17 00:00:00 2001 From: gabryon99 Date: Mon, 13 Sep 2021 21:35:16 +0200 Subject: [PATCH 053/117] fix typo in CMakeLists.txt --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e671ab53..d8555cf0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,7 +73,7 @@ set(VCG_HEADERS vcg/complex/algorithms/inertia.h vcg/complex/algorithms/mesh_assert.h vcg/complex/algorithms/occupancy_grid.h - vcg/complex/algorithms/meshtree.h.h + vcg/complex/algorithms/meshtree.h vcg/complex/algorithms/cut_tree.h vcg/complex/algorithms/nring.h vcg/complex/algorithms/tetra/tetfuse_collapse.h From cfc21cd8d26b23480f1284b012a9652e6fc7ff1d Mon Sep 17 00:00:00 2001 From: gabryon99 Date: Tue, 14 Sep 2021 14:17:07 +0200 Subject: [PATCH 054/117] remove ScalarType from MeshTree --- vcg/complex/algorithms/meshtree.h | 104 +++++++++++++++++++----------- 1 file changed, 68 insertions(+), 36 deletions(-) diff --git a/vcg/complex/algorithms/meshtree.h b/vcg/complex/algorithms/meshtree.h index c66fadc7..3bd18a9a 100644 --- a/vcg/complex/algorithms/meshtree.h +++ b/vcg/complex/algorithms/meshtree.h @@ -1,9 +1,17 @@ #ifndef VCGLIB_MESHTREE_H #define VCGLIB_MESHTREE_H +#include +#include +#include + +#ifdef _OPENMP +#include +#endif + namespace vcg { - template + template class MeshTree { public: @@ -16,11 +24,11 @@ namespace vcg { MeshNode(MeshType *_m) : m{_m}, glued{false} {} - vcg::Matrix44 &tr() { + vcg::Matrix44d &tr() { return m->cm.Tr; } - const vcg::Box3 &bbox() const { + const vcg::Box3d &bbox() const { return m->cm.bbox; } @@ -36,8 +44,8 @@ namespace vcg { float recalcThreshold = 0.1f; }; - std::map nodeMap; - std::list resultList; + std::map nodeMap; + std::vector resultList; vcg::OccupancyGrid OG; vcg::CallBackPos * cb; @@ -46,7 +54,9 @@ namespace vcg { return nodeMap[i]->m; } - MeshTree(); + MeshTree() {} + + MeshTree(vcg::CallBackPos* _cb) : cb{_cb} {} void clear() { @@ -116,13 +126,16 @@ namespace vcg { return cnt; } - void Process(vcg::AlignPair::Param &ap, Param &mtp) { + void Process(vcg::AlignPair::Param &ap, MeshTree::Param &mtp) { - // QString buf; - // cb(0,qUtf8Printable(buf.sprintf("Starting Processing of %i glued meshes out of %zu meshes\n",gluedNum(),nodeMap.size()))); + char buf[1024]; + std::sprintf(buf, "Starting Processing of %i glued meshes out of %zu meshes\n", gluedNum(), nodeMap.size()); + cb(0, buf); /******* Occupancy Grid Computation *************/ - // cb(0,qUtf8Printable(buf.sprintf("Computing Overlaps %i glued meshes...\n",gluedNum() ))); + std::memset(buf, '\0', 1024); + std::sprintf(buf, "Computing Overlaps %i glued meshes...\n", gluedNum()); + cb(0, buf); OG.Init(static_cast(nodeMap.size()), vcg::Box3d::Construct(gluedBBox()), mtp.OGSize); @@ -140,8 +153,8 @@ namespace vcg { /*************** The long loop of arc computing **************/ // count existing arcs within current error threshold - float percentileThr = 0f; - if (resultList.size() > 0) { + float percentileThr = 0; + if (!resultList.empty()) { vcg::Distribution H; for (auto li = std::begin(resultList); li != std::end(resultList); ++li) { @@ -176,20 +189,27 @@ namespace vcg { //if there are no arcs at all complain and return if (totalArcNum == 0) { - // cb(0, qUtf8Printable(buf.sprintf("\n Failure. There are no overlapping meshes?\n No candidate alignment arcs. Nothing Done.\n"))); + std::memset(buf, '\0', 1024); + std::sprintf(buf, "\n Failure. There are no overlapping meshes?\n No candidate alignment arcs. Nothing Done.\n"); + cb(0, buf); return; } int num_max_thread = 1; - #ifdef _OPENMP +#ifdef _OPENMP if (totalArcNum > 32) num_max_thread = omp_get_max_threads(); - #endif - // cb(0,qUtf8Printable(buf.sprintf("Arc with good overlap %6zu (on %6zu)\n",totalArcNum,OG.SVA.size()))); - // cb(0,qUtf8Printable(buf.sprintf(" %6i preserved %i Recalc \n",preservedArcNum,recalcArcNum))); +#endif + std::memset(buf, '\0', 1024); + std::sprintf(buf, "Arc with good overlap %6zu (on %6zu)\n", totalArcNum, OG.SVA.size()); + cb(0, buf); + + std::memset(buf, '\0', 1024); + std::sprintf(buf, " %6i preserved %i Recalc \n", preservedArcNum, recalcArcNum); + cb(0, buf); bool hasValidAlign = false; - #pragma omp parallel for schedule(dynamic, 1) num_threads(num_max_thread) +#pragma omp parallel for schedule(dynamic, 1) num_threads(num_max_thread) // on windows, omp does not support unsigned types for indices on cycles for (int i = 0 ;i < static_cast(totalArcNum); ++i) { @@ -206,19 +226,26 @@ namespace vcg { if (curResult->isValid()) { hasValidAlign = true; std::pair dd = curResult->computeAvgErr(); - #pragma omp critical - //cb(0,qUtf8Printable(buf.sprintf("(%3i/%3zu) %2i -> %2i Aligned AvgErr dd=%f -> dd=%f \n",i+1,totalArcNum,OG.SVA[i].s,OG.SVA[i].t,dd.first,dd.second))); +#pragma omp critical + + std::memset(buf, '\0', 1024); + std::sprintf(buf, "(%3i/%3zu) %2i -> %2i Aligned AvgErr dd=%f -> dd=%f \n", i+1,totalArcNum,OG.SVA[i].s,OG.SVA[i].t,dd.first,dd.second); + cb(0, buf); } else { - #pragma omp critical - //cb(0,qUtf8Printable(buf.sprintf( "(%3i/%3zu) %2i -> %2i Failed Alignment of one arc %s\n",i+1,totalArcNum,OG.SVA[i].s,OG.SVA[i].t,vcg::AlignPair::errorMsg(curResult->status)))); +#pragma omp critical + std::memset(buf, '\0', 1024); + std::sprintf(buf, "(%3i/%3zu) %2i -> %2i Failed Alignment of one arc %s\n",i+1,totalArcNum,OG.SVA[i].s,OG.SVA[i].t,vcg::AlignPair::errorMsg(curResult->status)); + cb(0, buf); } } } //if there are no valid arcs complain and return if (!hasValidAlign) { - // cb(0,qUtf8Printable(buf.sprintf("\n Failure. No successful arc among candidate Alignment arcs. Nothing Done.\n"))); + std::memset(buf, '\0', 1024); + std::sprintf(buf, "\n Failure. No successful arc among candidate Alignment arcs. Nothing Done.\n"); + cb(0, buf); return; } @@ -229,7 +256,9 @@ namespace vcg { } } - //cb(0,qUtf8Printable(buf.sprintf("Completed Mesh-Mesh Alignment: Avg Err %5.3f; Median %5.3f; 90%% %5.3f\n", H.Avg(), H.Percentile(0.5f), H.Percentile(0.9f)))); + std::memset(buf, '\0', 1024); + std::sprintf(buf, "Completed Mesh-Mesh Alignment: Avg Err %5.3f; Median %5.3f; 90%% %5.3f\n", H.Avg(), H.Percentile(0.5f), H.Percentile(0.9f)); + cb(0, buf); ProcessGlobal(ap); } @@ -262,7 +291,7 @@ namespace vcg { AG.BuildGraph(ResVecPtr, GluedTrVec, GluedIdVec); float StartGlobErr = 0.001f; - while (!AG.GlobalAlign(names, StartGlobErr, 100, ap.MatchMode==vcg::AlignPair::Param::MMRigid, stdout)){ + while (!AG.GlobalAlign(names, StartGlobErr, 100, ap.MatchMode == vcg::AlignPair::Param::MMRigid, stdout, cb)) { StartGlobErr *= 2; AG.BuildGraph(ResVecPtr,GluedTrVec, GluedIdVec); } @@ -286,16 +315,16 @@ namespace vcg { vcg::Matrix44d MovM = vcg::Matrix44d::Construct(find(movId)->tr()); vcg::Matrix44d MovToFix = Inverse(FixM) * MovM; - ProcessArc(fixId,movId,MovToFix,result,ap); + ProcessArc(fixId, movId, MovToFix, result, ap); } - void ProcessArc(int fixId, int movId, vcg::Matrix44d &MovToFix, vcg::AlignPair::Result &result, vcg::AlignPair::Param ap) { + void ProcessArc(int fixId, int movId, vcg::Matrix44d &MovM, vcg::AlignPair::Result &result, vcg::AlignPair::Param ap) { vcg::AlignPair::A2Mesh Fix; vcg::AlignPair aa; // 1) Convert fixed mesh and put it into the grid. - MM(fixId)->updateDataMask(MeshModel::MM_FACEMARK); + MM(fixId)->updateDataMask(MeshType::MeshModel::MM_FACEMARK); aa.convertMesh(MM(fixId)->cm,Fix); vcg::AlignPair::A2Grid UG; @@ -311,7 +340,7 @@ namespace vcg { } // 2) Convert the second mesh and sample a points on it. - MM(movId)->updateDataMask(MeshModel::MM_FACEMARK); + MM(movId)->updateDataMask(MeshType::MeshModel::MM_FACEMARK); std::vector tmpmv; aa.convertVertex(MM(movId)->cm.vert,tmpmv); aa.sampleMovVert(tmpmv, ap.SampleNum, ap.SampleMode); @@ -320,7 +349,7 @@ namespace vcg { aa.fix=&Fix; aa.ap = ap; - vcg::Matrix44d In=MovM; + vcg::Matrix44d In = MovM; // Perform the ICP algorithm aa.align(In,UG,VG,result); @@ -328,19 +357,22 @@ namespace vcg { result.MovName=movId; } - inline Box3m bbox() { - Box3m FullBBox; + inline vcg::Box3d bbox() { + + vcg::Box3d FullBBox; for (auto ni = std::begin(nodeMap); ni != std::end(nodeMap); ++ni) { - FullBBox.Add(Matrix44m::Construct(ni->second->tr()),ni->second->bbox()); + FullBBox.Add(vcg::Matrix44d::Construct(ni->second->tr()),ni->second->bbox()); } return FullBBox; } - inline Box3m gluedBBox() { - Box3m FullBBox; + inline vcg::Box3d gluedBBox() { + + vcg::Box3d FullBBox; + for (auto ni = std::begin(nodeMap); ni != std::end(nodeMap); ++ni) { if (ni->second->glued) { - FullBBox.Add(Matrix44m::Construct(ni->second->tr()), ni->second->bbox()); + FullBBox.Add(vcg::Matrix44d::Construct(ni->second->tr()), ni->second->bbox()); } } return FullBBox; From 2b507b55400369df87bfc6fe5f58b0e46ed72d4c Mon Sep 17 00:00:00 2001 From: gabryon99 Date: Tue, 14 Sep 2021 14:19:17 +0200 Subject: [PATCH 055/117] add align_global.h --- CMakeLists.txt | 487 +++++++++--------- vcg/complex/algorithms/align_global.h | 695 ++++++++++++++++++++++++++ 2 files changed, 939 insertions(+), 243 deletions(-) create mode 100644 vcg/complex/algorithms/align_global.h diff --git a/CMakeLists.txt b/CMakeLists.txt index d8555cf0..a4f6c76d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,263 +30,264 @@ elseif(ALLOW_BUNDLED_EIGEN AND EXISTS "${VCG_EIGEN_DIR}/Eigen/Eigen") set(EIGEN_INCLUDE_DIRS ${VCG_EIGEN_DIR}) else() message( - FATAL_ERROR + FATAL_ERROR "Eigen is required - at least one of ALLOW_SYSTEM_EIGEN or ALLOW_BUNDLED_EIGEN must be enabled and found.") endif() ### VCGLib headers and sources set(VCG_HEADERS - vcg/complex/append.h - vcg/complex/all_types.h - vcg/complex/complex.h - vcg/complex/allocate.h - vcg/complex/exception.h - vcg/complex/algorithms/overlap_estimation.h - vcg/complex/algorithms/dual_meshing.h - vcg/complex/algorithms/intersection.h - vcg/complex/algorithms/clip.h - vcg/complex/algorithms/geodesic.h - vcg/complex/algorithms/parametrization/poisson_solver.h - vcg/complex/algorithms/parametrization/uv_utils.h - vcg/complex/algorithms/parametrization/distortion.h - vcg/complex/algorithms/parametrization/tangent_field_operators.h - vcg/complex/algorithms/parametrization/voronoi_atlas.h - vcg/complex/algorithms/edge_collapse.h - vcg/complex/algorithms/hole.h - vcg/complex/algorithms/align_pair.h - vcg/complex/algorithms/closest.h - vcg/complex/algorithms/tetra_implicit_smooth.h - vcg/complex/algorithms/bitquad_support.h - vcg/complex/algorithms/skeleton.h - vcg/complex/algorithms/symmetry.h - vcg/complex/algorithms/voronoi_volume_sampling.h - vcg/complex/algorithms/polygon_polychord_collapse.h - vcg/complex/algorithms/inside.h - vcg/complex/algorithms/local_optimization/tri_edge_flip.h - vcg/complex/algorithms/local_optimization/quad_diag_collapse.h - vcg/complex/algorithms/local_optimization/tri_edge_collapse_quadric.h - vcg/complex/algorithms/local_optimization/tri_edge_collapse_quadric_tex.h - vcg/complex/algorithms/local_optimization/tri_edge_collapse.h - vcg/complex/algorithms/local_optimization/tetra_edge_collapse.h - vcg/complex/algorithms/polygonal_algorithms.h - vcg/complex/algorithms/inertia.h - vcg/complex/algorithms/mesh_assert.h - vcg/complex/algorithms/occupancy_grid.h - vcg/complex/algorithms/meshtree.h - vcg/complex/algorithms/cut_tree.h - vcg/complex/algorithms/nring.h - vcg/complex/algorithms/tetra/tetfuse_collapse.h - vcg/complex/algorithms/stat.h - vcg/complex/algorithms/ransac_matching.h - vcg/complex/algorithms/refine.h - vcg/complex/algorithms/outline_support.h - vcg/complex/algorithms/convex_hull.h - vcg/complex/algorithms/clean.h - vcg/complex/algorithms/mesh_to_matrix.h - vcg/complex/algorithms/quadrangulator.h - vcg/complex/algorithms/isotropic_remeshing.h - vcg/complex/algorithms/smooth.h - vcg/complex/algorithms/autoalign_4pcs.h - vcg/complex/algorithms/local_optimization.h - vcg/complex/algorithms/curve_on_manifold.h - vcg/complex/algorithms/clustering.h - vcg/complex/algorithms/refine_loop.h - vcg/complex/algorithms/cylinder_clipping.h - vcg/complex/algorithms/pointcloud_normal.h - vcg/complex/algorithms/bitquad_creation.h - vcg/complex/algorithms/crease_cut.h - vcg/complex/algorithms/implicit_smooth.h - vcg/complex/algorithms/voronoi_remesher.h - vcg/complex/algorithms/polygon_support.h - vcg/complex/algorithms/point_sampling.h - vcg/complex/algorithms/create/mc_lookup_table.h - vcg/complex/algorithms/create/mc_trivial_walker.h - vcg/complex/algorithms/create/extrude.h - vcg/complex/algorithms/create/resampler.h - vcg/complex/algorithms/create/ball_pivoting.h - vcg/complex/algorithms/create/readme.txt - vcg/complex/algorithms/create/zonohedron.h - vcg/complex/algorithms/create/platonic.h - vcg/complex/algorithms/create/marching_cubes.h - vcg/complex/algorithms/create/plymc/voxel.h - vcg/complex/algorithms/create/plymc/simplemeshprovider.h - vcg/complex/algorithms/create/plymc/tri_edge_collapse_mc.h - vcg/complex/algorithms/create/plymc/volume.h - vcg/complex/algorithms/create/plymc/plymc.h - vcg/complex/algorithms/create/plymc/svoxel.h - vcg/complex/algorithms/create/tetramesh_support.h - vcg/complex/algorithms/create/advancing_front.h - vcg/complex/algorithms/textcoord_optimization.h - vcg/complex/algorithms/bitquad_optimization.h - vcg/complex/algorithms/halfedge_quad_clean.h - vcg/complex/algorithms/voronoi_processing.h - vcg/complex/algorithms/update/quality.h - vcg/complex/algorithms/update/selection.h - vcg/complex/algorithms/update/fitmaps.h - vcg/complex/algorithms/update/component_ep.h - vcg/complex/algorithms/update/texture.h - vcg/complex/algorithms/update/curvature_fitting.h - vcg/complex/algorithms/update/normal.h - vcg/complex/algorithms/update/position.h - vcg/complex/algorithms/update/halfedge_topology.h - vcg/complex/algorithms/update/topology.h - vcg/complex/algorithms/update/flag.h - vcg/complex/algorithms/update/bounding.h - vcg/complex/algorithms/update/halfedge_indexed.h - vcg/complex/algorithms/update/color.h - vcg/complex/algorithms/update/curvature.h - vcg/complex/algorithms/point_outlier.h - vcg/complex/algorithms/harmonic.h - vcg/complex/algorithms/point_matching_scale.h - vcg/complex/algorithms/attribute_seam.h - vcg/complex/foreach.h - vcg/complex/base.h - vcg/complex/used_types.h - vcg/container/entries_allocation_table.h - vcg/container/container_allocation_table.h - vcg/container/derivation_chain.h - vcg/container/vector_occ.h - vcg/container/simple_temporary_data.h - vcg/space/segment2.h - vcg/space/fitting3.h - vcg/space/tetra3.h - vcg/space/triangle2.h - vcg/space/ray2.h - vcg/space/deprecated_point2.h - vcg/space/point4.h - vcg/space/box2.h - vcg/space/ray3.h - vcg/space/planar_polygon_tessellation.h - vcg/space/texcoord2.h - vcg/space/deprecated_point3.h - vcg/space/intersection/triangle_triangle3.h - vcg/space/distance2.h - vcg/space/point3.h - vcg/space/deprecated_point.h - vcg/space/space.h - vcg/space/point.h - vcg/space/colorspace.h - vcg/space/rect_packer.h - vcg/space/triangle3.h - vcg/space/obox3.h - vcg/space/point2.h - vcg/space/smallest_enclosing.h - vcg/space/color4.h - vcg/space/polygon3.h - vcg/space/line3.h - vcg/space/index/octree.h - vcg/space/index/grid_util2d.h - vcg/space/index/grid_closest.h - vcg/space/index/grid_static_ptr.h - vcg/space/index/grid_util.h - vcg/space/index/spatial_hashing.h - vcg/space/index/closest2d.h - vcg/space/index/grid_static_obj.h - vcg/space/index/kdtree/kdtree.h - vcg/space/index/kdtree/priorityqueue.h - vcg/space/index/kdtree/kdtree_face.h - vcg/space/index/kdtree/mlsutils.h - vcg/space/index/octree_template.h - vcg/space/index/aabb_binary_tree/kclosest.h - vcg/space/index/aabb_binary_tree/closest.h - vcg/space/index/aabb_binary_tree/ray.h - vcg/space/index/aabb_binary_tree/frustum_cull.h - vcg/space/index/aabb_binary_tree/aabb_binary_tree.h - vcg/space/index/aabb_binary_tree/base.h - vcg/space/index/grid_closest2d.h - vcg/space/index/spatial_hashing2d.h - vcg/space/index/space_iterators.h - vcg/space/index/grid_static_ptr2d.h - vcg/space/index/base2d.h - vcg/space/index/base.h - vcg/space/index/perfect_spatial_hashing.h - vcg/space/index/space_iterators2d.h - vcg/space/line2.h - vcg/space/point_matching.h - vcg/space/intersection3.h - vcg/space/deprecated_point4.h - vcg/space/rasterized_outline2_packer.h - vcg/space/box.h - vcg/space/plane3.h - vcg/space/outline2_packer.h - vcg/space/segment3.h - vcg/space/intersection2.h - vcg/space/sphere3.h - vcg/space/box3.h - vcg/space/distance3.h - vcg/math/quadric5.h - vcg/math/factorial.h - vcg/math/eigen_matrix_addons.h - vcg/math/quadric.h - vcg/math/perlin_noise.h - vcg/math/shot.h - vcg/math/spherical_harmonics.h - vcg/math/eigen_matrixbase_addons.h - vcg/math/quaternion.h - vcg/math/similarity.h - vcg/math/disjoint_set.h - vcg/math/random_generator.h - vcg/math/camera.h - vcg/math/linear.h - vcg/math/matrix44.h - vcg/math/eigen.h - vcg/math/old_lin_algebra.h - vcg/math/similarity2.h - vcg/math/gen_normal.h - vcg/math/old_matrix44.h - vcg/math/old_deprecated_matrix.h - vcg/math/old_matrix33.h - vcg/math/polar_decomposition.h - vcg/math/base.h - vcg/math/histogram.h - vcg/math/legendre.h - vcg/math/matrix33.h - vcg/math/old_matrix.h - vcg/simplex/edge/distance.h - vcg/simplex/edge/topology.h - vcg/simplex/edge/pos.h - vcg/simplex/edge/component.h - vcg/simplex/edge/base.h - vcg/simplex/tetrahedron/tetrahedron.h - vcg/simplex/tetrahedron/topology.h - vcg/simplex/tetrahedron/pos.h - vcg/simplex/tetrahedron/component.h - vcg/simplex/tetrahedron/base.h - vcg/simplex/face/component_occ.h - vcg/simplex/face/component_ep.h - vcg/simplex/face/jumping_pos.h - vcg/simplex/face/distance.h - vcg/simplex/face/component_polygon.h - vcg/simplex/face/topology.h - vcg/simplex/face/pos.h - vcg/simplex/face/component.h - vcg/simplex/face/component_ocf.h - vcg/simplex/face/base.h - vcg/simplex/vertex/component_occ.h - vcg/simplex/vertex/component_sph.h - vcg/simplex/vertex/distance.h - vcg/simplex/vertex/component.h - vcg/simplex/vertex/component_ocf.h - vcg/simplex/vertex/base.h - vcg/connectors/halfedge_pos.h - vcg/connectors/hedge.h - vcg/connectors/hedge_component.h + vcg/complex/append.h + vcg/complex/all_types.h + vcg/complex/complex.h + vcg/complex/allocate.h + vcg/complex/exception.h + vcg/complex/algorithms/overlap_estimation.h + vcg/complex/algorithms/dual_meshing.h + vcg/complex/algorithms/intersection.h + vcg/complex/algorithms/clip.h + vcg/complex/algorithms/geodesic.h + vcg/complex/algorithms/parametrization/poisson_solver.h + vcg/complex/algorithms/parametrization/uv_utils.h + vcg/complex/algorithms/parametrization/distortion.h + vcg/complex/algorithms/parametrization/tangent_field_operators.h + vcg/complex/algorithms/parametrization/voronoi_atlas.h + vcg/complex/algorithms/edge_collapse.h + vcg/complex/algorithms/hole.h + vcg/complex/algorithms/align_pair.h + vcg/complex/algorithms/closest.h + vcg/complex/algorithms/tetra_implicit_smooth.h + vcg/complex/algorithms/bitquad_support.h + vcg/complex/algorithms/skeleton.h + vcg/complex/algorithms/symmetry.h + vcg/complex/algorithms/voronoi_volume_sampling.h + vcg/complex/algorithms/polygon_polychord_collapse.h + vcg/complex/algorithms/inside.h + vcg/complex/algorithms/local_optimization/tri_edge_flip.h + vcg/complex/algorithms/local_optimization/quad_diag_collapse.h + vcg/complex/algorithms/local_optimization/tri_edge_collapse_quadric.h + vcg/complex/algorithms/local_optimization/tri_edge_collapse_quadric_tex.h + vcg/complex/algorithms/local_optimization/tri_edge_collapse.h + vcg/complex/algorithms/local_optimization/tetra_edge_collapse.h + vcg/complex/algorithms/polygonal_algorithms.h + vcg/complex/algorithms/inertia.h + vcg/complex/algorithms/mesh_assert.h + vcg/complex/algorithms/occupancy_grid.h + vcg/complex/algorithms/meshtree.h + vcg/complex/algorithms/align_global.h + vcg/complex/algorithms/cut_tree.h + vcg/complex/algorithms/nring.h + vcg/complex/algorithms/tetra/tetfuse_collapse.h + vcg/complex/algorithms/stat.h + vcg/complex/algorithms/ransac_matching.h + vcg/complex/algorithms/refine.h + vcg/complex/algorithms/outline_support.h + vcg/complex/algorithms/convex_hull.h + vcg/complex/algorithms/clean.h + vcg/complex/algorithms/mesh_to_matrix.h + vcg/complex/algorithms/quadrangulator.h + vcg/complex/algorithms/isotropic_remeshing.h + vcg/complex/algorithms/smooth.h + vcg/complex/algorithms/autoalign_4pcs.h + vcg/complex/algorithms/local_optimization.h + vcg/complex/algorithms/curve_on_manifold.h + vcg/complex/algorithms/clustering.h + vcg/complex/algorithms/refine_loop.h + vcg/complex/algorithms/cylinder_clipping.h + vcg/complex/algorithms/pointcloud_normal.h + vcg/complex/algorithms/bitquad_creation.h + vcg/complex/algorithms/crease_cut.h + vcg/complex/algorithms/implicit_smooth.h + vcg/complex/algorithms/voronoi_remesher.h + vcg/complex/algorithms/polygon_support.h + vcg/complex/algorithms/point_sampling.h + vcg/complex/algorithms/create/mc_lookup_table.h + vcg/complex/algorithms/create/mc_trivial_walker.h + vcg/complex/algorithms/create/extrude.h + vcg/complex/algorithms/create/resampler.h + vcg/complex/algorithms/create/ball_pivoting.h + vcg/complex/algorithms/create/readme.txt + vcg/complex/algorithms/create/zonohedron.h + vcg/complex/algorithms/create/platonic.h + vcg/complex/algorithms/create/marching_cubes.h + vcg/complex/algorithms/create/plymc/voxel.h + vcg/complex/algorithms/create/plymc/simplemeshprovider.h + vcg/complex/algorithms/create/plymc/tri_edge_collapse_mc.h + vcg/complex/algorithms/create/plymc/volume.h + vcg/complex/algorithms/create/plymc/plymc.h + vcg/complex/algorithms/create/plymc/svoxel.h + vcg/complex/algorithms/create/tetramesh_support.h + vcg/complex/algorithms/create/advancing_front.h + vcg/complex/algorithms/textcoord_optimization.h + vcg/complex/algorithms/bitquad_optimization.h + vcg/complex/algorithms/halfedge_quad_clean.h + vcg/complex/algorithms/voronoi_processing.h + vcg/complex/algorithms/update/quality.h + vcg/complex/algorithms/update/selection.h + vcg/complex/algorithms/update/fitmaps.h + vcg/complex/algorithms/update/component_ep.h + vcg/complex/algorithms/update/texture.h + vcg/complex/algorithms/update/curvature_fitting.h + vcg/complex/algorithms/update/normal.h + vcg/complex/algorithms/update/position.h + vcg/complex/algorithms/update/halfedge_topology.h + vcg/complex/algorithms/update/topology.h + vcg/complex/algorithms/update/flag.h + vcg/complex/algorithms/update/bounding.h + vcg/complex/algorithms/update/halfedge_indexed.h + vcg/complex/algorithms/update/color.h + vcg/complex/algorithms/update/curvature.h + vcg/complex/algorithms/point_outlier.h + vcg/complex/algorithms/harmonic.h + vcg/complex/algorithms/point_matching_scale.h + vcg/complex/algorithms/attribute_seam.h + vcg/complex/foreach.h + vcg/complex/base.h + vcg/complex/used_types.h + vcg/container/entries_allocation_table.h + vcg/container/container_allocation_table.h + vcg/container/derivation_chain.h + vcg/container/vector_occ.h + vcg/container/simple_temporary_data.h + vcg/space/segment2.h + vcg/space/fitting3.h + vcg/space/tetra3.h + vcg/space/triangle2.h + vcg/space/ray2.h + vcg/space/deprecated_point2.h + vcg/space/point4.h + vcg/space/box2.h + vcg/space/ray3.h + vcg/space/planar_polygon_tessellation.h + vcg/space/texcoord2.h + vcg/space/deprecated_point3.h + vcg/space/intersection/triangle_triangle3.h + vcg/space/distance2.h + vcg/space/point3.h + vcg/space/deprecated_point.h + vcg/space/space.h + vcg/space/point.h + vcg/space/colorspace.h + vcg/space/rect_packer.h + vcg/space/triangle3.h + vcg/space/obox3.h + vcg/space/point2.h + vcg/space/smallest_enclosing.h + vcg/space/color4.h + vcg/space/polygon3.h + vcg/space/line3.h + vcg/space/index/octree.h + vcg/space/index/grid_util2d.h + vcg/space/index/grid_closest.h + vcg/space/index/grid_static_ptr.h + vcg/space/index/grid_util.h + vcg/space/index/spatial_hashing.h + vcg/space/index/closest2d.h + vcg/space/index/grid_static_obj.h + vcg/space/index/kdtree/kdtree.h + vcg/space/index/kdtree/priorityqueue.h + vcg/space/index/kdtree/kdtree_face.h + vcg/space/index/kdtree/mlsutils.h + vcg/space/index/octree_template.h + vcg/space/index/aabb_binary_tree/kclosest.h + vcg/space/index/aabb_binary_tree/closest.h + vcg/space/index/aabb_binary_tree/ray.h + vcg/space/index/aabb_binary_tree/frustum_cull.h + vcg/space/index/aabb_binary_tree/aabb_binary_tree.h + vcg/space/index/aabb_binary_tree/base.h + vcg/space/index/grid_closest2d.h + vcg/space/index/spatial_hashing2d.h + vcg/space/index/space_iterators.h + vcg/space/index/grid_static_ptr2d.h + vcg/space/index/base2d.h + vcg/space/index/base.h + vcg/space/index/perfect_spatial_hashing.h + vcg/space/index/space_iterators2d.h + vcg/space/line2.h + vcg/space/point_matching.h + vcg/space/intersection3.h + vcg/space/deprecated_point4.h + vcg/space/rasterized_outline2_packer.h + vcg/space/box.h + vcg/space/plane3.h + vcg/space/outline2_packer.h + vcg/space/segment3.h + vcg/space/intersection2.h + vcg/space/sphere3.h + vcg/space/box3.h + vcg/space/distance3.h + vcg/math/quadric5.h + vcg/math/factorial.h + vcg/math/eigen_matrix_addons.h + vcg/math/quadric.h + vcg/math/perlin_noise.h + vcg/math/shot.h + vcg/math/spherical_harmonics.h + vcg/math/eigen_matrixbase_addons.h + vcg/math/quaternion.h + vcg/math/similarity.h + vcg/math/disjoint_set.h + vcg/math/random_generator.h + vcg/math/camera.h + vcg/math/linear.h + vcg/math/matrix44.h + vcg/math/eigen.h + vcg/math/old_lin_algebra.h + vcg/math/similarity2.h + vcg/math/gen_normal.h + vcg/math/old_matrix44.h + vcg/math/old_deprecated_matrix.h + vcg/math/old_matrix33.h + vcg/math/polar_decomposition.h + vcg/math/base.h + vcg/math/histogram.h + vcg/math/legendre.h + vcg/math/matrix33.h + vcg/math/old_matrix.h + vcg/simplex/edge/distance.h + vcg/simplex/edge/topology.h + vcg/simplex/edge/pos.h + vcg/simplex/edge/component.h + vcg/simplex/edge/base.h + vcg/simplex/tetrahedron/tetrahedron.h + vcg/simplex/tetrahedron/topology.h + vcg/simplex/tetrahedron/pos.h + vcg/simplex/tetrahedron/component.h + vcg/simplex/tetrahedron/base.h + vcg/simplex/face/component_occ.h + vcg/simplex/face/component_ep.h + vcg/simplex/face/jumping_pos.h + vcg/simplex/face/distance.h + vcg/simplex/face/component_polygon.h + vcg/simplex/face/topology.h + vcg/simplex/face/pos.h + vcg/simplex/face/component.h + vcg/simplex/face/component_ocf.h + vcg/simplex/face/base.h + vcg/simplex/vertex/component_occ.h + vcg/simplex/vertex/component_sph.h + vcg/simplex/vertex/distance.h + vcg/simplex/vertex/component.h + vcg/simplex/vertex/component_ocf.h + vcg/simplex/vertex/base.h + vcg/connectors/halfedge_pos.h + vcg/connectors/hedge.h + vcg/connectors/hedge_component.h - #wrap - wrap/callback.h -) + #wrap + wrap/callback.h + ) set(SOURCES -) + ) if (VCG_HEADER_ONLY) if (NOT TARGET vcglib) # to be sure that vcglib target is created just one time add_library(vcglib INTERFACE) target_include_directories( - vcglib INTERFACE - ${CMAKE_CURRENT_LIST_DIR} - ${EIGEN_INCLUDE_DIRS}) + vcglib INTERFACE + ${CMAKE_CURRENT_LIST_DIR} + ${EIGEN_INCLUDE_DIRS}) #just to show headers in ide add_custom_target(vcglib_ide SOURCES ${VCG_HEADERS}) diff --git a/vcg/complex/algorithms/align_global.h b/vcg/complex/algorithms/align_global.h new file mode 100644 index 00000000..fbd049df --- /dev/null +++ b/vcg/complex/algorithms/align_global.h @@ -0,0 +1,695 @@ +#include +#include + +#include + +#ifndef MESHLAB_ALIGNGLOBAL_H +#define MESHLAB_ALIGNGLOBAL_H + +namespace vcg { + class AlignGlobal { + public: + + /** + * Forward declaration for the `VirtAlign` class. + */ + class Node; + + /** + * Allineamento virtuale tra due mesh (estratto da un alignresult). + * Nota Importante: la trasformazione e i punti qui memorizzati si intendono al netto delle trasf di base delle due mesh in gioco. + * Quindi se qualcuno sposta una mesh le pos dei punti sono ancora valide ma non la trasf da applicarvi. + */ + class VirtAlign + { + public: + + AlignGlobal::Node *Fix, *Mov; // allineamento tra i e j + std::vector FixP; // punti su Fix + std::vector MovP; // punti su Mov + std::vector FixN; // Normali su Fix + std::vector MovN; // Normali su Mov + vcg::Matrix44d M2F; //la matrice da applicare ai punti di Mov per ottenere quelli su Fix + vcg::Matrix44d F2M; //la matrice da applicare ai punti di Fix per ottenere quelli su Mov + /* + Nel caso semplificato che le mesh avessero come trasf di base l'identita' deve valere: + + N2A(N).Apply( P(N)) ~= AdjP(N) + A2N(N).Apply(AdjP(N)) ~= P(N) + + In generale un nodo N qualsiasi dell'VirtAlign vale che: + + N2A(N).Apply( N->M.Apply( P(N)) ) ~= AdjN(N)->M.Apply( AdjP(N) ); + A2M(N).Apply( AdjN(N)->M.Apply(AdjP(N)) ) ~= N->M.Apply( P(N) ); + + in cui il ~= significa uguale al netto dell'errore di allineamento. + + Per ottenere i virtualmate relativi ad un nodo n: + */ + + inline vcg::Matrix44d &N2A(AlignGlobal::Node *n) {if(n==Fix) return F2M; else return M2F;} + inline vcg::Matrix44d &A2N(AlignGlobal::Node *n) {if(n==Fix) return M2F; else return F2M;} + + inline std::vector &P(AlignGlobal::Node *n) {if(n==Fix) return FixP; else return MovP;} + inline std::vector &N(AlignGlobal::Node *n) {if(n==Fix) return FixN; else return MovN;} + + inline std::vector &AdjP(AlignGlobal::Node *n) {if(n==Fix) return MovP; else return FixP;} + inline std::vector &AdjN(AlignGlobal::Node *n) {if(n==Fix) return MovN; else return FixN;} + + AlignGlobal::Node *Adj(Node *n) const { + + assert(n == Fix || n == Mov); + if (n == Fix) return Mov; + + return Fix; + } + + bool Check() const { + + if (FixP.size() != MovP.size()) return false; + + Point3d mp, fp; + + double md = 0, fd = 0; + double md2 = 0, fd2 = 0; + + Matrix44d &MovTr=Mov->M; + Matrix44d &FixTr=Fix->M; + + for (std::size_t i = 0; i < FixP.size(); ++i) { + + mp = MovTr * MovP[i]; + fp = FixTr * FixP[i]; + + md += Distance(fp, M2F * mp); + md2 += SquaredDistance(fp, M2F * mp); + + fd += Distance(mp, F2M * fp); + fd2 += SquaredDistance(mp, F2M * fp); + } + + int nn = static_cast(MovP.size()); + + std::fprintf(stdout, "Arc %3i -> %3i : %i pt\n", Fix->id, Mov->id, nn); + std::fprintf(stdout, "SquaredSum Distance %7.3f %7.3f Avg %7.3f %7.3f\n", fd2, md2, fd2/nn, md2/nn); + std::fprintf(stdout, " Sum Distance %7.3f %7.3f Avg %7.3f %7.3f\n", fd , md , fd/nn, md/nn); + return true; + } + }; + + class Node { + public: + + int id; // id della mesh a cui corrisponde il nodo + int sid; // Subgraph id; + Matrix44d M; // La matrice che mette la mesh nella sua posizione di base; + std::list Adj; + + /*** + * True if the node is inside the active set + */ + bool Active; + + /*** + * False if it's dormant + */ + bool Queued; + bool Discarded; + + Node() : id{-1}, Active{false}, Discarded{false}, Queued{false} {} + + // Allinea un nodo con tutti i suoi vicini + double AlignWithActiveAdj(bool Rigid) { + + std::printf("--- AlignWithActiveAdj --- \nMoving node %i with respect to nodes:", id); + + for (auto li = std::begin(Adj); li != std::end(Adj); ++li) { + if ((*li)->Adj(this)->Active) { + std::printf(" %i,", (*li)->Adj(this)->id); + } + } + + std::printf("\n"); + + //printf("Base Matrix of Node %i\n",id);print(M); + + // Step 1; Costruiamo le due liste di punti da allineare + std::vector FixP, MovP, FixN, MovN; + Box3d FixBox, MovBox; + FixBox.SetNull(); MovBox.SetNull(); + + for (auto li = std::begin(Adj); li != std::end(Adj); ++li) { + + // scorro tutti i nodi adiacenti attivi + if ((*li)->Adj(this)->Active) { + //printf("Base Matrix of Node %i adj to %i\n",id,(*li)->Adj(this)->id); + //print((*li)->Adj(this)->M); + std::vector &AP=(*li)->AdjP(this); // Punti sul nodo adiacente corrente; + std::vector &AN=(*li)->AdjN(this); // Normali sul nodo adiacente corrente; + + //printf("Transf that bring points of %i onto %i\n",id,(*li)->Adj(this)->id); + //print((*li)->A2N(this)); + //printf("Transf that bring points of %i onto %i\n",(*li)->Adj(this)->id,id); + //print((*li)->N2A(this)); + vcg::Point3d pf, nf; + vcg::Point3d pm; + + for (std::size_t i = 0; i < AP.size(); ++i) { + + pf = (*li)->Adj(this)->M*AP[i]; // i punti fissi sono quelli sulla sup degli adiacenti messi nella loro pos corrente + FixP.push_back(pf); + FixBox.Add(pf); + nf=(*li)->Adj(this)->M*Point3d(AP[i]+AN[i])-pf; + nf.Normalize(); + FixN.push_back(nf); + + pm = (*li)->A2N(this)*pf; + MovP.push_back(pm); // i punti che si muovono sono quelli sul adj trasformati in modo tale da cascare sul nodo corr. + MovBox.Add(pm); + } + } + } + + vcg::Matrix44d out; + //if(Rigid) ret=ComputeRigidMatchMatrix(out,FixP,MovP); + //else ret=ComputeMatchMatrix2(out,FixP,FixN,MovP); + if (Rigid) { + ComputeRigidMatchMatrix(FixP,MovP,out); + } + else { + vcg::PointMatchingScale::computeRotoTranslationScalingMatchMatrix(out, FixP, MovP); + } + + Matrix44d outIn=vcg::Inverse(out); + //double maxdiff = MatrixNorm(out); + double maxdiff = MatrixBoxNorm(out,FixBox); + + // printf("Computed Transformation:\n"); print(out);printf("--\n"); + // printf("Collected %i points . Err = %f\n",FixP.size(),maxdiff); + + // La matrice out calcolata e' quella che applicata ai punti MovP li porta su FixP, quindi i punti della mesh corrente + // La nuova posizione di base della mesh diventa quindi + // M * out + // infatti se considero un punto della mesh originale applicarci la nuova matricie significa fare + // p * M * out + + // M=M*out; //--Orig + M = out * M; + + // come ultimo step occorre applicare la matrice trovata a tutti gli allineamenti in gioco. + // scorro tutti i nodi adiacenti attivi + for (auto li = std::begin(Adj); li != std::end(Adj); ++li) { + //print((*li)->N2A(this)); + //print((*li)->A2N(this));printf("--\n"); + + (*li)->N2A(this)=(*li)->N2A(this)*outIn; + (*li)->A2N(this)=(*li)->A2N(this)*out ; + //print((*li)->N2A(this)); + //print((*li)->A2N(this));printf("--\n"); + } + + return maxdiff; + } + + double MatrixNorm(vcg::Matrix44d &NewM) const { + + double maxDiff = 0; + + vcg::Matrix44d diff; + diff.SetIdentity(); + diff = diff-NewM; + + for (int i = 0; i < 4; ++i) { + for (int j = 0; j < 4; ++j) { + maxDiff += (diff[i][j] * diff[i][j]); + } + } + + return maxDiff; + } + + double MatrixBoxNorm(vcg::Matrix44d &NewM, vcg::Box3d &bb) const { + + double maxDiff = 0; + vcg::Point3d pt; + + pt = Point3d(bb.min[0], bb.min[1], bb.min[2]); maxDiff = std::max(maxDiff, Distance(pt, NewM * pt)); + pt = Point3d(bb.max[0], bb.min[1], bb.min[2]); maxDiff = std::max(maxDiff, Distance(pt, NewM * pt)); + pt = Point3d(bb.min[0], bb.max[1], bb.min[2]); maxDiff = std::max(maxDiff, Distance(pt, NewM * pt)); + pt = Point3d(bb.max[0], bb.max[1], bb.min[2]); maxDiff = std::max(maxDiff, Distance(pt, NewM * pt)); + pt = Point3d(bb.min[0], bb.min[1], bb.max[2]); maxDiff = std::max(maxDiff, Distance(pt, NewM * pt)); + pt = Point3d(bb.max[0], bb.min[1], bb.max[2]); maxDiff = std::max(maxDiff, Distance(pt, NewM * pt)); + pt = Point3d(bb.min[0], bb.max[1], bb.max[2]); maxDiff = std::max(maxDiff, Distance(pt, NewM * pt)); + pt = Point3d(bb.max[0], bb.max[1], bb.max[2]); maxDiff = std::max(maxDiff, Distance(pt, NewM * pt)); + + return maxDiff; + } + + int PushBackActiveAdj(std::queue &Q) { + + assert(Active); + + int count = 0; + AlignGlobal::Node *pt; + + for (auto li = std::begin(Adj); li != std::end(Adj); ++li) { + + pt = (*li)->Adj(this); + + if (pt->Active && !pt->Queued) { + ++count; + pt->Queued=true; + Q.push(pt); + } + } + return count; + } + + int DormantAdjNum() { + + int count = 0; + + for (auto li = std::begin(Adj); li != std::end(Adj); ++li) { + if (!(*li)->Adj(this)->Active) ++count; + } + + return count; + } + + int ActiveAdjNum() { + + int count = 0; + + for (auto li = std::begin(Adj); li != std::end(Adj); ++li) { + if ((*li)->Adj(this)->Active) ++count; + } + + return count; + } + }; + + class SubGraphInfo { + public: + int sid; + int size; + Node *root; + }; + + std::list N; + std::list A; + + /** + * Descrittori delle componenti connesse, riempito dalla ComputeConnectedComponents + */ + std::list CC; + + static inline void LOG( FILE *fp, const char * f, ... ) { + + if (fp == 0) return; + + va_list marker; + va_start(marker, f); + std::vfprintf(fp, f, marker); + va_end(marker); + std::fflush(fp); + } + + inline int DormantNum() const { + + int count = 0; + + for (auto li = std::begin(N); li != std::end(N); ++li) { + if (!(*li).Active) ++count; + } + + return count; + } + + inline int ActiveNum() const { + + int count = 0; + + for (auto li = std::begin(N); li != std::end(N); ++li) { + if ((*li).Active) ++count; + } + + return count; + } + + bool CheckGraph() { + + std::vector Visited(N.size(), false); + std::stack st; + + st.push(&(*N.begin())); + while (!st.empty()) { + + AlignGlobal::Node *cur=st.top(); + st.pop(); + // std::printf("Visiting node %i\n",cur->id); + + for (auto li = std::begin(cur->Adj); li != std::end(cur->Adj); ++li) { + if (!Visited[(*li)->Adj(cur)->id]) { + Visited[(*li)->Adj(cur)->id] = true; + st.push((*li)->Adj(cur)); + } + } + } + + size_t cnt = std::count(std::begin(Visited), std::end(Visited), true); + std::printf("Nodes that can be reached from root %zu on %zu \n", cnt, N.size()); + + return (cnt == N.size()); + } + + void Dump(FILE *fp) const { + std::fprintf(fp, "Alignment Graph of %lu nodes and %lu arcs\n", N.size(), A.size()); + // list::iterator li; + // for(li=A.begin();li!=A.end();++li) + // printf("Arc : %3i ->%3i\n",(*li)->Fix->id,(*li)->Mov->id); + } + + int ComputeConnectedComponents() { + + std::printf("Building Connected Components on a graph with %lu nodes and %lu arcs\n", N.size(), A.size()); + + CC.clear(); + + std::stack ToReach; // nodi ancora da visitare + std::stack st; // nodi che si stanno visitando + + for (auto li = std::begin(N); li != std::end(N); ++li) { + (*li).sid = -1; + ToReach.push(&*li); + } + + int cnt = 0; + + while (!ToReach.empty()) { + + SubGraphInfo sg; + st.push(&*ToReach.top()); + ToReach.pop(); + + assert(st.top()->sid==-1); + + sg.root=st.top(); + sg.sid=cnt; + sg.size=0; + st.top()->sid=cnt; + + while (!st.empty()) { + + AlignGlobal::Node *cur=st.top(); + st.pop(); + ++sg.size; + + assert(cur->sid==cnt); + // std::printf("Visiting node %2i %2i\n",cur->id,cur->sid); + + for (auto li = std::begin(cur->Adj); li != std::end(cur->Adj); ++li) { + + if ((*li)->Adj(cur)->sid == -1) { + (*li)->Adj(cur)->sid=cnt; + st.push((*li)->Adj(cur)); + } + else { + assert((*li)->Adj(cur)->sid == cnt); + } + } + + } + + cnt++; + CC.push_back(sg); + + while (!ToReach.empty() && ToReach.top()->sid != -1) ToReach.pop(); + } + + return cnt; + } + + void Clear() { + + for (auto li = std::begin(A); li != std::end(A); ++li) { + delete (*li); + } + + N.clear(); + A.clear(); + } + + void MakeAllDormant() { + for (auto li = std::begin(N); li != std::end(N); ++li) { + (*li).Active=false; + } + } + + bool GlobalAlign(const std::map &Names, const double epsilon, int maxiter, bool Rigid, FILE *elfp, vcg::CallBackPos* cb) { + + double change; + int step = 0, localmaxiter; + + if (cb != NULL) cb(0, "Global Alignment..."); + AlignGlobal::LOG(elfp,"----------------\n----------------\nGlobalAlignment (target eps %7.3f)\n", epsilon); + + std::queue Q; + MakeAllDormant(); + AlignGlobal::Node *curr = ChooseDormantWithMostDormantLink(); + curr->Active = true; + + int cursid = curr->sid; + AlignGlobal::LOG(elfp, "Root node %i '%s' with %i dormant link\n", curr->id, Names.find(curr->id)->second.c_str(), curr->DormantAdjNum()); + + while (DormantNum() > 0) { + + AlignGlobal::LOG(elfp,"---------\nGlobalAlignment loop DormantNum = %i\n", DormantNum()); + + curr = ChooseDormantWithMostActiveLink(); + if (!curr) { + // la componente connessa e' finita e si passa alla successiva cercando un dormant con tutti dormant. + AlignGlobal::LOG(elfp,"\nCompleted Connected Component %i\n", cursid); + AlignGlobal::LOG(elfp,"\nDormant Num: %i\n", DormantNum()); + + curr = ChooseDormantWithMostDormantLink(); + if (curr == 0) { + AlignGlobal::LOG(elfp,"\nFailed ChooseDormantWithMostDormantLink, chosen id:%i\n" ,0); + break; // non ci sono piu' componenti connesse composte da piu' di una singola mesh. + } + else { + AlignGlobal::LOG(elfp,"\nCompleted ChooseDormantWithMostDormantLink, chosen id:%i\n" ,curr->id); + } + + curr->Active = true; + cursid = curr->sid; + curr = ChooseDormantWithMostActiveLink (); + if (curr == 0) { + AlignGlobal::LOG(elfp, "\nFailed ChooseDormantWithMostActiveLink, chosen id:%i\n", 0); + } + else { + AlignGlobal::LOG(elfp, "\nCompleted ChooseDormantWithMostActiveLink, chosen id:%i\n", curr->id); + } + } + + AlignGlobal::LOG(elfp,"\nAdded node %i '%s' with %i/%i Active link\n",curr->id,Names.find(curr->id)->second.c_str(),curr->ActiveAdjNum(),curr->Adj.size()); + curr->Active=true; + curr->Queued=true; + + // Si suppone, ad occhio, che per risistemare un insieme di n mesh servano al piu' 10n passi; + localmaxiter = ActiveNum() * 10; + Q.push(curr); + step = 0; + + // Ciclo interno di allineamento + while (!Q.empty()) { + + curr = Q.front(); + Q.pop(); + + curr->Queued=false; + change = curr->AlignWithActiveAdj(Rigid); + step++; + + AlignGlobal::LOG(elfp, " Step %5i Queue size %5i Moved %4i err %10.4f\n", step, Q.size(), curr->id, change); + + if (change > epsilon) { + + curr->PushBackActiveAdj(Q); + AlignGlobal::LOG(elfp," Large Change pushing back active nodes adj to %i to Q (new size %i)\n",curr->id,Q.size()); + + if (change > epsilon * 1000) { + std::printf("Large Change Warning\n\n"); + } + } + if (step > localmaxiter) return false; + if (step > maxiter) return false; + } + } + + if (!curr) { + + AlignGlobal::LOG(elfp,"Alignment failed for %i meshes:\n",DormantNum()); + for (auto li = std::begin(N); li != std::end(N); ++li){ + if (!(*li).Active) { + //(*li).M.SetIdentity(); + (*li).Discarded=true; + AlignGlobal::LOG(elfp, "%5i\n", (*li).id); + } + } + } + + AlignGlobal::LOG(elfp,"Completed Alignment in %i steps with error %f\n",step,epsilon); + return true; + } + + AlignGlobal::Node* ChooseDormantWithMostDormantLink() { + + int MaxAdjNum = 0; + AlignGlobal::Node *BestNode = 0; + + for (auto li = std::begin(N); li != std::end(N); ++li) { + if (!(*li).Active) { + int AdjNum = (*li).DormantAdjNum(); + if (AdjNum > MaxAdjNum) { + MaxAdjNum = AdjNum; + BestNode = &(*li); + } + } + } + + assert(BestNode); + assert(!BestNode->Queued); + assert(!BestNode->Active); + + return BestNode; + } + + AlignGlobal::Node* ChooseDormantWithMostActiveLink() { + + int MaxAdjNum = 0; + AlignGlobal::Node* BestNode = 0; + + for (auto li = std::begin(N); li != std::end(N); ++li) { + if (!(*li).Active) { + int AdjNum = (*li).ActiveAdjNum(); + if (AdjNum > MaxAdjNum) { + MaxAdjNum = AdjNum; + BestNode = &(*li); + } + } + } + + if (!BestNode){ + // Abbiamo finito di sistemare questa componente connessa. + std::printf("Warning! Unable to find a Node with at least an active link!!\n"); + return 0; + } + + assert(BestNode); + assert(!BestNode->Queued); + assert(!BestNode->Active); + + return BestNode; + } + + void BuildGraph(std::vector &Res, std::vector &Tr, std::vector &Id) { + + Clear(); + // si suppone che la matrice Tr[i] sia relativa ad un nodo con id Id[i]; + int mn = static_cast(Tr.size()); + + // printf("building graph\n"); + AlignGlobal::Node rgn; + rgn.Active = false; + rgn.Queued = false; + rgn.Discarded = false; + + std::map Id2N; + std::map Id2I; + + for (int i = 0; i < mn; ++i) { + rgn.id = Id[i]; + rgn.M = Tr[i]; + N.push_back(rgn); + Id2N[rgn.id] = &(N.back()); + Id2I[rgn.id] = i; + } + + std::printf("building %zu graph arcs\n",Res.size()); + AlignGlobal::VirtAlign *tv; + + // Ciclo principale in cui si costruiscono i vari archi + // Si assume che i result siano fatti nel sistema di riferimento della matrici fix. + + for (auto rii = std::begin(Res); rii != std::end(Res); ++rii) { + + AlignPair::Result *ri = *rii; + tv = new VirtAlign(); + tv->Fix = Id2N[(*ri).FixName]; + tv->Mov = Id2N[(*ri).MovName]; + tv->Fix->Adj.push_back(tv); + tv->Mov->Adj.push_back(tv); + tv->FixP = (*ri).Pfix; + tv->MovP = (*ri).Pmov; + tv->FixN = (*ri).Nfix; + tv->MovN = (*ri).Nmov; + + /* + + Siano: + Pf e Pm i punti sulle mesh fix e mov nei sist di rif originali + Pft e Pmt i punti sulle mesh fix e mov dopo le trasf correnti; + Mf e Mm le trasf che portano le mesh fix e mov nelle posizioni correnti; + If e Im le trasf inverse di cui sopra + Vale: + Pft = Mf*Pf e Pmt = Mm*Pm + Pf = If*Pft e Pm = Im*Pmt + + Res * Pm = Pf; + Res * Im * Pmt = If * Pft + Mf * Res * Im * Pmt = Mf * If * Pft + (Mf * Res * Im) * Pmt = Pft + + */ + Matrix44d Mm = Tr[Id2I[(*ri).MovName]]; + Matrix44d Mf = Tr[Id2I[(*ri).FixName]]; + Matrix44d Im = Inverse(Mm); + Matrix44d If = Inverse(Mf); + + Matrix44d NewTr = Mf * (*ri).Tr * Im; // --- orig + + tv->M2F = NewTr; + tv->F2M = Inverse(NewTr); + + assert(tv->Check()); + A.push_back(tv); + } + + ComputeConnectedComponents(); + } + + bool GetMatrixVector(std::vector &Tr, std::vector &Id) { + + std::map Id2N; + + Tr.clear(); + + for (auto li = std::begin(N); li != std::end(N); ++li) { + Id2N[(*li).id] = &*li; + } + + Tr.resize(Id.size()); + + for (std::size_t i = 0; i < Id.size(); ++i) { + + if (Id2N[Id[i]] == 0) return false; + Tr[i] = Id2N[Id[i]]->M; + } + + return false; + } + + }; +} + +#endif //MESHLAB_ALIGNGLOBAL_H From df6f92da0125db90f2a2df16bd5a557869b03e21 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Tue, 14 Sep 2021 16:49:09 +0200 Subject: [PATCH 056/117] removed old .clang-format file --- wrap/openfbx/.clang-format | 42 -------------------------------------- 1 file changed, 42 deletions(-) delete mode 100755 wrap/openfbx/.clang-format diff --git a/wrap/openfbx/.clang-format b/wrap/openfbx/.clang-format deleted file mode 100755 index 2950cfd3..00000000 --- a/wrap/openfbx/.clang-format +++ /dev/null @@ -1,42 +0,0 @@ -BasedOnStyle: LLVM - -AlignAfterOpenBracket : false -AlignEscapedNewlinesLeft : true -AlignConsecutiveAssignments : false -AllowAllParametersOfDeclarationOnNextLine : false -AccessModifierOffset : -4 -AllowShortCaseLabelsOnASingleLine : true -AllowShortFunctionsOnASingleLine : Inline -AllowShortIfStatementsOnASingleLine : true -AllowShortLoopsOnASingleLine : true -AlwaysBreakAfterDefinitionReturnType : None -BinPackArguments : false -BinPackParameters : false -BreakBeforeBraces : Allman -BreakConstructorInitializersBeforeComma : true -ColumnLimit : 120 -ConstructorInitializerIndentWidth : 4 -ConstructorInitializerAllOnOneLineOrOnePerLine : false -ContinuationIndentWidth : 4 -IndentCaseLabels : true -IndentWidth : 4 -KeepEmptyLinesAtTheStartOfBlocks : true -MaxEmptyLinesToKeep : 2 -NamespaceIndentation : None -PenaltyBreakBeforeFirstCallParameter : 0 -PenaltyReturnTypeOnItsOwnLine : 1000 -PointerAlignment : Left -SpaceAfterCStyleCast : false -SpaceBeforeAssignmentOperators : true -SpaceBeforeParens : true -SpaceInEmptyParentheses : false -SpacesBeforeTrailingComments : 1 -SpacesInAngles : false -SpacesInCStyleCastParentheses : false -SpacesInParentheses : false -SpacesInSquareBrackets : false -Standard : Cpp11 -TabWidth : 4 -UseTab : true - - From 30f0383fc60e0137715a20dc9bcfa4b13b2765aa Mon Sep 17 00:00:00 2001 From: gabryon99 Date: Tue, 14 Sep 2021 17:47:56 +0200 Subject: [PATCH 057/117] add ScalarType to OccupancyGrid and MeshTree --- vcg/complex/algorithms/meshtree.h | 22 +++++++++++----------- vcg/complex/algorithms/occupancy_grid.h | 12 ++++++------ 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/vcg/complex/algorithms/meshtree.h b/vcg/complex/algorithms/meshtree.h index 3bd18a9a..081c81b2 100644 --- a/vcg/complex/algorithms/meshtree.h +++ b/vcg/complex/algorithms/meshtree.h @@ -11,7 +11,7 @@ namespace vcg { - template + template class MeshTree { public: @@ -24,11 +24,11 @@ namespace vcg { MeshNode(MeshType *_m) : m{_m}, glued{false} {} - vcg::Matrix44d &tr() { + vcg::Matrix44 &tr() { return m->cm.Tr; } - const vcg::Box3d &bbox() const { + const vcg::Box3 &bbox() const { return m->cm.bbox; } @@ -47,7 +47,7 @@ namespace vcg { std::map nodeMap; std::vector resultList; - vcg::OccupancyGrid OG; + vcg::OccupancyGrid OG; vcg::CallBackPos * cb; MeshType *MM(unsigned int i) { @@ -137,12 +137,12 @@ namespace vcg { std::sprintf(buf, "Computing Overlaps %i glued meshes...\n", gluedNum()); cb(0, buf); - OG.Init(static_cast(nodeMap.size()), vcg::Box3d::Construct(gluedBBox()), mtp.OGSize); + OG.Init(static_cast(nodeMap.size()), vcg::Box3::Construct(gluedBBox()), mtp.OGSize); for(auto ni = std::begin(nodeMap); ni != std::end(nodeMap); ++ni) { MeshTree::MeshNode *mn = ni->second; if (mn->glued) { - OG.AddMesh(mn->m->cm, vcg::Matrix44d::Construct(mn->tr()), mn->Id()); + OG.AddMesh(mn->m->cm, vcg::Matrix44::Construct(mn->tr()), mn->Id()); } } @@ -357,22 +357,22 @@ namespace vcg { result.MovName=movId; } - inline vcg::Box3d bbox() { + inline vcg::Box3 bbox() { - vcg::Box3d FullBBox; + vcg::Box3 FullBBox; for (auto ni = std::begin(nodeMap); ni != std::end(nodeMap); ++ni) { FullBBox.Add(vcg::Matrix44d::Construct(ni->second->tr()),ni->second->bbox()); } return FullBBox; } - inline vcg::Box3d gluedBBox() { + inline vcg::Box3 gluedBBox() { - vcg::Box3d FullBBox; + vcg::Box3 FullBBox; for (auto ni = std::begin(nodeMap); ni != std::end(nodeMap); ++ni) { if (ni->second->glued) { - FullBBox.Add(vcg::Matrix44d::Construct(ni->second->tr()), ni->second->bbox()); + FullBBox.Add(vcg::Matrix44::Construct(ni->second->tr()), ni->second->bbox()); } } return FullBBox; diff --git a/vcg/complex/algorithms/occupancy_grid.h b/vcg/complex/algorithms/occupancy_grid.h index 1c74ae6f..6ddcfd9c 100644 --- a/vcg/complex/algorithms/occupancy_grid.h +++ b/vcg/complex/algorithms/occupancy_grid.h @@ -13,7 +13,7 @@ #define OG_MESH_INFO_MAX_STAT 64 namespace vcg { - template + template class OccupancyGrid { public: @@ -165,7 +165,7 @@ namespace vcg { */ std::map VM; - bool Init(int _mn, Box3d bb, int size) { + bool Init(int _mn, Box3 bb, int size) { // the number of meshes (including all the unused ones; eg it is the range of the possible id) mn = _mn; @@ -180,7 +180,7 @@ namespace vcg { return true; } - void Add(const char *MeshName, Matrix44d &Tr, int id) { + void Add(const char *MeshName, Matrix44 &Tr, int id) { AlignPair::A2Mesh M; @@ -190,9 +190,9 @@ namespace vcg { AddMesh(M,Tr,id); } - void AddMeshes(std::vector &names, std::vector &trv,int size) { + void AddMeshes(std::vector &names, std::vector> &trv,int size) { - Box3d bb, totalbb; + Box3 bb, totalbb; bb.SetNull(); totalbb.SetNull(); @@ -212,7 +212,7 @@ namespace vcg { } } - void AddMesh(MeshType &mesh, const Matrix44d &Tr, int ind) { + void AddMesh(MeshType &mesh, const Matrix44 &Tr, int ind) { Matrix44f Trf; Trf.Import(Tr); From 1980f1a775ba3d2a020c0960286f58ea4be9813a Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Wed, 15 Sep 2021 15:15:28 +0200 Subject: [PATCH 058/117] curvature ocf const correctness --- vcg/simplex/vertex/component_ocf.h | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/vcg/simplex/vertex/component_ocf.h b/vcg/simplex/vertex/component_ocf.h index c063308c..8750066c 100644 --- a/vcg/simplex/vertex/component_ocf.h +++ b/vcg/simplex/vertex/component_ocf.h @@ -494,13 +494,17 @@ public: typedef typename CurvatureDirType::CurVecType CurVecType; typedef typename CurvatureDirType::CurScalarType CurScalarType; - CurVecType &PD1() { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CuDV[(*this).Index()].max_dir;} - CurVecType &PD2() { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CuDV[(*this).Index()].min_dir;} - CurVecType cPD1() const { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CuDV[(*this).Index()].max_dir;} - CurVecType cPD2() const { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CuDV[(*this).Index()].min_dir;} + CurVecType& PD1() { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CuDV[(*this).Index()].max_dir;} + CurVecType& PD2() { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CuDV[(*this).Index()].min_dir;} + const CurVecType& cPD1() const { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CuDV[(*this).Index()].max_dir;} + const CurVecType& cPD2() const { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CuDV[(*this).Index()].min_dir;} + const CurVecType& PD1() const { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CuDV[(*this).Index()].max_dir;} + const CurVecType& PD2() const { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CuDV[(*this).Index()].min_dir;} - CurScalarType &K1() { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CuDV[(*this).Index()].k1;} - CurScalarType &K2() { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CuDV[(*this).Index()].k2;} + CurScalarType& K1() { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CuDV[(*this).Index()].k1;} + CurScalarType& K2() { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CuDV[(*this).Index()].k2;} + CurScalarType K1() const { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CuDV[(*this).Index()].k1;} + CurScalarType K2() const { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CuDV[(*this).Index()].k2;} CurScalarType cK1() const { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CuDV[(*this).Index()].k1;} CurScalarType cK2() const { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CuDV[(*this).Index()].k2;} From 6d7eeb4908c500ec3ea6bc3056f3ef8e8b756135 Mon Sep 17 00:00:00 2001 From: gabryon99 Date: Wed, 15 Sep 2021 23:47:42 +0200 Subject: [PATCH 059/117] format occupancy_grid.h --- vcg/complex/algorithms/occupancy_grid.h | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/vcg/complex/algorithms/occupancy_grid.h b/vcg/complex/algorithms/occupancy_grid.h index 6ddcfd9c..e4603119 100644 --- a/vcg/complex/algorithms/occupancy_grid.h +++ b/vcg/complex/algorithms/occupancy_grid.h @@ -73,9 +73,9 @@ namespace vcg { bool operator < (const MeshCounter &c) const { - if (cnt==c.cnt) return false; + if (cnt == c.cnt) return false; - size_t ii = 0; + std::size_t ii = 0; while (ii < MeshCounter::MaxVal()){ if (cnt[ii] != c.cnt[ii]) { @@ -95,9 +95,9 @@ namespace vcg { public: - int id; // the id of the mesh - int area; // number of voxels in the OG touched by this mesh - int coverage; // quanto e' ricoperta da altre mesh eccetto se stessa (eg: se ho due mesh di 1000 con overlap al 30% la covrg e' 300) + int id {-1}; // the id of the mesh + int area {0}; // number of voxels in the OG touched by this mesh + int coverage {0}; // quanto e' ricoperta da altre mesh eccetto se stessa (eg: se ho due mesh di 1000 con overlap al 30% la covrg e' 300) bool used = false; @@ -106,12 +106,8 @@ namespace vcg { // are covered by othermeshes. Sum(densityDistribution) == area; // if densityDistribution[1] > 0 means that this mesh is the unique to cover some portion of the space. - OGMeshInfo() { - Init(-1); - } - void Init(int _id) { - coverage=0;area=0; id=_id; + id=_id; } bool operator < (OGMeshInfo &o) const { @@ -251,7 +247,7 @@ namespace vcg { std::vector VA; // virtual arcs VA.resize(mn * mn, 0); - std::map, int> VAMap; + std::map, int> VAMap; // First Loop: // Scan the grid and update possible arc count @@ -412,7 +408,7 @@ namespace vcg { int ccnt = 0; MaxCount = 0; - int sz=G.size(); + int sz = G.size(); for (int i = 0; i < sz; ++i) From 3cd68269fd79bfe3c328dac2ed517550da576e3d Mon Sep 17 00:00:00 2001 From: gabryon99 Date: Wed, 15 Sep 2021 23:48:59 +0200 Subject: [PATCH 060/117] replaced for with smart ones --- vcg/complex/algorithms/meshtree.h | 96 ++++++++++++++++--------------- 1 file changed, 49 insertions(+), 47 deletions(-) diff --git a/vcg/complex/algorithms/meshtree.h b/vcg/complex/algorithms/meshtree.h index 081c81b2..f5221f08 100644 --- a/vcg/complex/algorithms/meshtree.h +++ b/vcg/complex/algorithms/meshtree.h @@ -22,7 +22,7 @@ namespace vcg { bool glued; MeshType *m; - MeshNode(MeshType *_m) : m{_m}, glued{false} {} + explicit MeshNode(MeshType *_m) : m{_m}, glued{false} {} vcg::Matrix44 &tr() { return m->cm.Tr; @@ -47,21 +47,19 @@ namespace vcg { std::map nodeMap; std::vector resultList; - vcg::OccupancyGrid OG; - vcg::CallBackPos * cb; + vcg::OccupancyGrid OG{}; + vcg::CallBackPos* cb = vcg::DummyCallBackPos; MeshType *MM(unsigned int i) { return nodeMap[i]->m; } - MeshTree() {} - - MeshTree(vcg::CallBackPos* _cb) : cb{_cb} {} + MeshTree() = default; void clear() { - for (auto ni = std::begin(nodeMap); ni != std::end(nodeMap); ++ni) { - delete ni->second; + for (auto& ni : nodeMap) { + delete ni.second; } nodeMap.clear(); @@ -73,8 +71,8 @@ namespace vcg { auto li = std::begin(resultList); while (li != resultList.end()) { - if (li->MovName==mp->Id() || li->FixName==mp->Id()) { - li=resultList.erase(li); + if (li->MovName == mp->Id() || li->FixName == mp->Id()) { + li = resultList.erase(li); } else { ++li; @@ -84,21 +82,21 @@ namespace vcg { vcg::AlignPair::Result* findResult(int id1, int id2) { - for (auto li = std::begin(resultList); li != std::end(resultList); ++li) { - if ((li->MovName==id1 && li->FixName==id2) || (li->MovName==id2 && li->FixName==id1) ) { - return &*li; + for (auto& li : resultList) { + if ((li.MovName == id1 && li.FixName == id2) || (li.MovName == id2 && li.FixName == id1) ) { + return &li; } } - return 0; + return nullptr; } MeshTree::MeshNode *find(int id) { MeshTree::MeshNode *mp = nodeMap[id]; - if (mp==0 || mp->Id()!=id) { - assert("You are trying to find an unexistent mesh"==0); + if (mp == nullptr || mp->Id() != id) { + assert("You are trying to find a non existent mesh" == nullptr); } return mp; @@ -106,24 +104,23 @@ namespace vcg { MeshTree::MeshNode *find(MeshType *m) { - for (auto ni = std::begin(nodeMap); ni != std::end(nodeMap); ++ni) { - if (ni->second->m==m) return ni->second; + for (auto& ni : nodeMap) { + if (ni.second->m == m) return ni.second; } - assert("You are trying to find an unexistent mesh" ==0); - return 0; + assert("You are trying to find a non existent mesh" == nullptr); + return nullptr; } int gluedNum() { - int cnt = 0; + int count = 0; - for (auto ni = std::begin(nodeMap); ni != std::end(nodeMap); ++ni) { - MeshTree::MeshNode *mn=ni->second; - if (mn->glued) ++cnt; + for (auto& ni : nodeMap) { + if (ni.second->glued) ++count; } - return cnt; + return count; } void Process(vcg::AlignPair::Param &ap, MeshTree::Param &mtp) { @@ -139,8 +136,8 @@ namespace vcg { OG.Init(static_cast(nodeMap.size()), vcg::Box3::Construct(gluedBBox()), mtp.OGSize); - for(auto ni = std::begin(nodeMap); ni != std::end(nodeMap); ++ni) { - MeshTree::MeshNode *mn = ni->second; + for (auto& ni : nodeMap) { + MeshTree::MeshNode *mn = ni.second; if (mn->glued) { OG.AddMesh(mn->m->cm, vcg::Matrix44::Construct(mn->tr()), mn->Id()); } @@ -157,8 +154,8 @@ namespace vcg { if (!resultList.empty()) { vcg::Distribution H; - for (auto li = std::begin(resultList); li != std::end(resultList); ++li) { - H.Add(li->err); + for (auto& li : resultList) { + H.Add(li.err); } percentileThr = H.Percentile(1.0f - mtp.recalcThreshold); @@ -167,7 +164,7 @@ namespace vcg { std::size_t totalArcNum = 0; int preservedArcNum = 0, recalcArcNum = 0; - while(totalArcNum mtp.arcThreshold) + while(totalArcNum < OG.SVA.size() && OG.SVA[totalArcNum].norm_area > mtp.arcThreshold) { AlignPair::Result *curResult = findResult(OG.SVA[totalArcNum].s, OG.SVA[totalArcNum].t); if (curResult) { @@ -250,10 +247,8 @@ namespace vcg { } vcg::Distribution H; // stat for printing - for (auto li = std::begin(resultList); li != std::end(resultList); ++li) { - if ((*li).isValid()) { - H.Add(li->err); - } + for (auto& li : resultList) { + if (li.isValid()) H.Add(li.err); } std::memset(buf, '\0', 1024); @@ -265,26 +260,30 @@ namespace vcg { void ProcessGlobal(vcg::AlignPair::Param &ap) { + char buff[1024]; + std::memset(buff, '\0', 1024); + /************** Preparing Matrices for global alignment *************/ std::vector GluedIdVec; std::vector GluedTrVec; std::map names; - for (auto ni = std::begin(nodeMap); ni != std::end(nodeMap); ++ni) { - MeshTree::MeshNode *mn=ni->second; + for (auto& ni : nodeMap) { + + MeshTree::MeshNode *mn = ni.second; if (mn->glued) { GluedIdVec.push_back(mn->Id()); GluedTrVec.push_back(vcg::Matrix44d::Construct(mn->tr())); - names[mn->Id()]=qUtf8Printable(mn->m->label()); + names[mn->Id()] = qUtf8Printable(mn->m->label()); } } vcg::AlignGlobal AG; std::vector ResVecPtr; - for (auto li = std::begin(resultList); li != std::end(resultList); ++li) { - if ((*li).isValid()) { - ResVecPtr.push_back(&*li); + for (auto& li : resultList) { + if (li.isValid()) { + ResVecPtr.push_back(&li); } } @@ -304,6 +303,8 @@ namespace vcg { MM(GluedIdVec[ii])->cm.Tr.Import(GluedTrVecOut[ii]); } + std::sprintf(buff, "Completed Global Alignment (error bound %6.4f)\n", StartGlobErr); + cb(0, buff); } void ProcessArc(int fixId, int movId, vcg::AlignPair::Result &result, vcg::AlignPair::Param ap) { @@ -349,9 +350,8 @@ namespace vcg { aa.fix=&Fix; aa.ap = ap; - vcg::Matrix44d In = MovM; // Perform the ICP algorithm - aa.align(In,UG,VG,result); + aa.align(MovM,UG,VG,result); result.FixName=fixId; result.MovName=movId; @@ -360,9 +360,10 @@ namespace vcg { inline vcg::Box3 bbox() { vcg::Box3 FullBBox; - for (auto ni = std::begin(nodeMap); ni != std::end(nodeMap); ++ni) { - FullBBox.Add(vcg::Matrix44d::Construct(ni->second->tr()),ni->second->bbox()); + for (auto& ni : nodeMap) { + FullBBox.Add(vcg::Matrix44d::Construct(ni.second->tr()), ni.second->bbox()); } + return FullBBox; } @@ -370,11 +371,12 @@ namespace vcg { vcg::Box3 FullBBox; - for (auto ni = std::begin(nodeMap); ni != std::end(nodeMap); ++ni) { - if (ni->second->glued) { - FullBBox.Add(vcg::Matrix44::Construct(ni->second->tr()), ni->second->bbox()); + for (auto& ni : nodeMap) { + if (ni.second->glued) { + FullBBox.Add(vcg::Matrix44::Construct(ni.second->tr()), ni.second->bbox()); } } + return FullBBox; } From b98261e29fd6e35f73f467010dfc3f1a52ee3298 Mon Sep 17 00:00:00 2001 From: gabryon99 Date: Thu, 16 Sep 2021 18:58:41 +0200 Subject: [PATCH 061/117] fix meshtree params --- vcg/complex/algorithms/align_global.h | 15 ++++++++++----- vcg/complex/algorithms/meshtree.h | 9 ++++++--- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/vcg/complex/algorithms/align_global.h b/vcg/complex/algorithms/align_global.h index fbd049df..c695a623 100644 --- a/vcg/complex/algorithms/align_global.h +++ b/vcg/complex/algorithms/align_global.h @@ -472,7 +472,7 @@ namespace vcg { AlignGlobal::LOG(elfp,"\nDormant Num: %i\n", DormantNum()); curr = ChooseDormantWithMostDormantLink(); - if (curr == 0) { + if (curr == nullptr) { AlignGlobal::LOG(elfp,"\nFailed ChooseDormantWithMostDormantLink, chosen id:%i\n" ,0); break; // non ci sono piu' componenti connesse composte da piu' di una singola mesh. } @@ -483,7 +483,7 @@ namespace vcg { curr->Active = true; cursid = curr->sid; curr = ChooseDormantWithMostActiveLink (); - if (curr == 0) { + if (curr == nullptr) { AlignGlobal::LOG(elfp, "\nFailed ChooseDormantWithMostActiveLink, chosen id:%i\n", 0); } else { @@ -545,7 +545,7 @@ namespace vcg { AlignGlobal::Node* ChooseDormantWithMostDormantLink() { int MaxAdjNum = 0; - AlignGlobal::Node *BestNode = 0; + AlignGlobal::Node *BestNode = nullptr; for (auto li = std::begin(N); li != std::end(N); ++li) { if (!(*li).Active) { @@ -557,6 +557,11 @@ namespace vcg { } } + if (!BestNode){ + std::printf("Warning! Unable to find a Node with at least a dormant link!!\n"); + return nullptr; + } + assert(BestNode); assert(!BestNode->Queued); assert(!BestNode->Active); @@ -567,7 +572,7 @@ namespace vcg { AlignGlobal::Node* ChooseDormantWithMostActiveLink() { int MaxAdjNum = 0; - AlignGlobal::Node* BestNode = 0; + AlignGlobal::Node* BestNode = nullptr; for (auto li = std::begin(N); li != std::end(N); ++li) { if (!(*li).Active) { @@ -582,7 +587,7 @@ namespace vcg { if (!BestNode){ // Abbiamo finito di sistemare questa componente connessa. std::printf("Warning! Unable to find a Node with at least an active link!!\n"); - return 0; + return nullptr; } assert(BestNode); diff --git a/vcg/complex/algorithms/meshtree.h b/vcg/complex/algorithms/meshtree.h index f5221f08..13d0d3a9 100644 --- a/vcg/complex/algorithms/meshtree.h +++ b/vcg/complex/algorithms/meshtree.h @@ -39,7 +39,7 @@ namespace vcg { class Param { public: - int OGSize = 5000; + int OGSize = 50000; float arcThreshold = 0.3f; float recalcThreshold = 0.1f; }; @@ -50,12 +50,14 @@ namespace vcg { vcg::OccupancyGrid OG{}; vcg::CallBackPos* cb = vcg::DummyCallBackPos; + MeshTree() = default; + + ~MeshTree() { clear(); } + MeshType *MM(unsigned int i) { return nodeMap[i]->m; } - MeshTree() = default; - void clear() { for (auto& ni : nodeMap) { @@ -381,6 +383,7 @@ namespace vcg { } }; + } #endif //VCGLIB_MESHTREE_H From 9bdcf887f2d97c030516c13089afc7107b436863 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Tue, 5 Oct 2021 16:57:17 +0200 Subject: [PATCH 062/117] fix eigen compile error on curvature_fitting.h --- vcg/complex/algorithms/update/curvature_fitting.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/vcg/complex/algorithms/update/curvature_fitting.h b/vcg/complex/algorithms/update/curvature_fitting.h index 27e96182..44cd60e0 100644 --- a/vcg/complex/algorithms/update/curvature_fitting.h +++ b/vcg/complex/algorithms/update/curvature_fitting.h @@ -372,8 +372,8 @@ class Quadric { assert(VV.size() >= 5); Eigen::MatrixXd A(VV.size(),5); - Eigen::MatrixXd b(VV.size(),1); - Eigen::MatrixXd sol(5,1); + Eigen::VectorXd b(VV.size()); + Eigen::VectorXd sol(5); for(unsigned int c=0; c < VV.size(); ++c) { @@ -580,12 +580,12 @@ class Quadric c_val = -c_val; CoordType v1, v2; - v1[0] = c_vec[0]; - v1[1] = c_vec[1]; + v1[0] = c_vec(0); + v1[1] = c_vec(1); v1[2] = d * v1[0] + e * v1[1]; - v2[0] = c_vec[2]; - v2[1] = c_vec[3]; + v2[0] = c_vec(2); + v2[1] = c_vec(3); v2[2] = d * v2[0] + e * v2[1]; v1 = v1.Normalize(); From fa6bab75912840168c7814d9157bf11bc5be4224 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Wed, 13 Oct 2021 15:29:56 +0200 Subject: [PATCH 063/117] fix export ply scalar precision on texcoords --- wrap/io_trimesh/export_ply.h | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/wrap/io_trimesh/export_ply.h b/wrap/io_trimesh/export_ply.h index 4f120237..3823c337 100644 --- a/wrap/io_trimesh/export_ply.h +++ b/wrap/io_trimesh/export_ply.h @@ -104,7 +104,9 @@ public: const int DGTS = vcg::tri::io::Precision::digits(); const int DGTVQ = vcg::tri::io::Precision::digits(); const int DGTVR = vcg::tri::io::Precision::digits(); + const int DGTVT = vcg::tri::io::Precision::digits(); const int DGTFQ = vcg::tri::io::Precision::digits(); + const int DGTFT = vcg::tri::io::Precision::digits(); bool saveTexIndexFlag = false; if(binary) h=hbin; @@ -202,9 +204,11 @@ public: } if( ( HasPerVertexTexCoord(m) && pi.mask & Mask::IOM_VERTTEXCOORD ) ) { + const char* rdtp = vcg::tri::io::Precision::typeName(); fprintf(fpout, - "property float texture_u\n" - "property float texture_v\n"); + "property %s texture_u\n" + "property %s texture_v\n", + rdtp, rdtp); } for(size_t i=0;i::typeName(); fprintf(fpout, - "property list uchar float texcoord\n" ); + "property list uchar %s texcoord\n", rdtp ); } // The texture index information has to be saved for each face (if necessary) both for PerVert and PerWedg if( saveTexIndexFlag && @@ -493,10 +498,10 @@ public: fwrite(&r,sizeof(typename VertexType::RadiusType),1,fpout); } - if( HasPerVertexTexCoord(m) && (pi.mask & Mask::IOM_VERTTEXCOORD) ) - { - t = ScalarType(vp->T().u()); fwrite(&t,sizeof(ScalarType),1,fpout); - t = ScalarType(vp->T().v()); fwrite(&t,sizeof(ScalarType),1,fpout); + if( HasPerVertexTexCoord(m) && (pi.mask & Mask::IOM_VERTTEXCOORD) ){ + typename VertexType::TexCoordType::ScalarType t; + t = ScalarType(vp->T().u()); fwrite(&t,sizeof(typename VertexType::TexCoordType::ScalarType),1,fpout); + t = ScalarType(vp->T().v()); fwrite(&t,sizeof(typename VertexType::TexCoordType::ScalarType),1,fpout); } for(size_t i=0;iR()); if( HasPerVertexTexCoord(m) && (pi.mask & Mask::IOM_VERTTEXCOORD) ) - fprintf(fpout,"%f %f",vp->T().u(),vp->T().v()); + fprintf(fpout,"%.*g %.*g",DGTVT,vp->T().u(),vp->T().v()); for(size_t i=0;iV(k)->T().u(); t[k*2+1] = fp->V(k)->T().v(); } - fwrite(t,sizeof(float),6,fpout); + fwrite(t,sizeof(typename FaceType::TexCoordType::ScalarType),6,fpout); } else if( HasPerWedgeTexCoord(m) && (pi.mask & Mask::IOM_WEDGTEXCOORD) ) { fwrite(&b6char,sizeof(char),1,fpout); - float t[6]; + typename FaceType::TexCoordType::ScalarType t[6]; for(int k=0;k<3;++k) { t[k*2+0] = fp->WT(k).u(); t[k*2+1] = fp->WT(k).v(); } - fwrite(t,sizeof(float),6,fpout); + fwrite(t,sizeof(typename FaceType::TexCoordType::ScalarType),6,fpout); } if(saveTexIndexFlag) @@ -778,7 +783,8 @@ public: { fprintf(fpout,"%d ",fp->VN()*2); for(int k=0;kVN();++k) - fprintf(fpout,"%f %f " + fprintf(fpout,"%.*g %.*g " + ,DGTFT ,fp->V(k)->T().u() ,fp->V(k)->T().v() ); From 3bb6cfc71aa3081c4f8a30bce45df3bfcd0ce547 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Thu, 14 Oct 2021 17:06:30 +0200 Subject: [PATCH 064/117] missing include in complex/base.h --- vcg/complex/base.h | 1 + 1 file changed, 1 insertion(+) diff --git a/vcg/complex/base.h b/vcg/complex/base.h index 2656a318..befda76c 100644 --- a/vcg/complex/base.h +++ b/vcg/complex/base.h @@ -29,6 +29,7 @@ #include +#include "exception.h" #include "used_types.h" namespace vcg { From cdd0a520a981ed8f5662626ba98ecb47659b6452 Mon Sep 17 00:00:00 2001 From: Paolo Cignoni Date: Thu, 14 Oct 2021 23:02:13 +0200 Subject: [PATCH 065/117] Update curvature_fitting.h updated curvature local, added callback --- .../algorithms/update/curvature_fitting.h | 42 +++---------------- 1 file changed, 5 insertions(+), 37 deletions(-) diff --git a/vcg/complex/algorithms/update/curvature_fitting.h b/vcg/complex/algorithms/update/curvature_fitting.h index 44cd60e0..9de9fe3e 100644 --- a/vcg/complex/algorithms/update/curvature_fitting.h +++ b/vcg/complex/algorithms/update/curvature_fitting.h @@ -619,9 +619,8 @@ class Quadric - static void updateCurvatureLocal (MeshType & mesh, float radiusSphere) + static void updateCurvatureLocal (MeshType & mesh, float radiusSphere, vcg::CallBackPos * cb = NULL) { - bool verbose = false; bool projectionPlaneCheck = true; int vertexesPerFit = 0; @@ -631,24 +630,16 @@ class Quadric { std::vector vv; std::vector vvtmp; - + if (cb && ((i%1024)==00)) { + (*cb)(int(100.0f * (float)i / (float)mesh.vn),"Vertices Analysis"); + } int count; - if (verbose && !((count = (vi - mesh.vert.begin())) % 1000)) - printf ("vertex %d of %d\n",count,mesh.vert.size()); - - // if (kRing != 0) - // expandRing (&*vi, kRing, 5, &vv); - // else expandSphereLocal (mesh, &*vi, radiusSphere, 5, &vv); assert (vv.size() >= 5); CoordType ppn; - // if (averageNormalMode) - // //ppn = (*vi).N(); getAverageNormal (&*vi, vv, &ppn); - // else - // getProjPlaneNormal (&*vi, vv, &ppn); if (projectionPlaneCheck) { @@ -659,33 +650,12 @@ class Quadric } vvtmp.clear(); - - // if (montecarloMaxVertexNum) - // { - // //printf ("P: %d\n", vv.size()); - // vvtmp.reserve (vv.size ()); - // //printf ("TP: %d\n", vvtmp.size()); - // applyMontecarlo (montecarloMaxVertexNum, vv, &vvtmp); - // //printf ("TD: %d\n", vvtmp.size()); - // vv = vvtmp; - // //printf ("D: %d\n", vv.size()); - // //printf ("\n"); - // } - assert (vv.size() >= 5); std::vector ref; computeReferenceFramesLocal (&*vi, ppn, &ref); - /* - printf ("%lf %lf %lf - %lf %lf %lf - %lf %lf %lf\n", - ref[0][0], ref[0][1], ref[0][2], - ref[1][0], ref[1][1], ref[1][2], - ref[2][0], ref[2][1], ref[2][2]); - */ - vertexesPerFit += vv.size(); - //printf ("size: %d\n", vv.size()); QuadricLocal q; fitQuadricLocal (&*vi, ref, vv, &q); @@ -694,9 +664,7 @@ class Quadric } - //if (verbose) - //printf ("average vertex num in each fit: %f, total %d, vn %d\n", ((float) vertexesPerFit) / mesh.vn, vertexesPerFit, mesh.vn); - if (verbose) + if (cb) printf ("average vertex num in each fit: %f\n", ((float) vertexesPerFit) / mesh.vn); } From 623f3600f3169e59114e9cf8ed11892ef7262153 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Tue, 19 Oct 2021 11:35:23 +0200 Subject: [PATCH 066/117] eigen copyright mozilla homepage link substitution --- eigenlib/Eigen/Cholesky | 2 +- eigenlib/Eigen/CholmodSupport | 2 +- eigenlib/Eigen/Core | 2 +- eigenlib/Eigen/Eigenvalues | 2 +- eigenlib/Eigen/Geometry | 2 +- eigenlib/Eigen/Householder | 2 +- eigenlib/Eigen/IterativeLinearSolvers | 2 +- eigenlib/Eigen/Jacobi | 2 +- eigenlib/Eigen/LU | 2 +- eigenlib/Eigen/MetisSupport | 2 +- eigenlib/Eigen/OrderingMethods | 2 +- eigenlib/Eigen/PaStiXSupport | 2 +- eigenlib/Eigen/PardisoSupport | 2 +- eigenlib/Eigen/QR | 2 +- eigenlib/Eigen/QtAlignedMalloc | 2 +- eigenlib/Eigen/SPQRSupport | 2 +- eigenlib/Eigen/SVD | 2 +- eigenlib/Eigen/Sparse | 2 +- eigenlib/Eigen/SparseCholesky | 2 +- eigenlib/Eigen/SparseCore | 2 +- eigenlib/Eigen/SparseLU | 2 +- eigenlib/Eigen/SparseQR | 2 +- eigenlib/Eigen/StdDeque | 2 +- eigenlib/Eigen/StdList | 2 +- eigenlib/Eigen/StdVector | 2 +- eigenlib/Eigen/SuperLUSupport | 2 +- eigenlib/Eigen/UmfPackSupport | 2 +- eigenlib/Eigen/src/Cholesky/LDLT.h | 2 +- eigenlib/Eigen/src/Cholesky/LLT.h | 2 +- eigenlib/Eigen/src/CholmodSupport/CholmodSupport.h | 2 +- eigenlib/Eigen/src/Core/Array.h | 2 +- eigenlib/Eigen/src/Core/ArrayBase.h | 2 +- eigenlib/Eigen/src/Core/ArrayWrapper.h | 2 +- eigenlib/Eigen/src/Core/Assign.h | 2 +- eigenlib/Eigen/src/Core/AssignEvaluator.h | 2 +- eigenlib/Eigen/src/Core/BandMatrix.h | 2 +- eigenlib/Eigen/src/Core/Block.h | 2 +- eigenlib/Eigen/src/Core/BooleanRedux.h | 2 +- eigenlib/Eigen/src/Core/CommaInitializer.h | 2 +- eigenlib/Eigen/src/Core/ConditionEstimator.h | 2 +- eigenlib/Eigen/src/Core/CoreEvaluators.h | 2 +- eigenlib/Eigen/src/Core/CoreIterators.h | 2 +- eigenlib/Eigen/src/Core/CwiseBinaryOp.h | 2 +- eigenlib/Eigen/src/Core/CwiseNullaryOp.h | 2 +- eigenlib/Eigen/src/Core/CwiseTernaryOp.h | 2 +- eigenlib/Eigen/src/Core/CwiseUnaryOp.h | 2 +- eigenlib/Eigen/src/Core/CwiseUnaryView.h | 2 +- eigenlib/Eigen/src/Core/DenseBase.h | 2 +- eigenlib/Eigen/src/Core/DenseCoeffsBase.h | 2 +- eigenlib/Eigen/src/Core/DenseStorage.h | 2 +- eigenlib/Eigen/src/Core/Diagonal.h | 2 +- eigenlib/Eigen/src/Core/DiagonalMatrix.h | 2 +- eigenlib/Eigen/src/Core/DiagonalProduct.h | 2 +- eigenlib/Eigen/src/Core/Dot.h | 2 +- eigenlib/Eigen/src/Core/EigenBase.h | 2 +- eigenlib/Eigen/src/Core/ForceAlignedAccess.h | 2 +- eigenlib/Eigen/src/Core/Fuzzy.h | 2 +- eigenlib/Eigen/src/Core/GeneralProduct.h | 2 +- eigenlib/Eigen/src/Core/GenericPacketMath.h | 2 +- eigenlib/Eigen/src/Core/GlobalFunctions.h | 2 +- eigenlib/Eigen/src/Core/IO.h | 2 +- eigenlib/Eigen/src/Core/Inverse.h | 2 +- eigenlib/Eigen/src/Core/Map.h | 2 +- eigenlib/Eigen/src/Core/MapBase.h | 2 +- eigenlib/Eigen/src/Core/MathFunctions.h | 2 +- eigenlib/Eigen/src/Core/MathFunctionsImpl.h | 2 +- eigenlib/Eigen/src/Core/Matrix.h | 2 +- eigenlib/Eigen/src/Core/MatrixBase.h | 2 +- eigenlib/Eigen/src/Core/NestByValue.h | 2 +- eigenlib/Eigen/src/Core/NoAlias.h | 2 +- eigenlib/Eigen/src/Core/NumTraits.h | 2 +- eigenlib/Eigen/src/Core/PermutationMatrix.h | 2 +- eigenlib/Eigen/src/Core/PlainObjectBase.h | 2 +- eigenlib/Eigen/src/Core/Product.h | 2 +- eigenlib/Eigen/src/Core/ProductEvaluators.h | 2 +- eigenlib/Eigen/src/Core/Random.h | 2 +- eigenlib/Eigen/src/Core/Redux.h | 2 +- eigenlib/Eigen/src/Core/Ref.h | 2 +- eigenlib/Eigen/src/Core/Replicate.h | 2 +- eigenlib/Eigen/src/Core/ReturnByValue.h | 2 +- eigenlib/Eigen/src/Core/Reverse.h | 2 +- eigenlib/Eigen/src/Core/Select.h | 2 +- eigenlib/Eigen/src/Core/SelfAdjointView.h | 2 +- eigenlib/Eigen/src/Core/SelfCwiseBinaryOp.h | 2 +- eigenlib/Eigen/src/Core/Solve.h | 2 +- eigenlib/Eigen/src/Core/SolveTriangular.h | 2 +- eigenlib/Eigen/src/Core/SolverBase.h | 2 +- eigenlib/Eigen/src/Core/StableNorm.h | 2 +- eigenlib/Eigen/src/Core/Stride.h | 2 +- eigenlib/Eigen/src/Core/Swap.h | 2 +- eigenlib/Eigen/src/Core/Transpose.h | 2 +- eigenlib/Eigen/src/Core/Transpositions.h | 2 +- eigenlib/Eigen/src/Core/TriangularMatrix.h | 2 +- eigenlib/Eigen/src/Core/VectorBlock.h | 2 +- eigenlib/Eigen/src/Core/VectorwiseOp.h | 2 +- eigenlib/Eigen/src/Core/Visitor.h | 2 +- eigenlib/Eigen/src/Core/arch/AVX/Complex.h | 2 +- eigenlib/Eigen/src/Core/arch/AVX/MathFunctions.h | 2 +- eigenlib/Eigen/src/Core/arch/AVX/PacketMath.h | 2 +- eigenlib/Eigen/src/Core/arch/AVX/TypeCasting.h | 2 +- eigenlib/Eigen/src/Core/arch/AVX512/MathFunctions.h | 2 +- eigenlib/Eigen/src/Core/arch/AVX512/PacketMath.h | 2 +- eigenlib/Eigen/src/Core/arch/AltiVec/Complex.h | 2 +- eigenlib/Eigen/src/Core/arch/AltiVec/MathFunctions.h | 2 +- eigenlib/Eigen/src/Core/arch/AltiVec/PacketMath.h | 2 +- eigenlib/Eigen/src/Core/arch/CUDA/Complex.h | 2 +- eigenlib/Eigen/src/Core/arch/CUDA/Half.h | 2 +- eigenlib/Eigen/src/Core/arch/CUDA/MathFunctions.h | 2 +- eigenlib/Eigen/src/Core/arch/CUDA/PacketMath.h | 2 +- eigenlib/Eigen/src/Core/arch/CUDA/PacketMathHalf.h | 2 +- eigenlib/Eigen/src/Core/arch/CUDA/TypeCasting.h | 2 +- eigenlib/Eigen/src/Core/arch/Default/ConjHelper.h | 2 +- eigenlib/Eigen/src/Core/arch/Default/Settings.h | 2 +- eigenlib/Eigen/src/Core/arch/NEON/Complex.h | 2 +- eigenlib/Eigen/src/Core/arch/NEON/MathFunctions.h | 2 +- eigenlib/Eigen/src/Core/arch/NEON/PacketMath.h | 2 +- eigenlib/Eigen/src/Core/arch/SSE/Complex.h | 2 +- eigenlib/Eigen/src/Core/arch/SSE/MathFunctions.h | 2 +- eigenlib/Eigen/src/Core/arch/SSE/PacketMath.h | 2 +- eigenlib/Eigen/src/Core/arch/SSE/TypeCasting.h | 2 +- eigenlib/Eigen/src/Core/arch/ZVector/Complex.h | 2 +- eigenlib/Eigen/src/Core/arch/ZVector/MathFunctions.h | 2 +- eigenlib/Eigen/src/Core/arch/ZVector/PacketMath.h | 2 +- eigenlib/Eigen/src/Core/functors/AssignmentFunctors.h | 2 +- eigenlib/Eigen/src/Core/functors/BinaryFunctors.h | 2 +- eigenlib/Eigen/src/Core/functors/NullaryFunctors.h | 2 +- eigenlib/Eigen/src/Core/functors/StlFunctors.h | 2 +- eigenlib/Eigen/src/Core/functors/TernaryFunctors.h | 2 +- eigenlib/Eigen/src/Core/functors/UnaryFunctors.h | 2 +- eigenlib/Eigen/src/Core/products/GeneralBlockPanelKernel.h | 2 +- eigenlib/Eigen/src/Core/products/GeneralMatrixMatrix.h | 2 +- .../Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h | 2 +- eigenlib/Eigen/src/Core/products/GeneralMatrixVector.h | 2 +- eigenlib/Eigen/src/Core/products/Parallelizer.h | 2 +- eigenlib/Eigen/src/Core/products/SelfadjointMatrixMatrix.h | 2 +- eigenlib/Eigen/src/Core/products/SelfadjointMatrixVector.h | 2 +- eigenlib/Eigen/src/Core/products/SelfadjointProduct.h | 2 +- eigenlib/Eigen/src/Core/products/SelfadjointRank2Update.h | 2 +- eigenlib/Eigen/src/Core/products/TriangularMatrixMatrix.h | 2 +- eigenlib/Eigen/src/Core/products/TriangularMatrixVector.h | 2 +- eigenlib/Eigen/src/Core/products/TriangularSolverMatrix.h | 2 +- eigenlib/Eigen/src/Core/products/TriangularSolverVector.h | 2 +- eigenlib/Eigen/src/Core/util/BlasUtil.h | 2 +- eigenlib/Eigen/src/Core/util/Constants.h | 2 +- eigenlib/Eigen/src/Core/util/ForwardDeclarations.h | 2 +- eigenlib/Eigen/src/Core/util/Macros.h | 2 +- eigenlib/Eigen/src/Core/util/Memory.h | 2 +- eigenlib/Eigen/src/Core/util/Meta.h | 2 +- eigenlib/Eigen/src/Core/util/StaticAssert.h | 2 +- eigenlib/Eigen/src/Core/util/XprHelper.h | 2 +- eigenlib/Eigen/src/Eigenvalues/ComplexEigenSolver.h | 2 +- eigenlib/Eigen/src/Eigenvalues/ComplexSchur.h | 2 +- eigenlib/Eigen/src/Eigenvalues/EigenSolver.h | 2 +- eigenlib/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h | 2 +- .../src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h | 2 +- eigenlib/Eigen/src/Eigenvalues/HessenbergDecomposition.h | 2 +- eigenlib/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h | 2 +- eigenlib/Eigen/src/Eigenvalues/RealQZ.h | 2 +- eigenlib/Eigen/src/Eigenvalues/RealSchur.h | 2 +- eigenlib/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h | 2 +- eigenlib/Eigen/src/Eigenvalues/Tridiagonalization.h | 2 +- eigenlib/Eigen/src/Geometry/AlignedBox.h | 2 +- eigenlib/Eigen/src/Geometry/AngleAxis.h | 2 +- eigenlib/Eigen/src/Geometry/EulerAngles.h | 2 +- eigenlib/Eigen/src/Geometry/Homogeneous.h | 2 +- eigenlib/Eigen/src/Geometry/Hyperplane.h | 2 +- eigenlib/Eigen/src/Geometry/OrthoMethods.h | 2 +- eigenlib/Eigen/src/Geometry/ParametrizedLine.h | 2 +- eigenlib/Eigen/src/Geometry/Quaternion.h | 2 +- eigenlib/Eigen/src/Geometry/Rotation2D.h | 2 +- eigenlib/Eigen/src/Geometry/RotationBase.h | 2 +- eigenlib/Eigen/src/Geometry/Scaling.h | 2 +- eigenlib/Eigen/src/Geometry/Transform.h | 2 +- eigenlib/Eigen/src/Geometry/Translation.h | 2 +- eigenlib/Eigen/src/Geometry/Umeyama.h | 2 +- eigenlib/Eigen/src/Geometry/arch/Geometry_SSE.h | 2 +- eigenlib/Eigen/src/Householder/BlockHouseholder.h | 2 +- eigenlib/Eigen/src/Householder/Householder.h | 2 +- eigenlib/Eigen/src/Householder/HouseholderSequence.h | 2 +- .../Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h | 2 +- eigenlib/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h | 2 +- .../Eigen/src/IterativeLinearSolvers/ConjugateGradient.h | 2 +- .../Eigen/src/IterativeLinearSolvers/IncompleteCholesky.h | 2 +- eigenlib/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h | 2 +- .../Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h | 2 +- .../IterativeLinearSolvers/LeastSquareConjugateGradient.h | 2 +- eigenlib/Eigen/src/IterativeLinearSolvers/SolveWithGuess.h | 2 +- eigenlib/Eigen/src/Jacobi/Jacobi.h | 2 +- eigenlib/Eigen/src/LU/Determinant.h | 2 +- eigenlib/Eigen/src/LU/FullPivLU.h | 2 +- eigenlib/Eigen/src/LU/InverseImpl.h | 2 +- eigenlib/Eigen/src/LU/PartialPivLU.h | 2 +- eigenlib/Eigen/src/LU/arch/Inverse_SSE.h | 2 +- eigenlib/Eigen/src/MetisSupport/MetisSupport.h | 2 +- eigenlib/Eigen/src/OrderingMethods/Eigen_Colamd.h | 2 +- eigenlib/Eigen/src/OrderingMethods/Ordering.h | 2 +- eigenlib/Eigen/src/PaStiXSupport/PaStiXSupport.h | 2 +- eigenlib/Eigen/src/QR/ColPivHouseholderQR.h | 2 +- eigenlib/Eigen/src/QR/CompleteOrthogonalDecomposition.h | 2 +- eigenlib/Eigen/src/QR/FullPivHouseholderQR.h | 2 +- eigenlib/Eigen/src/QR/HouseholderQR.h | 2 +- eigenlib/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h | 2 +- eigenlib/Eigen/src/SVD/BDCSVD.h | 2 +- eigenlib/Eigen/src/SVD/JacobiSVD.h | 2 +- eigenlib/Eigen/src/SVD/SVDBase.h | 2 +- eigenlib/Eigen/src/SVD/UpperBidiagonalization.h | 2 +- eigenlib/Eigen/src/SparseCholesky/SimplicialCholesky.h | 2 +- eigenlib/Eigen/src/SparseCore/AmbiVector.h | 2 +- eigenlib/Eigen/src/SparseCore/CompressedStorage.h | 2 +- .../Eigen/src/SparseCore/ConservativeSparseSparseProduct.h | 2 +- eigenlib/Eigen/src/SparseCore/MappedSparseMatrix.h | 2 +- eigenlib/Eigen/src/SparseCore/SparseAssign.h | 2 +- eigenlib/Eigen/src/SparseCore/SparseBlock.h | 2 +- eigenlib/Eigen/src/SparseCore/SparseColEtree.h | 2 +- eigenlib/Eigen/src/SparseCore/SparseCompressedBase.h | 2 +- eigenlib/Eigen/src/SparseCore/SparseCwiseBinaryOp.h | 2 +- eigenlib/Eigen/src/SparseCore/SparseCwiseUnaryOp.h | 2 +- eigenlib/Eigen/src/SparseCore/SparseDenseProduct.h | 2 +- eigenlib/Eigen/src/SparseCore/SparseDiagonalProduct.h | 2 +- eigenlib/Eigen/src/SparseCore/SparseDot.h | 2 +- eigenlib/Eigen/src/SparseCore/SparseFuzzy.h | 2 +- eigenlib/Eigen/src/SparseCore/SparseMap.h | 2 +- eigenlib/Eigen/src/SparseCore/SparseMatrix.h | 2 +- eigenlib/Eigen/src/SparseCore/SparseMatrixBase.h | 2 +- eigenlib/Eigen/src/SparseCore/SparsePermutation.h | 2 +- eigenlib/Eigen/src/SparseCore/SparseProduct.h | 2 +- eigenlib/Eigen/src/SparseCore/SparseRedux.h | 2 +- eigenlib/Eigen/src/SparseCore/SparseRef.h | 2 +- eigenlib/Eigen/src/SparseCore/SparseSelfAdjointView.h | 2 +- eigenlib/Eigen/src/SparseCore/SparseSolverBase.h | 2 +- .../Eigen/src/SparseCore/SparseSparseProductWithPruning.h | 2 +- eigenlib/Eigen/src/SparseCore/SparseTranspose.h | 2 +- eigenlib/Eigen/src/SparseCore/SparseTriangularView.h | 2 +- eigenlib/Eigen/src/SparseCore/SparseUtil.h | 2 +- eigenlib/Eigen/src/SparseCore/SparseVector.h | 2 +- eigenlib/Eigen/src/SparseCore/SparseView.h | 2 +- eigenlib/Eigen/src/SparseCore/TriangularSolver.h | 2 +- eigenlib/Eigen/src/SparseLU/SparseLU.h | 2 +- eigenlib/Eigen/src/SparseLU/SparseLUImpl.h | 2 +- eigenlib/Eigen/src/SparseLU/SparseLU_Memory.h | 2 +- eigenlib/Eigen/src/SparseLU/SparseLU_Structs.h | 2 +- eigenlib/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h | 2 +- eigenlib/Eigen/src/SparseLU/SparseLU_Utils.h | 2 +- eigenlib/Eigen/src/SparseLU/SparseLU_column_bmod.h | 2 +- eigenlib/Eigen/src/SparseLU/SparseLU_column_dfs.h | 2 +- eigenlib/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h | 2 +- eigenlib/Eigen/src/SparseLU/SparseLU_gemm_kernel.h | 2 +- eigenlib/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h | 2 +- eigenlib/Eigen/src/SparseLU/SparseLU_kernel_bmod.h | 2 +- eigenlib/Eigen/src/SparseLU/SparseLU_panel_bmod.h | 2 +- eigenlib/Eigen/src/SparseLU/SparseLU_panel_dfs.h | 2 +- eigenlib/Eigen/src/SparseLU/SparseLU_pivotL.h | 2 +- eigenlib/Eigen/src/SparseLU/SparseLU_pruneL.h | 2 +- eigenlib/Eigen/src/SparseLU/SparseLU_relax_snode.h | 2 +- eigenlib/Eigen/src/SparseQR/SparseQR.h | 2 +- eigenlib/Eigen/src/StlSupport/StdDeque.h | 2 +- eigenlib/Eigen/src/StlSupport/StdList.h | 2 +- eigenlib/Eigen/src/StlSupport/StdVector.h | 2 +- eigenlib/Eigen/src/StlSupport/details.h | 2 +- eigenlib/Eigen/src/SuperLUSupport/SuperLUSupport.h | 2 +- eigenlib/Eigen/src/UmfPackSupport/UmfPackSupport.h | 2 +- eigenlib/Eigen/src/misc/Image.h | 2 +- eigenlib/Eigen/src/misc/Kernel.h | 2 +- eigenlib/Eigen/src/misc/RealSvd2x2.h | 2 +- eigenlib/Eigen/src/plugins/BlockMethods.h | 2 +- eigenlib/Eigen/src/plugins/CommonCwiseBinaryOps.h | 2 +- eigenlib/Eigen/src/plugins/CommonCwiseUnaryOps.h | 2 +- eigenlib/Eigen/src/plugins/MatrixCwiseBinaryOps.h | 2 +- eigenlib/Eigen/src/plugins/MatrixCwiseUnaryOps.h | 2 +- eigenlib/howto.txt | 5 +++++ 270 files changed, 274 insertions(+), 269 deletions(-) diff --git a/eigenlib/Eigen/Cholesky b/eigenlib/Eigen/Cholesky index 1332b540..b37dc4e4 100644 --- a/eigenlib/Eigen/Cholesky +++ b/eigenlib/Eigen/Cholesky @@ -3,7 +3,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_CHOLESKY_MODULE_H #define EIGEN_CHOLESKY_MODULE_H diff --git a/eigenlib/Eigen/CholmodSupport b/eigenlib/Eigen/CholmodSupport index bed8924d..96cb4e4f 100644 --- a/eigenlib/Eigen/CholmodSupport +++ b/eigenlib/Eigen/CholmodSupport @@ -3,7 +3,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_CHOLMODSUPPORT_MODULE_H #define EIGEN_CHOLMODSUPPORT_MODULE_H diff --git a/eigenlib/Eigen/Core b/eigenlib/Eigen/Core index ac7c5b30..c2808c5f 100644 --- a/eigenlib/Eigen/Core +++ b/eigenlib/Eigen/Core @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_CORE_H #define EIGEN_CORE_H diff --git a/eigenlib/Eigen/Eigenvalues b/eigenlib/Eigen/Eigenvalues index 7d6ac787..b740e0b6 100644 --- a/eigenlib/Eigen/Eigenvalues +++ b/eigenlib/Eigen/Eigenvalues @@ -3,7 +3,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_EIGENVALUES_MODULE_H #define EIGEN_EIGENVALUES_MODULE_H diff --git a/eigenlib/Eigen/Geometry b/eigenlib/Eigen/Geometry index da88c03b..b053d41b 100644 --- a/eigenlib/Eigen/Geometry +++ b/eigenlib/Eigen/Geometry @@ -3,7 +3,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_GEOMETRY_MODULE_H #define EIGEN_GEOMETRY_MODULE_H diff --git a/eigenlib/Eigen/Householder b/eigenlib/Eigen/Householder index 89cd81b1..18eec747 100644 --- a/eigenlib/Eigen/Householder +++ b/eigenlib/Eigen/Householder @@ -3,7 +3,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_HOUSEHOLDER_MODULE_H #define EIGEN_HOUSEHOLDER_MODULE_H diff --git a/eigenlib/Eigen/IterativeLinearSolvers b/eigenlib/Eigen/IterativeLinearSolvers index 957d5750..1865a38e 100644 --- a/eigenlib/Eigen/IterativeLinearSolvers +++ b/eigenlib/Eigen/IterativeLinearSolvers @@ -3,7 +3,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_ITERATIVELINEARSOLVERS_MODULE_H #define EIGEN_ITERATIVELINEARSOLVERS_MODULE_H diff --git a/eigenlib/Eigen/Jacobi b/eigenlib/Eigen/Jacobi index 17c1d785..3116ea4e 100644 --- a/eigenlib/Eigen/Jacobi +++ b/eigenlib/Eigen/Jacobi @@ -3,7 +3,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_JACOBI_MODULE_H #define EIGEN_JACOBI_MODULE_H diff --git a/eigenlib/Eigen/LU b/eigenlib/Eigen/LU index 6418a86e..ec6aa837 100644 --- a/eigenlib/Eigen/LU +++ b/eigenlib/Eigen/LU @@ -3,7 +3,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_LU_MODULE_H #define EIGEN_LU_MODULE_H diff --git a/eigenlib/Eigen/MetisSupport b/eigenlib/Eigen/MetisSupport index 85c41bf3..4e85d3d4 100644 --- a/eigenlib/Eigen/MetisSupport +++ b/eigenlib/Eigen/MetisSupport @@ -3,7 +3,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_METISSUPPORT_MODULE_H #define EIGEN_METISSUPPORT_MODULE_H diff --git a/eigenlib/Eigen/OrderingMethods b/eigenlib/Eigen/OrderingMethods index d8ea3619..14f718fe 100644 --- a/eigenlib/Eigen/OrderingMethods +++ b/eigenlib/Eigen/OrderingMethods @@ -3,7 +3,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_ORDERINGMETHODS_MODULE_H #define EIGEN_ORDERINGMETHODS_MODULE_H diff --git a/eigenlib/Eigen/PaStiXSupport b/eigenlib/Eigen/PaStiXSupport index de3a63b4..307f6ece 100644 --- a/eigenlib/Eigen/PaStiXSupport +++ b/eigenlib/Eigen/PaStiXSupport @@ -3,7 +3,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_PASTIXSUPPORT_MODULE_H #define EIGEN_PASTIXSUPPORT_MODULE_H diff --git a/eigenlib/Eigen/PardisoSupport b/eigenlib/Eigen/PardisoSupport index 340edf51..7d1a211d 100755 --- a/eigenlib/Eigen/PardisoSupport +++ b/eigenlib/Eigen/PardisoSupport @@ -3,7 +3,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_PARDISOSUPPORT_MODULE_H #define EIGEN_PARDISOSUPPORT_MODULE_H diff --git a/eigenlib/Eigen/QR b/eigenlib/Eigen/QR index 1be1863a..a6ebbb90 100644 --- a/eigenlib/Eigen/QR +++ b/eigenlib/Eigen/QR @@ -3,7 +3,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_QR_MODULE_H #define EIGEN_QR_MODULE_H diff --git a/eigenlib/Eigen/QtAlignedMalloc b/eigenlib/Eigen/QtAlignedMalloc index 4f07df02..f0e75efd 100644 --- a/eigenlib/Eigen/QtAlignedMalloc +++ b/eigenlib/Eigen/QtAlignedMalloc @@ -3,7 +3,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_QTMALLOC_MODULE_H #define EIGEN_QTMALLOC_MODULE_H diff --git a/eigenlib/Eigen/SPQRSupport b/eigenlib/Eigen/SPQRSupport index f70390c1..db840f91 100644 --- a/eigenlib/Eigen/SPQRSupport +++ b/eigenlib/Eigen/SPQRSupport @@ -3,7 +3,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPQRSUPPORT_MODULE_H #define EIGEN_SPQRSUPPORT_MODULE_H diff --git a/eigenlib/Eigen/SVD b/eigenlib/Eigen/SVD index 5d0e75f7..541181d8 100644 --- a/eigenlib/Eigen/SVD +++ b/eigenlib/Eigen/SVD @@ -3,7 +3,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SVD_MODULE_H #define EIGEN_SVD_MODULE_H diff --git a/eigenlib/Eigen/Sparse b/eigenlib/Eigen/Sparse index 136e681a..77d4fe83 100644 --- a/eigenlib/Eigen/Sparse +++ b/eigenlib/Eigen/Sparse @@ -3,7 +3,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSE_MODULE_H #define EIGEN_SPARSE_MODULE_H diff --git a/eigenlib/Eigen/SparseCholesky b/eigenlib/Eigen/SparseCholesky index b6a320c4..efa36126 100644 --- a/eigenlib/Eigen/SparseCholesky +++ b/eigenlib/Eigen/SparseCholesky @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSECHOLESKY_MODULE_H #define EIGEN_SPARSECHOLESKY_MODULE_H diff --git a/eigenlib/Eigen/SparseCore b/eigenlib/Eigen/SparseCore index 76966c4c..83466e64 100644 --- a/eigenlib/Eigen/SparseCore +++ b/eigenlib/Eigen/SparseCore @@ -3,7 +3,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSECORE_MODULE_H #define EIGEN_SPARSECORE_MODULE_H diff --git a/eigenlib/Eigen/SparseLU b/eigenlib/Eigen/SparseLU index 38b38b53..782ce834 100644 --- a/eigenlib/Eigen/SparseLU +++ b/eigenlib/Eigen/SparseLU @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSELU_MODULE_H #define EIGEN_SPARSELU_MODULE_H diff --git a/eigenlib/Eigen/SparseQR b/eigenlib/Eigen/SparseQR index f5fc5fa7..dc1d7dc5 100644 --- a/eigenlib/Eigen/SparseQR +++ b/eigenlib/Eigen/SparseQR @@ -3,7 +3,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSEQR_MODULE_H #define EIGEN_SPARSEQR_MODULE_H diff --git a/eigenlib/Eigen/StdDeque b/eigenlib/Eigen/StdDeque index bc68397b..0b9e253d 100644 --- a/eigenlib/Eigen/StdDeque +++ b/eigenlib/Eigen/StdDeque @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_STDDEQUE_MODULE_H #define EIGEN_STDDEQUE_MODULE_H diff --git a/eigenlib/Eigen/StdList b/eigenlib/Eigen/StdList index 4c6262c0..aadb0343 100644 --- a/eigenlib/Eigen/StdList +++ b/eigenlib/Eigen/StdList @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_STDLIST_MODULE_H #define EIGEN_STDLIST_MODULE_H diff --git a/eigenlib/Eigen/StdVector b/eigenlib/Eigen/StdVector index 0c4697ad..17f348d1 100644 --- a/eigenlib/Eigen/StdVector +++ b/eigenlib/Eigen/StdVector @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_STDVECTOR_MODULE_H #define EIGEN_STDVECTOR_MODULE_H diff --git a/eigenlib/Eigen/SuperLUSupport b/eigenlib/Eigen/SuperLUSupport index 59312a82..11b8bce5 100644 --- a/eigenlib/Eigen/SuperLUSupport +++ b/eigenlib/Eigen/SuperLUSupport @@ -3,7 +3,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SUPERLUSUPPORT_MODULE_H #define EIGEN_SUPERLUSUPPORT_MODULE_H diff --git a/eigenlib/Eigen/UmfPackSupport b/eigenlib/Eigen/UmfPackSupport index 00eec808..fcc89a24 100644 --- a/eigenlib/Eigen/UmfPackSupport +++ b/eigenlib/Eigen/UmfPackSupport @@ -3,7 +3,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_UMFPACKSUPPORT_MODULE_H #define EIGEN_UMFPACKSUPPORT_MODULE_H diff --git a/eigenlib/Eigen/src/Cholesky/LDLT.h b/eigenlib/Eigen/src/Cholesky/LDLT.h index 15ccf24f..60d3e386 100644 --- a/eigenlib/Eigen/src/Cholesky/LDLT.h +++ b/eigenlib/Eigen/src/Cholesky/LDLT.h @@ -8,7 +8,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_LDLT_H #define EIGEN_LDLT_H diff --git a/eigenlib/Eigen/src/Cholesky/LLT.h b/eigenlib/Eigen/src/Cholesky/LLT.h index e1624d21..9dc23767 100644 --- a/eigenlib/Eigen/src/Cholesky/LLT.h +++ b/eigenlib/Eigen/src/Cholesky/LLT.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_LLT_H #define EIGEN_LLT_H diff --git a/eigenlib/Eigen/src/CholmodSupport/CholmodSupport.h b/eigenlib/Eigen/src/CholmodSupport/CholmodSupport.h index 57197202..291c3a93 100644 --- a/eigenlib/Eigen/src/CholmodSupport/CholmodSupport.h +++ b/eigenlib/Eigen/src/CholmodSupport/CholmodSupport.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_CHOLMODSUPPORT_H #define EIGEN_CHOLMODSUPPORT_H diff --git a/eigenlib/Eigen/src/Core/Array.h b/eigenlib/Eigen/src/Core/Array.h index 16770fc7..5a651310 100644 --- a/eigenlib/Eigen/src/Core/Array.h +++ b/eigenlib/Eigen/src/Core/Array.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_ARRAY_H #define EIGEN_ARRAY_H diff --git a/eigenlib/Eigen/src/Core/ArrayBase.h b/eigenlib/Eigen/src/Core/ArrayBase.h index 33f644e2..e32601b1 100644 --- a/eigenlib/Eigen/src/Core/ArrayBase.h +++ b/eigenlib/Eigen/src/Core/ArrayBase.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_ARRAYBASE_H #define EIGEN_ARRAYBASE_H diff --git a/eigenlib/Eigen/src/Core/ArrayWrapper.h b/eigenlib/Eigen/src/Core/ArrayWrapper.h index 688aadd6..e8e84190 100644 --- a/eigenlib/Eigen/src/Core/ArrayWrapper.h +++ b/eigenlib/Eigen/src/Core/ArrayWrapper.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_ARRAYWRAPPER_H #define EIGEN_ARRAYWRAPPER_H diff --git a/eigenlib/Eigen/src/Core/Assign.h b/eigenlib/Eigen/src/Core/Assign.h index 53806ba3..1bb3af64 100644 --- a/eigenlib/Eigen/src/Core/Assign.h +++ b/eigenlib/Eigen/src/Core/Assign.h @@ -7,7 +7,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_ASSIGN_H #define EIGEN_ASSIGN_H diff --git a/eigenlib/Eigen/src/Core/AssignEvaluator.h b/eigenlib/Eigen/src/Core/AssignEvaluator.h index dbe435d8..67e28412 100644 --- a/eigenlib/Eigen/src/Core/AssignEvaluator.h +++ b/eigenlib/Eigen/src/Core/AssignEvaluator.h @@ -7,7 +7,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_ASSIGN_EVALUATOR_H #define EIGEN_ASSIGN_EVALUATOR_H diff --git a/eigenlib/Eigen/src/Core/BandMatrix.h b/eigenlib/Eigen/src/Core/BandMatrix.h index 4978c914..130fa201 100644 --- a/eigenlib/Eigen/src/Core/BandMatrix.h +++ b/eigenlib/Eigen/src/Core/BandMatrix.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_BANDMATRIX_H #define EIGEN_BANDMATRIX_H diff --git a/eigenlib/Eigen/src/Core/Block.h b/eigenlib/Eigen/src/Core/Block.h index 11de45c2..86028c61 100644 --- a/eigenlib/Eigen/src/Core/Block.h +++ b/eigenlib/Eigen/src/Core/Block.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_BLOCK_H #define EIGEN_BLOCK_H diff --git a/eigenlib/Eigen/src/Core/BooleanRedux.h b/eigenlib/Eigen/src/Core/BooleanRedux.h index 8409d874..23287ae0 100644 --- a/eigenlib/Eigen/src/Core/BooleanRedux.h +++ b/eigenlib/Eigen/src/Core/BooleanRedux.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_ALLANDANY_H #define EIGEN_ALLANDANY_H diff --git a/eigenlib/Eigen/src/Core/CommaInitializer.h b/eigenlib/Eigen/src/Core/CommaInitializer.h index d218e981..cb89ed2a 100644 --- a/eigenlib/Eigen/src/Core/CommaInitializer.h +++ b/eigenlib/Eigen/src/Core/CommaInitializer.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_COMMAINITIALIZER_H #define EIGEN_COMMAINITIALIZER_H diff --git a/eigenlib/Eigen/src/Core/ConditionEstimator.h b/eigenlib/Eigen/src/Core/ConditionEstimator.h index 51a2e5f1..3424da52 100644 --- a/eigenlib/Eigen/src/Core/ConditionEstimator.h +++ b/eigenlib/Eigen/src/Core/ConditionEstimator.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_CONDITIONESTIMATOR_H #define EIGEN_CONDITIONESTIMATOR_H diff --git a/eigenlib/Eigen/src/Core/CoreEvaluators.h b/eigenlib/Eigen/src/Core/CoreEvaluators.h index 910889ef..3e12ad13 100644 --- a/eigenlib/Eigen/src/Core/CoreEvaluators.h +++ b/eigenlib/Eigen/src/Core/CoreEvaluators.h @@ -7,7 +7,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_COREEVALUATORS_H diff --git a/eigenlib/Eigen/src/Core/CoreIterators.h b/eigenlib/Eigen/src/Core/CoreIterators.h index 4eb42b93..5b20e935 100644 --- a/eigenlib/Eigen/src/Core/CoreIterators.h +++ b/eigenlib/Eigen/src/Core/CoreIterators.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_COREITERATORS_H #define EIGEN_COREITERATORS_H diff --git a/eigenlib/Eigen/src/Core/CwiseBinaryOp.h b/eigenlib/Eigen/src/Core/CwiseBinaryOp.h index a36765e3..6348a7f0 100644 --- a/eigenlib/Eigen/src/Core/CwiseBinaryOp.h +++ b/eigenlib/Eigen/src/Core/CwiseBinaryOp.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_CWISE_BINARY_OP_H #define EIGEN_CWISE_BINARY_OP_H diff --git a/eigenlib/Eigen/src/Core/CwiseNullaryOp.h b/eigenlib/Eigen/src/Core/CwiseNullaryOp.h index ddd607e3..98a6385a 100644 --- a/eigenlib/Eigen/src/Core/CwiseNullaryOp.h +++ b/eigenlib/Eigen/src/Core/CwiseNullaryOp.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_CWISE_NULLARY_OP_H #define EIGEN_CWISE_NULLARY_OP_H diff --git a/eigenlib/Eigen/src/Core/CwiseTernaryOp.h b/eigenlib/Eigen/src/Core/CwiseTernaryOp.h index 9f3576fe..fef6e3c2 100644 --- a/eigenlib/Eigen/src/Core/CwiseTernaryOp.h +++ b/eigenlib/Eigen/src/Core/CwiseTernaryOp.h @@ -7,7 +7,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_CWISE_TERNARY_OP_H #define EIGEN_CWISE_TERNARY_OP_H diff --git a/eigenlib/Eigen/src/Core/CwiseUnaryOp.h b/eigenlib/Eigen/src/Core/CwiseUnaryOp.h index 1d2dd19f..269b139c 100644 --- a/eigenlib/Eigen/src/Core/CwiseUnaryOp.h +++ b/eigenlib/Eigen/src/Core/CwiseUnaryOp.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_CWISE_UNARY_OP_H #define EIGEN_CWISE_UNARY_OP_H diff --git a/eigenlib/Eigen/src/Core/CwiseUnaryView.h b/eigenlib/Eigen/src/Core/CwiseUnaryView.h index 5a30fa8d..ab165ebe 100644 --- a/eigenlib/Eigen/src/Core/CwiseUnaryView.h +++ b/eigenlib/Eigen/src/Core/CwiseUnaryView.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_CWISE_UNARY_VIEW_H #define EIGEN_CWISE_UNARY_VIEW_H diff --git a/eigenlib/Eigen/src/Core/DenseBase.h b/eigenlib/Eigen/src/Core/DenseBase.h index c55a6823..c568378e 100644 --- a/eigenlib/Eigen/src/Core/DenseBase.h +++ b/eigenlib/Eigen/src/Core/DenseBase.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_DENSEBASE_H #define EIGEN_DENSEBASE_H diff --git a/eigenlib/Eigen/src/Core/DenseCoeffsBase.h b/eigenlib/Eigen/src/Core/DenseCoeffsBase.h index c4af48ab..50269426 100644 --- a/eigenlib/Eigen/src/Core/DenseCoeffsBase.h +++ b/eigenlib/Eigen/src/Core/DenseCoeffsBase.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_DENSECOEFFSBASE_H #define EIGEN_DENSECOEFFSBASE_H diff --git a/eigenlib/Eigen/src/Core/DenseStorage.h b/eigenlib/Eigen/src/Core/DenseStorage.h index 7d6d4e66..45891dd3 100644 --- a/eigenlib/Eigen/src/Core/DenseStorage.h +++ b/eigenlib/Eigen/src/Core/DenseStorage.h @@ -7,7 +7,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_MATRIXSTORAGE_H #define EIGEN_MATRIXSTORAGE_H diff --git a/eigenlib/Eigen/src/Core/Diagonal.h b/eigenlib/Eigen/src/Core/Diagonal.h index afcaf357..0eb8d458 100644 --- a/eigenlib/Eigen/src/Core/Diagonal.h +++ b/eigenlib/Eigen/src/Core/Diagonal.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_DIAGONAL_H #define EIGEN_DIAGONAL_H diff --git a/eigenlib/Eigen/src/Core/DiagonalMatrix.h b/eigenlib/Eigen/src/Core/DiagonalMatrix.h index ecfdce8e..98a2eac7 100644 --- a/eigenlib/Eigen/src/Core/DiagonalMatrix.h +++ b/eigenlib/Eigen/src/Core/DiagonalMatrix.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_DIAGONALMATRIX_H #define EIGEN_DIAGONALMATRIX_H diff --git a/eigenlib/Eigen/src/Core/DiagonalProduct.h b/eigenlib/Eigen/src/Core/DiagonalProduct.h index d372b938..aead5fec 100644 --- a/eigenlib/Eigen/src/Core/DiagonalProduct.h +++ b/eigenlib/Eigen/src/Core/DiagonalProduct.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_DIAGONALPRODUCT_H #define EIGEN_DIAGONALPRODUCT_H diff --git a/eigenlib/Eigen/src/Core/Dot.h b/eigenlib/Eigen/src/Core/Dot.h index 1fe7a84a..c8daa897 100644 --- a/eigenlib/Eigen/src/Core/Dot.h +++ b/eigenlib/Eigen/src/Core/Dot.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_DOT_H #define EIGEN_DOT_H diff --git a/eigenlib/Eigen/src/Core/EigenBase.h b/eigenlib/Eigen/src/Core/EigenBase.h index b195506a..f1e4f685 100644 --- a/eigenlib/Eigen/src/Core/EigenBase.h +++ b/eigenlib/Eigen/src/Core/EigenBase.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_EIGENBASE_H #define EIGEN_EIGENBASE_H diff --git a/eigenlib/Eigen/src/Core/ForceAlignedAccess.h b/eigenlib/Eigen/src/Core/ForceAlignedAccess.h index 7b08b45e..d1669b75 100644 --- a/eigenlib/Eigen/src/Core/ForceAlignedAccess.h +++ b/eigenlib/Eigen/src/Core/ForceAlignedAccess.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_FORCEALIGNEDACCESS_H #define EIGEN_FORCEALIGNEDACCESS_H diff --git a/eigenlib/Eigen/src/Core/Fuzzy.h b/eigenlib/Eigen/src/Core/Fuzzy.h index 3e403a09..c5904f6b 100644 --- a/eigenlib/Eigen/src/Core/Fuzzy.h +++ b/eigenlib/Eigen/src/Core/Fuzzy.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_FUZZY_H #define EIGEN_FUZZY_H diff --git a/eigenlib/Eigen/src/Core/GeneralProduct.h b/eigenlib/Eigen/src/Core/GeneralProduct.h index 6f0cc80e..61401c96 100644 --- a/eigenlib/Eigen/src/Core/GeneralProduct.h +++ b/eigenlib/Eigen/src/Core/GeneralProduct.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_GENERAL_PRODUCT_H #define EIGEN_GENERAL_PRODUCT_H diff --git a/eigenlib/Eigen/src/Core/GenericPacketMath.h b/eigenlib/Eigen/src/Core/GenericPacketMath.h index e5944377..e7f1b283 100644 --- a/eigenlib/Eigen/src/Core/GenericPacketMath.h +++ b/eigenlib/Eigen/src/Core/GenericPacketMath.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_GENERIC_PACKET_MATH_H #define EIGEN_GENERIC_PACKET_MATH_H diff --git a/eigenlib/Eigen/src/Core/GlobalFunctions.h b/eigenlib/Eigen/src/Core/GlobalFunctions.h index 769dc255..ed9ea125 100644 --- a/eigenlib/Eigen/src/Core/GlobalFunctions.h +++ b/eigenlib/Eigen/src/Core/GlobalFunctions.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_GLOBAL_FUNCTIONS_H #define EIGEN_GLOBAL_FUNCTIONS_H diff --git a/eigenlib/Eigen/src/Core/IO.h b/eigenlib/Eigen/src/Core/IO.h index da7fd6cc..ec72a1c5 100644 --- a/eigenlib/Eigen/src/Core/IO.h +++ b/eigenlib/Eigen/src/Core/IO.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_IO_H #define EIGEN_IO_H diff --git a/eigenlib/Eigen/src/Core/Inverse.h b/eigenlib/Eigen/src/Core/Inverse.h index b76f0439..0f0787cf 100644 --- a/eigenlib/Eigen/src/Core/Inverse.h +++ b/eigenlib/Eigen/src/Core/Inverse.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_INVERSE_H #define EIGEN_INVERSE_H diff --git a/eigenlib/Eigen/src/Core/Map.h b/eigenlib/Eigen/src/Core/Map.h index 548bf9a2..166b61cc 100644 --- a/eigenlib/Eigen/src/Core/Map.h +++ b/eigenlib/Eigen/src/Core/Map.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_MAP_H #define EIGEN_MAP_H diff --git a/eigenlib/Eigen/src/Core/MapBase.h b/eigenlib/Eigen/src/Core/MapBase.h index 92c3b281..af003116 100644 --- a/eigenlib/Eigen/src/Core/MapBase.h +++ b/eigenlib/Eigen/src/Core/MapBase.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_MAPBASE_H #define EIGEN_MAPBASE_H diff --git a/eigenlib/Eigen/src/Core/MathFunctions.h b/eigenlib/Eigen/src/Core/MathFunctions.h index 01736c2a..a2dce17b 100644 --- a/eigenlib/Eigen/src/Core/MathFunctions.h +++ b/eigenlib/Eigen/src/Core/MathFunctions.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_MATHFUNCTIONS_H #define EIGEN_MATHFUNCTIONS_H diff --git a/eigenlib/Eigen/src/Core/MathFunctionsImpl.h b/eigenlib/Eigen/src/Core/MathFunctionsImpl.h index 9c1ceb0e..f5d8d717 100644 --- a/eigenlib/Eigen/src/Core/MathFunctionsImpl.h +++ b/eigenlib/Eigen/src/Core/MathFunctionsImpl.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_MATHFUNCTIONSIMPL_H #define EIGEN_MATHFUNCTIONSIMPL_H diff --git a/eigenlib/Eigen/src/Core/Matrix.h b/eigenlib/Eigen/src/Core/Matrix.h index 7f4a7af9..b66a3958 100644 --- a/eigenlib/Eigen/src/Core/Matrix.h +++ b/eigenlib/Eigen/src/Core/Matrix.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_MATRIX_H #define EIGEN_MATRIX_H diff --git a/eigenlib/Eigen/src/Core/MatrixBase.h b/eigenlib/Eigen/src/Core/MatrixBase.h index f8bcc8c6..8c5b93fc 100644 --- a/eigenlib/Eigen/src/Core/MatrixBase.h +++ b/eigenlib/Eigen/src/Core/MatrixBase.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_MATRIXBASE_H #define EIGEN_MATRIXBASE_H diff --git a/eigenlib/Eigen/src/Core/NestByValue.h b/eigenlib/Eigen/src/Core/NestByValue.h index 13adf070..a00255d4 100644 --- a/eigenlib/Eigen/src/Core/NestByValue.h +++ b/eigenlib/Eigen/src/Core/NestByValue.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_NESTBYVALUE_H #define EIGEN_NESTBYVALUE_H diff --git a/eigenlib/Eigen/src/Core/NoAlias.h b/eigenlib/Eigen/src/Core/NoAlias.h index 33908010..198792d4 100644 --- a/eigenlib/Eigen/src/Core/NoAlias.h +++ b/eigenlib/Eigen/src/Core/NoAlias.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_NOALIAS_H #define EIGEN_NOALIAS_H diff --git a/eigenlib/Eigen/src/Core/NumTraits.h b/eigenlib/Eigen/src/Core/NumTraits.h index daf48987..45bb8e41 100644 --- a/eigenlib/Eigen/src/Core/NumTraits.h +++ b/eigenlib/Eigen/src/Core/NumTraits.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_NUMTRAITS_H #define EIGEN_NUMTRAITS_H diff --git a/eigenlib/Eigen/src/Core/PermutationMatrix.h b/eigenlib/Eigen/src/Core/PermutationMatrix.h index 47c06ba7..142a04ff 100644 --- a/eigenlib/Eigen/src/Core/PermutationMatrix.h +++ b/eigenlib/Eigen/src/Core/PermutationMatrix.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_PERMUTATIONMATRIX_H #define EIGEN_PERMUTATIONMATRIX_H diff --git a/eigenlib/Eigen/src/Core/PlainObjectBase.h b/eigenlib/Eigen/src/Core/PlainObjectBase.h index 0f3632cf..c8dee155 100644 --- a/eigenlib/Eigen/src/Core/PlainObjectBase.h +++ b/eigenlib/Eigen/src/Core/PlainObjectBase.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_DENSESTORAGEBASE_H #define EIGEN_DENSESTORAGEBASE_H diff --git a/eigenlib/Eigen/src/Core/Product.h b/eigenlib/Eigen/src/Core/Product.h index 676c4802..1ec2130e 100644 --- a/eigenlib/Eigen/src/Core/Product.h +++ b/eigenlib/Eigen/src/Core/Product.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_PRODUCT_H #define EIGEN_PRODUCT_H diff --git a/eigenlib/Eigen/src/Core/ProductEvaluators.h b/eigenlib/Eigen/src/Core/ProductEvaluators.h index bce1310c..176e0ea3 100644 --- a/eigenlib/Eigen/src/Core/ProductEvaluators.h +++ b/eigenlib/Eigen/src/Core/ProductEvaluators.h @@ -7,7 +7,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_PRODUCTEVALUATORS_H diff --git a/eigenlib/Eigen/src/Core/Random.h b/eigenlib/Eigen/src/Core/Random.h index 6faf789c..ff1a8e67 100644 --- a/eigenlib/Eigen/src/Core/Random.h +++ b/eigenlib/Eigen/src/Core/Random.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_RANDOM_H #define EIGEN_RANDOM_H diff --git a/eigenlib/Eigen/src/Core/Redux.h b/eigenlib/Eigen/src/Core/Redux.h index 760e9f86..fc97f551 100644 --- a/eigenlib/Eigen/src/Core/Redux.h +++ b/eigenlib/Eigen/src/Core/Redux.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_REDUX_H #define EIGEN_REDUX_H diff --git a/eigenlib/Eigen/src/Core/Ref.h b/eigenlib/Eigen/src/Core/Ref.h index 17a1496b..0698b011 100644 --- a/eigenlib/Eigen/src/Core/Ref.h +++ b/eigenlib/Eigen/src/Core/Ref.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_REF_H #define EIGEN_REF_H diff --git a/eigenlib/Eigen/src/Core/Replicate.h b/eigenlib/Eigen/src/Core/Replicate.h index 9960ef88..271bbf3a 100644 --- a/eigenlib/Eigen/src/Core/Replicate.h +++ b/eigenlib/Eigen/src/Core/Replicate.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_REPLICATE_H #define EIGEN_REPLICATE_H diff --git a/eigenlib/Eigen/src/Core/ReturnByValue.h b/eigenlib/Eigen/src/Core/ReturnByValue.h index c44b7673..89d77c62 100644 --- a/eigenlib/Eigen/src/Core/ReturnByValue.h +++ b/eigenlib/Eigen/src/Core/ReturnByValue.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_RETURNBYVALUE_H #define EIGEN_RETURNBYVALUE_H diff --git a/eigenlib/Eigen/src/Core/Reverse.h b/eigenlib/Eigen/src/Core/Reverse.h index 0640cda2..597c047a 100644 --- a/eigenlib/Eigen/src/Core/Reverse.h +++ b/eigenlib/Eigen/src/Core/Reverse.h @@ -7,7 +7,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_REVERSE_H #define EIGEN_REVERSE_H diff --git a/eigenlib/Eigen/src/Core/Select.h b/eigenlib/Eigen/src/Core/Select.h index 79eec1b5..7cd3afb9 100644 --- a/eigenlib/Eigen/src/Core/Select.h +++ b/eigenlib/Eigen/src/Core/Select.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SELECT_H #define EIGEN_SELECT_H diff --git a/eigenlib/Eigen/src/Core/SelfAdjointView.h b/eigenlib/Eigen/src/Core/SelfAdjointView.h index b2e51f37..c68a861e 100644 --- a/eigenlib/Eigen/src/Core/SelfAdjointView.h +++ b/eigenlib/Eigen/src/Core/SelfAdjointView.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SELFADJOINTMATRIX_H #define EIGEN_SELFADJOINTMATRIX_H diff --git a/eigenlib/Eigen/src/Core/SelfCwiseBinaryOp.h b/eigenlib/Eigen/src/Core/SelfCwiseBinaryOp.h index 7c89c2e2..82d88955 100644 --- a/eigenlib/Eigen/src/Core/SelfCwiseBinaryOp.h +++ b/eigenlib/Eigen/src/Core/SelfCwiseBinaryOp.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SELFCWISEBINARYOP_H #define EIGEN_SELFCWISEBINARYOP_H diff --git a/eigenlib/Eigen/src/Core/Solve.h b/eigenlib/Eigen/src/Core/Solve.h index a8daea51..6195e3af 100644 --- a/eigenlib/Eigen/src/Core/Solve.h +++ b/eigenlib/Eigen/src/Core/Solve.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SOLVE_H #define EIGEN_SOLVE_H diff --git a/eigenlib/Eigen/src/Core/SolveTriangular.h b/eigenlib/Eigen/src/Core/SolveTriangular.h index fd0acb1a..d7f45e5f 100644 --- a/eigenlib/Eigen/src/Core/SolveTriangular.h +++ b/eigenlib/Eigen/src/Core/SolveTriangular.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SOLVETRIANGULAR_H #define EIGEN_SOLVETRIANGULAR_H diff --git a/eigenlib/Eigen/src/Core/SolverBase.h b/eigenlib/Eigen/src/Core/SolverBase.h index 8a4adc22..a2693031 100644 --- a/eigenlib/Eigen/src/Core/SolverBase.h +++ b/eigenlib/Eigen/src/Core/SolverBase.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SOLVERBASE_H #define EIGEN_SOLVERBASE_H diff --git a/eigenlib/Eigen/src/Core/StableNorm.h b/eigenlib/Eigen/src/Core/StableNorm.h index 88c8d989..e969d7fe 100644 --- a/eigenlib/Eigen/src/Core/StableNorm.h +++ b/eigenlib/Eigen/src/Core/StableNorm.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_STABLENORM_H #define EIGEN_STABLENORM_H diff --git a/eigenlib/Eigen/src/Core/Stride.h b/eigenlib/Eigen/src/Core/Stride.h index 513742f3..cac9a278 100644 --- a/eigenlib/Eigen/src/Core/Stride.h +++ b/eigenlib/Eigen/src/Core/Stride.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_STRIDE_H #define EIGEN_STRIDE_H diff --git a/eigenlib/Eigen/src/Core/Swap.h b/eigenlib/Eigen/src/Core/Swap.h index d7020091..bb5f2c10 100644 --- a/eigenlib/Eigen/src/Core/Swap.h +++ b/eigenlib/Eigen/src/Core/Swap.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SWAP_H #define EIGEN_SWAP_H diff --git a/eigenlib/Eigen/src/Core/Transpose.h b/eigenlib/Eigen/src/Core/Transpose.h index 960dc451..0b3c8272 100644 --- a/eigenlib/Eigen/src/Core/Transpose.h +++ b/eigenlib/Eigen/src/Core/Transpose.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_TRANSPOSE_H #define EIGEN_TRANSPOSE_H diff --git a/eigenlib/Eigen/src/Core/Transpositions.h b/eigenlib/Eigen/src/Core/Transpositions.h index 7718625e..41e2da49 100644 --- a/eigenlib/Eigen/src/Core/Transpositions.h +++ b/eigenlib/Eigen/src/Core/Transpositions.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_TRANSPOSITIONS_H #define EIGEN_TRANSPOSITIONS_H diff --git a/eigenlib/Eigen/src/Core/TriangularMatrix.h b/eigenlib/Eigen/src/Core/TriangularMatrix.h index 9abb7e31..1f2d3a70 100644 --- a/eigenlib/Eigen/src/Core/TriangularMatrix.h +++ b/eigenlib/Eigen/src/Core/TriangularMatrix.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_TRIANGULARMATRIX_H #define EIGEN_TRIANGULARMATRIX_H diff --git a/eigenlib/Eigen/src/Core/VectorBlock.h b/eigenlib/Eigen/src/Core/VectorBlock.h index d72fbf7e..96bea9a8 100644 --- a/eigenlib/Eigen/src/Core/VectorBlock.h +++ b/eigenlib/Eigen/src/Core/VectorBlock.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_VECTORBLOCK_H #define EIGEN_VECTORBLOCK_H diff --git a/eigenlib/Eigen/src/Core/VectorwiseOp.h b/eigenlib/Eigen/src/Core/VectorwiseOp.h index 4fe267e9..0e167b9f 100644 --- a/eigenlib/Eigen/src/Core/VectorwiseOp.h +++ b/eigenlib/Eigen/src/Core/VectorwiseOp.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_PARTIAL_REDUX_H #define EIGEN_PARTIAL_REDUX_H diff --git a/eigenlib/Eigen/src/Core/Visitor.h b/eigenlib/Eigen/src/Core/Visitor.h index 54c1883d..98cd67fb 100644 --- a/eigenlib/Eigen/src/Core/Visitor.h +++ b/eigenlib/Eigen/src/Core/Visitor.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_VISITOR_H #define EIGEN_VISITOR_H diff --git a/eigenlib/Eigen/src/Core/arch/AVX/Complex.h b/eigenlib/Eigen/src/Core/arch/AVX/Complex.h index 7fa61969..fed35e5b 100644 --- a/eigenlib/Eigen/src/Core/arch/AVX/Complex.h +++ b/eigenlib/Eigen/src/Core/arch/AVX/Complex.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_COMPLEX_AVX_H #define EIGEN_COMPLEX_AVX_H diff --git a/eigenlib/Eigen/src/Core/arch/AVX/MathFunctions.h b/eigenlib/Eigen/src/Core/arch/AVX/MathFunctions.h index 6af67ce2..c5f966b2 100644 --- a/eigenlib/Eigen/src/Core/arch/AVX/MathFunctions.h +++ b/eigenlib/Eigen/src/Core/arch/AVX/MathFunctions.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_MATH_FUNCTIONS_AVX_H #define EIGEN_MATH_FUNCTIONS_AVX_H diff --git a/eigenlib/Eigen/src/Core/arch/AVX/PacketMath.h b/eigenlib/Eigen/src/Core/arch/AVX/PacketMath.h index 923a124b..9ab6dc9b 100644 --- a/eigenlib/Eigen/src/Core/arch/AVX/PacketMath.h +++ b/eigenlib/Eigen/src/Core/arch/AVX/PacketMath.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_PACKET_MATH_AVX_H #define EIGEN_PACKET_MATH_AVX_H diff --git a/eigenlib/Eigen/src/Core/arch/AVX/TypeCasting.h b/eigenlib/Eigen/src/Core/arch/AVX/TypeCasting.h index 83bfdc60..301eb4cb 100644 --- a/eigenlib/Eigen/src/Core/arch/AVX/TypeCasting.h +++ b/eigenlib/Eigen/src/Core/arch/AVX/TypeCasting.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_TYPE_CASTING_AVX_H #define EIGEN_TYPE_CASTING_AVX_H diff --git a/eigenlib/Eigen/src/Core/arch/AVX512/MathFunctions.h b/eigenlib/Eigen/src/Core/arch/AVX512/MathFunctions.h index b259c1e1..f30f2a9e 100644 --- a/eigenlib/Eigen/src/Core/arch/AVX512/MathFunctions.h +++ b/eigenlib/Eigen/src/Core/arch/AVX512/MathFunctions.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef THIRD_PARTY_EIGEN3_EIGEN_SRC_CORE_ARCH_AVX512_MATHFUNCTIONS_H_ #define THIRD_PARTY_EIGEN3_EIGEN_SRC_CORE_ARCH_AVX512_MATHFUNCTIONS_H_ diff --git a/eigenlib/Eigen/src/Core/arch/AVX512/PacketMath.h b/eigenlib/Eigen/src/Core/arch/AVX512/PacketMath.h index 000b7762..b8b11153 100644 --- a/eigenlib/Eigen/src/Core/arch/AVX512/PacketMath.h +++ b/eigenlib/Eigen/src/Core/arch/AVX512/PacketMath.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_PACKET_MATH_AVX512_H #define EIGEN_PACKET_MATH_AVX512_H diff --git a/eigenlib/Eigen/src/Core/arch/AltiVec/Complex.h b/eigenlib/Eigen/src/Core/arch/AltiVec/Complex.h index 3e665730..32590a53 100644 --- a/eigenlib/Eigen/src/Core/arch/AltiVec/Complex.h +++ b/eigenlib/Eigen/src/Core/arch/AltiVec/Complex.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_COMPLEX32_ALTIVEC_H #define EIGEN_COMPLEX32_ALTIVEC_H diff --git a/eigenlib/Eigen/src/Core/arch/AltiVec/MathFunctions.h b/eigenlib/Eigen/src/Core/arch/AltiVec/MathFunctions.h index c5e4bede..74e76687 100644 --- a/eigenlib/Eigen/src/Core/arch/AltiVec/MathFunctions.h +++ b/eigenlib/Eigen/src/Core/arch/AltiVec/MathFunctions.h @@ -7,7 +7,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page /* The sin, cos, exp, and log functions of this file come from * Julien Pommier's sse math library: http://gruntthepeon.free.fr/ssemath/ diff --git a/eigenlib/Eigen/src/Core/arch/AltiVec/PacketMath.h b/eigenlib/Eigen/src/Core/arch/AltiVec/PacketMath.h index 08a27d15..e3d31bb5 100755 --- a/eigenlib/Eigen/src/Core/arch/AltiVec/PacketMath.h +++ b/eigenlib/Eigen/src/Core/arch/AltiVec/PacketMath.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_PACKET_MATH_ALTIVEC_H #define EIGEN_PACKET_MATH_ALTIVEC_H diff --git a/eigenlib/Eigen/src/Core/arch/CUDA/Complex.h b/eigenlib/Eigen/src/Core/arch/CUDA/Complex.h index 9c253650..e82b52fb 100644 --- a/eigenlib/Eigen/src/Core/arch/CUDA/Complex.h +++ b/eigenlib/Eigen/src/Core/arch/CUDA/Complex.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_COMPLEX_CUDA_H #define EIGEN_COMPLEX_CUDA_H diff --git a/eigenlib/Eigen/src/Core/arch/CUDA/Half.h b/eigenlib/Eigen/src/Core/arch/CUDA/Half.h index 59717b4f..52573bce 100644 --- a/eigenlib/Eigen/src/Core/arch/CUDA/Half.h +++ b/eigenlib/Eigen/src/Core/arch/CUDA/Half.h @@ -3,7 +3,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page // // The conversion routines are Copyright (c) Fabian Giesen, 2016. // The original license follows: diff --git a/eigenlib/Eigen/src/Core/arch/CUDA/MathFunctions.h b/eigenlib/Eigen/src/Core/arch/CUDA/MathFunctions.h index 0348b41d..df229ce1 100644 --- a/eigenlib/Eigen/src/Core/arch/CUDA/MathFunctions.h +++ b/eigenlib/Eigen/src/Core/arch/CUDA/MathFunctions.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_MATH_FUNCTIONS_CUDA_H #define EIGEN_MATH_FUNCTIONS_CUDA_H diff --git a/eigenlib/Eigen/src/Core/arch/CUDA/PacketMath.h b/eigenlib/Eigen/src/Core/arch/CUDA/PacketMath.h index 4dda6318..b4c55655 100644 --- a/eigenlib/Eigen/src/Core/arch/CUDA/PacketMath.h +++ b/eigenlib/Eigen/src/Core/arch/CUDA/PacketMath.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_PACKET_MATH_CUDA_H #define EIGEN_PACKET_MATH_CUDA_H diff --git a/eigenlib/Eigen/src/Core/arch/CUDA/PacketMathHalf.h b/eigenlib/Eigen/src/Core/arch/CUDA/PacketMathHalf.h index f749c573..43378e23 100644 --- a/eigenlib/Eigen/src/Core/arch/CUDA/PacketMathHalf.h +++ b/eigenlib/Eigen/src/Core/arch/CUDA/PacketMathHalf.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_PACKET_MATH_HALF_CUDA_H #define EIGEN_PACKET_MATH_HALF_CUDA_H diff --git a/eigenlib/Eigen/src/Core/arch/CUDA/TypeCasting.h b/eigenlib/Eigen/src/Core/arch/CUDA/TypeCasting.h index aa5fbce8..84c00611 100644 --- a/eigenlib/Eigen/src/Core/arch/CUDA/TypeCasting.h +++ b/eigenlib/Eigen/src/Core/arch/CUDA/TypeCasting.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_TYPE_CASTING_CUDA_H #define EIGEN_TYPE_CASTING_CUDA_H diff --git a/eigenlib/Eigen/src/Core/arch/Default/ConjHelper.h b/eigenlib/Eigen/src/Core/arch/Default/ConjHelper.h index 4cfe34e0..279066e0 100644 --- a/eigenlib/Eigen/src/Core/arch/Default/ConjHelper.h +++ b/eigenlib/Eigen/src/Core/arch/Default/ConjHelper.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_ARCH_CONJ_HELPER_H #define EIGEN_ARCH_CONJ_HELPER_H diff --git a/eigenlib/Eigen/src/Core/arch/Default/Settings.h b/eigenlib/Eigen/src/Core/arch/Default/Settings.h index 097373c8..2f2cf85d 100644 --- a/eigenlib/Eigen/src/Core/arch/Default/Settings.h +++ b/eigenlib/Eigen/src/Core/arch/Default/Settings.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page /* All the parameters defined in this file can be specialized in the diff --git a/eigenlib/Eigen/src/Core/arch/NEON/Complex.h b/eigenlib/Eigen/src/Core/arch/NEON/Complex.h index 306a309b..097b3bb2 100644 --- a/eigenlib/Eigen/src/Core/arch/NEON/Complex.h +++ b/eigenlib/Eigen/src/Core/arch/NEON/Complex.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_COMPLEX_NEON_H #define EIGEN_COMPLEX_NEON_H diff --git a/eigenlib/Eigen/src/Core/arch/NEON/MathFunctions.h b/eigenlib/Eigen/src/Core/arch/NEON/MathFunctions.h index 6bb05bb9..3e3fd4ff 100644 --- a/eigenlib/Eigen/src/Core/arch/NEON/MathFunctions.h +++ b/eigenlib/Eigen/src/Core/arch/NEON/MathFunctions.h @@ -3,7 +3,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page /* The sin, cos, exp, and log functions of this file come from * Julien Pommier's sse math library: http://gruntthepeon.free.fr/ssemath/ diff --git a/eigenlib/Eigen/src/Core/arch/NEON/PacketMath.h b/eigenlib/Eigen/src/Core/arch/NEON/PacketMath.h index 3d5ed0d2..c7050a43 100644 --- a/eigenlib/Eigen/src/Core/arch/NEON/PacketMath.h +++ b/eigenlib/Eigen/src/Core/arch/NEON/PacketMath.h @@ -7,7 +7,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_PACKET_MATH_NEON_H #define EIGEN_PACKET_MATH_NEON_H diff --git a/eigenlib/Eigen/src/Core/arch/SSE/Complex.h b/eigenlib/Eigen/src/Core/arch/SSE/Complex.h index d075043c..0796ef30 100644 --- a/eigenlib/Eigen/src/Core/arch/SSE/Complex.h +++ b/eigenlib/Eigen/src/Core/arch/SSE/Complex.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_COMPLEX_SSE_H #define EIGEN_COMPLEX_SSE_H diff --git a/eigenlib/Eigen/src/Core/arch/SSE/MathFunctions.h b/eigenlib/Eigen/src/Core/arch/SSE/MathFunctions.h index 7b5f948e..24c842ee 100644 --- a/eigenlib/Eigen/src/Core/arch/SSE/MathFunctions.h +++ b/eigenlib/Eigen/src/Core/arch/SSE/MathFunctions.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page /* The sin, cos, exp, and log functions of this file come from * Julien Pommier's sse math library: http://gruntthepeon.free.fr/ssemath/ diff --git a/eigenlib/Eigen/src/Core/arch/SSE/PacketMath.h b/eigenlib/Eigen/src/Core/arch/SSE/PacketMath.h index 60e2517e..0fe51aea 100755 --- a/eigenlib/Eigen/src/Core/arch/SSE/PacketMath.h +++ b/eigenlib/Eigen/src/Core/arch/SSE/PacketMath.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_PACKET_MATH_SSE_H #define EIGEN_PACKET_MATH_SSE_H diff --git a/eigenlib/Eigen/src/Core/arch/SSE/TypeCasting.h b/eigenlib/Eigen/src/Core/arch/SSE/TypeCasting.h index c6ca8c71..81b5ba91 100644 --- a/eigenlib/Eigen/src/Core/arch/SSE/TypeCasting.h +++ b/eigenlib/Eigen/src/Core/arch/SSE/TypeCasting.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_TYPE_CASTING_SSE_H #define EIGEN_TYPE_CASTING_SSE_H diff --git a/eigenlib/Eigen/src/Core/arch/ZVector/Complex.h b/eigenlib/Eigen/src/Core/arch/ZVector/Complex.h index 1bfb7339..2a367b59 100644 --- a/eigenlib/Eigen/src/Core/arch/ZVector/Complex.h +++ b/eigenlib/Eigen/src/Core/arch/ZVector/Complex.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_COMPLEX32_ALTIVEC_H #define EIGEN_COMPLEX32_ALTIVEC_H diff --git a/eigenlib/Eigen/src/Core/arch/ZVector/MathFunctions.h b/eigenlib/Eigen/src/Core/arch/ZVector/MathFunctions.h index 5c7aa725..ee5a3f43 100644 --- a/eigenlib/Eigen/src/Core/arch/ZVector/MathFunctions.h +++ b/eigenlib/Eigen/src/Core/arch/ZVector/MathFunctions.h @@ -7,7 +7,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page /* The sin, cos, exp, and log functions of this file come from * Julien Pommier's sse math library: http://gruntthepeon.free.fr/ssemath/ diff --git a/eigenlib/Eigen/src/Core/arch/ZVector/PacketMath.h b/eigenlib/Eigen/src/Core/arch/ZVector/PacketMath.h index 57b01fc6..34775cd7 100755 --- a/eigenlib/Eigen/src/Core/arch/ZVector/PacketMath.h +++ b/eigenlib/Eigen/src/Core/arch/ZVector/PacketMath.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_PACKET_MATH_ZVECTOR_H #define EIGEN_PACKET_MATH_ZVECTOR_H diff --git a/eigenlib/Eigen/src/Core/functors/AssignmentFunctors.h b/eigenlib/Eigen/src/Core/functors/AssignmentFunctors.h index 4153b877..9bf268da 100644 --- a/eigenlib/Eigen/src/Core/functors/AssignmentFunctors.h +++ b/eigenlib/Eigen/src/Core/functors/AssignmentFunctors.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_ASSIGNMENT_FUNCTORS_H #define EIGEN_ASSIGNMENT_FUNCTORS_H diff --git a/eigenlib/Eigen/src/Core/functors/BinaryFunctors.h b/eigenlib/Eigen/src/Core/functors/BinaryFunctors.h index 3eae6b8c..b056cdd2 100644 --- a/eigenlib/Eigen/src/Core/functors/BinaryFunctors.h +++ b/eigenlib/Eigen/src/Core/functors/BinaryFunctors.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_BINARY_FUNCTORS_H #define EIGEN_BINARY_FUNCTORS_H diff --git a/eigenlib/Eigen/src/Core/functors/NullaryFunctors.h b/eigenlib/Eigen/src/Core/functors/NullaryFunctors.h index b03be026..ba84d941 100644 --- a/eigenlib/Eigen/src/Core/functors/NullaryFunctors.h +++ b/eigenlib/Eigen/src/Core/functors/NullaryFunctors.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_NULLARY_FUNCTORS_H #define EIGEN_NULLARY_FUNCTORS_H diff --git a/eigenlib/Eigen/src/Core/functors/StlFunctors.h b/eigenlib/Eigen/src/Core/functors/StlFunctors.h index 9c1d7585..3ea133c7 100644 --- a/eigenlib/Eigen/src/Core/functors/StlFunctors.h +++ b/eigenlib/Eigen/src/Core/functors/StlFunctors.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_STL_FUNCTORS_H #define EIGEN_STL_FUNCTORS_H diff --git a/eigenlib/Eigen/src/Core/functors/TernaryFunctors.h b/eigenlib/Eigen/src/Core/functors/TernaryFunctors.h index b254e96c..e6ae4ce0 100644 --- a/eigenlib/Eigen/src/Core/functors/TernaryFunctors.h +++ b/eigenlib/Eigen/src/Core/functors/TernaryFunctors.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_TERNARY_FUNCTORS_H #define EIGEN_TERNARY_FUNCTORS_H diff --git a/eigenlib/Eigen/src/Core/functors/UnaryFunctors.h b/eigenlib/Eigen/src/Core/functors/UnaryFunctors.h index b56e7afd..fcd8e7b5 100644 --- a/eigenlib/Eigen/src/Core/functors/UnaryFunctors.h +++ b/eigenlib/Eigen/src/Core/functors/UnaryFunctors.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_UNARY_FUNCTORS_H #define EIGEN_UNARY_FUNCTORS_H diff --git a/eigenlib/Eigen/src/Core/products/GeneralBlockPanelKernel.h b/eigenlib/Eigen/src/Core/products/GeneralBlockPanelKernel.h index 681451cc..3a6d29aa 100644 --- a/eigenlib/Eigen/src/Core/products/GeneralBlockPanelKernel.h +++ b/eigenlib/Eigen/src/Core/products/GeneralBlockPanelKernel.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_GENERAL_BLOCK_PANEL_H #define EIGEN_GENERAL_BLOCK_PANEL_H diff --git a/eigenlib/Eigen/src/Core/products/GeneralMatrixMatrix.h b/eigenlib/Eigen/src/Core/products/GeneralMatrixMatrix.h index ed6234c3..2bb0815c 100644 --- a/eigenlib/Eigen/src/Core/products/GeneralMatrixMatrix.h +++ b/eigenlib/Eigen/src/Core/products/GeneralMatrixMatrix.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_GENERAL_MATRIX_MATRIX_H #define EIGEN_GENERAL_MATRIX_MATRIX_H diff --git a/eigenlib/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h b/eigenlib/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h index d68d2f96..cc8697cb 100644 --- a/eigenlib/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h +++ b/eigenlib/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_GENERAL_MATRIX_MATRIX_TRIANGULAR_H #define EIGEN_GENERAL_MATRIX_MATRIX_TRIANGULAR_H diff --git a/eigenlib/Eigen/src/Core/products/GeneralMatrixVector.h b/eigenlib/Eigen/src/Core/products/GeneralMatrixVector.h index a597c1f4..ab8d96e4 100644 --- a/eigenlib/Eigen/src/Core/products/GeneralMatrixVector.h +++ b/eigenlib/Eigen/src/Core/products/GeneralMatrixVector.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_GENERAL_MATRIX_VECTOR_H #define EIGEN_GENERAL_MATRIX_VECTOR_H diff --git a/eigenlib/Eigen/src/Core/products/Parallelizer.h b/eigenlib/Eigen/src/Core/products/Parallelizer.h index a3cc05b7..02d53a83 100644 --- a/eigenlib/Eigen/src/Core/products/Parallelizer.h +++ b/eigenlib/Eigen/src/Core/products/Parallelizer.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_PARALLELIZER_H #define EIGEN_PARALLELIZER_H diff --git a/eigenlib/Eigen/src/Core/products/SelfadjointMatrixMatrix.h b/eigenlib/Eigen/src/Core/products/SelfadjointMatrixMatrix.h index 04c93348..576c986e 100644 --- a/eigenlib/Eigen/src/Core/products/SelfadjointMatrixMatrix.h +++ b/eigenlib/Eigen/src/Core/products/SelfadjointMatrixMatrix.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SELFADJOINT_MATRIX_MATRIX_H #define EIGEN_SELFADJOINT_MATRIX_MATRIX_H diff --git a/eigenlib/Eigen/src/Core/products/SelfadjointMatrixVector.h b/eigenlib/Eigen/src/Core/products/SelfadjointMatrixVector.h index 3fd180e6..c16dc61f 100644 --- a/eigenlib/Eigen/src/Core/products/SelfadjointMatrixVector.h +++ b/eigenlib/Eigen/src/Core/products/SelfadjointMatrixVector.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SELFADJOINT_MATRIX_VECTOR_H #define EIGEN_SELFADJOINT_MATRIX_VECTOR_H diff --git a/eigenlib/Eigen/src/Core/products/SelfadjointProduct.h b/eigenlib/Eigen/src/Core/products/SelfadjointProduct.h index ef12c98f..0fcc7f1d 100644 --- a/eigenlib/Eigen/src/Core/products/SelfadjointProduct.h +++ b/eigenlib/Eigen/src/Core/products/SelfadjointProduct.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SELFADJOINT_PRODUCT_H #define EIGEN_SELFADJOINT_PRODUCT_H diff --git a/eigenlib/Eigen/src/Core/products/SelfadjointRank2Update.h b/eigenlib/Eigen/src/Core/products/SelfadjointRank2Update.h index 2ae36411..f1de1785 100644 --- a/eigenlib/Eigen/src/Core/products/SelfadjointRank2Update.h +++ b/eigenlib/Eigen/src/Core/products/SelfadjointRank2Update.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SELFADJOINTRANK2UPTADE_H #define EIGEN_SELFADJOINTRANK2UPTADE_H diff --git a/eigenlib/Eigen/src/Core/products/TriangularMatrixMatrix.h b/eigenlib/Eigen/src/Core/products/TriangularMatrixMatrix.h index 2fb408d1..cbe49fbd 100644 --- a/eigenlib/Eigen/src/Core/products/TriangularMatrixMatrix.h +++ b/eigenlib/Eigen/src/Core/products/TriangularMatrixMatrix.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_TRIANGULAR_MATRIX_MATRIX_H #define EIGEN_TRIANGULAR_MATRIX_MATRIX_H diff --git a/eigenlib/Eigen/src/Core/products/TriangularMatrixVector.h b/eigenlib/Eigen/src/Core/products/TriangularMatrixVector.h index 76bfa159..0a7c6ee3 100644 --- a/eigenlib/Eigen/src/Core/products/TriangularMatrixVector.h +++ b/eigenlib/Eigen/src/Core/products/TriangularMatrixVector.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_TRIANGULARMATRIXVECTOR_H #define EIGEN_TRIANGULARMATRIXVECTOR_H diff --git a/eigenlib/Eigen/src/Core/products/TriangularSolverMatrix.h b/eigenlib/Eigen/src/Core/products/TriangularSolverMatrix.h index e3ed2cd1..c165ac73 100644 --- a/eigenlib/Eigen/src/Core/products/TriangularSolverMatrix.h +++ b/eigenlib/Eigen/src/Core/products/TriangularSolverMatrix.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_TRIANGULAR_SOLVER_MATRIX_H #define EIGEN_TRIANGULAR_SOLVER_MATRIX_H diff --git a/eigenlib/Eigen/src/Core/products/TriangularSolverVector.h b/eigenlib/Eigen/src/Core/products/TriangularSolverVector.h index b994759b..185a2084 100644 --- a/eigenlib/Eigen/src/Core/products/TriangularSolverVector.h +++ b/eigenlib/Eigen/src/Core/products/TriangularSolverVector.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_TRIANGULAR_SOLVER_VECTOR_H #define EIGEN_TRIANGULAR_SOLVER_VECTOR_H diff --git a/eigenlib/Eigen/src/Core/util/BlasUtil.h b/eigenlib/Eigen/src/Core/util/BlasUtil.h index 3dff9bc9..cc99967f 100755 --- a/eigenlib/Eigen/src/Core/util/BlasUtil.h +++ b/eigenlib/Eigen/src/Core/util/BlasUtil.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_BLASUTIL_H #define EIGEN_BLASUTIL_H diff --git a/eigenlib/Eigen/src/Core/util/Constants.h b/eigenlib/Eigen/src/Core/util/Constants.h index 7587d684..5beb0ba2 100644 --- a/eigenlib/Eigen/src/Core/util/Constants.h +++ b/eigenlib/Eigen/src/Core/util/Constants.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_CONSTANTS_H #define EIGEN_CONSTANTS_H diff --git a/eigenlib/Eigen/src/Core/util/ForwardDeclarations.h b/eigenlib/Eigen/src/Core/util/ForwardDeclarations.h index 134544f9..f6bbee78 100644 --- a/eigenlib/Eigen/src/Core/util/ForwardDeclarations.h +++ b/eigenlib/Eigen/src/Core/util/ForwardDeclarations.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_FORWARDDECLARATIONS_H #define EIGEN_FORWARDDECLARATIONS_H diff --git a/eigenlib/Eigen/src/Core/util/Macros.h b/eigenlib/Eigen/src/Core/util/Macros.h index 6b0399eb..ba1e9540 100644 --- a/eigenlib/Eigen/src/Core/util/Macros.h +++ b/eigenlib/Eigen/src/Core/util/Macros.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_MACROS_H #define EIGEN_MACROS_H diff --git a/eigenlib/Eigen/src/Core/util/Memory.h b/eigenlib/Eigen/src/Core/util/Memory.h index 291383c5..3cc0f9be 100644 --- a/eigenlib/Eigen/src/Core/util/Memory.h +++ b/eigenlib/Eigen/src/Core/util/Memory.h @@ -10,7 +10,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page /***************************************************************************** diff --git a/eigenlib/Eigen/src/Core/util/Meta.h b/eigenlib/Eigen/src/Core/util/Meta.h index 9b61ff03..72e02b03 100755 --- a/eigenlib/Eigen/src/Core/util/Meta.h +++ b/eigenlib/Eigen/src/Core/util/Meta.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_META_H #define EIGEN_META_H diff --git a/eigenlib/Eigen/src/Core/util/StaticAssert.h b/eigenlib/Eigen/src/Core/util/StaticAssert.h index 500e4779..9d8bfd33 100644 --- a/eigenlib/Eigen/src/Core/util/StaticAssert.h +++ b/eigenlib/Eigen/src/Core/util/StaticAssert.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_STATIC_ASSERT_H #define EIGEN_STATIC_ASSERT_H diff --git a/eigenlib/Eigen/src/Core/util/XprHelper.h b/eigenlib/Eigen/src/Core/util/XprHelper.h index 6bb49708..80c0cb47 100644 --- a/eigenlib/Eigen/src/Core/util/XprHelper.h +++ b/eigenlib/Eigen/src/Core/util/XprHelper.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_XPRHELPER_H #define EIGEN_XPRHELPER_H diff --git a/eigenlib/Eigen/src/Eigenvalues/ComplexEigenSolver.h b/eigenlib/Eigen/src/Eigenvalues/ComplexEigenSolver.h index dc5fae06..fb11b600 100644 --- a/eigenlib/Eigen/src/Eigenvalues/ComplexEigenSolver.h +++ b/eigenlib/Eigen/src/Eigenvalues/ComplexEigenSolver.h @@ -7,7 +7,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_COMPLEX_EIGEN_SOLVER_H #define EIGEN_COMPLEX_EIGEN_SOLVER_H diff --git a/eigenlib/Eigen/src/Eigenvalues/ComplexSchur.h b/eigenlib/Eigen/src/Eigenvalues/ComplexSchur.h index 4354e401..dba70e5c 100644 --- a/eigenlib/Eigen/src/Eigenvalues/ComplexSchur.h +++ b/eigenlib/Eigen/src/Eigenvalues/ComplexSchur.h @@ -7,7 +7,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_COMPLEX_SCHUR_H #define EIGEN_COMPLEX_SCHUR_H diff --git a/eigenlib/Eigen/src/Eigenvalues/EigenSolver.h b/eigenlib/Eigen/src/Eigenvalues/EigenSolver.h index f205b185..aec9b7da 100644 --- a/eigenlib/Eigen/src/Eigenvalues/EigenSolver.h +++ b/eigenlib/Eigen/src/Eigenvalues/EigenSolver.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_EIGENSOLVER_H #define EIGEN_EIGENSOLVER_H diff --git a/eigenlib/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h b/eigenlib/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h index 87d789b3..94d643cf 100644 --- a/eigenlib/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h +++ b/eigenlib/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h @@ -7,7 +7,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_GENERALIZEDEIGENSOLVER_H #define EIGEN_GENERALIZEDEIGENSOLVER_H diff --git a/eigenlib/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h b/eigenlib/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h index 5f6bb828..41871709 100644 --- a/eigenlib/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h +++ b/eigenlib/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_GENERALIZEDSELFADJOINTEIGENSOLVER_H #define EIGEN_GENERALIZEDSELFADJOINTEIGENSOLVER_H diff --git a/eigenlib/Eigen/src/Eigenvalues/HessenbergDecomposition.h b/eigenlib/Eigen/src/Eigenvalues/HessenbergDecomposition.h index f647f69b..e712b019 100644 --- a/eigenlib/Eigen/src/Eigenvalues/HessenbergDecomposition.h +++ b/eigenlib/Eigen/src/Eigenvalues/HessenbergDecomposition.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_HESSENBERGDECOMPOSITION_H #define EIGEN_HESSENBERGDECOMPOSITION_H diff --git a/eigenlib/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h b/eigenlib/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h index e4e42607..633d76e9 100644 --- a/eigenlib/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h +++ b/eigenlib/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_MATRIXBASEEIGENVALUES_H #define EIGEN_MATRIXBASEEIGENVALUES_H diff --git a/eigenlib/Eigen/src/Eigenvalues/RealQZ.h b/eigenlib/Eigen/src/Eigenvalues/RealQZ.h index b3a910dd..3d332d38 100644 --- a/eigenlib/Eigen/src/Eigenvalues/RealQZ.h +++ b/eigenlib/Eigen/src/Eigenvalues/RealQZ.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_REAL_QZ_H #define EIGEN_REAL_QZ_H diff --git a/eigenlib/Eigen/src/Eigenvalues/RealSchur.h b/eigenlib/Eigen/src/Eigenvalues/RealSchur.h index 9191519a..ec1375f5 100644 --- a/eigenlib/Eigen/src/Eigenvalues/RealSchur.h +++ b/eigenlib/Eigen/src/Eigenvalues/RealSchur.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_REAL_SCHUR_H #define EIGEN_REAL_SCHUR_H diff --git a/eigenlib/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h b/eigenlib/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h index d37656fa..350d4648 100644 --- a/eigenlib/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h +++ b/eigenlib/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SELFADJOINTEIGENSOLVER_H #define EIGEN_SELFADJOINTEIGENSOLVER_H diff --git a/eigenlib/Eigen/src/Eigenvalues/Tridiagonalization.h b/eigenlib/Eigen/src/Eigenvalues/Tridiagonalization.h index 1d102c17..116f53e3 100644 --- a/eigenlib/Eigen/src/Eigenvalues/Tridiagonalization.h +++ b/eigenlib/Eigen/src/Eigenvalues/Tridiagonalization.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_TRIDIAGONALIZATION_H #define EIGEN_TRIDIAGONALIZATION_H diff --git a/eigenlib/Eigen/src/Geometry/AlignedBox.h b/eigenlib/Eigen/src/Geometry/AlignedBox.h index 066eae4f..e46fa872 100644 --- a/eigenlib/Eigen/src/Geometry/AlignedBox.h +++ b/eigenlib/Eigen/src/Geometry/AlignedBox.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_ALIGNEDBOX_H #define EIGEN_ALIGNEDBOX_H diff --git a/eigenlib/Eigen/src/Geometry/AngleAxis.h b/eigenlib/Eigen/src/Geometry/AngleAxis.h index 83ee1be4..1f92ba7e 100644 --- a/eigenlib/Eigen/src/Geometry/AngleAxis.h +++ b/eigenlib/Eigen/src/Geometry/AngleAxis.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_ANGLEAXIS_H #define EIGEN_ANGLEAXIS_H diff --git a/eigenlib/Eigen/src/Geometry/EulerAngles.h b/eigenlib/Eigen/src/Geometry/EulerAngles.h index c633268a..26d782d8 100644 --- a/eigenlib/Eigen/src/Geometry/EulerAngles.h +++ b/eigenlib/Eigen/src/Geometry/EulerAngles.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_EULERANGLES_H #define EIGEN_EULERANGLES_H diff --git a/eigenlib/Eigen/src/Geometry/Homogeneous.h b/eigenlib/Eigen/src/Geometry/Homogeneous.h index 5f0da1a9..040a1973 100644 --- a/eigenlib/Eigen/src/Geometry/Homogeneous.h +++ b/eigenlib/Eigen/src/Geometry/Homogeneous.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_HOMOGENEOUS_H #define EIGEN_HOMOGENEOUS_H diff --git a/eigenlib/Eigen/src/Geometry/Hyperplane.h b/eigenlib/Eigen/src/Geometry/Hyperplane.h index 05929b29..d46c6138 100644 --- a/eigenlib/Eigen/src/Geometry/Hyperplane.h +++ b/eigenlib/Eigen/src/Geometry/Hyperplane.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_HYPERPLANE_H #define EIGEN_HYPERPLANE_H diff --git a/eigenlib/Eigen/src/Geometry/OrthoMethods.h b/eigenlib/Eigen/src/Geometry/OrthoMethods.h index a035e631..42cc46ae 100644 --- a/eigenlib/Eigen/src/Geometry/OrthoMethods.h +++ b/eigenlib/Eigen/src/Geometry/OrthoMethods.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_ORTHOMETHODS_H #define EIGEN_ORTHOMETHODS_H diff --git a/eigenlib/Eigen/src/Geometry/ParametrizedLine.h b/eigenlib/Eigen/src/Geometry/ParametrizedLine.h index 1e985d8c..e7b20361 100644 --- a/eigenlib/Eigen/src/Geometry/ParametrizedLine.h +++ b/eigenlib/Eigen/src/Geometry/ParametrizedLine.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_PARAMETRIZEDLINE_H #define EIGEN_PARAMETRIZEDLINE_H diff --git a/eigenlib/Eigen/src/Geometry/Quaternion.h b/eigenlib/Eigen/src/Geometry/Quaternion.h index b8182065..025328c7 100644 --- a/eigenlib/Eigen/src/Geometry/Quaternion.h +++ b/eigenlib/Eigen/src/Geometry/Quaternion.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_QUATERNION_H #define EIGEN_QUATERNION_H diff --git a/eigenlib/Eigen/src/Geometry/Rotation2D.h b/eigenlib/Eigen/src/Geometry/Rotation2D.h index 884b7d0e..f62b0e74 100644 --- a/eigenlib/Eigen/src/Geometry/Rotation2D.h +++ b/eigenlib/Eigen/src/Geometry/Rotation2D.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_ROTATION2D_H #define EIGEN_ROTATION2D_H diff --git a/eigenlib/Eigen/src/Geometry/RotationBase.h b/eigenlib/Eigen/src/Geometry/RotationBase.h index f0ee0bd0..f59d2ddc 100644 --- a/eigenlib/Eigen/src/Geometry/RotationBase.h +++ b/eigenlib/Eigen/src/Geometry/RotationBase.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_ROTATIONBASE_H #define EIGEN_ROTATIONBASE_H diff --git a/eigenlib/Eigen/src/Geometry/Scaling.h b/eigenlib/Eigen/src/Geometry/Scaling.h index 33eabd81..3372508d 100644 --- a/eigenlib/Eigen/src/Geometry/Scaling.h +++ b/eigenlib/Eigen/src/Geometry/Scaling.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SCALING_H #define EIGEN_SCALING_H diff --git a/eigenlib/Eigen/src/Geometry/Transform.h b/eigenlib/Eigen/src/Geometry/Transform.h index c21d9e55..45a71815 100644 --- a/eigenlib/Eigen/src/Geometry/Transform.h +++ b/eigenlib/Eigen/src/Geometry/Transform.h @@ -7,7 +7,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_TRANSFORM_H #define EIGEN_TRANSFORM_H diff --git a/eigenlib/Eigen/src/Geometry/Translation.h b/eigenlib/Eigen/src/Geometry/Translation.h index 0e99ce68..c6cbb1d4 100644 --- a/eigenlib/Eigen/src/Geometry/Translation.h +++ b/eigenlib/Eigen/src/Geometry/Translation.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_TRANSLATION_H #define EIGEN_TRANSLATION_H diff --git a/eigenlib/Eigen/src/Geometry/Umeyama.h b/eigenlib/Eigen/src/Geometry/Umeyama.h index 6b755008..566b824c 100644 --- a/eigenlib/Eigen/src/Geometry/Umeyama.h +++ b/eigenlib/Eigen/src/Geometry/Umeyama.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_UMEYAMA_H #define EIGEN_UMEYAMA_H diff --git a/eigenlib/Eigen/src/Geometry/arch/Geometry_SSE.h b/eigenlib/Eigen/src/Geometry/arch/Geometry_SSE.h index f68cab58..625ee0a0 100644 --- a/eigenlib/Eigen/src/Geometry/arch/Geometry_SSE.h +++ b/eigenlib/Eigen/src/Geometry/arch/Geometry_SSE.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_GEOMETRY_SSE_H #define EIGEN_GEOMETRY_SSE_H diff --git a/eigenlib/Eigen/src/Householder/BlockHouseholder.h b/eigenlib/Eigen/src/Householder/BlockHouseholder.h index 01a7ed18..17a661c5 100644 --- a/eigenlib/Eigen/src/Householder/BlockHouseholder.h +++ b/eigenlib/Eigen/src/Householder/BlockHouseholder.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_BLOCK_HOUSEHOLDER_H #define EIGEN_BLOCK_HOUSEHOLDER_H diff --git a/eigenlib/Eigen/src/Householder/Householder.h b/eigenlib/Eigen/src/Householder/Householder.h index 80de2c30..c6133f6b 100644 --- a/eigenlib/Eigen/src/Householder/Householder.h +++ b/eigenlib/Eigen/src/Householder/Householder.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_HOUSEHOLDER_H #define EIGEN_HOUSEHOLDER_H diff --git a/eigenlib/Eigen/src/Householder/HouseholderSequence.h b/eigenlib/Eigen/src/Householder/HouseholderSequence.h index 3ce0a693..bfd54244 100644 --- a/eigenlib/Eigen/src/Householder/HouseholderSequence.h +++ b/eigenlib/Eigen/src/Householder/HouseholderSequence.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_HOUSEHOLDER_SEQUENCE_H #define EIGEN_HOUSEHOLDER_SEQUENCE_H diff --git a/eigenlib/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h b/eigenlib/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h index f66c846e..835b5feb 100644 --- a/eigenlib/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h +++ b/eigenlib/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_BASIC_PRECONDITIONERS_H #define EIGEN_BASIC_PRECONDITIONERS_H diff --git a/eigenlib/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h b/eigenlib/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h index 454f4681..dc8485f7 100644 --- a/eigenlib/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h +++ b/eigenlib/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_BICGSTAB_H #define EIGEN_BICGSTAB_H diff --git a/eigenlib/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h b/eigenlib/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h index f7ce4713..6d55f5cf 100644 --- a/eigenlib/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h +++ b/eigenlib/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_CONJUGATE_GRADIENT_H #define EIGEN_CONJUGATE_GRADIENT_H diff --git a/eigenlib/Eigen/src/IterativeLinearSolvers/IncompleteCholesky.h b/eigenlib/Eigen/src/IterativeLinearSolvers/IncompleteCholesky.h index e45c272b..4caab13e 100644 --- a/eigenlib/Eigen/src/IterativeLinearSolvers/IncompleteCholesky.h +++ b/eigenlib/Eigen/src/IterativeLinearSolvers/IncompleteCholesky.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_INCOMPLETE_CHOlESKY_H #define EIGEN_INCOMPLETE_CHOlESKY_H diff --git a/eigenlib/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h b/eigenlib/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h index 338e6f10..a86f4d41 100644 --- a/eigenlib/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h +++ b/eigenlib/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_INCOMPLETE_LUT_H #define EIGEN_INCOMPLETE_LUT_H diff --git a/eigenlib/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h b/eigenlib/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h index 7c2326eb..07a0a51d 100644 --- a/eigenlib/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h +++ b/eigenlib/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_ITERATIVE_SOLVER_BASE_H #define EIGEN_ITERATIVE_SOLVER_BASE_H diff --git a/eigenlib/Eigen/src/IterativeLinearSolvers/LeastSquareConjugateGradient.h b/eigenlib/Eigen/src/IterativeLinearSolvers/LeastSquareConjugateGradient.h index 0aea0e09..6062e8dc 100644 --- a/eigenlib/Eigen/src/IterativeLinearSolvers/LeastSquareConjugateGradient.h +++ b/eigenlib/Eigen/src/IterativeLinearSolvers/LeastSquareConjugateGradient.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_LEAST_SQUARE_CONJUGATE_GRADIENT_H #define EIGEN_LEAST_SQUARE_CONJUGATE_GRADIENT_H diff --git a/eigenlib/Eigen/src/IterativeLinearSolvers/SolveWithGuess.h b/eigenlib/Eigen/src/IterativeLinearSolvers/SolveWithGuess.h index 0ace4517..6677f4fc 100644 --- a/eigenlib/Eigen/src/IterativeLinearSolvers/SolveWithGuess.h +++ b/eigenlib/Eigen/src/IterativeLinearSolvers/SolveWithGuess.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SOLVEWITHGUESS_H #define EIGEN_SOLVEWITHGUESS_H diff --git a/eigenlib/Eigen/src/Jacobi/Jacobi.h b/eigenlib/Eigen/src/Jacobi/Jacobi.h index 1998c632..2129b64b 100644 --- a/eigenlib/Eigen/src/Jacobi/Jacobi.h +++ b/eigenlib/Eigen/src/Jacobi/Jacobi.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_JACOBI_H #define EIGEN_JACOBI_H diff --git a/eigenlib/Eigen/src/LU/Determinant.h b/eigenlib/Eigen/src/LU/Determinant.h index d6a3c1e5..516583b6 100644 --- a/eigenlib/Eigen/src/LU/Determinant.h +++ b/eigenlib/Eigen/src/LU/Determinant.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_DETERMINANT_H #define EIGEN_DETERMINANT_H diff --git a/eigenlib/Eigen/src/LU/FullPivLU.h b/eigenlib/Eigen/src/LU/FullPivLU.h index 03b6af70..69e7c249 100644 --- a/eigenlib/Eigen/src/LU/FullPivLU.h +++ b/eigenlib/Eigen/src/LU/FullPivLU.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_LU_H #define EIGEN_LU_H diff --git a/eigenlib/Eigen/src/LU/InverseImpl.h b/eigenlib/Eigen/src/LU/InverseImpl.h index f49f2336..68166e85 100644 --- a/eigenlib/Eigen/src/LU/InverseImpl.h +++ b/eigenlib/Eigen/src/LU/InverseImpl.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_INVERSE_IMPL_H #define EIGEN_INVERSE_IMPL_H diff --git a/eigenlib/Eigen/src/LU/PartialPivLU.h b/eigenlib/Eigen/src/LU/PartialPivLU.h index 6b10f39f..935adbcc 100644 --- a/eigenlib/Eigen/src/LU/PartialPivLU.h +++ b/eigenlib/Eigen/src/LU/PartialPivLU.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_PARTIALLU_H #define EIGEN_PARTIALLU_H diff --git a/eigenlib/Eigen/src/LU/arch/Inverse_SSE.h b/eigenlib/Eigen/src/LU/arch/Inverse_SSE.h index 4dce2ef2..89227a2a 100644 --- a/eigenlib/Eigen/src/LU/arch/Inverse_SSE.h +++ b/eigenlib/Eigen/src/LU/arch/Inverse_SSE.h @@ -7,7 +7,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page // The SSE code for the 4x4 float and double matrix inverse in this file // comes from the following Intel's library: diff --git a/eigenlib/Eigen/src/MetisSupport/MetisSupport.h b/eigenlib/Eigen/src/MetisSupport/MetisSupport.h index 4c15304a..cbed964c 100644 --- a/eigenlib/Eigen/src/MetisSupport/MetisSupport.h +++ b/eigenlib/Eigen/src/MetisSupport/MetisSupport.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef METIS_SUPPORT_H #define METIS_SUPPORT_H diff --git a/eigenlib/Eigen/src/OrderingMethods/Eigen_Colamd.h b/eigenlib/Eigen/src/OrderingMethods/Eigen_Colamd.h index da85b4d6..19c87d02 100644 --- a/eigenlib/Eigen/src/OrderingMethods/Eigen_Colamd.h +++ b/eigenlib/Eigen/src/OrderingMethods/Eigen_Colamd.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page // This file is modified from the colamd/symamd library. The copyright is below diff --git a/eigenlib/Eigen/src/OrderingMethods/Ordering.h b/eigenlib/Eigen/src/OrderingMethods/Ordering.h index 7ea9b14d..d3c74f77 100644 --- a/eigenlib/Eigen/src/OrderingMethods/Ordering.h +++ b/eigenlib/Eigen/src/OrderingMethods/Ordering.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_ORDERING_H #define EIGEN_ORDERING_H diff --git a/eigenlib/Eigen/src/PaStiXSupport/PaStiXSupport.h b/eigenlib/Eigen/src/PaStiXSupport/PaStiXSupport.h index 160d8a52..91df321d 100644 --- a/eigenlib/Eigen/src/PaStiXSupport/PaStiXSupport.h +++ b/eigenlib/Eigen/src/PaStiXSupport/PaStiXSupport.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_PASTIXSUPPORT_H #define EIGEN_PASTIXSUPPORT_H diff --git a/eigenlib/Eigen/src/QR/ColPivHouseholderQR.h b/eigenlib/Eigen/src/QR/ColPivHouseholderQR.h index a7b47d55..1c0e4360 100644 --- a/eigenlib/Eigen/src/QR/ColPivHouseholderQR.h +++ b/eigenlib/Eigen/src/QR/ColPivHouseholderQR.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_COLPIVOTINGHOUSEHOLDERQR_H #define EIGEN_COLPIVOTINGHOUSEHOLDERQR_H diff --git a/eigenlib/Eigen/src/QR/CompleteOrthogonalDecomposition.h b/eigenlib/Eigen/src/QR/CompleteOrthogonalDecomposition.h index 34c637b7..13b260d7 100644 --- a/eigenlib/Eigen/src/QR/CompleteOrthogonalDecomposition.h +++ b/eigenlib/Eigen/src/QR/CompleteOrthogonalDecomposition.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_COMPLETEORTHOGONALDECOMPOSITION_H #define EIGEN_COMPLETEORTHOGONALDECOMPOSITION_H diff --git a/eigenlib/Eigen/src/QR/FullPivHouseholderQR.h b/eigenlib/Eigen/src/QR/FullPivHouseholderQR.h index e489bddc..a4437795 100644 --- a/eigenlib/Eigen/src/QR/FullPivHouseholderQR.h +++ b/eigenlib/Eigen/src/QR/FullPivHouseholderQR.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_FULLPIVOTINGHOUSEHOLDERQR_H #define EIGEN_FULLPIVOTINGHOUSEHOLDERQR_H diff --git a/eigenlib/Eigen/src/QR/HouseholderQR.h b/eigenlib/Eigen/src/QR/HouseholderQR.h index 3513d995..e4e94280 100644 --- a/eigenlib/Eigen/src/QR/HouseholderQR.h +++ b/eigenlib/Eigen/src/QR/HouseholderQR.h @@ -7,7 +7,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_QR_H #define EIGEN_QR_H diff --git a/eigenlib/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h b/eigenlib/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h index 953d57c9..2237e0b3 100644 --- a/eigenlib/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h +++ b/eigenlib/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SUITESPARSEQRSUPPORT_H #define EIGEN_SUITESPARSEQRSUPPORT_H diff --git a/eigenlib/Eigen/src/SVD/BDCSVD.h b/eigenlib/Eigen/src/SVD/BDCSVD.h index a5b73f8f..82fdccc5 100644 --- a/eigenlib/Eigen/src/SVD/BDCSVD.h +++ b/eigenlib/Eigen/src/SVD/BDCSVD.h @@ -15,7 +15,7 @@ // // Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_BDCSVD_H #define EIGEN_BDCSVD_H diff --git a/eigenlib/Eigen/src/SVD/JacobiSVD.h b/eigenlib/Eigen/src/SVD/JacobiSVD.h index 43488b1e..a36bd85e 100644 --- a/eigenlib/Eigen/src/SVD/JacobiSVD.h +++ b/eigenlib/Eigen/src/SVD/JacobiSVD.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_JACOBISVD_H #define EIGEN_JACOBISVD_H diff --git a/eigenlib/Eigen/src/SVD/SVDBase.h b/eigenlib/Eigen/src/SVD/SVDBase.h index 53da2848..9c6577c3 100644 --- a/eigenlib/Eigen/src/SVD/SVDBase.h +++ b/eigenlib/Eigen/src/SVD/SVDBase.h @@ -11,7 +11,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SVDBASE_H #define EIGEN_SVDBASE_H diff --git a/eigenlib/Eigen/src/SVD/UpperBidiagonalization.h b/eigenlib/Eigen/src/SVD/UpperBidiagonalization.h index 11ac847e..22c74c6d 100644 --- a/eigenlib/Eigen/src/SVD/UpperBidiagonalization.h +++ b/eigenlib/Eigen/src/SVD/UpperBidiagonalization.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_BIDIAGONALIZATION_H #define EIGEN_BIDIAGONALIZATION_H diff --git a/eigenlib/Eigen/src/SparseCholesky/SimplicialCholesky.h b/eigenlib/Eigen/src/SparseCholesky/SimplicialCholesky.h index 369e6804..60e7252e 100644 --- a/eigenlib/Eigen/src/SparseCholesky/SimplicialCholesky.h +++ b/eigenlib/Eigen/src/SparseCholesky/SimplicialCholesky.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SIMPLICIAL_CHOLESKY_H #define EIGEN_SIMPLICIAL_CHOLESKY_H diff --git a/eigenlib/Eigen/src/SparseCore/AmbiVector.h b/eigenlib/Eigen/src/SparseCore/AmbiVector.h index 2cb7747c..471c83be 100644 --- a/eigenlib/Eigen/src/SparseCore/AmbiVector.h +++ b/eigenlib/Eigen/src/SparseCore/AmbiVector.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_AMBIVECTOR_H #define EIGEN_AMBIVECTOR_H diff --git a/eigenlib/Eigen/src/SparseCore/CompressedStorage.h b/eigenlib/Eigen/src/SparseCore/CompressedStorage.h index d89fa0da..fbe1be96 100644 --- a/eigenlib/Eigen/src/SparseCore/CompressedStorage.h +++ b/eigenlib/Eigen/src/SparseCore/CompressedStorage.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_COMPRESSED_STORAGE_H #define EIGEN_COMPRESSED_STORAGE_H diff --git a/eigenlib/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h b/eigenlib/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h index 9db119b6..a0ee6db2 100644 --- a/eigenlib/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h +++ b/eigenlib/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_CONSERVATIVESPARSESPARSEPRODUCT_H #define EIGEN_CONSERVATIVESPARSESPARSEPRODUCT_H diff --git a/eigenlib/Eigen/src/SparseCore/MappedSparseMatrix.h b/eigenlib/Eigen/src/SparseCore/MappedSparseMatrix.h index 67718c85..70bd1f2f 100644 --- a/eigenlib/Eigen/src/SparseCore/MappedSparseMatrix.h +++ b/eigenlib/Eigen/src/SparseCore/MappedSparseMatrix.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_MAPPED_SPARSEMATRIX_H #define EIGEN_MAPPED_SPARSEMATRIX_H diff --git a/eigenlib/Eigen/src/SparseCore/SparseAssign.h b/eigenlib/Eigen/src/SparseCore/SparseAssign.h index 18352a84..93fdbedf 100644 --- a/eigenlib/Eigen/src/SparseCore/SparseAssign.h +++ b/eigenlib/Eigen/src/SparseCore/SparseAssign.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSEASSIGN_H #define EIGEN_SPARSEASSIGN_H diff --git a/eigenlib/Eigen/src/SparseCore/SparseBlock.h b/eigenlib/Eigen/src/SparseCore/SparseBlock.h index 511e92b2..ee948927 100644 --- a/eigenlib/Eigen/src/SparseCore/SparseBlock.h +++ b/eigenlib/Eigen/src/SparseCore/SparseBlock.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSE_BLOCK_H #define EIGEN_SPARSE_BLOCK_H diff --git a/eigenlib/Eigen/src/SparseCore/SparseColEtree.h b/eigenlib/Eigen/src/SparseCore/SparseColEtree.h index ebe02d1a..caa95511 100644 --- a/eigenlib/Eigen/src/SparseCore/SparseColEtree.h +++ b/eigenlib/Eigen/src/SparseCore/SparseColEtree.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page /* diff --git a/eigenlib/Eigen/src/SparseCore/SparseCompressedBase.h b/eigenlib/Eigen/src/SparseCore/SparseCompressedBase.h index 5ccb4665..bf34f95c 100644 --- a/eigenlib/Eigen/src/SparseCore/SparseCompressedBase.h +++ b/eigenlib/Eigen/src/SparseCore/SparseCompressedBase.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSE_COMPRESSED_BASE_H #define EIGEN_SPARSE_COMPRESSED_BASE_H diff --git a/eigenlib/Eigen/src/SparseCore/SparseCwiseBinaryOp.h b/eigenlib/Eigen/src/SparseCore/SparseCwiseBinaryOp.h index e315e355..10f24a3d 100644 --- a/eigenlib/Eigen/src/SparseCore/SparseCwiseBinaryOp.h +++ b/eigenlib/Eigen/src/SparseCore/SparseCwiseBinaryOp.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSE_CWISE_BINARY_OP_H #define EIGEN_SPARSE_CWISE_BINARY_OP_H diff --git a/eigenlib/Eigen/src/SparseCore/SparseCwiseUnaryOp.h b/eigenlib/Eigen/src/SparseCore/SparseCwiseUnaryOp.h index df6c28d2..6dd1d872 100644 --- a/eigenlib/Eigen/src/SparseCore/SparseCwiseUnaryOp.h +++ b/eigenlib/Eigen/src/SparseCore/SparseCwiseUnaryOp.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSE_CWISE_UNARY_OP_H #define EIGEN_SPARSE_CWISE_UNARY_OP_H diff --git a/eigenlib/Eigen/src/SparseCore/SparseDenseProduct.h b/eigenlib/Eigen/src/SparseCore/SparseDenseProduct.h index 0547db59..dc836bd6 100644 --- a/eigenlib/Eigen/src/SparseCore/SparseDenseProduct.h +++ b/eigenlib/Eigen/src/SparseCore/SparseDenseProduct.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSEDENSEPRODUCT_H #define EIGEN_SPARSEDENSEPRODUCT_H diff --git a/eigenlib/Eigen/src/SparseCore/SparseDiagonalProduct.h b/eigenlib/Eigen/src/SparseCore/SparseDiagonalProduct.h index 941c03be..192beba5 100644 --- a/eigenlib/Eigen/src/SparseCore/SparseDiagonalProduct.h +++ b/eigenlib/Eigen/src/SparseCore/SparseDiagonalProduct.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSE_DIAGONAL_PRODUCT_H #define EIGEN_SPARSE_DIAGONAL_PRODUCT_H diff --git a/eigenlib/Eigen/src/SparseCore/SparseDot.h b/eigenlib/Eigen/src/SparseCore/SparseDot.h index 38bc4aa9..72c05593 100644 --- a/eigenlib/Eigen/src/SparseCore/SparseDot.h +++ b/eigenlib/Eigen/src/SparseCore/SparseDot.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSE_DOT_H #define EIGEN_SPARSE_DOT_H diff --git a/eigenlib/Eigen/src/SparseCore/SparseFuzzy.h b/eigenlib/Eigen/src/SparseCore/SparseFuzzy.h index 7d47eb94..0d0c3eb7 100644 --- a/eigenlib/Eigen/src/SparseCore/SparseFuzzy.h +++ b/eigenlib/Eigen/src/SparseCore/SparseFuzzy.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSE_FUZZY_H #define EIGEN_SPARSE_FUZZY_H diff --git a/eigenlib/Eigen/src/SparseCore/SparseMap.h b/eigenlib/Eigen/src/SparseCore/SparseMap.h index f99be337..e199e262 100644 --- a/eigenlib/Eigen/src/SparseCore/SparseMap.h +++ b/eigenlib/Eigen/src/SparseCore/SparseMap.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSE_MAP_H #define EIGEN_SPARSE_MAP_H diff --git a/eigenlib/Eigen/src/SparseCore/SparseMatrix.h b/eigenlib/Eigen/src/SparseCore/SparseMatrix.h index a5396538..0f590cc1 100644 --- a/eigenlib/Eigen/src/SparseCore/SparseMatrix.h +++ b/eigenlib/Eigen/src/SparseCore/SparseMatrix.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSEMATRIX_H #define EIGEN_SPARSEMATRIX_H diff --git a/eigenlib/Eigen/src/SparseCore/SparseMatrixBase.h b/eigenlib/Eigen/src/SparseCore/SparseMatrixBase.h index c6b548f1..021cedc0 100644 --- a/eigenlib/Eigen/src/SparseCore/SparseMatrixBase.h +++ b/eigenlib/Eigen/src/SparseCore/SparseMatrixBase.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSEMATRIXBASE_H #define EIGEN_SPARSEMATRIXBASE_H diff --git a/eigenlib/Eigen/src/SparseCore/SparsePermutation.h b/eigenlib/Eigen/src/SparseCore/SparsePermutation.h index ef38357a..41df5bed 100644 --- a/eigenlib/Eigen/src/SparseCore/SparsePermutation.h +++ b/eigenlib/Eigen/src/SparseCore/SparsePermutation.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSE_PERMUTATION_H #define EIGEN_SPARSE_PERMUTATION_H diff --git a/eigenlib/Eigen/src/SparseCore/SparseProduct.h b/eigenlib/Eigen/src/SparseCore/SparseProduct.h index 4cbf6878..73e042c9 100644 --- a/eigenlib/Eigen/src/SparseCore/SparseProduct.h +++ b/eigenlib/Eigen/src/SparseCore/SparseProduct.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSEPRODUCT_H #define EIGEN_SPARSEPRODUCT_H diff --git a/eigenlib/Eigen/src/SparseCore/SparseRedux.h b/eigenlib/Eigen/src/SparseCore/SparseRedux.h index 45877496..6ea90b57 100644 --- a/eigenlib/Eigen/src/SparseCore/SparseRedux.h +++ b/eigenlib/Eigen/src/SparseCore/SparseRedux.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSEREDUX_H #define EIGEN_SPARSEREDUX_H diff --git a/eigenlib/Eigen/src/SparseCore/SparseRef.h b/eigenlib/Eigen/src/SparseCore/SparseRef.h index d91f38f9..58388bfc 100644 --- a/eigenlib/Eigen/src/SparseCore/SparseRef.h +++ b/eigenlib/Eigen/src/SparseCore/SparseRef.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSE_REF_H #define EIGEN_SPARSE_REF_H diff --git a/eigenlib/Eigen/src/SparseCore/SparseSelfAdjointView.h b/eigenlib/Eigen/src/SparseCore/SparseSelfAdjointView.h index 76117a01..70ed2f0b 100644 --- a/eigenlib/Eigen/src/SparseCore/SparseSelfAdjointView.h +++ b/eigenlib/Eigen/src/SparseCore/SparseSelfAdjointView.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSE_SELFADJOINTVIEW_H #define EIGEN_SPARSE_SELFADJOINTVIEW_H diff --git a/eigenlib/Eigen/src/SparseCore/SparseSolverBase.h b/eigenlib/Eigen/src/SparseCore/SparseSolverBase.h index b4c9a422..6ac6fcc6 100644 --- a/eigenlib/Eigen/src/SparseCore/SparseSolverBase.h +++ b/eigenlib/Eigen/src/SparseCore/SparseSolverBase.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSESOLVERBASE_H #define EIGEN_SPARSESOLVERBASE_H diff --git a/eigenlib/Eigen/src/SparseCore/SparseSparseProductWithPruning.h b/eigenlib/Eigen/src/SparseCore/SparseSparseProductWithPruning.h index 88820a48..c8c289b8 100644 --- a/eigenlib/Eigen/src/SparseCore/SparseSparseProductWithPruning.h +++ b/eigenlib/Eigen/src/SparseCore/SparseSparseProductWithPruning.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSESPARSEPRODUCTWITHPRUNING_H #define EIGEN_SPARSESPARSEPRODUCTWITHPRUNING_H diff --git a/eigenlib/Eigen/src/SparseCore/SparseTranspose.h b/eigenlib/Eigen/src/SparseCore/SparseTranspose.h index 3757d4c6..3a3169a6 100644 --- a/eigenlib/Eigen/src/SparseCore/SparseTranspose.h +++ b/eigenlib/Eigen/src/SparseCore/SparseTranspose.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSETRANSPOSE_H #define EIGEN_SPARSETRANSPOSE_H diff --git a/eigenlib/Eigen/src/SparseCore/SparseTriangularView.h b/eigenlib/Eigen/src/SparseCore/SparseTriangularView.h index 9ac12026..84145809 100644 --- a/eigenlib/Eigen/src/SparseCore/SparseTriangularView.h +++ b/eigenlib/Eigen/src/SparseCore/SparseTriangularView.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSE_TRIANGULARVIEW_H #define EIGEN_SPARSE_TRIANGULARVIEW_H diff --git a/eigenlib/Eigen/src/SparseCore/SparseUtil.h b/eigenlib/Eigen/src/SparseCore/SparseUtil.h index 74df0d49..6daddd8f 100644 --- a/eigenlib/Eigen/src/SparseCore/SparseUtil.h +++ b/eigenlib/Eigen/src/SparseCore/SparseUtil.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSEUTIL_H #define EIGEN_SPARSEUTIL_H diff --git a/eigenlib/Eigen/src/SparseCore/SparseVector.h b/eigenlib/Eigen/src/SparseCore/SparseVector.h index 19b0fbc9..f48aed45 100644 --- a/eigenlib/Eigen/src/SparseCore/SparseVector.h +++ b/eigenlib/Eigen/src/SparseCore/SparseVector.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSEVECTOR_H #define EIGEN_SPARSEVECTOR_H diff --git a/eigenlib/Eigen/src/SparseCore/SparseView.h b/eigenlib/Eigen/src/SparseCore/SparseView.h index 92b3d1f7..72cad92a 100644 --- a/eigenlib/Eigen/src/SparseCore/SparseView.h +++ b/eigenlib/Eigen/src/SparseCore/SparseView.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSEVIEW_H #define EIGEN_SPARSEVIEW_H diff --git a/eigenlib/Eigen/src/SparseCore/TriangularSolver.h b/eigenlib/Eigen/src/SparseCore/TriangularSolver.h index f9c56ba7..5e5c20c7 100644 --- a/eigenlib/Eigen/src/SparseCore/TriangularSolver.h +++ b/eigenlib/Eigen/src/SparseCore/TriangularSolver.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSETRIANGULARSOLVER_H #define EIGEN_SPARSETRIANGULARSOLVER_H diff --git a/eigenlib/Eigen/src/SparseLU/SparseLU.h b/eigenlib/Eigen/src/SparseLU/SparseLU.h index 87f0efe3..754974cf 100644 --- a/eigenlib/Eigen/src/SparseLU/SparseLU.h +++ b/eigenlib/Eigen/src/SparseLU/SparseLU.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSE_LU_H diff --git a/eigenlib/Eigen/src/SparseLU/SparseLUImpl.h b/eigenlib/Eigen/src/SparseLU/SparseLUImpl.h index fc0cfc4d..60360ee5 100644 --- a/eigenlib/Eigen/src/SparseLU/SparseLUImpl.h +++ b/eigenlib/Eigen/src/SparseLU/SparseLUImpl.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef SPARSELU_IMPL_H #define SPARSELU_IMPL_H diff --git a/eigenlib/Eigen/src/SparseLU/SparseLU_Memory.h b/eigenlib/Eigen/src/SparseLU/SparseLU_Memory.h index 4dc42e87..b96d76f4 100644 --- a/eigenlib/Eigen/src/SparseLU/SparseLU_Memory.h +++ b/eigenlib/Eigen/src/SparseLU/SparseLU_Memory.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page /* diff --git a/eigenlib/Eigen/src/SparseLU/SparseLU_Structs.h b/eigenlib/Eigen/src/SparseLU/SparseLU_Structs.h index cf5ec449..11701629 100644 --- a/eigenlib/Eigen/src/SparseLU/SparseLU_Structs.h +++ b/eigenlib/Eigen/src/SparseLU/SparseLU_Structs.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page /* * NOTE: This file comes from a partly modified version of files slu_[s,d,c,z]defs.h diff --git a/eigenlib/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h b/eigenlib/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h index 721e1883..c3340fb4 100644 --- a/eigenlib/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h +++ b/eigenlib/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSELU_SUPERNODAL_MATRIX_H #define EIGEN_SPARSELU_SUPERNODAL_MATRIX_H diff --git a/eigenlib/Eigen/src/SparseLU/SparseLU_Utils.h b/eigenlib/Eigen/src/SparseLU/SparseLU_Utils.h index 9e3dab44..f06c903c 100644 --- a/eigenlib/Eigen/src/SparseLU/SparseLU_Utils.h +++ b/eigenlib/Eigen/src/SparseLU/SparseLU_Utils.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSELU_UTILS_H diff --git a/eigenlib/Eigen/src/SparseLU/SparseLU_column_bmod.h b/eigenlib/Eigen/src/SparseLU/SparseLU_column_bmod.h index b57f0680..57f05ca5 100644 --- a/eigenlib/Eigen/src/SparseLU/SparseLU_column_bmod.h +++ b/eigenlib/Eigen/src/SparseLU/SparseLU_column_bmod.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page /* diff --git a/eigenlib/Eigen/src/SparseLU/SparseLU_column_dfs.h b/eigenlib/Eigen/src/SparseLU/SparseLU_column_dfs.h index c98b30e3..4f672baa 100644 --- a/eigenlib/Eigen/src/SparseLU/SparseLU_column_dfs.h +++ b/eigenlib/Eigen/src/SparseLU/SparseLU_column_dfs.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page /* diff --git a/eigenlib/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h b/eigenlib/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h index c32d8d8b..fa54bd4a 100644 --- a/eigenlib/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h +++ b/eigenlib/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page /* * NOTE: This file is the modified version of [s,d,c,z]copy_to_ucol.c file in SuperLU diff --git a/eigenlib/Eigen/src/SparseLU/SparseLU_gemm_kernel.h b/eigenlib/Eigen/src/SparseLU/SparseLU_gemm_kernel.h index 95ba7413..a521692f 100644 --- a/eigenlib/Eigen/src/SparseLU/SparseLU_gemm_kernel.h +++ b/eigenlib/Eigen/src/SparseLU/SparseLU_gemm_kernel.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSELU_GEMM_KERNEL_H #define EIGEN_SPARSELU_GEMM_KERNEL_H diff --git a/eigenlib/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h b/eigenlib/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h index 6f75d500..3c0fe279 100644 --- a/eigenlib/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h +++ b/eigenlib/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page /* This file is a modified version of heap_relax_snode.c file in SuperLU * -- SuperLU routine (version 3.0) -- diff --git a/eigenlib/Eigen/src/SparseLU/SparseLU_kernel_bmod.h b/eigenlib/Eigen/src/SparseLU/SparseLU_kernel_bmod.h index 8c1b3e8b..c7420989 100644 --- a/eigenlib/Eigen/src/SparseLU/SparseLU_kernel_bmod.h +++ b/eigenlib/Eigen/src/SparseLU/SparseLU_kernel_bmod.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef SPARSELU_KERNEL_BMOD_H #define SPARSELU_KERNEL_BMOD_H diff --git a/eigenlib/Eigen/src/SparseLU/SparseLU_panel_bmod.h b/eigenlib/Eigen/src/SparseLU/SparseLU_panel_bmod.h index 822cf32c..934b5bb0 100644 --- a/eigenlib/Eigen/src/SparseLU/SparseLU_panel_bmod.h +++ b/eigenlib/Eigen/src/SparseLU/SparseLU_panel_bmod.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page /* diff --git a/eigenlib/Eigen/src/SparseLU/SparseLU_panel_dfs.h b/eigenlib/Eigen/src/SparseLU/SparseLU_panel_dfs.h index 155df733..bcb2aea6 100644 --- a/eigenlib/Eigen/src/SparseLU/SparseLU_panel_dfs.h +++ b/eigenlib/Eigen/src/SparseLU/SparseLU_panel_dfs.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page /* diff --git a/eigenlib/Eigen/src/SparseLU/SparseLU_pivotL.h b/eigenlib/Eigen/src/SparseLU/SparseLU_pivotL.h index a86dac93..08d5dbe7 100644 --- a/eigenlib/Eigen/src/SparseLU/SparseLU_pivotL.h +++ b/eigenlib/Eigen/src/SparseLU/SparseLU_pivotL.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page /* diff --git a/eigenlib/Eigen/src/SparseLU/SparseLU_pruneL.h b/eigenlib/Eigen/src/SparseLU/SparseLU_pruneL.h index ad32fed5..6506e3e4 100644 --- a/eigenlib/Eigen/src/SparseLU/SparseLU_pruneL.h +++ b/eigenlib/Eigen/src/SparseLU/SparseLU_pruneL.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page /* diff --git a/eigenlib/Eigen/src/SparseLU/SparseLU_relax_snode.h b/eigenlib/Eigen/src/SparseLU/SparseLU_relax_snode.h index c408d01b..a5ca46bd 100644 --- a/eigenlib/Eigen/src/SparseLU/SparseLU_relax_snode.h +++ b/eigenlib/Eigen/src/SparseLU/SparseLU_relax_snode.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page /* This file is a modified version of heap_relax_snode.c file in SuperLU * -- SuperLU routine (version 3.0) -- diff --git a/eigenlib/Eigen/src/SparseQR/SparseQR.h b/eigenlib/Eigen/src/SparseQR/SparseQR.h index 7409fcae..fce3ee5c 100644 --- a/eigenlib/Eigen/src/SparseQR/SparseQR.h +++ b/eigenlib/Eigen/src/SparseQR/SparseQR.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SPARSE_QR_H #define EIGEN_SPARSE_QR_H diff --git a/eigenlib/Eigen/src/StlSupport/StdDeque.h b/eigenlib/Eigen/src/StlSupport/StdDeque.h index af158f42..563d0464 100644 --- a/eigenlib/Eigen/src/StlSupport/StdDeque.h +++ b/eigenlib/Eigen/src/StlSupport/StdDeque.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_STDDEQUE_H #define EIGEN_STDDEQUE_H diff --git a/eigenlib/Eigen/src/StlSupport/StdList.h b/eigenlib/Eigen/src/StlSupport/StdList.h index e1eba498..3fbc53f4 100644 --- a/eigenlib/Eigen/src/StlSupport/StdList.h +++ b/eigenlib/Eigen/src/StlSupport/StdList.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_STDLIST_H #define EIGEN_STDLIST_H diff --git a/eigenlib/Eigen/src/StlSupport/StdVector.h b/eigenlib/Eigen/src/StlSupport/StdVector.h index ec22821d..da36f8e0 100644 --- a/eigenlib/Eigen/src/StlSupport/StdVector.h +++ b/eigenlib/Eigen/src/StlSupport/StdVector.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_STDVECTOR_H #define EIGEN_STDVECTOR_H diff --git a/eigenlib/Eigen/src/StlSupport/details.h b/eigenlib/Eigen/src/StlSupport/details.h index 2cfd13e0..d60c28b8 100644 --- a/eigenlib/Eigen/src/StlSupport/details.h +++ b/eigenlib/Eigen/src/StlSupport/details.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_STL_DETAILS_H #define EIGEN_STL_DETAILS_H diff --git a/eigenlib/Eigen/src/SuperLUSupport/SuperLUSupport.h b/eigenlib/Eigen/src/SuperLUSupport/SuperLUSupport.h index 7261c7d0..38739c67 100644 --- a/eigenlib/Eigen/src/SuperLUSupport/SuperLUSupport.h +++ b/eigenlib/Eigen/src/SuperLUSupport/SuperLUSupport.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_SUPERLUSUPPORT_H #define EIGEN_SUPERLUSUPPORT_H diff --git a/eigenlib/Eigen/src/UmfPackSupport/UmfPackSupport.h b/eigenlib/Eigen/src/UmfPackSupport/UmfPackSupport.h index 91c09ab1..25ace727 100644 --- a/eigenlib/Eigen/src/UmfPackSupport/UmfPackSupport.h +++ b/eigenlib/Eigen/src/UmfPackSupport/UmfPackSupport.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_UMFPACKSUPPORT_H #define EIGEN_UMFPACKSUPPORT_H diff --git a/eigenlib/Eigen/src/misc/Image.h b/eigenlib/Eigen/src/misc/Image.h index b8b8a045..4d880a52 100644 --- a/eigenlib/Eigen/src/misc/Image.h +++ b/eigenlib/Eigen/src/misc/Image.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_MISC_IMAGE_H #define EIGEN_MISC_IMAGE_H diff --git a/eigenlib/Eigen/src/misc/Kernel.h b/eigenlib/Eigen/src/misc/Kernel.h index bef5d6ff..054afc67 100644 --- a/eigenlib/Eigen/src/misc/Kernel.h +++ b/eigenlib/Eigen/src/misc/Kernel.h @@ -5,7 +5,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_MISC_KERNEL_H #define EIGEN_MISC_KERNEL_H diff --git a/eigenlib/Eigen/src/misc/RealSvd2x2.h b/eigenlib/Eigen/src/misc/RealSvd2x2.h index abb4d3c2..843fe479 100644 --- a/eigenlib/Eigen/src/misc/RealSvd2x2.h +++ b/eigenlib/Eigen/src/misc/RealSvd2x2.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_REALSVD2X2_H #define EIGEN_REALSVD2X2_H diff --git a/eigenlib/Eigen/src/plugins/BlockMethods.h b/eigenlib/Eigen/src/plugins/BlockMethods.h index ac35a008..39055dc0 100644 --- a/eigenlib/Eigen/src/plugins/BlockMethods.h +++ b/eigenlib/Eigen/src/plugins/BlockMethods.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page #ifndef EIGEN_PARSED_BY_DOXYGEN diff --git a/eigenlib/Eigen/src/plugins/CommonCwiseBinaryOps.h b/eigenlib/Eigen/src/plugins/CommonCwiseBinaryOps.h index 8b6730ed..11084ec5 100644 --- a/eigenlib/Eigen/src/plugins/CommonCwiseBinaryOps.h +++ b/eigenlib/Eigen/src/plugins/CommonCwiseBinaryOps.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page // This file is a base class plugin containing common coefficient wise functions. diff --git a/eigenlib/Eigen/src/plugins/CommonCwiseUnaryOps.h b/eigenlib/Eigen/src/plugins/CommonCwiseUnaryOps.h index 89f4faaa..a71c4bcf 100644 --- a/eigenlib/Eigen/src/plugins/CommonCwiseUnaryOps.h +++ b/eigenlib/Eigen/src/plugins/CommonCwiseUnaryOps.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page // This file is a base class plugin containing common coefficient wise functions. diff --git a/eigenlib/Eigen/src/plugins/MatrixCwiseBinaryOps.h b/eigenlib/Eigen/src/plugins/MatrixCwiseBinaryOps.h index f1084abe..f937d43d 100644 --- a/eigenlib/Eigen/src/plugins/MatrixCwiseBinaryOps.h +++ b/eigenlib/Eigen/src/plugins/MatrixCwiseBinaryOps.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page // This file is a base class plugin containing matrix specifics coefficient wise functions. diff --git a/eigenlib/Eigen/src/plugins/MatrixCwiseUnaryOps.h b/eigenlib/Eigen/src/plugins/MatrixCwiseUnaryOps.h index b1be3d56..fa75838d 100644 --- a/eigenlib/Eigen/src/plugins/MatrixCwiseUnaryOps.h +++ b/eigenlib/Eigen/src/plugins/MatrixCwiseUnaryOps.h @@ -6,7 +6,7 @@ // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. +// with this file, You can obtain one at the mozilla.org home page // This file is included into the body of the base classes supporting matrix specific coefficient-wise functions. // This include MatrixBase and SparseMatrixBase. diff --git a/eigenlib/howto.txt b/eigenlib/howto.txt index 99b20682..d88199d5 100644 --- a/eigenlib/howto.txt +++ b/eigenlib/howto.txt @@ -9,6 +9,11 @@ To update the lib: - download Eigen - unzip it somewhere - delete (in the filesystem) the content of the folder eigenlib/Eigen - copy the folders 'Eigen' there +- execute the two following shell commands in the folder Eigen + + grep -RiIl 'http://mozilla.org/MPL/2.0/.' * | xargs sed -i 's/http:\/\/mozilla.org\/MPL\/2.0\/./the mozilla.org home page/g' + grep -RiIl 'http' * | xargs sed -i 's/http/xxxp/g' + - check the git status. - update this file - commit everything From ca59ed7c8d60584842ac75aa9f0356f5082f4eb1 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Tue, 19 Oct 2021 11:38:36 +0200 Subject: [PATCH 067/117] modify links into eigen --- eigenlib/Eigen/CholmodSupport | 2 +- eigenlib/Eigen/Core | 6 +++--- eigenlib/Eigen/MetisSupport | 2 +- eigenlib/Eigen/PaStiXSupport | 2 +- eigenlib/Eigen/SPQRSupport | 2 +- eigenlib/Eigen/SuperLUSupport | 2 +- eigenlib/Eigen/UmfPackSupport | 2 +- eigenlib/Eigen/src/Core/ConditionEstimator.h | 2 +- eigenlib/Eigen/src/Core/DenseStorage.h | 6 +++--- eigenlib/Eigen/src/Core/Dot.h | 2 +- eigenlib/Eigen/src/Core/MathFunctions.h | 2 +- eigenlib/Eigen/src/Core/MathFunctionsImpl.h | 2 +- eigenlib/Eigen/src/Core/NumTraits.h | 4 ++-- eigenlib/Eigen/src/Core/PlainObjectBase.h | 2 +- eigenlib/Eigen/src/Core/arch/AVX/MathFunctions.h | 4 ++-- eigenlib/Eigen/src/Core/arch/AltiVec/MathFunctions.h | 4 ++-- eigenlib/Eigen/src/Core/arch/AltiVec/PacketMath.h | 10 +++++----- eigenlib/Eigen/src/Core/arch/CUDA/Half.h | 6 +++--- eigenlib/Eigen/src/Core/arch/NEON/MathFunctions.h | 2 +- eigenlib/Eigen/src/Core/arch/NEON/PacketMath.h | 12 ++++++------ eigenlib/Eigen/src/Core/arch/SSE/MathFunctions.h | 6 +++--- eigenlib/Eigen/src/Core/arch/ZVector/MathFunctions.h | 2 +- eigenlib/Eigen/src/Core/arch/ZVector/PacketMath.h | 2 +- eigenlib/Eigen/src/Core/util/DisableStupidWarnings.h | 2 +- eigenlib/Eigen/src/Core/util/Macros.h | 2 +- eigenlib/Eigen/src/Core/util/Memory.h | 10 +++++----- eigenlib/Eigen/src/Eigenvalues/ComplexSchur.h | 2 +- eigenlib/Eigen/src/Eigenvalues/EigenSolver.h | 2 +- eigenlib/Eigen/src/Eigenvalues/RealSchur.h | 2 +- eigenlib/Eigen/src/Geometry/OrthoMethods.h | 2 +- eigenlib/Eigen/src/Geometry/Quaternion.h | 4 ++-- .../src/IterativeLinearSolvers/IncompleteCholesky.h | 2 +- .../Eigen/src/IterativeLinearSolvers/IncompleteLUT.h | 6 +++--- eigenlib/Eigen/src/LU/arch/Inverse_SSE.h | 2 +- eigenlib/Eigen/src/OrderingMethods/Amd.h | 2 +- eigenlib/Eigen/src/OrderingMethods/Eigen_Colamd.h | 2 +- eigenlib/Eigen/src/QR/ColPivHouseholderQR.h | 4 ++-- eigenlib/Eigen/src/SVD/BDCSVD.h | 2 +- eigenlib/Eigen/src/SparseCore/MappedSparseMatrix.h | 2 +- eigenlib/Eigen/src/SparseCore/SparseVector.h | 2 +- eigenlib/Eigen/src/SparseLU/SparseLU.h | 2 +- 41 files changed, 69 insertions(+), 69 deletions(-) diff --git a/eigenlib/Eigen/CholmodSupport b/eigenlib/Eigen/CholmodSupport index 96cb4e4f..88913ad8 100644 --- a/eigenlib/Eigen/CholmodSupport +++ b/eigenlib/Eigen/CholmodSupport @@ -19,7 +19,7 @@ extern "C" { /** \ingroup Support_modules * \defgroup CholmodSupport_Module CholmodSupport module * - * This module provides an interface to the Cholmod library which is part of the suitesparse package. + * This module provides an interface to the Cholmod library which is part of the suitesparse package. * It provides the two following main factorization classes: * - class CholmodSupernodalLLT: a supernodal LLT Cholesky factorization. * - class CholmodDecomposiiton: a general L(D)LT Cholesky factorization with automatic or explicit runtime selection of the underlying factorization method (supernodal or simplicial). diff --git a/eigenlib/Eigen/Core b/eigenlib/Eigen/Core index c2808c5f..3a202c7a 100644 --- a/eigenlib/Eigen/Core +++ b/eigenlib/Eigen/Core @@ -88,7 +88,7 @@ #include "src/Core/util/Macros.h" // Disable the ipa-cp-clone optimization flag with MinGW 6.x or newer (enabled by default with -O3) -// See http://eigen.tuxfamily.org/bz/show_bug.cgi?id=556 for details. +// See xxxp://eigen.tuxfamily.org/bz/show_bug.cgi?id=556 for details. #if EIGEN_COMP_MINGW && EIGEN_GNUC_AT_LEAST(4,6) #pragma GCC optimize ("-fno-ipa-cp-clone") #endif @@ -179,7 +179,7 @@ // include files // This extern "C" works around a MINGW-w64 compilation issue - // https://sourceforge.net/tracker/index.php?func=detail&aid=3018394&group_id=202880&atid=983354 + // xxxps://sourceforge.net/tracker/index.php?func=detail&aid=3018394&group_id=202880&atid=983354 // In essence, intrin.h is included by windows.h and also declares intrinsics (just as emmintrin.h etc. below do). // However, intrin.h uses an extern "C" declaration, and g++ thus complains of duplicate declarations // with conflicting linkage. The linkage for intrinsics doesn't matter, but at that stage the compiler doesn't know; @@ -340,7 +340,7 @@ inline static const char *SimdInstructionSetsInUse(void) { #if defined EIGEN2_SUPPORT_STAGE40_FULL_EIGEN3_STRICTNESS || defined EIGEN2_SUPPORT_STAGE30_FULL_EIGEN3_API || defined EIGEN2_SUPPORT_STAGE20_RESOLVE_API_CONFLICTS || defined EIGEN2_SUPPORT_STAGE10_FULL_EIGEN2_API || defined EIGEN2_SUPPORT // This will generate an error message: -#error Eigen2-support is only available up to version 3.2. Please go to "http://eigen.tuxfamily.org/index.php?title=Eigen2" for further information +#error Eigen2-support is only available up to version 3.2. Please go to "xxxp://eigen.tuxfamily.org/index.php?title=Eigen2" for further information #endif namespace Eigen { diff --git a/eigenlib/Eigen/MetisSupport b/eigenlib/Eigen/MetisSupport index 4e85d3d4..8ced5fff 100644 --- a/eigenlib/Eigen/MetisSupport +++ b/eigenlib/Eigen/MetisSupport @@ -23,7 +23,7 @@ extern "C" { * \code * #include * \endcode - * This module defines an interface to the METIS reordering package (http://glaros.dtc.umn.edu/gkhome/views/metis). + * This module defines an interface to the METIS reordering package (xxxp://glaros.dtc.umn.edu/gkhome/views/metis). * It can be used just as any other built-in method as explained in \link OrderingMethods_Module here. \endlink */ diff --git a/eigenlib/Eigen/PaStiXSupport b/eigenlib/Eigen/PaStiXSupport index 307f6ece..90429aa4 100644 --- a/eigenlib/Eigen/PaStiXSupport +++ b/eigenlib/Eigen/PaStiXSupport @@ -24,7 +24,7 @@ extern "C" { /** \ingroup Support_modules * \defgroup PaStiXSupport_Module PaStiXSupport module * - * This module provides an interface to the PaSTiX library. + * This module provides an interface to the PaSTiX library. * PaSTiX is a general \b supernodal, \b parallel and \b opensource sparse solver. * It provides the two following main factorization classes: * - class PastixLLT : a supernodal, parallel LLt Cholesky factorization. diff --git a/eigenlib/Eigen/SPQRSupport b/eigenlib/Eigen/SPQRSupport index db840f91..eb83920a 100644 --- a/eigenlib/Eigen/SPQRSupport +++ b/eigenlib/Eigen/SPQRSupport @@ -17,7 +17,7 @@ /** \ingroup Support_modules * \defgroup SPQRSupport_Module SuiteSparseQR module * - * This module provides an interface to the SPQR library, which is part of the suitesparse package. + * This module provides an interface to the SPQR library, which is part of the suitesparse package. * * \code * #include diff --git a/eigenlib/Eigen/SuperLUSupport b/eigenlib/Eigen/SuperLUSupport index 11b8bce5..296c953b 100644 --- a/eigenlib/Eigen/SuperLUSupport +++ b/eigenlib/Eigen/SuperLUSupport @@ -38,7 +38,7 @@ namespace Eigen { struct SluMatrix; } /** \ingroup Support_modules * \defgroup SuperLUSupport_Module SuperLUSupport module * - * This module provides an interface to the SuperLU library. + * This module provides an interface to the SuperLU library. * It provides the following factorization class: * - class SuperLU: a supernodal sequential LU factorization. * - class SuperILU: a supernodal sequential incomplete LU factorization (to be used as a preconditioner for iterative methods). diff --git a/eigenlib/Eigen/UmfPackSupport b/eigenlib/Eigen/UmfPackSupport index fcc89a24..5dcec6d7 100644 --- a/eigenlib/Eigen/UmfPackSupport +++ b/eigenlib/Eigen/UmfPackSupport @@ -19,7 +19,7 @@ extern "C" { /** \ingroup Support_modules * \defgroup UmfPackSupport_Module UmfPackSupport module * - * This module provides an interface to the UmfPack library which is part of the suitesparse package. + * This module provides an interface to the UmfPack library which is part of the suitesparse package. * It provides the following factorization class: * - class UmfPackLU: a multifrontal sequential LU factorization. * diff --git a/eigenlib/Eigen/src/Core/ConditionEstimator.h b/eigenlib/Eigen/src/Core/ConditionEstimator.h index 3424da52..e93a5568 100644 --- a/eigenlib/Eigen/src/Core/ConditionEstimator.h +++ b/eigenlib/Eigen/src/Core/ConditionEstimator.h @@ -37,7 +37,7 @@ struct rcond_compute_sign { * \a matrix that implements .solve() and .adjoint().solve() methods. * * This function implements Algorithms 4.1 and 5.1 from - * http://www.maths.manchester.ac.uk/~higham/narep/narep135.pdf + * xxxp://www.maths.manchester.ac.uk/~higham/narep/narep135.pdf * which also forms the basis for the condition number estimators in * LAPACK. Since at most 10 calls to the solve method of dec are * performed, the total cost is O(dims^2), as opposed to O(dims^3) diff --git a/eigenlib/Eigen/src/Core/DenseStorage.h b/eigenlib/Eigen/src/Core/DenseStorage.h index 45891dd3..191be539 100644 --- a/eigenlib/Eigen/src/Core/DenseStorage.h +++ b/eigenlib/Eigen/src/Core/DenseStorage.h @@ -62,20 +62,20 @@ struct plain_array #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) #elif EIGEN_GNUC_AT_LEAST(4,7) // GCC 4.7 is too aggressive in its optimizations and remove the alignement test based on the fact the array is declared to be aligned. - // See this bug report: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53900 + // See this bug report: xxxp://gcc.gnu.org/bugzilla/show_bug.cgi?id=53900 // Hiding the origin of the array pointer behind a function argument seems to do the trick even if the function is inlined: template EIGEN_ALWAYS_INLINE PtrType eigen_unaligned_array_assert_workaround_gcc47(PtrType array) { return array; } #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) \ eigen_assert((internal::UIntPtr(eigen_unaligned_array_assert_workaround_gcc47(array)) & (sizemask)) == 0 \ && "this assertion is explained here: " \ - "http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html" \ + "xxxp://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html" \ " **** READ THIS WEB PAGE !!! ****"); #else #define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) \ eigen_assert((internal::UIntPtr(array) & (sizemask)) == 0 \ && "this assertion is explained here: " \ - "http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html" \ + "xxxp://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html" \ " **** READ THIS WEB PAGE !!! ****"); #endif diff --git a/eigenlib/Eigen/src/Core/Dot.h b/eigenlib/Eigen/src/Core/Dot.h index c8daa897..d170aa09 100644 --- a/eigenlib/Eigen/src/Core/Dot.h +++ b/eigenlib/Eigen/src/Core/Dot.h @@ -253,7 +253,7 @@ struct lpNorm_selector * * In all cases, if \c *this is empty, then the value 0 is returned. * - * \note For matrices, this function does not compute the operator-norm. That is, if \c *this is a matrix, then its coefficients are interpreted as a 1D vector. Nonetheless, you can easily compute the 1-norm and \f$\infty\f$-norm matrix operator norms using \link TutorialReductionsVisitorsBroadcastingReductionsNorm partial reductions \endlink. + * \note For matrices, this function does not compute the operator-norm. That is, if \c *this is a matrix, then its coefficients are interpreted as a 1D vector. Nonetheless, you can easily compute the 1-norm and \f$\infty\f$-norm matrix operator norms using \link TutorialReductionsVisitorsBroadcastingReductionsNorm partial reductions \endlink. * * \sa norm() */ diff --git a/eigenlib/Eigen/src/Core/MathFunctions.h b/eigenlib/Eigen/src/Core/MathFunctions.h index a2dce17b..c262ede9 100644 --- a/eigenlib/Eigen/src/Core/MathFunctions.h +++ b/eigenlib/Eigen/src/Core/MathFunctions.h @@ -10,7 +10,7 @@ #ifndef EIGEN_MATHFUNCTIONS_H #define EIGEN_MATHFUNCTIONS_H -// source: http://www.geom.uiuc.edu/~huberty/math5337/groupe/digits.html +// source: xxxp://www.geom.uiuc.edu/~huberty/math5337/groupe/digits.html // TODO this should better be moved to NumTraits #define EIGEN_PI 3.141592653589793238462643383279502884197169399375105820974944592307816406L diff --git a/eigenlib/Eigen/src/Core/MathFunctionsImpl.h b/eigenlib/Eigen/src/Core/MathFunctionsImpl.h index f5d8d717..42da1d6d 100644 --- a/eigenlib/Eigen/src/Core/MathFunctionsImpl.h +++ b/eigenlib/Eigen/src/Core/MathFunctionsImpl.h @@ -33,7 +33,7 @@ T generic_fast_tanh_float(const T& a_x) // step such that if a_x is nan, x will be either 9 or -9, // and tanh will return 1 or -1 instead of nan. // This is supposed to be fixed in gcc6.3, - // see: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72867 + // see: xxxps://gcc.gnu.org/bugzilla/show_bug.cgi?id=72867 const T x = pmax(minus_9,pmin(plus_9,a_x)); // The monomial coefficients of the numerator polynomial (odd). const T alpha_1 = pset1(4.89352455891786e-03f); diff --git a/eigenlib/Eigen/src/Core/NumTraits.h b/eigenlib/Eigen/src/Core/NumTraits.h index 45bb8e41..c811ea6a 100644 --- a/eigenlib/Eigen/src/Core/NumTraits.h +++ b/eigenlib/Eigen/src/Core/NumTraits.h @@ -75,13 +75,13 @@ struct default_digits10_impl // Integer * \li An enum value \a IsSigned. It is equal to \c 1 if \a T is a signed type and to 0 if \a T is unsigned. * \li An enum value \a RequireInitialization. It is equal to \c 1 if the constructor of the numeric type \a T must * be called, and to 0 if it is safe not to call it. Default is 0 if \a T is an arithmetic type, and 1 otherwise. - * \li An epsilon() function which, unlike std::numeric_limits::epsilon(), + * \li An epsilon() function which, unlike std::numeric_limits::epsilon(), * it returns a \a Real instead of a \a T. * \li A dummy_precision() function returning a weak epsilon value. It is mainly used as a default * value by the fuzzy comparison operators. * \li highest() and lowest() functions returning the highest and lowest possible values respectively. * \li digits10() function returning the number of decimal digits that can be represented without change. This is - * the analogue of std::numeric_limits::digits10 + * the analogue of std::numeric_limits::digits10 * which is used as the default implementation if specialized. */ diff --git a/eigenlib/Eigen/src/Core/PlainObjectBase.h b/eigenlib/Eigen/src/Core/PlainObjectBase.h index c8dee155..4559e823 100644 --- a/eigenlib/Eigen/src/Core/PlainObjectBase.h +++ b/eigenlib/Eigen/src/Core/PlainObjectBase.h @@ -39,7 +39,7 @@ template<> struct check_rows_cols_for_overflow { EIGEN_DEVICE_FUNC static EIGEN_ALWAYS_INLINE void run(Index rows, Index cols) { - // http://hg.mozilla.org/mozilla-central/file/6c8a909977d3/xpcom/ds/CheckedInt.h#l242 + // xxxp://hg.mozilla.org/mozilla-central/file/6c8a909977d3/xpcom/ds/CheckedInt.h#l242 // we assume Index is signed Index max_index = (std::size_t(1) << (8 * sizeof(Index) - 1)) - 1; // assume Index is signed bool error = (rows == 0 || cols == 0) ? false diff --git a/eigenlib/Eigen/src/Core/arch/AVX/MathFunctions.h b/eigenlib/Eigen/src/Core/arch/AVX/MathFunctions.h index c5f966b2..aa90a6df 100644 --- a/eigenlib/Eigen/src/Core/arch/AVX/MathFunctions.h +++ b/eigenlib/Eigen/src/Core/arch/AVX/MathFunctions.h @@ -11,7 +11,7 @@ #define EIGEN_MATH_FUNCTIONS_AVX_H /* The sin, cos, exp, and log functions of this file are loosely derived from - * Julien Pommier's sse math library: http://gruntthepeon.free.fr/ssemath/ + * Julien Pommier's sse math library: xxxp://gruntthepeon.free.fr/ssemath/ */ namespace Eigen { @@ -359,7 +359,7 @@ pexp(const Packet4d& _x) { // The main advantage of this approach is not just speed, but also the fact that // it can be inlined and pipelined with other computations, further reducing its // effective latency. This is similar to Quake3's fast inverse square root. -// For detail see here: http://www.beyond3d.com/content/articles/8/ +// For detail see here: xxxp://www.beyond3d.com/content/articles/8/ #if EIGEN_FAST_MATH template <> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED Packet8f diff --git a/eigenlib/Eigen/src/Core/arch/AltiVec/MathFunctions.h b/eigenlib/Eigen/src/Core/arch/AltiVec/MathFunctions.h index 74e76687..e2c4ece2 100644 --- a/eigenlib/Eigen/src/Core/arch/AltiVec/MathFunctions.h +++ b/eigenlib/Eigen/src/Core/arch/AltiVec/MathFunctions.h @@ -10,7 +10,7 @@ // with this file, You can obtain one at the mozilla.org home page /* The sin, cos, exp, and log functions of this file come from - * Julien Pommier's sse math library: http://gruntthepeon.free.fr/ssemath/ + * Julien Pommier's sse math library: xxxp://gruntthepeon.free.fr/ssemath/ */ #ifndef EIGEN_MATH_FUNCTIONS_ALTIVEC_H @@ -230,7 +230,7 @@ Packet2d psqrt(const Packet2d& x) // vec_cts to efficiently convert Packet2d to Packet2l. Otherwise, use // a slow version that works with older compilers. // Update: apparently vec_cts/vec_ctf intrinsics for 64-bit doubles -// are buggy, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70963 +// are buggy, xxxps://gcc.gnu.org/bugzilla/show_bug.cgi?id=70963 static inline Packet2l ConvertToPacket2l(const Packet2d& x) { #if EIGEN_GNUC_AT_LEAST(5, 4) || \ (EIGEN_GNUC_AT(6, 1) && __GNUC_PATCHLEVEL__ >= 1) diff --git a/eigenlib/Eigen/src/Core/arch/AltiVec/PacketMath.h b/eigenlib/Eigen/src/Core/arch/AltiVec/PacketMath.h index e3d31bb5..ccf3bc15 100755 --- a/eigenlib/Eigen/src/Core/arch/AltiVec/PacketMath.h +++ b/eigenlib/Eigen/src/Core/arch/AltiVec/PacketMath.h @@ -443,7 +443,7 @@ template<> EIGEN_STRONG_INLINE Packet4f ploadu(const float* from) template<> EIGEN_STRONG_INLINE Packet4i ploadu(const int* from) { EIGEN_DEBUG_ALIGNED_LOAD - // Taken from http://developer.apple.com/hardwaredrivers/ve/alignment.html + // Taken from xxxp://developer.apple.com/hardwaredrivers/ve/alignment.html Packet16uc MSQ, LSQ; Packet16uc mask; MSQ = vec_ld(0, (unsigned char *)from); // most significant quadword @@ -484,7 +484,7 @@ template<> EIGEN_STRONG_INLINE Packet4i ploaddup(const int* from) template<> EIGEN_STRONG_INLINE void pstoreu(float* to, const Packet4f& from) { EIGEN_DEBUG_UNALIGNED_STORE - // Taken from http://developer.apple.com/hardwaredrivers/ve/alignment.html + // Taken from xxxp://developer.apple.com/hardwaredrivers/ve/alignment.html // Warning: not thread safe! Packet16uc MSQ, LSQ, edges; Packet16uc edgeAlign, align; @@ -502,7 +502,7 @@ template<> EIGEN_STRONG_INLINE void pstoreu(float* to, const Packet4f& f template<> EIGEN_STRONG_INLINE void pstoreu(int* to, const Packet4i& from) { EIGEN_DEBUG_UNALIGNED_STORE - // Taken from http://developer.apple.com/hardwaredrivers/ve/alignment.html + // Taken from xxxp://developer.apple.com/hardwaredrivers/ve/alignment.html // Warning: not thread safe! Packet16uc MSQ, LSQ, edges; Packet16uc edgeAlign, align; @@ -563,7 +563,7 @@ template<> EIGEN_STRONG_INLINE Packet4f preduxp(const Packet4f* vecs) Packet4f v[4], sum[4]; // It's easier and faster to transpose then add as columns - // Check: http://www.freevec.org/function/matrix_4x4_transpose_floats for explanation + // Check: xxxp://www.freevec.org/function/matrix_4x4_transpose_floats for explanation // Do the transpose, first set of moves v[0] = vec_mergeh(vecs[0], vecs[2]); v[1] = vec_mergel(vecs[0], vecs[2]); @@ -603,7 +603,7 @@ template<> EIGEN_STRONG_INLINE Packet4i preduxp(const Packet4i* vecs) Packet4i v[4], sum[4]; // It's easier and faster to transpose then add as columns - // Check: http://www.freevec.org/function/matrix_4x4_transpose_floats for explanation + // Check: xxxp://www.freevec.org/function/matrix_4x4_transpose_floats for explanation // Do the transpose, first set of moves v[0] = vec_mergeh(vecs[0], vecs[2]); v[1] = vec_mergel(vecs[0], vecs[2]); diff --git a/eigenlib/Eigen/src/Core/arch/CUDA/Half.h b/eigenlib/Eigen/src/Core/arch/CUDA/Half.h index 52573bce..436f15d3 100644 --- a/eigenlib/Eigen/src/Core/arch/CUDA/Half.h +++ b/eigenlib/Eigen/src/Core/arch/CUDA/Half.h @@ -165,8 +165,8 @@ struct numeric_limits { static const bool is_bounded = false; static const bool is_modulo = false; static const int digits = 11; - static const int digits10 = 3; // according to http://half.sourceforge.net/structstd_1_1numeric__limits_3_01half__float_1_1half_01_4.html - static const int max_digits10 = 5; // according to http://half.sourceforge.net/structstd_1_1numeric__limits_3_01half__float_1_1half_01_4.html + static const int digits10 = 3; // according to xxxp://half.sourceforge.net/structstd_1_1numeric__limits_3_01half__float_1_1half_01_4.html + static const int max_digits10 = 5; // according to xxxp://half.sourceforge.net/structstd_1_1numeric__limits_3_01half__float_1_1half_01_4.html static const int radix = 2; static const int min_exponent = -13; static const int min_exponent10 = -4; @@ -189,7 +189,7 @@ struct numeric_limits { // If std::numeric_limits is specialized, should also specialize // std::numeric_limits, std::numeric_limits, and // std::numeric_limits -// https://stackoverflow.com/a/16519653/ +// xxxps://stackoverflow.com/a/16519653/ template<> struct numeric_limits : numeric_limits {}; template<> diff --git a/eigenlib/Eigen/src/Core/arch/NEON/MathFunctions.h b/eigenlib/Eigen/src/Core/arch/NEON/MathFunctions.h index 3e3fd4ff..89f16fe8 100644 --- a/eigenlib/Eigen/src/Core/arch/NEON/MathFunctions.h +++ b/eigenlib/Eigen/src/Core/arch/NEON/MathFunctions.h @@ -6,7 +6,7 @@ // with this file, You can obtain one at the mozilla.org home page /* The sin, cos, exp, and log functions of this file come from - * Julien Pommier's sse math library: http://gruntthepeon.free.fr/ssemath/ + * Julien Pommier's sse math library: xxxp://gruntthepeon.free.fr/ssemath/ */ #ifndef EIGEN_MATH_FUNCTIONS_NEON_H diff --git a/eigenlib/Eigen/src/Core/arch/NEON/PacketMath.h b/eigenlib/Eigen/src/Core/arch/NEON/PacketMath.h index c7050a43..89ae2b83 100644 --- a/eigenlib/Eigen/src/Core/arch/NEON/PacketMath.h +++ b/eigenlib/Eigen/src/Core/arch/NEON/PacketMath.h @@ -207,7 +207,7 @@ template<> EIGEN_STRONG_INLINE Packet4i pdiv(const Packet4i& /*a*/, co // Clang/ARM wrongly advertises __ARM_FEATURE_FMA even when it's not available, // then implements a slow software scalar fallback calling fmaf()! // Filed LLVM bug: -// https://llvm.org/bugs/show_bug.cgi?id=27216 +// xxxps://llvm.org/bugs/show_bug.cgi?id=27216 #if (defined __ARM_FEATURE_FMA) && !(EIGEN_COMP_CLANG && EIGEN_ARCH_ARM) // See bug 936. // FMA is available on VFPv4 i.e. when compiling with -mfpu=neon-vfpv4. @@ -223,9 +223,9 @@ template<> EIGEN_STRONG_INLINE Packet4f pmadd(const Packet4f& a, const Packet4f& // at least -mcpu=cortex-a8 and -mcpu=cortex-a7. Since the former is the default on // -march=armv7-a, that is a very common case. // See e.g. this thread: - // http://lists.llvm.org/pipermail/llvm-dev/2013-December/068806.html + // xxxp://lists.llvm.org/pipermail/llvm-dev/2013-December/068806.html // Filed LLVM bug: - // https://llvm.org/bugs/show_bug.cgi?id=27219 + // xxxps://llvm.org/bugs/show_bug.cgi?id=27219 Packet4f r = c; asm volatile( "vmla.f32 %q[r], %q[a], %q[b]" @@ -508,7 +508,7 @@ template<> EIGEN_STRONG_INLINE int32_t predux_max(const Packet4i& a) } // this PALIGN_NEON business is to work around a bug in LLVM Clang 3.0 causing incorrect compilation errors, -// see bug 347 and this LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=11074 +// see bug 347 and this LLVM bug: xxxp://llvm.org/bugs/show_bug.cgi?id=11074 #define PALIGN_NEON(Offset,Type,Command) \ template<>\ struct palign_impl\ @@ -558,7 +558,7 @@ ptranspose(PacketBlock& kernel) { // Confirmed at least with __apple_build_version__ = 6000054. #ifdef __apple_build_version__ // Let's hope that by the time __apple_build_version__ hits the 601* range, the bug will be fixed. -// https://gist.github.com/yamaya/2924292 suggests that the 3 first digits are only updated with +// xxxps://gist.github.com/yamaya/2924292 suggests that the 3 first digits are only updated with // major toolchain updates. #define EIGEN_APPLE_DOUBLE_NEON_BUG (__apple_build_version__ < 6010000) #else @@ -727,7 +727,7 @@ template<> EIGEN_STRONG_INLINE double predux_min(const Packet2d& a) { template<> EIGEN_STRONG_INLINE double predux_max(const Packet2d& a) { return vgetq_lane_f64(vpmaxq_f64(a, a), 0); } // this PALIGN_NEON business is to work around a bug in LLVM Clang 3.0 causing incorrect compilation errors, -// see bug 347 and this LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=11074 +// see bug 347 and this LLVM bug: xxxp://llvm.org/bugs/show_bug.cgi?id=11074 #define PALIGN_NEON(Offset,Type,Command) \ template<>\ struct palign_impl\ diff --git a/eigenlib/Eigen/src/Core/arch/SSE/MathFunctions.h b/eigenlib/Eigen/src/Core/arch/SSE/MathFunctions.h index 24c842ee..53da97e2 100644 --- a/eigenlib/Eigen/src/Core/arch/SSE/MathFunctions.h +++ b/eigenlib/Eigen/src/Core/arch/SSE/MathFunctions.h @@ -9,7 +9,7 @@ // with this file, You can obtain one at the mozilla.org home page /* The sin, cos, exp, and log functions of this file come from - * Julien Pommier's sse math library: http://gruntthepeon.free.fr/ssemath/ + * Julien Pommier's sse math library: xxxp://gruntthepeon.free.fr/ssemath/ */ #ifndef EIGEN_MATH_FUNCTIONS_SSE_H @@ -451,7 +451,7 @@ Packet4f pcos(const Packet4f& _x) // The main advantage of this approach is not just speed, but also the fact that // it can be inlined and pipelined with other computations, further reducing its // effective latency. This is similar to Quake3's fast inverse square root. -// For detail see here: http://www.beyond3d.com/content/articles/8/ +// For detail see here: xxxp://www.beyond3d.com/content/articles/8/ template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED Packet4f psqrt(const Packet4f& _x) { @@ -548,7 +548,7 @@ double sqrt(const double &x) { #if EIGEN_COMP_GNUC_STRICT // This works around a GCC bug generating poor code for _mm_sqrt_pd - // See https://bitbucket.org/eigen/eigen/commits/14f468dba4d350d7c19c9b93072e19f7b3df563b + // See xxxps://bitbucket.org/eigen/eigen/commits/14f468dba4d350d7c19c9b93072e19f7b3df563b return internal::pfirst(internal::Packet2d(__builtin_ia32_sqrtsd(_mm_set_sd(x)))); #else return internal::pfirst(internal::Packet2d(_mm_sqrt_pd(_mm_set_sd(x)))); diff --git a/eigenlib/Eigen/src/Core/arch/ZVector/MathFunctions.h b/eigenlib/Eigen/src/Core/arch/ZVector/MathFunctions.h index ee5a3f43..25d52950 100644 --- a/eigenlib/Eigen/src/Core/arch/ZVector/MathFunctions.h +++ b/eigenlib/Eigen/src/Core/arch/ZVector/MathFunctions.h @@ -10,7 +10,7 @@ // with this file, You can obtain one at the mozilla.org home page /* The sin, cos, exp, and log functions of this file come from - * Julien Pommier's sse math library: http://gruntthepeon.free.fr/ssemath/ + * Julien Pommier's sse math library: xxxp://gruntthepeon.free.fr/ssemath/ */ #ifndef EIGEN_MATH_FUNCTIONS_ALTIVEC_H diff --git a/eigenlib/Eigen/src/Core/arch/ZVector/PacketMath.h b/eigenlib/Eigen/src/Core/arch/ZVector/PacketMath.h index 34775cd7..34878a8b 100755 --- a/eigenlib/Eigen/src/Core/arch/ZVector/PacketMath.h +++ b/eigenlib/Eigen/src/Core/arch/ZVector/PacketMath.h @@ -743,7 +743,7 @@ template<> EIGEN_STRONG_INLINE Packet4i preduxp(const Packet4i* vecs) Packet4i v[4], sum[4]; // It's easier and faster to transpose then add as columns - // Check: http://www.freevec.org/function/matrix_4x4_transpose_floats for explanation + // Check: xxxp://www.freevec.org/function/matrix_4x4_transpose_floats for explanation // Do the transpose, first set of moves v[0] = vec_mergeh(vecs[0], vecs[2]); v[1] = vec_mergel(vecs[0], vecs[2]); diff --git a/eigenlib/Eigen/src/Core/util/DisableStupidWarnings.h b/eigenlib/Eigen/src/Core/util/DisableStupidWarnings.h index 74f74cc4..3127053c 100755 --- a/eigenlib/Eigen/src/Core/util/DisableStupidWarnings.h +++ b/eigenlib/Eigen/src/Core/util/DisableStupidWarnings.h @@ -58,7 +58,7 @@ #pragma GCC diagnostic ignored "-Wignored-attributes" #endif #if __GNUC__==7 - // See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89325 + // See: xxxps://gcc.gnu.org/bugzilla/show_bug.cgi?id=89325 #pragma GCC diagnostic ignored "-Wattributes" #endif #endif diff --git a/eigenlib/Eigen/src/Core/util/Macros.h b/eigenlib/Eigen/src/Core/util/Macros.h index ba1e9540..1595da9f 100644 --- a/eigenlib/Eigen/src/Core/util/Macros.h +++ b/eigenlib/Eigen/src/Core/util/Macros.h @@ -833,7 +833,7 @@ namespace Eigen { // for older MSVC versions, as well as 1900 && CUDA 8, using the base operator is sufficient (cf Bugs 1000, 1324) #define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \ using Base::operator =; -#elif EIGEN_COMP_CLANG // workaround clang bug (see http://forum.kde.org/viewtopic.php?f=74&t=102653) +#elif EIGEN_COMP_CLANG // workaround clang bug (see xxxp://forum.kde.org/viewtopic.php?f=74&t=102653) #define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \ using Base::operator =; \ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator=(const Derived& other) { Base::operator=(other); return *this; } \ diff --git a/eigenlib/Eigen/src/Core/util/Memory.h b/eigenlib/Eigen/src/Core/util/Memory.h index 3cc0f9be..9368e97c 100644 --- a/eigenlib/Eigen/src/Core/util/Memory.h +++ b/eigenlib/Eigen/src/Core/util/Memory.h @@ -25,10 +25,10 @@ // Try to determine automatically if malloc is already aligned. // On 64-bit systems, glibc's malloc returns 16-byte-aligned pointers, see: -// http://www.gnu.org/s/libc/manual/html_node/Aligned-Memory-Blocks.html +// xxxp://www.gnu.org/s/libc/manual/html_node/Aligned-Memory-Blocks.html // This is true at least since glibc 2.8. // This leaves the question how to detect 64-bit. According to this document, -// http://gcc.fyxm.net/summit/2003/Porting%20to%2064%20bit.pdf +// xxxp://gcc.fyxm.net/summit/2003/Porting%20to%2064%20bit.pdf // page 114, "[The] LP64 model [...] is used by all 64-bit UNIX ports" so it's indeed // quite safe, at least within the context of glibc, to equate 64-bit with LP64. #if defined(__GLIBC__) && ((__GLIBC__>=2 && __GLIBC_MINOR__ >= 8) || __GLIBC__>2) \ @@ -39,9 +39,9 @@ #endif // FreeBSD 6 seems to have 16-byte aligned malloc -// See http://svn.freebsd.org/viewvc/base/stable/6/lib/libc/stdlib/malloc.c?view=markup +// See xxxp://svn.freebsd.org/viewvc/base/stable/6/lib/libc/stdlib/malloc.c?view=markup // FreeBSD 7 seems to have 16-byte aligned malloc except on ARM and MIPS architectures -// See http://svn.freebsd.org/viewvc/base/stable/7/lib/libc/stdlib/malloc.c?view=markup +// See xxxp://svn.freebsd.org/viewvc/base/stable/7/lib/libc/stdlib/malloc.c?view=markup #if defined(__FreeBSD__) && !(EIGEN_ARCH_ARM || EIGEN_ARCH_MIPS) && (EIGEN_DEFAULT_ALIGN_BYTES == 16) #define EIGEN_FREEBSD_MALLOC_ALREADY_ALIGNED 1 #else @@ -749,7 +749,7 @@ public: internal::check_size_for_overflow(num); size_type size = num * sizeof(T); #if EIGEN_COMP_GNUC_STRICT && EIGEN_GNUC_AT_LEAST(7,0) - // workaround gcc bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87544 + // workaround gcc bug xxxps://gcc.gnu.org/bugzilla/show_bug.cgi?id=87544 // It triggered eigen/Eigen/src/Core/util/Memory.h:189:12: warning: argument 1 value '18446744073709551612' exceeds maximum object size 9223372036854775807 if(size>=std::size_t((std::numeric_limits::max)())) return 0; diff --git a/eigenlib/Eigen/src/Eigenvalues/ComplexSchur.h b/eigenlib/Eigen/src/Eigenvalues/ComplexSchur.h index dba70e5c..baefac7e 100644 --- a/eigenlib/Eigen/src/Eigenvalues/ComplexSchur.h +++ b/eigenlib/Eigen/src/Eigenvalues/ComplexSchur.h @@ -283,7 +283,7 @@ typename ComplexSchur::ComplexScalar ComplexSchur::compu using std::abs; if (iter == 10 || iter == 20) { - // exceptional shift, taken from http://www.netlib.org/eispack/comqr.f + // exceptional shift, taken from xxxp://www.netlib.org/eispack/comqr.f return abs(numext::real(m_matT.coeff(iu,iu-1))) + abs(numext::real(m_matT.coeff(iu-1,iu-2))); } diff --git a/eigenlib/Eigen/src/Eigenvalues/EigenSolver.h b/eigenlib/Eigen/src/Eigenvalues/EigenSolver.h index aec9b7da..141b6ae9 100644 --- a/eigenlib/Eigen/src/Eigenvalues/EigenSolver.h +++ b/eigenlib/Eigen/src/Eigenvalues/EigenSolver.h @@ -56,7 +56,7 @@ namespace Eigen { * example of the typical use of this class. * * \note The implementation is adapted from - * JAMA (public domain). + * JAMA (public domain). * Their code is based on EISPACK. * * \sa MatrixBase::eigenvalues(), class ComplexEigenSolver, class SelfAdjointEigenSolver diff --git a/eigenlib/Eigen/src/Eigenvalues/RealSchur.h b/eigenlib/Eigen/src/Eigenvalues/RealSchur.h index ec1375f5..3d96b6bd 100644 --- a/eigenlib/Eigen/src/Eigenvalues/RealSchur.h +++ b/eigenlib/Eigen/src/Eigenvalues/RealSchur.h @@ -46,7 +46,7 @@ namespace Eigen { * of the typical use of this class. * * \note The implementation is adapted from - * JAMA (public domain). + * JAMA (public domain). * Their code is based on EISPACK. * * \sa class ComplexSchur, class EigenSolver, class ComplexEigenSolver diff --git a/eigenlib/Eigen/src/Geometry/OrthoMethods.h b/eigenlib/Eigen/src/Geometry/OrthoMethods.h index 42cc46ae..6ef33314 100644 --- a/eigenlib/Eigen/src/Geometry/OrthoMethods.h +++ b/eigenlib/Eigen/src/Geometry/OrthoMethods.h @@ -17,7 +17,7 @@ namespace Eigen { * * \returns the cross product of \c *this and \a other * - * Here is a very good explanation of cross-product: http://xkcd.com/199/ + * Here is a very good explanation of cross-product: xxxp://xkcd.com/199/ * * With complex numbers, the cross product is implemented as * \f$ (\mathbf{a}+i\mathbf{b}) \times (\mathbf{c}+i\mathbf{d}) = (\mathbf{a} \times \mathbf{c} - \mathbf{b} \times \mathbf{d}) - i(\mathbf{a} \times \mathbf{d} - \mathbf{b} \times \mathbf{c})\f$ diff --git a/eigenlib/Eigen/src/Geometry/Quaternion.h b/eigenlib/Eigen/src/Geometry/Quaternion.h index 025328c7..503ed322 100644 --- a/eigenlib/Eigen/src/Geometry/Quaternion.h +++ b/eigenlib/Eigen/src/Geometry/Quaternion.h @@ -635,7 +635,7 @@ EIGEN_DEVICE_FUNC inline Derived& QuaternionBase::setFromTwoVectors(con /** \returns a random unit quaternion following a uniform distribution law on SO(3) * - * \note The implementation is based on http://planning.cs.uiuc.edu/node198.html + * \note The implementation is based on xxxp://planning.cs.uiuc.edu/node198.html */ template EIGEN_DEVICE_FUNC Quaternion Quaternion::UnitRandom() @@ -736,7 +736,7 @@ QuaternionBase::angularDistance(const QuaternionBase& oth * \c *this and \a other at the parameter \a t in [0;1]. * * This represents an interpolation for a constant motion between \c *this and \a other, - * see also http://en.wikipedia.org/wiki/Slerp. + * see also xxxp://en.wikipedia.org/wiki/Slerp. */ template template diff --git a/eigenlib/Eigen/src/IterativeLinearSolvers/IncompleteCholesky.h b/eigenlib/Eigen/src/IterativeLinearSolvers/IncompleteCholesky.h index 4caab13e..57651e58 100644 --- a/eigenlib/Eigen/src/IterativeLinearSolvers/IncompleteCholesky.h +++ b/eigenlib/Eigen/src/IterativeLinearSolvers/IncompleteCholesky.h @@ -190,7 +190,7 @@ class IncompleteCholesky : public SparseSolverBase template void IncompleteCholesky::factorize(const _MatrixType& mat) diff --git a/eigenlib/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h b/eigenlib/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h index a86f4d41..56aa1db4 100644 --- a/eigenlib/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h +++ b/eigenlib/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h @@ -88,12 +88,12 @@ Index QuickSplit(VectorV &row, VectorI &ind, Index ncut) * NOTE : The following implementation is derived from the ILUT implementation * in the SPARSKIT package, Copyright (C) 2005, the Regents of the University of Minnesota * released under the terms of the GNU LGPL: - * http://www-users.cs.umn.edu/~saad/software/SPARSKIT/README + * xxxp://www-users.cs.umn.edu/~saad/software/SPARSKIT/README * However, Yousef Saad gave us permission to relicense his ILUT code to MPL2. * See the Eigen mailing list archive, thread: ILUT, date: July 8, 2012: - * http://listengine.tuxfamily.org/lists.tuxfamily.org/eigen/2012/07/msg00064.html + * xxxp://listengine.tuxfamily.org/lists.tuxfamily.org/eigen/2012/07/msg00064.html * alternatively, on GMANE: - * http://comments.gmane.org/gmane.comp.lib.eigen/3302 + * xxxp://comments.gmane.org/gmane.comp.lib.eigen/3302 */ template class IncompleteLUT : public SparseSolverBase > diff --git a/eigenlib/Eigen/src/LU/arch/Inverse_SSE.h b/eigenlib/Eigen/src/LU/arch/Inverse_SSE.h index 89227a2a..11f4018c 100644 --- a/eigenlib/Eigen/src/LU/arch/Inverse_SSE.h +++ b/eigenlib/Eigen/src/LU/arch/Inverse_SSE.h @@ -11,7 +11,7 @@ // The SSE code for the 4x4 float and double matrix inverse in this file // comes from the following Intel's library: -// http://software.intel.com/en-us/articles/optimized-matrix-library-for-use-with-the-intel-pentiumr-4-processors-sse2-instructions/ +// xxxp://software.intel.com/en-us/articles/optimized-matrix-library-for-use-with-the-intel-pentiumr-4-processors-sse2-instructions/ // // Here is the respective copyright and license statement: // diff --git a/eigenlib/Eigen/src/OrderingMethods/Amd.h b/eigenlib/Eigen/src/OrderingMethods/Amd.h index f91ecb24..208e8e5b 100644 --- a/eigenlib/Eigen/src/OrderingMethods/Amd.h +++ b/eigenlib/Eigen/src/OrderingMethods/Amd.h @@ -8,7 +8,7 @@ NOTE: this routine has been adapted from the CSparse library: Copyright (c) 2006, Timothy A. Davis. -http://www.suitesparse.com +xxxp://www.suitesparse.com CSparse is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public diff --git a/eigenlib/Eigen/src/OrderingMethods/Eigen_Colamd.h b/eigenlib/Eigen/src/OrderingMethods/Eigen_Colamd.h index 19c87d02..50cd9dcc 100644 --- a/eigenlib/Eigen/src/OrderingMethods/Eigen_Colamd.h +++ b/eigenlib/Eigen/src/OrderingMethods/Eigen_Colamd.h @@ -41,7 +41,7 @@ // // The colamd/symamd library is available at // -// http://www.suitesparse.com +// xxxp://www.suitesparse.com #ifndef EIGEN_COLAMD_H diff --git a/eigenlib/Eigen/src/QR/ColPivHouseholderQR.h b/eigenlib/Eigen/src/QR/ColPivHouseholderQR.h index 1c0e4360..b6b39f36 100644 --- a/eigenlib/Eigen/src/QR/ColPivHouseholderQR.h +++ b/eigenlib/Eigen/src/QR/ColPivHouseholderQR.h @@ -550,9 +550,9 @@ void ColPivHouseholderQR::computeInPlace() // update our table of norms of the columns for (Index j = k + 1; j < cols; ++j) { // The following implements the stable norm downgrade step discussed in - // http://www.netlib.org/lapack/lawnspdf/lawn176.pdf + // xxxp://www.netlib.org/lapack/lawnspdf/lawn176.pdf // and used in LAPACK routines xGEQPF and xGEQP3. - // See lines 278-297 in http://www.netlib.org/lapack/explore-html/dc/df4/sgeqpf_8f_source.html + // See lines 278-297 in xxxp://www.netlib.org/lapack/explore-html/dc/df4/sgeqpf_8f_source.html if (m_colNormsUpdated.coeffRef(j) != RealScalar(0)) { RealScalar temp = abs(m_qr.coeffRef(k, j)) / m_colNormsUpdated.coeffRef(j); temp = (RealScalar(1) + temp) * (RealScalar(1) - temp); diff --git a/eigenlib/Eigen/src/SVD/BDCSVD.h b/eigenlib/Eigen/src/SVD/BDCSVD.h index 82fdccc5..d451f61f 100644 --- a/eigenlib/Eigen/src/SVD/BDCSVD.h +++ b/eigenlib/Eigen/src/SVD/BDCSVD.h @@ -566,7 +566,7 @@ void BDCSVD::divide (Index firstCol, Index lastCol, Index firstRowW, // // TODO Opportunities for optimization: better root finding algo, better stopping criterion, better // handling of round-off errors, be consistent in ordering -// For instance, to solve the secular equation using FMM, see http://www.stat.uchicago.edu/~lekheng/courses/302/classics/greengard-rokhlin.pdf +// For instance, to solve the secular equation using FMM, see xxxp://www.stat.uchicago.edu/~lekheng/courses/302/classics/greengard-rokhlin.pdf template void BDCSVD::computeSVDofM(Index firstCol, Index n, MatrixXr& U, VectorType& singVals, MatrixXr& V) { diff --git a/eigenlib/Eigen/src/SparseCore/MappedSparseMatrix.h b/eigenlib/Eigen/src/SparseCore/MappedSparseMatrix.h index 70bd1f2f..c6a0f2af 100644 --- a/eigenlib/Eigen/src/SparseCore/MappedSparseMatrix.h +++ b/eigenlib/Eigen/src/SparseCore/MappedSparseMatrix.h @@ -19,7 +19,7 @@ namespace Eigen { * * \param _Scalar the scalar type, i.e. the type of the coefficients * - * See http://www.netlib.org/linalg/html_templates/node91.html for details on the storage scheme. + * See xxxp://www.netlib.org/linalg/html_templates/node91.html for details on the storage scheme. * */ namespace internal { diff --git a/eigenlib/Eigen/src/SparseCore/SparseVector.h b/eigenlib/Eigen/src/SparseCore/SparseVector.h index f48aed45..35c70092 100644 --- a/eigenlib/Eigen/src/SparseCore/SparseVector.h +++ b/eigenlib/Eigen/src/SparseCore/SparseVector.h @@ -19,7 +19,7 @@ namespace Eigen { * * \tparam _Scalar the scalar type, i.e. the type of the coefficients * - * See http://www.netlib.org/linalg/html_templates/node91.html for details on the storage scheme. + * See xxxp://www.netlib.org/linalg/html_templates/node91.html for details on the storage scheme. * * This class can be extended with the help of the plugin mechanism described on the page * \ref TopicCustomizing_Plugins by defining the preprocessor symbol \c EIGEN_SPARSEVECTOR_PLUGIN. diff --git a/eigenlib/Eigen/src/SparseLU/SparseLU.h b/eigenlib/Eigen/src/SparseLU/SparseLU.h index 754974cf..7b921fbd 100644 --- a/eigenlib/Eigen/src/SparseLU/SparseLU.h +++ b/eigenlib/Eigen/src/SparseLU/SparseLU.h @@ -25,7 +25,7 @@ template struct SparseLUMatrixURetu * * This class implements the supernodal LU factorization for general matrices. * It uses the main techniques from the sequential SuperLU package - * (http://crd-legacy.lbl.gov/~xiaoye/SuperLU/). It handles transparently real + * (xxxp://crd-legacy.lbl.gov/~xiaoye/SuperLU/). It handles transparently real * and complex arithmetics with single and double precision, depending on the * scalar type of your input matrix. * The code has been optimized to provide BLAS-3 operations during supernode-panel updates. From 70ac3d8248c8c51816fdd736566e2bb9af91407f Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Tue, 19 Oct 2021 11:57:02 +0200 Subject: [PATCH 068/117] remove memset from align_pair.h and marching_cubes.h --- vcg/complex/algorithms/align_pair.h | 27 +++++++++---------- .../algorithms/create/marching_cubes.h | 6 +++-- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/vcg/complex/algorithms/align_pair.h b/vcg/complex/algorithms/align_pair.h index 284e5ac0..6b71a235 100644 --- a/vcg/complex/algorithms/align_pair.h +++ b/vcg/complex/algorithms/align_pair.h @@ -128,22 +128,21 @@ public: public: IterInfo() { - memset ( (void *) this, 0, sizeof(IterInfo)); } - double MinDistAbs; - int DistanceDiscarded; - int AngleDiscarded; - int BorderDiscarded; - int SampleTested; // how many points have been tested - int SampleUsed; // how many points have been actually used to compute the transformation - double pcl50; - double pclhi; - double AVG; - double RMS; - double StdDev; - int Time; // Ending time of this iteration - + double MinDistAbs = 0; + int DistanceDiscarded = 0; + int AngleDiscarded = 0; + int BorderDiscarded = 0; + int SampleTested = 0; // how many points have been tested + // how many points have been actually used to compute the transformation + int SampleUsed = 0; + double pcl50 = 0; + double pclhi = 0; + double AVG = 0; + double RMS = 0; + double StdDev = 0; + int Time = 0; // Ending time of this iteration }; std::vector I; diff --git a/vcg/complex/algorithms/create/marching_cubes.h b/vcg/complex/algorithms/create/marching_cubes.h index 830e0e1d..43e31cba 100644 --- a/vcg/complex/algorithms/create/marching_cubes.h +++ b/vcg/complex/algorithms/create/marching_cubes.h @@ -26,6 +26,7 @@ #define __VCG_MARCHING_CUBES #include "mc_lookup_table.h" +#include namespace vcg { @@ -665,14 +666,15 @@ namespace vcg VertexPointer vp = NULL; size_t face_idx = _mesh->face.size(); size_t v12_idx = -1; - size_t vertices_idx[3]; + std::array vertices_idx; if (v12 != NULL) v12_idx = v12 - &_mesh->vert[0]; AllocatorType::AddFaces(*_mesh, (int) n); for (int trig=0; trig<3*n; face_idx++ ) { vp = NULL; - memset(vertices_idx, -1, 3*sizeof(size_t)); + vertices_idx.fill(-1); + //memset(vertices_idx, -1, 3*sizeof(size_t)); for (int vert=0; vert<3; vert++, trig++) //ok { From 5e17997b37dc8075f9c6ef68efcc6ba5d4032b57 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Tue, 19 Oct 2021 12:14:31 +0200 Subject: [PATCH 069/117] remove memset from meshtree.h --- vcg/complex/algorithms/meshtree.h | 338 +++++++++++++++++------------- 1 file changed, 190 insertions(+), 148 deletions(-) diff --git a/vcg/complex/algorithms/meshtree.h b/vcg/complex/algorithms/meshtree.h index 13d0d3a9..de9f12a8 100644 --- a/vcg/complex/algorithms/meshtree.h +++ b/vcg/complex/algorithms/meshtree.h @@ -125,189 +125,231 @@ namespace vcg { return count; } - void Process(vcg::AlignPair::Param &ap, MeshTree::Param &mtp) { + void Process(vcg::AlignPair::Param& ap, MeshTree::Param& mtp) + { + std::array buf; + std::sprintf( + buf.data(), + "Starting Processing of %i glued meshes out of %zu meshes\n", + gluedNum(), + nodeMap.size()); + cb(0, buf.data()); - char buf[1024]; - std::sprintf(buf, "Starting Processing of %i glued meshes out of %zu meshes\n", gluedNum(), nodeMap.size()); - cb(0, buf); + /******* Occupancy Grid Computation *************/ + buf.fill('\0'); + std::sprintf(buf.data(), "Computing Overlaps %i glued meshes...\n", gluedNum()); + cb(0, buf.data()); - /******* Occupancy Grid Computation *************/ - std::memset(buf, '\0', 1024); - std::sprintf(buf, "Computing Overlaps %i glued meshes...\n", gluedNum()); - cb(0, buf); + OG.Init( + static_cast(nodeMap.size()), + vcg::Box3::Construct(gluedBBox()), + mtp.OGSize); - OG.Init(static_cast(nodeMap.size()), vcg::Box3::Construct(gluedBBox()), mtp.OGSize); + for (auto& ni : nodeMap) { + MeshTree::MeshNode* mn = ni.second; + if (mn->glued) { + OG.AddMesh(mn->m->cm, vcg::Matrix44::Construct(mn->tr()), mn->Id()); + } + } - for (auto& ni : nodeMap) { - MeshTree::MeshNode *mn = ni.second; - if (mn->glued) { - OG.AddMesh(mn->m->cm, vcg::Matrix44::Construct(mn->tr()), mn->Id()); - } - } + OG.Compute(); + OG.Dump(stdout); + // Note: the s and t of the OG translate into fix and mov, respectively. - OG.Compute(); - OG.Dump(stdout); - // Note: the s and t of the OG translate into fix and mov, respectively. + /*************** The long loop of arc computing **************/ - /*************** The long loop of arc computing **************/ + // count existing arcs within current error threshold + float percentileThr = 0; + if (!resultList.empty()) { + vcg::Distribution H; + for (auto& li : resultList) { + H.Add(li.err); + } - // count existing arcs within current error threshold - float percentileThr = 0; - if (!resultList.empty()) { + percentileThr = H.Percentile(1.0f - mtp.recalcThreshold); + } - vcg::Distribution H; - for (auto& li : resultList) { - H.Add(li.err); - } + std::size_t totalArcNum = 0; + int preservedArcNum = 0, recalcArcNum = 0; - percentileThr = H.Percentile(1.0f - mtp.recalcThreshold); - } + while (totalArcNum < OG.SVA.size() && + OG.SVA[totalArcNum].norm_area > mtp.arcThreshold) { + AlignPair::Result* curResult = + findResult(OG.SVA[totalArcNum].s, OG.SVA[totalArcNum].t); + if (curResult) { + if (curResult->err < percentileThr) { + ++preservedArcNum; + } + else { + ++recalcArcNum; + } + } + else { + resultList.push_back(AlignPair::Result()); + resultList.back().FixName = OG.SVA[totalArcNum].s; + resultList.back().MovName = OG.SVA[totalArcNum].t; + resultList.back().err = std::numeric_limits::max(); + } + ++totalArcNum; + } - std::size_t totalArcNum = 0; - int preservedArcNum = 0, recalcArcNum = 0; + // if there are no arcs at all complain and return + if (totalArcNum == 0) { + buf.fill('\0'); + std::sprintf( + buf.data(), + "\n Failure. There are no overlapping meshes?\n No candidate alignment arcs. " + "Nothing Done.\n"); + cb(0, buf.data()); + return; + } - while(totalArcNum < OG.SVA.size() && OG.SVA[totalArcNum].norm_area > mtp.arcThreshold) - { - AlignPair::Result *curResult = findResult(OG.SVA[totalArcNum].s, OG.SVA[totalArcNum].t); - if (curResult) { - if (curResult->err < percentileThr) { - ++preservedArcNum; - } - else { - ++recalcArcNum; - } - } - else { - resultList.push_back(AlignPair::Result()); - resultList.back().FixName = OG.SVA[totalArcNum].s; - resultList.back().MovName = OG.SVA[totalArcNum].t; - resultList.back().err = std::numeric_limits::max(); - } - ++totalArcNum; - } - - //if there are no arcs at all complain and return - if (totalArcNum == 0) { - std::memset(buf, '\0', 1024); - std::sprintf(buf, "\n Failure. There are no overlapping meshes?\n No candidate alignment arcs. Nothing Done.\n"); - cb(0, buf); - return; - } - - int num_max_thread = 1; + int num_max_thread = 1; #ifdef _OPENMP - if (totalArcNum > 32) num_max_thread = omp_get_max_threads(); + if (totalArcNum > 32) + num_max_thread = omp_get_max_threads(); #endif - std::memset(buf, '\0', 1024); - std::sprintf(buf, "Arc with good overlap %6zu (on %6zu)\n", totalArcNum, OG.SVA.size()); - cb(0, buf); + buf.fill('\0'); + std::sprintf( + buf.data(), "Arc with good overlap %6zu (on %6zu)\n", totalArcNum, OG.SVA.size()); + cb(0, buf.data()); - std::memset(buf, '\0', 1024); - std::sprintf(buf, " %6i preserved %i Recalc \n", preservedArcNum, recalcArcNum); - cb(0, buf); + buf.fill('\0'); + std::sprintf(buf.data(), " %6i preserved %i Recalc \n", preservedArcNum, recalcArcNum); + cb(0, buf.data()); - bool hasValidAlign = false; + bool hasValidAlign = false; #pragma omp parallel for schedule(dynamic, 1) num_threads(num_max_thread) - // on windows, omp does not support unsigned types for indices on cycles - for (int i = 0 ;i < static_cast(totalArcNum); ++i) { + // on windows, omp does not support unsigned types for indices on cycles + for (int i = 0; i < static_cast(totalArcNum); ++i) { + std::fprintf( + stdout, + "%4i -> %4i Area:%5i NormArea:%5.3f\n", + OG.SVA[i].s, + OG.SVA[i].t, + OG.SVA[i].area, + OG.SVA[i].norm_area); + AlignPair::Result* curResult = findResult(OG.SVA[i].s, OG.SVA[i].t); - std::fprintf(stdout,"%4i -> %4i Area:%5i NormArea:%5.3f\n",OG.SVA[i].s,OG.SVA[i].t,OG.SVA[i].area,OG.SVA[i].norm_area); - AlignPair::Result *curResult = findResult(OG.SVA[i].s,OG.SVA[i].t); + // // missing arc and arc with great error must be recomputed. + if (curResult->err >= percentileThr) { + ProcessArc(OG.SVA[i].s, OG.SVA[i].t, *curResult, ap); + curResult->area = OG.SVA[i].norm_area; - // // missing arc and arc with great error must be recomputed. - if (curResult->err >= percentileThr) { - - ProcessArc(OG.SVA[i].s, OG.SVA[i].t, *curResult, ap); - curResult->area = OG.SVA[i].norm_area; - - if (curResult->isValid()) { - hasValidAlign = true; - std::pair dd = curResult->computeAvgErr(); + if (curResult->isValid()) { + hasValidAlign = true; + std::pair dd = curResult->computeAvgErr(); #pragma omp critical - std::memset(buf, '\0', 1024); - std::sprintf(buf, "(%3i/%3zu) %2i -> %2i Aligned AvgErr dd=%f -> dd=%f \n", i+1,totalArcNum,OG.SVA[i].s,OG.SVA[i].t,dd.first,dd.second); - cb(0, buf); - } - else { + buf.fill('\0'); + std::sprintf( + buf.data(), + "(%3i/%3zu) %2i -> %2i Aligned AvgErr dd=%f -> dd=%f \n", + i + 1, + totalArcNum, + OG.SVA[i].s, + OG.SVA[i].t, + dd.first, + dd.second); + cb(0, buf.data()); + } + else { #pragma omp critical - std::memset(buf, '\0', 1024); - std::sprintf(buf, "(%3i/%3zu) %2i -> %2i Failed Alignment of one arc %s\n",i+1,totalArcNum,OG.SVA[i].s,OG.SVA[i].t,vcg::AlignPair::errorMsg(curResult->status)); - cb(0, buf); - } - } - } + buf.fill('\0'); + std::sprintf( + buf.data(), + "(%3i/%3zu) %2i -> %2i Failed Alignment of one arc %s\n", + i + 1, + totalArcNum, + OG.SVA[i].s, + OG.SVA[i].t, + vcg::AlignPair::errorMsg(curResult->status)); + cb(0, buf.data()); + } + } + } - //if there are no valid arcs complain and return - if (!hasValidAlign) { - std::memset(buf, '\0', 1024); - std::sprintf(buf, "\n Failure. No successful arc among candidate Alignment arcs. Nothing Done.\n"); - cb(0, buf); - return; - } + // if there are no valid arcs complain and return + if (!hasValidAlign) { + buf.fill('\0'); + std::sprintf( + buf.data(), + "\n Failure. No successful arc among candidate Alignment arcs. Nothing " + "Done.\n"); + cb(0, buf.data()); + return; + } - vcg::Distribution H; // stat for printing - for (auto& li : resultList) { - if (li.isValid()) H.Add(li.err); - } + vcg::Distribution H; // stat for printing + for (auto& li : resultList) { + if (li.isValid()) + H.Add(li.err); + } - std::memset(buf, '\0', 1024); - std::sprintf(buf, "Completed Mesh-Mesh Alignment: Avg Err %5.3f; Median %5.3f; 90%% %5.3f\n", H.Avg(), H.Percentile(0.5f), H.Percentile(0.9f)); - cb(0, buf); + buf.fill('\0'); + std::sprintf( + buf.data(), + "Completed Mesh-Mesh Alignment: Avg Err %5.3f; Median %5.3f; 90%% %5.3f\n", + H.Avg(), + H.Percentile(0.5f), + H.Percentile(0.9f)); + cb(0, buf.data()); - ProcessGlobal(ap); - } + ProcessGlobal(ap); + } - void ProcessGlobal(vcg::AlignPair::Param &ap) { + void ProcessGlobal(vcg::AlignPair::Param& ap) + { + /************** Preparing Matrices for global alignment *************/ + std::vector GluedIdVec; + std::vector GluedTrVec; - char buff[1024]; - std::memset(buff, '\0', 1024); + std::map names; - /************** Preparing Matrices for global alignment *************/ - std::vector GluedIdVec; - std::vector GluedTrVec; + for (auto& ni : nodeMap) { + MeshTree::MeshNode* mn = ni.second; + if (mn->glued) { + GluedIdVec.push_back(mn->Id()); + GluedTrVec.push_back(vcg::Matrix44d::Construct(mn->tr())); + names[mn->Id()] = qUtf8Printable(mn->m->label()); + } + } - std::map names; + vcg::AlignGlobal AG; + std::vector ResVecPtr; + for (auto& li : resultList) { + if (li.isValid()) { + ResVecPtr.push_back(&li); + } + } - for (auto& ni : nodeMap) { + AG.BuildGraph(ResVecPtr, GluedTrVec, GluedIdVec); - MeshTree::MeshNode *mn = ni.second; - if (mn->glued) { - GluedIdVec.push_back(mn->Id()); - GluedTrVec.push_back(vcg::Matrix44d::Construct(mn->tr())); - names[mn->Id()] = qUtf8Printable(mn->m->label()); - } - } + float StartGlobErr = 0.001f; + while (!AG.GlobalAlign( + names, + StartGlobErr, + 100, + ap.MatchMode == vcg::AlignPair::Param::MMRigid, + stdout, + cb)) { + StartGlobErr *= 2; + AG.BuildGraph(ResVecPtr, GluedTrVec, GluedIdVec); + } - vcg::AlignGlobal AG; - std::vector ResVecPtr; - for (auto& li : resultList) { - if (li.isValid()) { - ResVecPtr.push_back(&li); - } - } + std::vector GluedTrVecOut(GluedTrVec.size()); + AG.GetMatrixVector(GluedTrVecOut, GluedIdVec); - AG.BuildGraph(ResVecPtr, GluedTrVec, GluedIdVec); - - float StartGlobErr = 0.001f; - while (!AG.GlobalAlign(names, StartGlobErr, 100, ap.MatchMode == vcg::AlignPair::Param::MMRigid, stdout, cb)) { - StartGlobErr *= 2; - AG.BuildGraph(ResVecPtr,GluedTrVec, GluedIdVec); - } - - std::vector GluedTrVecOut(GluedTrVec.size()); - AG.GetMatrixVector(GluedTrVecOut,GluedIdVec); - - // Now get back the results! - for (std::size_t ii = 0; ii < GluedTrVecOut.size(); ++ii) { - MM(GluedIdVec[ii])->cm.Tr.Import(GluedTrVecOut[ii]); - } - - std::sprintf(buff, "Completed Global Alignment (error bound %6.4f)\n", StartGlobErr); - cb(0, buff); - } + // Now get back the results! + for (std::size_t ii = 0; ii < GluedTrVecOut.size(); ++ii) { + MM(GluedIdVec[ii])->cm.Tr.Import(GluedTrVecOut[ii]); + } + std::string str = + "Completed Global Alignment (error bound " + std::to_string(StartGlobErr) + ")\n"; + cb(0, str.c_str()); + } void ProcessArc(int fixId, int movId, vcg::AlignPair::Result &result, vcg::AlignPair::Param ap) { From da77800d0214c9c78ef9f71abe7ce43b42cd9dc3 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Tue, 19 Oct 2021 12:45:05 +0200 Subject: [PATCH 070/117] remove memset from simple_temporary_data and matrix44, remove old_matrix --- CMakeLists.txt | 5 - .../algorithms/create/marching_cubes.h | 1 - vcg/container/simple_temporary_data.h | 23 +- vcg/math/matrix44.h | 16 +- vcg/math/old_deprecated_matrix.h | 786 ------------------ vcg/math/old_lin_algebra.h | 634 -------------- vcg/math/old_matrix.h | 184 ---- vcg/math/old_matrix33.h | 298 ------- vcg/math/old_matrix44.h | 493 ----------- 9 files changed, 21 insertions(+), 2419 deletions(-) delete mode 100644 vcg/math/old_deprecated_matrix.h delete mode 100644 vcg/math/old_lin_algebra.h delete mode 100644 vcg/math/old_matrix.h delete mode 100644 vcg/math/old_matrix33.h delete mode 100644 vcg/math/old_matrix44.h diff --git a/CMakeLists.txt b/CMakeLists.txt index a4f6c76d..e48b6816 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -232,18 +232,13 @@ set(VCG_HEADERS vcg/math/linear.h vcg/math/matrix44.h vcg/math/eigen.h - vcg/math/old_lin_algebra.h vcg/math/similarity2.h vcg/math/gen_normal.h - vcg/math/old_matrix44.h - vcg/math/old_deprecated_matrix.h - vcg/math/old_matrix33.h vcg/math/polar_decomposition.h vcg/math/base.h vcg/math/histogram.h vcg/math/legendre.h vcg/math/matrix33.h - vcg/math/old_matrix.h vcg/simplex/edge/distance.h vcg/simplex/edge/topology.h vcg/simplex/edge/pos.h diff --git a/vcg/complex/algorithms/create/marching_cubes.h b/vcg/complex/algorithms/create/marching_cubes.h index 43e31cba..cbc8f5dd 100644 --- a/vcg/complex/algorithms/create/marching_cubes.h +++ b/vcg/complex/algorithms/create/marching_cubes.h @@ -674,7 +674,6 @@ namespace vcg { vp = NULL; vertices_idx.fill(-1); - //memset(vertices_idx, -1, 3*sizeof(size_t)); for (int vert=0; vert<3; vert++, trig++) //ok { diff --git a/vcg/container/simple_temporary_data.h b/vcg/container/simple_temporary_data.h index 9b175faf..13db925e 100644 --- a/vcg/container/simple_temporary_data.h +++ b/vcg/container/simple_temporary_data.h @@ -79,17 +79,18 @@ public: datareserve = sz; } - void resize(size_t sz) - { - int oldDatasize = datasize; - if ((int)sz <= oldDatasize) - return; - if (sz > datareserve) - reserve(sz); - datasize = sz; - memset(&booldata[oldDatasize], 0, datasize - oldDatasize); - } - void push_back(const bool &v) + void resize(size_t sz) + { + int oldDatasize = datasize; + if ((int) sz <= oldDatasize) + return; + if (sz > datareserve) + reserve(sz); + datasize = sz; + for (unsigned int i = oldDatasize; i < datasize; ++i) + booldata[i] = false; + } + void push_back(const bool &v) { resize(datasize + 1); booldata[datasize] = v; diff --git a/vcg/math/matrix44.h b/vcg/math/matrix44.h index 11d228d9..bd9d3a69 100644 --- a/vcg/math/matrix44.h +++ b/vcg/math/matrix44.h @@ -73,7 +73,7 @@ for 'column' vectors. */ template class Matrix44 { protected: - T _a[16]; + std::array _a; public: typedef T ScalarType; @@ -258,7 +258,9 @@ typedef Matrix44 Matrix44d; //} template Matrix44::Matrix44(const T v[]) { - memcpy((T *)_a, v, 16 * sizeof(T)); +// memcpy((T *)_a, v, 16 * sizeof(T)); + for (unsigned int i = 0; i < 16; ++i) + _a[i] = v[i]; } template T &Matrix44::ElementAt(const int row, const int col) { @@ -284,15 +286,15 @@ template T Matrix44::ElementAt(const int row, const int col) const //} template T *Matrix44::operator[](const int i) { assert(i >= 0 && i < 4); - return _a+i*4; + return &_a[i*4]; } template const T *Matrix44::operator[](const int i) const { assert(i >= 0 && i < 4); - return _a+i*4; + return &_a[i*4]; } -template T *Matrix44::V() { return _a;} -template const T *Matrix44::V() const { return _a;} +template T *Matrix44::V() { return _a.data();} +template const T *Matrix44::V() const { return _a.data();} template Matrix44 Matrix44::operator+(const Matrix44 &m) const { @@ -421,7 +423,7 @@ void Matrix44::FromEulerAngles(T alpha, T beta, T gamma) } template void Matrix44::SetZero() { - memset((T *)_a, 0, 16 * sizeof(T)); + _a.fill(0); } template void Matrix44::SetIdentity() { diff --git a/vcg/math/old_deprecated_matrix.h b/vcg/math/old_deprecated_matrix.h deleted file mode 100644 index b0f232e1..00000000 --- a/vcg/math/old_deprecated_matrix.h +++ /dev/null @@ -1,786 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004-2016 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ -/*************************************************************************** -$Log: not supported by cvs2svn $ -Revision 1.9 2006/09/11 16:11:39 marfr960 -Added const to declarations of the overloaded (operators *). -Otherwise the * operator would always attempt to convert any type of data passed as an argument to Point3 - -Revision 1.8 2006/08/23 15:24:45 marfr960 -Copy constructor : faster memcpy instead of slow 'for' cycle -empty constructor - -Revision 1.7 2006/04/29 10:26:04 fiorin -Added some utility methods (swapping of columns and rows, matrix-vector multiplication) - -Revision 1.6 2006/04/11 08:09:35 zifnab1974 -changes necessary for gcc 3.4.5 on linux 64bit. Please take note of case-sensitivity of filenames - -Revision 1.5 2005/12/12 11:25:00 ganovelli -added diagonal matrix, outer produce and namespace - -***************************************************************************/ - -#ifndef MATRIX_VCGLIB -#define MATRIX_VCGLIB - -#include -#include -#include -#include -#include -#include - -namespace vcg{ - namespace ndim{ - - /** \addtogroup math */ - /* @{ */ - - /*! - * This class represent a diagonal mm matrix. - */ - - class MatrixDiagBase{public: - virtual const int & Dimension()const =0; - virtual float operator[](const int & i)const = 0; - }; - template - class MatrixDiag: public Point, public MatrixDiagBase{ - public: - const int & Dimension() const {return N;} - MatrixDiag(const Point&p):Point(p){} - }; - -/*! - * This class represent a generic mn matrix. The class is templated over the scalar type field. - * @param TYPE (Templete Parameter) Specifies the ScalarType field. - */ - template - class Matrix - { - - public: - typedef TYPE ScalarType; - - /*! - * Default constructor - * All the elements are initialized to zero. - * \param m the number of matrix rows - * \param n the number of matrix columns - */ - Matrix(unsigned int m, unsigned int n) - { - _rows = m; - _columns = n; - _data = new ScalarType[m*n]; - memset(_data, 0, m*n*sizeof(ScalarType)); - }; - - /*! - * Constructor - * The matrix elements are initialized with the values of the elements in \i values. - * \param m the number of matrix rows - * \param n the number of matrix columns - * \param values the values of the matrix elements - */ - Matrix(unsigned int m, unsigned int n, TYPE *values) - { - _rows = m; - _columns = n; - unsigned int dim = m*n; - _data = new ScalarType[dim]; - memcpy(_data, values, dim*sizeof(ScalarType)); - //unsigned int i; - //for (i=0; i<_rows*_columns; i++) - // _data[i] = values[i]; - }; - - /*! - * Empty constructor - * Just create the object - */ - Matrix() - { - _rows = 0; - _columns = 0; - _data = NULL; - }; - - /*! - * Copy constructor - * The matrix elements are initialized with the value of the corresponding element in \i m - * \param m the matrix to be copied - */ - Matrix(const Matrix &m) - { - _rows = m._rows; - _columns = m._columns; - _data = new ScalarType[_rows*_columns]; - - unsigned int dim = _rows * _columns; - memcpy(_data, m._data, dim * sizeof(ScalarType)); - -// for (unsigned int i=0; i<_rows*_columns; i++) -// _data[i] = m._data[i]; - }; - - /*! - * Default destructor - */ - ~Matrix() - { - delete []_data; - }; - - /*! - * Number of columns - */ - inline unsigned int ColumnsNumber() const - { - return _columns; - }; - - - /*! - * Number of rows - */ - inline unsigned int RowsNumber() const - { - return _rows; - }; - - /*! - * Equality operator. - * \param m - * \return true iff the matrices have same size and its elements have same values. - */ - bool operator==(const Matrix &m) const - { - if (_rows==m._rows && _columns==m._columns) - { - bool result = true; - for (unsigned int i=0; i<_rows*_columns && result; i++) - result = (_data[i]==m._data[i]); - return result; - } - return false; - }; - - /*! - * Inequality operator - * \param m - * \return true iff the matrices have different size or if their elements have different values. - */ - bool operator!=(const Matrix &m) const - { - if (_rows==m._rows && _columns==m._columns) - { - bool result = false; - for (unsigned int i=0; i<_rows*_columns && !result; i++) - result = (_data[i]!=m._data[i]); - return result; - } - return true; - }; - - /*! - * Return the element stored in the i-th rows at the j-th column - * \param i the row index - * \param j the column index - * \return the element - */ - inline TYPE ElementAt(unsigned int i, unsigned int j) - { - assert(i>=0 && i<_rows); - assert(j>=0 && j<_columns); - return _data[i*_columns+j]; - }; - - /*! - * Calculate and return the matrix determinant (Laplace) - * \return the matrix determinant - */ - TYPE Determinant() const - { - assert(_rows == _columns); - switch (_rows) - { - case 2: - { - return _data[0]*_data[3]-_data[1]*_data[2]; - break; - }; - case 3: - { - return _data[0]*(_data[4]*_data[8]-_data[5]*_data[7]) - - _data[1]*(_data[3]*_data[8]-_data[5]*_data[6]) + - _data[2]*(_data[3]*_data[7]-_data[4]*_data[6]) ; - break; - }; - default: - { - // da migliorare: si puo' cercare la riga/colonna con maggior numero di zeri - ScalarType det = 0; - for (unsigned int j=0; j<_columns; j++) - if (_data[j]!=0) - det += _data[j]*this->Cofactor(0, j); - - return det; - } - }; - }; - - /*! - * Return the cofactor Ai,j of the ai,j element - * \return ... - */ - TYPE Cofactor(unsigned int i, unsigned int j) const - { - assert(_rows == _columns); - assert(_rows>2); - TYPE *values = new TYPE[(_rows-1)*(_columns-1)]; - unsigned int u, v, p, q, s, t; - for (u=0, p=0, s=0, t=0; u<_rows; u++, t+=_rows) - { - if (i==u) - continue; - - for (v=0, q=0; v<_columns; v++) - { - if (j==v) - continue; - values[s+q] = _data[t+v]; - q++; - } - p++; - s+=(_rows-1); - } - Matrix temp(_rows-1, _columns-1, values); - return (pow(TYPE(-1.0), TYPE(i+j))*temp.Determinant()); - }; - - /*! - * Subscript operator: - * \param i the index of the row - * \return a reference to the i-th matrix row - */ - inline TYPE* operator[](const unsigned int i) - { - assert(i<_rows); - return _data + i*_columns; - }; - - /*! - * Const subscript operator - * \param i the index of the row - * \return a reference to the i-th matrix row - */ - inline const TYPE* operator[](const unsigned int i) const - { - assert(i<_rows); - return _data + i*_columns; - }; - - /*! - * Get the j-th column on the matrix. - * \param j the column index. - * \return the reference to the column elements. This pointer must be deallocated by the caller. - */ - TYPE* GetColumn(const unsigned int j) - { - assert(j>=0 && j<_columns); - ScalarType *v = new ScalarType[_columns]; - unsigned int i, p; - for (i=0, p=j; i<_rows; i++, p+=_columns) - v[i] = _data[p]; - return v; - }; - - /*! - * Get the i-th row on the matrix. - * \param i the column index. - * \return the reference to the row elements. This pointer must be deallocated by the caller. - */ - TYPE* GetRow(const unsigned int i) - { - assert(i>=0 && i<_rows); - ScalarType *v = new ScalarType[_rows]; - unsigned int j, p; - for (j=0, p=i*_columns; j<_columns; j++, p++) - v[j] = _data[p]; - return v; - }; - - /*! - * Swaps the values of the elements between the i-th and the j-th column. - * \param i the index of the first column - * \param j the index of the second column - */ - void SwapColumns(const unsigned int i, const unsigned int j) - { - assert(0<=i && i<_columns); - assert(0<=j && j<_columns); - if (i==j) - return; - - unsigned int r, e0, e1; - for (r=0, e0=i, e1=j; r<_rows; r++, e0+=_columns, e1+=_columns) - std::swap(_data[e0], _data[e1]); - }; - - /*! - * Swaps the values of the elements between the i-th and the j-th row. - * \param i the index of the first row - * \param j the index of the second row - */ - void SwapRows(const unsigned int i, const unsigned int j) - { - assert(0<=i && i<_rows); - assert(0<=j && j<_rows); - if (i==j) - return; - - unsigned int r, e0, e1; - for (r=0, e0=i*_columns, e1=j*_columns; r<_columns; r++, e0++, e1++) - std::swap(_data[e0], _data[e1]); - }; - - /*! - * Assignment operator - * \param m ... - */ - Matrix& operator=(const Matrix &m) - { - if (this != &m) - { - assert(_rows == m._rows); - assert(_columns == m._columns); - for (unsigned int i=0; i<_rows*_columns; i++) - _data[i] = m._data[i]; - } - return *this; - }; - - /*! - * Adds a matrix m to this matrix. - * \param m reference to matrix to add to this - * \return the matrix sum. - */ - Matrix& operator+=(const Matrix &m) - { - assert(_rows == m._rows); - assert(_columns == m._columns); - for (unsigned int i=0; i<_rows*_columns; i++) - _data[i] += m._data[i]; - return *this; - }; - - /*! - * Subtracts a matrix m to this matrix. - * \param m reference to matrix to subtract - * \return the matrix difference. - */ - Matrix& operator-=(const Matrix &m) - { - assert(_rows == m._rows); - assert(_columns == m._columns); - for (unsigned int i=0; i<_rows*_columns; i++) - _data[i] -= m._data[i]; - return *this; - }; - - /*! - * (Modifier) Add to each element of this matrix the scalar constant k. - * \param k the scalar constant - * \return the modified matrix - */ - Matrix& operator+=(const TYPE k) - { - for (unsigned int i=0; i<_rows*_columns; i++) - _data[i] += k; - return *this; - }; - - /*! - * (Modifier) Subtract from each element of this matrix the scalar constant k. - * \param k the scalar constant - * \return the modified matrix - */ - Matrix& operator-=(const TYPE k) - { - for (unsigned int i=0; i<_rows*_columns; i++) - _data[i] -= k; - return *this; - }; - - /*! - * (Modifier) Multiplies each element of this matrix by the scalar constant k. - * \param k the scalar constant - * \return the modified matrix - */ - Matrix& operator*=(const TYPE k) - { - for (unsigned int i=0; i<_rows*_columns; i++) - _data[i] *= k; - return *this; - }; - - /*! - * (Modifier) Divides each element of this matrix by the scalar constant k. - * \param k the scalar constant - * \return the modified matrix - */ - Matrix& operator/=(const TYPE k) - { - assert(k!=0); - for (unsigned int i=0; i<_rows*_columns; i++) - _data[i] /= k; - return *this; - }; - - /*! - * Matrix multiplication: calculates the cross product. - * \param m reference to the matrix to multiply by - * \return the matrix product - */ - Matrix operator*(const Matrix &m) const - { - assert(_columns == m._rows); - Matrix result(_rows, m._columns); - unsigned int i, j, k, p, q, r; - for (i=0, p=0, r=0; i - void DotProduct(Point &m,Point &result) - { - unsigned int i, j, p, r; - for (i=0, p=0, r=0; i operator*(const MatrixDiagBase &m) const - { - assert(_columns == _rows); - assert(_columns == m.Dimension()); - int i,j; - Matrix result(_rows, _columns); - - for (i=0; i - void OuterProduct(const Point a, const Point< M,TYPE> b) - { - assert(N == _rows); - assert(M == _columns); - Matrix result(_rows,_columns); - unsigned int i, j; - - for (i=0; i operator*(Point3 &p) const - { - assert(_columns==3 && _rows==3); - vcg::Point3 result; - result[0] = _data[0]*p[0]+_data[1]*p[1]+_data[2]*p[2]; - result[1] = _data[3]*p[0]+_data[4]*p[1]+_data[5]*p[2]; - result[2] = _data[6]*p[0]+_data[7]*p[1]+_data[8]*p[2]; - return result; - }; - - - /*! - * Scalar sum. - * \param k - * \return the resultant matrix - */ - Matrix operator+(const TYPE k) - { - Matrix result(_rows, _columns); - for (unsigned int i=0; i<_rows*_columns; i++) - result._data[i] = _data[i]+k; - return result; - }; - - /*! - * Scalar difference. - * \param k - * \return the resultant matrix - */ - Matrix operator-(const TYPE k) - { - Matrix result(_rows, _columns); - for (unsigned int i=0; i<_rows*_columns; i++) - result._data[i] = _data[i]-k; - return result; - }; - - /*! - * Negate all matrix elements - * \return the modified matrix - */ - Matrix operator-() const - { - Matrix result(_rows, _columns, _data); - for (unsigned int i=0; i<_columns*_rows; i++) - result._data[i] = -1*_data[i]; - return result; - }; - - /*! - * Scalar multiplication. - * \param k value to multiply every member by - * \return the resultant matrix - */ - Matrix operator*(const TYPE k) const - { - Matrix result(_rows, _columns); - for (unsigned int i=0; i<_rows*_columns; i++) - result._data[i] = _data[i]*k; - return result; - }; - - /*! - * Scalar division. - * \param k value to divide every member by - * \return the resultant matrix - */ - Matrix operator/(const TYPE k) - { - Matrix result(_rows, _columns); - for (unsigned int i=0; i<_rows*_columns; i++) - result._data[i] = _data[i]/k; - return result; - }; - - - /*! - * Set all the matrix elements to zero. - */ - void SetZero() - { - for (unsigned int i=0; i<_rows*_columns; i++) - _data[i] = ScalarType(0.0); - }; - - /*! - * Set the matrix to identity. - */ - void SetIdentity() - { - assert(_rows==_columns); - for (unsigned int i=0; i<_rows; i++) - for (unsigned int j=0; j<_columns; j++) - _data[i] = (i==j) ? ScalarType(1.0) : ScalarType(0.0f); - }; - - /*! - * Set the values of j-th column to v[j] - * \param j the column index - * \param v ... - */ - void SetColumn(const unsigned int j, TYPE* v) - { - assert(j>=0 && j<_columns); - unsigned int i, p; - for (i=0, p=j; i<_rows; i++, p+=_columns) - _data[p] = v[i]; - }; - - /*! - * Set the elements of the i-th row to v[j] - * \param i the row index - * \param v ... - */ - void SetRow(const unsigned int i, TYPE* v) - { - assert(i>=0 && i<_rows); - unsigned int j, p; - for (j=0, p=i*_rows; j<_columns; j++, p++) - _data[p] = v[j]; - }; - - /*! - * Set the diagonal elements vi,i to v[i] - * \param v - */ - void SetDiagonal(TYPE *v) - { - assert(_rows == _columns); - for (unsigned int i=0, p=0; i<_rows; i++, p+=_rows) - _data[p+i] = v[i]; - }; - - /*! - * Resize the current matrix. - * \param m the number of matrix rows. - * \param n the number of matrix columns. - */ - void Resize(const unsigned int m, const unsigned int n) - { - assert(m>=2); - assert(n>=2); - _rows = m; - _columns = n; - delete []_data; - _data = new ScalarType[m*n]; - for (unsigned int i=0; i MatrixMNd; - typedef vcg::ndim::Matrix MatrixMNf; - - /*! @} */ - -// template -// void Invert(MatrixType & m){ -// typedef typename MatrixType::ScalarType X; -// X *diag; -// diag = new X [m.ColumnsNumber()]; - -// MatrixType res(m.RowsNumber(),m.ColumnsNumber()); -// vcg::SingularValueDecomposition (m,&diag[0],res,LeaveUnsorted,50 ); -// m.Transpose(); -// // prodotto per la diagonale -// unsigned int i,j; -// for (i=0; i -#include -#include -#ifndef _YES_I_WANT_TO_USE_DANGEROUS_STUFF -#error "Please do not never user this file. Use EIGEN!!!!" -#endif -namespace vcg -{ - /** \addtogroup math */ - /* @{ */ - - /*! - * - */ - template< typename MATRIX_TYPE > - static void JacobiRotate(MATRIX_TYPE &A, typename MATRIX_TYPE::ScalarType s, typename MATRIX_TYPE::ScalarType tau, int i,int j,int k,int l) - { - typename MATRIX_TYPE::ScalarType g=A[i][j]; - typename MATRIX_TYPE::ScalarType h=A[k][l]; - A[i][j]=g-s*(h+g*tau); - A[k][l]=h+s*(g-h*tau); - }; - - /*! - * Computes all eigenvalues and eigenvectors of a real symmetric matrix . - * On output, elements of the input matrix above the diagonal are destroyed. - * \param d returns the eigenvalues of a. - * \param v is a matrix whose columns contain, the normalized eigenvectors - * \param nrot returns the number of Jacobi rotations that were required. - */ - template - static void Jacobi(MATRIX_TYPE &w, POINT_TYPE &d, MATRIX_TYPE &v, int &nrot) - { - typedef typename MATRIX_TYPE::ScalarType ScalarType; - assert(w.RowsNumber()==w.ColumnsNumber()); - int dimension = w.RowsNumber(); - - int j,iq,ip,i; - //assert(w.IsSymmetric()); - typename MATRIX_TYPE::ScalarType tresh, theta, tau, t, sm, s, h, g, c; - POINT_TYPE b, z; - - v.SetIdentity(); - - for (ip=0;ip4 && (float)(fabs(d[ip])+g) == (float)fabs(d[ip]) && (float)(fabs(d[iq])+g) == (float)fabs(d[iq])) - w[ip][iq]=ScalarType(0.0); - else if (fabs(w[ip][iq]) > tresh) - { - h=d[iq]-d[ip]; - if ((float)(fabs(h)+g) == (float)fabs(h)) - t=(w[ip][iq])/h; //t =1/(2#) - else - { - theta=ScalarType(0.5)*h/(w[ip][iq]); //Equation (11.1.10). - t=ScalarType(1.0)/(fabs(theta)+sqrt(ScalarType(1.0)+theta*theta)); - if (theta < ScalarType(0.0)) t = -t; - } - c=ScalarType(1.0)/sqrt(ScalarType(1.0)+t*t); - s=t*c; - tau=s/(ScalarType(1.0)+c); - h=t*w[ip][iq]; - z[ip] -= h; - z[iq] += h; - d[ip] -= h; - d[iq] += h; - w[ip][iq]=ScalarType(0.0); - for (j=0;j<=ip-1;j++) { //Case of rotations 1 <= j < p. - JacobiRotate(w,s,tau,j,ip,j,iq) ; - } - for (j=ip+1;j<=iq-1;j++) { //Case of rotations p < j < q. - JacobiRotate(w,s,tau,ip,j,j,iq); - } - for (j=iq+1;j(w,s,tau,ip,j,iq,j); - } - for (j=0;j(v,s,tau,j,ip,j,iq); - } - ++nrot; - } - } - } - for (ip=0;ip - void SortEigenvaluesAndEigenvectors(POINT_TYPE &eigenvalues, MATRIX_TYPE &eigenvectors, bool absComparison = false) - { - assert(eigenvectors.ColumnsNumber()==eigenvectors.RowsNumber()); - int dimension = eigenvectors.ColumnsNumber(); - int i, j, k; - float p,q; - for (i=0; i= p) - { - p = q; - k = j; - } - p = eigenvalues[k]; - } - else - { - p = eigenvalues[ k=i ]; - for (j=i+1; j= p) - p = eigenvalues[ k=j ]; - } - - if (k != i) - { - eigenvalues[k] = eigenvalues[i]; // i.e. - eigenvalues[i] = p; // swaps the value of the elements i-th and k-th - - for (j=0; j - inline static TYPE sqr(TYPE a) - { - TYPE sqr_arg = a; - return (sqr_arg == 0 ? 0 : sqr_arg*sqr_arg); - } - - // Computes (a^2 + b^2)^(1/2) without destructive underflow or overflow. - template - inline static TYPE pythagora(TYPE a, TYPE b) - { - TYPE abs_a = fabs(a); - TYPE abs_b = fabs(b); - if (abs_a > abs_b) - return abs_a*sqrt((TYPE)1.0+sqr(abs_b/abs_a)); - else - return (abs_b == (TYPE)0.0 ? (TYPE)0.0 : abs_b*sqrt((TYPE)1.0+sqr(abs_a/abs_b))); - } - - template - inline static TYPE sign(TYPE a, TYPE b) - { - return (b >= 0.0 ? fabs(a) : -fabs(a)); - } - - /*! - * - */ - enum SortingStrategy {LeaveUnsorted=0, SortAscending=1, SortDescending=2}; - template< typename MATRIX_TYPE > - void Sort(MATRIX_TYPE &U, typename MATRIX_TYPE::ScalarType W[], MATRIX_TYPE &V, const SortingStrategy sorting) ; - - - /*! - * Given a matrix Amxn, this routine computes its singular value decomposition, - * i.e. A=UxWxVT. The matrix A will be destroyed! - * (This is the implementation described in Numerical Recipies). - * \param A the matrix to be decomposed - * \param W the diagonal matrix of singular values W, stored as a vector W[1...N] - * \param V the matrix V (not the transpose VT) - * \param max_iters max iteration number (default = 30). - * \return - */ - template - static bool SingularValueDecomposition(MATRIX_TYPE &A, typename MATRIX_TYPE::ScalarType *W, MATRIX_TYPE &V, const SortingStrategy sorting=LeaveUnsorted, const int max_iters=30) - { - typedef typename MATRIX_TYPE::ScalarType ScalarType; - int m = (int) A.RowsNumber(); - int n = (int) A.ColumnsNumber(); - int flag,i,its,j,jj,k,l,nm; - ScalarType anorm, c, f, g, h, s, scale, x, y, z, *rv1; - bool convergence = true; - - rv1 = new ScalarType[n]; - g = scale = anorm = 0; - // Householder reduction to bidiagonal form. - for (i=0; i( sqrt(s), f ); - h = f*g - s; - A[i][i]=f-g; - for (j=l; j(sqrt(s),f); - h = f*g - s; - A[i][l] = f-g; - for (k=l; k=0; i--) - { - //Accumulation of right-hand transformations. - if (i < (n-1)) - { - if (g) - { - for (j=l; j=0; i--) - { - l = i+1; - g = W[i]; - for (j=l; j=0; k--) - { - for (its=1; its<=max_iters; its++) - { - flag=1; - for (l=k; l>=0; l--) - { - // Test for splitting. - nm=l-1; - // Note that rv1[1] is always zero. - if ((double)(fabs(rv1[l])+anorm) == anorm) - { - flag=0; - break; - } - if ((double)(fabs(W[nm])+anorm) == anorm) - break; - } - if (flag) - { - c=0.0; //Cancellation of rv1[l], if l > 1. - s=1.0; - for (i=l ;i<=k; i++) - { - f = s*rv1[i]; - rv1[i] = c*rv1[i]; - if ((double)(fabs(f)+anorm) == anorm) - break; - g = W[i]; - h = pythagora(f,g); - W[i] = h; - h = (ScalarType)1.0/h; - c = g*h; - s = -f*h; - for (j=0; j(f,1.0); - f=((x-z)*(x+z) + h*((y/(f+sign(g,f)))-h))/x; - c=s=1.0; - //Next QR transformation: - for (j=l; j<= nm;j++) - { - i = j+1; - g = rv1[i]; - y = W[i]; - h = s*g; - g = c*g; - z = pythagora(f,h); - rv1[j] = z; - c = f/z; - s = h/z; - f = x*c + g*s; - g = g*c - x*s; - h = y*s; - y *= c; - for (jj=0; jj(f,h); - W[j] = z; - // Rotation can be arbitrary if z = 0. - if (z) - { - z = (ScalarType)1.0/z; - c = f*z; - s = h*z; - } - f = c*g + s*y; - x = c*y - s*g; - for (jj=0; jj(A, W, V, sorting); - - return convergence; - }; - - - /*! - * Sort the singular values computed by the SingularValueDecomposition procedure and - * modify the matrices U and V accordingly. - */ - // TODO modify the last parameter type - template< typename MATRIX_TYPE > - void Sort(MATRIX_TYPE &U, typename MATRIX_TYPE::ScalarType W[], MATRIX_TYPE &V, const SortingStrategy sorting) - { - typedef typename MATRIX_TYPE::ScalarType ScalarType; - - assert(U.ColumnsNumber()==V.ColumnsNumber()); - - int mu = U.RowsNumber(); - int mv = V.RowsNumber(); - int n = U.ColumnsNumber(); - - //ScalarType* u = &U[0][0]; - //ScalarType* v = &V[0][0]; - - for (int i=0; i p) - { - k = j; - p = W[j]; - } - } - break; - } - case LeaveUnsorted: break; // nothing to do. - } - if (k != i) - { - W[k] = W[i]; // i.e. - W[i] = p; // swaps the i-th and the k-th elements - - int j = mu; - //ScalarType* uji = u + i; // uji = &U[0][i] - //ScalarType* ujk = u + k; // ujk = &U[0][k] - //ScalarType* vji = v + i; // vji = &V[0][i] - //ScalarType* vjk = v + k; // vjk = &V[0][k] - //if (j) - //{ - // for(;;) for( ; j!=0; --j, uji+=n, ujk+=n) - // { { - // p = *uji; p = *uji; // i.e. - // *uji = *ujk; *uji = *ujk; // swap( U[s][i], U[s][k] ) - // *ujk = p; *ujk = p; // - // if (!(--j)) } - // break; - // uji += n; - // ujk += n; - // } - //} - for(int s=0; j!=0; ++s, --j) - std::swap(U[s][i], U[s][k]); - - j = mv; - //if (j!=0) - //{ - // for(;;) for ( ; j!=0; --j, vji+=n, ujk+=n) - // { { - // p = *vji; p = *vji; // i.e. - // *vji = *vjk; *vji = *vjk; // swap( V[s][i], V[s][k] ) - // *vjk = p; *vjk = p; // - // if (!(--j)) } - // break; - // vji += n; - // vjk += n; - // } - //} - for (int s=0; j!=0; ++s, --j) - std::swap(V[s][i], V[s][k]); - } - } - } - - - /*! - * Solves AxX = B for a vector X, where A is specified by the matrices Umxn, - * Wnx1 and Vnxn as returned by SingularValueDecomposition. - * No input quantities are destroyed, so the routine may be called sequentially with different bxs. - * \param x is the output solution vector (xnx1) - * \param b is the input right-hand side (bnx1) - */ - template - static void SingularValueBacksubstitution(const MATRIX_TYPE &U, - const typename MATRIX_TYPE::ScalarType *W, - const MATRIX_TYPE &V, - typename MATRIX_TYPE::ScalarType *x, - const typename MATRIX_TYPE::ScalarType *b) - { - typedef typename MATRIX_TYPE::ScalarType ScalarType; - unsigned int jj, j, i; - unsigned int columns_number = U.ColumnsNumber(); - unsigned int rows_number = U.RowsNumber(); - ScalarType s; - ScalarType *tmp = new ScalarType[columns_number]; - for (j=0; j - -namespace vcg{ -namespace ndim{ -template class Matrix; -} -} - -namespace Eigen{ -template -struct ei_traits > : ei_traits > {}; -template struct ei_to_vcgtype -{ typedef vcg::ndim::Matrix type; }; -} - -namespace vcg{ -namespace ndim{ - -/** \addtogroup math */ -/* @{ */ - -/*! - * \deprecated use Matrix or Matrix or any typedef - * This class represent a generic mn matrix. The class is templated over the scalar type field. - * @param Scalar (Templete Parameter) Specifies the ScalarType field. - */ -template -class Matrix : public Eigen::Matrix<_Scalar,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor> // FIXME col or row major ? -{ - typedef Eigen::Matrix<_Scalar,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor> _Base; - -public: - - _EIGEN_GENERIC_PUBLIC_INTERFACE(Matrix,_Base); - typedef _Scalar ScalarType; - VCG_EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Matrix) - - /*! - * Default constructor - * All the elements are initialized to zero. - * \param m the number of matrix rows - * \param n the number of matrix columns - */ - Matrix(int m, int n) - : Base(m,n) - { - memset(Base::data(), 0, m*n*sizeof(Scalar)); - } - - /*! - * Constructor - * The matrix elements are initialized with the values of the elements in \i values. - * \param m the number of matrix rows - * \param n the number of matrix columns - * \param values the values of the matrix elements - */ - Matrix(int m, int n, Scalar *values) - : Base(m,n) - { - *this = Eigen::Map >(values, m , n); - } - - /*! - * Empty constructor - * Just create the object - */ - Matrix() : Base() {} - - /*! - * Copy constructor - * The matrix elements are initialized with the value of the corresponding element in \i m - * \param m the matrix to be copied - */ - Matrix(const Matrix &m) : Base(m) {} - - template - Matrix(const Eigen::MatrixBase &m) : Base(m) {} - - /*! - * Default destructor - */ - ~Matrix() {} - - /*! - * \deprecated use *this.row(i) - * Subscript operator: - * \param i the index of the row - * \return a reference to the i-th matrix row - */ - inline typename Base::RowXpr operator[](const unsigned int i) - { return Base::row(i); } - - /*! - * \deprecated use *this.row(i) - * Const subscript operator - * \param i the index of the row - * \return a reference to the i-th matrix row - */ - inline const typename Base::RowXpr operator[](const unsigned int i) const - { return Base::row(i); } - - - /*! - * Matrix multiplication: calculates the cross product. - * \param reference to the matrix to multiply by - * \return the matrix product - */ - // FIXME what the hell is that ! - /*template - void DotProduct(Point &m,Point &result) - { - unsigned int i, j, p, r; - for (i=0, p=0, r=0; i=2); - assert(n>=2); - Base::resize(m,n); - memset(Base::data(), 0, m*n*sizeof(Scalar)); - }; -}; - -typedef vcg::ndim::Matrix MatrixMNd; -typedef vcg::ndim::Matrix MatrixMNf; - -/*! @} */ - -template -void Invert(MatrixType & m) -{ - m = m.inverse(); -} - -} -} // end of namespace - -#endif - -#endif - diff --git a/vcg/math/old_matrix33.h b/vcg/math/old_matrix33.h deleted file mode 100644 index 0aebd8b0..00000000 --- a/vcg/math/old_matrix33.h +++ /dev/null @@ -1,298 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004-2016 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ - -#ifndef VCG_USE_EIGEN -#include "deprecated_matrix33.h" -#else - -#ifndef __VCGLIB_MATRIX33_H -#define __VCGLIB_MATRIX33_H - -#include "eigen.h" -#include "matrix44.h" - -namespace vcg{ -template class Matrix33; -} - -namespace Eigen{ -template -struct ei_traits > : ei_traits > {}; -template struct ei_to_vcgtype -{ typedef vcg::Matrix33 type; }; -} - -namespace vcg { - -/** \deprecated use Matrix - @name Matrix33 - Class Matrix33. - This is the class for definition of a matrix 3x3. - @param S (Templete Parameter) Specifies the ScalarType field. -*/ -template -class Matrix33 : public Eigen::Matrix<_Scalar,3,3,Eigen::RowMajor> // FIXME col or row major ? -{ - - typedef Eigen::Matrix<_Scalar,3,3,Eigen::RowMajor> _Base; -public: - - using _Base::coeff; - using _Base::coeffRef; - using _Base::setZero; - - _EIGEN_GENERIC_PUBLIC_INTERFACE(Matrix33,_Base); - typedef _Scalar ScalarType; - - VCG_EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Matrix33) - - /// Default constructor - inline Matrix33() : Base() {} - - /// Copy constructor - Matrix33(const Matrix33& m ) : Base(m) {} - - /// create from a \b row-major array - Matrix33(const Scalar * v ) : Base(Eigen::Map >(v)) {} - - /// create from Matrix44 excluding row and column k - Matrix33(const Matrix44 & m, const int & k) : Base(m.minor(k,k)) {} - - template - Matrix33(const Eigen::MatrixBase& other) : Base(other) {} - - /*! \deprecated use *this.row(i) */ - inline typename Base::RowXpr operator[](const unsigned int i) - { return Base::row(i); } - - /*! \deprecated use *this.row(i) */ - inline const typename Base::RowXpr operator[](const unsigned int i) const - { return Base::row(i); } - - /** \deprecated */ - Matrix33 & SetRotateRad(Scalar angle, const Point3 & axis ) - { - *this = Eigen::AngleAxis(angle,axis).toRotationMatrix(); - return (*this); - } - /** \deprecated */ - Matrix33 & SetRotateDeg(Scalar angle, const Point3 & axis ){ - return SetRotateRad(math::ToRad(angle),axis); - } - - // Warning, this Inversion code can be HIGHLY NUMERICALLY UNSTABLE! - // In most case you are advised to use the Invert() method based on SVD decomposition. - /** \deprecated */ - Matrix33 & FastInvert() { return *this = Base::inverse(); } - - void show(FILE * fp) - { - for(int i=0;i<3;++i) - printf("| %g \t%g \t%g |\n",coeff(i,0),coeff(i,1),coeff(i,2)); - } - - /** \deprecated use a * b.transpose() - compute the matrix generated by the product of a * b^T - */ - // hm.... this is the outer product - void ExternalProduct(const Point3 &a, const Point3 &b) { *this = a * b.transpose(); } - - /** Compute the Frobenius Norm of the Matrix */ - Scalar Norm() { return Base::cwise().abs2().sum(); } - - /** Computes the covariance matrix of a set of 3d points. Returns the barycenter. - */ - // FIXME should be outside Matrix - - - /** - It computes the cross covariance matrix of two set of 3d points P and X; - it returns also the barycenters of P and X. - fonte: - - Besl, McKay - A method for registration o f 3d Shapes - IEEE TPAMI Vol 14, No 2 1992 - - */ - // FIXME should be outside Matrix - template - void CrossCovariance(const STLPOINTCONTAINER &P, const STLPOINTCONTAINER &X, - Point3 &bp, Point3 &bx) - { - setZero(); - assert(P.size()==X.size()); - bx.setZero(); - bp.setZero(); - Matrix33 tmp; - typename std::vector >::const_iterator pi,xi; - for(pi=P.begin(),xi=X.begin();pi!=P.end();++pi,++xi){ - bp+=*pi; - bx+=*xi; - tmp.ExternalProduct(*pi,*xi); - (*this)+=tmp; - } - bp/=P.size(); - bx/=X.size(); - (*this)/=P.size(); - tmp.ExternalProduct(bp,bx); - (*this)-=tmp; - } - - template - void WeightedCrossCovariance(const STLREALCONTAINER & weights, - const STLPOINTCONTAINER &P, - const STLPOINTCONTAINER &X, - Point3 &bp, - Point3 &bx) - { - setZero(); - assert(P.size()==X.size()); - bx.SetZero(); - bp.SetZero(); - Matrix33 tmp; - typename std::vector >::const_iterator pi,xi; - typename STLREALCONTAINER::const_iterator pw; - - for(pi=P.begin(),xi=X.begin();pi!=P.end();++pi,++xi){ - bp+=(*pi); - bx+=(*xi); - } - bp/=P.size(); - bx/=X.size(); - - for(pi=P.begin(),xi=X.begin(),pw = weights.begin();pi!=P.end();++pi,++xi,++pw){ - - tmp.ExternalProduct(((*pi)-(bp)),((*xi)-(bp))); - - (*this)+=tmp*(*pw); - } - } -}; - -template -void Invert(Matrix33 &m) { m = m.lu().inverse(); } - -template -Matrix33 Inverse(const Matrix33&m) { return m.lu().inverse(); } - -///given 2 vector centered into origin calculate the rotation matrix from first to the second -template -Matrix33 RotationMatrix(vcg::Point3 v0,vcg::Point3 v1,bool normalized=true) - { - typedef typename vcg::Point3 CoordType; - Matrix33 rotM; - const S epsilon=0.00001; - if (!normalized) - { - v0.Normalize(); - v1.Normalize(); - } - S dot=v0.dot(v1); - ///control if there is no rotation - if (dot>((S)1-epsilon)) - { - rotM.SetIdentity(); - return rotM; - } - - ///find the axis of rotation - CoordType axis; - axis=v0^v1; - axis.Normalize(); - - ///construct rotation matrix - S u=axis.X(); - S v=axis.Y(); - S w=axis.Z(); - S phi=acos(dot); - S rcos = cos(phi); - S rsin = sin(phi); - - rotM[0][0] = rcos + u*u*(1-rcos); - rotM[1][0] = w * rsin + v*u*(1-rcos); - rotM[2][0] = -v * rsin + w*u*(1-rcos); - rotM[0][1] = -w * rsin + u*v*(1-rcos); - rotM[1][1] = rcos + v*v*(1-rcos); - rotM[2][1] = u * rsin + w*v*(1-rcos); - rotM[0][2] = v * rsin + u*w*(1-rcos); - rotM[1][2] = -u * rsin + v*w*(1-rcos); - rotM[2][2] = rcos + w*w*(1-rcos); - - return rotM; - } - -///return the rotation matrix along axis -template -Matrix33 RotationMatrix(const vcg::Point3 &axis, - const float &angleRad) - { - vcg::Matrix44 matr44; - vcg::Matrix33 matr33; - matr44.SetRotate(angleRad,axis); - for (int i=0;i<3;i++) - for (int j=0;j<3;j++) - matr33[i][j]=matr44[i][j]; - return matr33; - } - -/// return a random rotation matrix, from the paper: -/// Fast Random Rotation Matrices, James Arvo -/// Graphics Gems III pp. 117-120 -template - Matrix33 RandomRotation(){ - S x1,x2,x3; - Matrix33 R,H,M,vv; - Point3 v; - R.SetIdentity(); - H.SetIdentity(); - x1 = rand()/S(RAND_MAX); - x2 = rand()/S(RAND_MAX); - x3 = rand()/S(RAND_MAX); - - R[0][0] = cos(S(2)*M_PI*x1); - R[0][1] = sin(S(2)*M_PI*x1); - R[1][0] = - R[0][1]; - R[1][1] = R[0][0]; - - v[0] = cos(2.0 * M_PI * x2)*sqrt(x3); - v[1] = sin(2.0 * M_PI * x2)*sqrt(x3); - v[2] = sqrt(1-x3); - - vv.OuterProduct(v,v); - H -= vv*S(2); - M = H*R*S(-1); - return M; -} - -/// -typedef Matrix33 Matrix33s; -typedef Matrix33 Matrix33i; -typedef Matrix33 Matrix33f; -typedef Matrix33 Matrix33d; - -} // end of namespace - -#endif - -#endif diff --git a/vcg/math/old_matrix44.h b/vcg/math/old_matrix44.h deleted file mode 100644 index d4a7ae9a..00000000 --- a/vcg/math/old_matrix44.h +++ /dev/null @@ -1,493 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004-2016 \/)\/ * -* Visual Computing Lab /\/| * -* ISTI - Italian National Research Council | * -* \ * -* All rights reserved. * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU General Public License as published by * -* the Free Software Foundation; either version 2 of the License, or * -* (at your option) any later version. * -* * -* This program is distributed in the hope that it will be useful, * -* but WITHOUT ANY WARRANTY; without even the implied warranty of * -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * -* for more details. * -* * -****************************************************************************/ - -#ifndef VCG_USE_EIGEN -#include "deprecated_matrix44.h" -#else - -#ifndef __VCGLIB_MATRIX44 -#define __VCGLIB_MATRIX44 - -#include "eigen.h" -#include -#include -#include -#include - -namespace vcg{ -template class Matrix44; -} - -namespace Eigen{ -template -struct ei_traits > : ei_traits > {}; -template struct ei_to_vcgtype -{ typedef vcg::Matrix44 type; }; -} - -namespace vcg { - - /* - Annotations: -Opengl stores matrix in column-major order. That is, the matrix is stored as: - - a0 a4 a8 a12 - a1 a5 a9 a13 - a2 a6 a10 a14 - a3 a7 a11 a15 - - Usually in opengl (see opengl specs) vectors are 'column' vectors - so usually matrix are PRE-multiplied for a vector. - So the command glTranslate generate a matrix that - is ready to be premultipled for a vector: - - 1 0 0 tx - 0 1 0 ty - 0 0 1 tz - 0 0 0 1 - -Matrix44 stores matrix in row-major order i.e. - - a0 a1 a2 a3 - a4 a5 a6 a7 - a8 a9 a10 a11 - a12 a13 a14 a15 - -So for the use of that matrix in opengl with their supposed meaning you have to transpose them before feeding to glMultMatrix. -This mechanism is hidden by the templated function defined in wrap/gl/math.h; -If your machine has the ARB_transpose_matrix extension it will use the appropriate; -The various gl-like command SetRotate, SetTranslate assume that you are making matrix -for 'column' vectors. - -*/ - -// Note that we have to pass Dim and HDim because it is not allowed to use a template -// parameter to define a template specialization. To be more precise, in the following -// specializations, it is not allowed to use Dim+1 instead of HDim. -template< typename Other, - int OtherRows=Eigen::ei_traits::RowsAtCompileTime, - int OtherCols=Eigen::ei_traits::ColsAtCompileTime> -struct ei_matrix44_product_impl; - -/** \deprecated use Eigen::Matrix (or the typedef) you want a real 4x4 matrix, or use Eigen::Transform if you want a transformation matrix for a 3D space (a Eigen::Transform is internally a 4x4 col-major matrix) - * - * This class represents a 4x4 matrix. T is the kind of element in the matrix. - */ -template -class Matrix44 : public Eigen::Matrix<_Scalar,4,4,Eigen::RowMajor> // FIXME col or row major ! -{ - - typedef Eigen::Matrix<_Scalar,4,4,Eigen::RowMajor> _Base; -public: - - using _Base::coeff; - using _Base::coeffRef; - using _Base::ElementAt; - using _Base::setZero; - - _EIGEN_GENERIC_PUBLIC_INTERFACE(Matrix44,_Base); - typedef _Scalar ScalarType; - VCG_EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Matrix44) - - Matrix44() : Base() {} - ~Matrix44() {} - Matrix44(const Matrix44 &m) : Base(m) {} - Matrix44(const Scalar * v ) : Base(Eigen::Map >(v)) {} - template - Matrix44(const Eigen::MatrixBase& other) : Base(other) {} - - const typename Base::RowXpr operator[](int i) const { return Base::row(i); } - typename Base::RowXpr operator[](int i) { return Base::row(i); } - - typename Base::ColXpr GetColumn4(const int& i) const { return Base::col(i); } - const Eigen::Block GetColumn3(const int& i) const { return this->template block<3,1>(0,i); } - - typename Base::RowXpr GetRow4(const int& i) const { return Base::row(i); } - Eigen::Block GetRow3(const int& i) const { return this->template block<1,3>(i,0); } - - template - void ToMatrix(Matrix44Type & m) const { m = (*this).template cast(); } - - void ToEulerAngles(Scalar &alpha, Scalar &beta, Scalar &gamma); - - template - void FromMatrix(const Matrix44Type & m) { for(int i = 0; i < 16; i++) Base::data()[i] = m.data()[i]; } - - void FromEulerAngles(Scalar alpha, Scalar beta, Scalar gamma); - void SetDiagonal(const Scalar k); - Matrix44 &SetScale(const Scalar sx, const Scalar sy, const Scalar sz); - Matrix44 &SetScale(const Point3 &t); - Matrix44 &SetTranslate(const Point3 &t); - Matrix44 &SetTranslate(const Scalar sx, const Scalar sy, const Scalar sz); - Matrix44 &SetShearXY(const Scalar sz); - Matrix44 &SetShearXZ(const Scalar sy); - Matrix44 &SetShearYZ(const Scalar sx); - - ///use radiants for angle. - Matrix44 &SetRotateDeg(Scalar AngleDeg, const Point3 & axis); - Matrix44 &SetRotateRad(Scalar AngleRad, const Point3 & axis); - - /** taken from Eigen::Transform - * \returns the product between the transform \c *this and a matrix expression \a other - * - * The right hand side \a other might be either: - * \li a matrix expression with 4 rows - * \li a 3D vector/point - */ - template - inline const typename ei_matrix44_product_impl::ResultType - operator * (const Eigen::MatrixBase &other) const - { return ei_matrix44_product_impl::run(*this,other.derived()); } - - void print() {std::cout << *this << "\n\n";} - -}; - -//return NULL matrix if not invertible -template Matrix44 &Invert(Matrix44 &m); -template Matrix44 Inverse(const Matrix44 &m); - -typedef Matrix44 Matrix44s; -typedef Matrix44 Matrix44i; -typedef Matrix44 Matrix44f; -typedef Matrix44 Matrix44d; - -template < class PointType , class T > void operator*=( std::vector &vert, const Matrix44 & m ) { - typename std::vector::iterator ii; - for(ii=vert.begin();ii!=vert.end();++ii) - (*ii).P()=m * (*ii).P(); -} - -template -void Matrix44::ToEulerAngles(Scalar &alpha, Scalar &beta, Scalar &gamma) -{ - alpha = atan2(coeff(1,2), coeff(2,2)); - beta = asin(-coeff(0,2)); - gamma = atan2(coeff(0,1), coeff(1,1)); -} - -template -void Matrix44::FromEulerAngles(Scalar alpha, Scalar beta, Scalar gamma) -{ - this->SetZero(); - - T cosalpha = cos(alpha); - T cosbeta = cos(beta); - T cosgamma = cos(gamma); - T sinalpha = sin(alpha); - T sinbeta = sin(beta); - T singamma = sin(gamma); - - ElementAt(0,0) = cosbeta * cosgamma; - ElementAt(1,0) = -cosalpha * singamma + sinalpha * sinbeta * cosgamma; - ElementAt(2,0) = sinalpha * singamma + cosalpha * sinbeta * cosgamma; - - ElementAt(0,1) = cosbeta * singamma; - ElementAt(1,1) = cosalpha * cosgamma + sinalpha * sinbeta * singamma; - ElementAt(2,1) = -sinalpha * cosgamma + cosalpha * sinbeta * singamma; - - ElementAt(0,2) = -sinbeta; - ElementAt(1,2) = sinalpha * cosbeta; - ElementAt(2,2) = cosalpha * cosbeta; - - ElementAt(3,3) = 1; -} - -template void Matrix44::SetDiagonal(const Scalar k) { - setZero(); - ElementAt(0, 0) = k; - ElementAt(1, 1) = k; - ElementAt(2, 2) = k; - ElementAt(3, 3) = 1; -} - -template Matrix44 &Matrix44::SetScale(const Point3 &t) { - SetScale(t[0], t[1], t[2]); - return *this; -} -template Matrix44 &Matrix44::SetScale(const Scalar sx, const Scalar sy, const Scalar sz) { - setZero(); - ElementAt(0, 0) = sx; - ElementAt(1, 1) = sy; - ElementAt(2, 2) = sz; - ElementAt(3, 3) = 1; - return *this; -} - -template Matrix44 &Matrix44::SetTranslate(const Point3 &t) { - SetTranslate(t[0], t[1], t[2]); - return *this; -} -template Matrix44 &Matrix44::SetTranslate(const Scalar tx, const Scalar ty, const Scalar tz) { - Base::setIdentity(); - ElementAt(0, 3) = tx; - ElementAt(1, 3) = ty; - ElementAt(2, 3) = tz; - return *this; -} - -template Matrix44 &Matrix44::SetRotateDeg(Scalar AngleDeg, const Point3 & axis) { - return SetRotateRad(math::ToRad(AngleDeg),axis); -} - -template Matrix44 &Matrix44::SetRotateRad(Scalar AngleRad, const Point3 & axis) { - //angle = angle*(T)3.14159265358979323846/180; e' in radianti! - T c = math::Cos(AngleRad); - T s = math::Sin(AngleRad); - T q = 1-c; - Point3 t = axis; - t.Normalize(); - ElementAt(0,0) = t[0]*t[0]*q + c; - ElementAt(0,1) = t[0]*t[1]*q - t[2]*s; - ElementAt(0,2) = t[0]*t[2]*q + t[1]*s; - ElementAt(0,3) = 0; - ElementAt(1,0) = t[1]*t[0]*q + t[2]*s; - ElementAt(1,1) = t[1]*t[1]*q + c; - ElementAt(1,2) = t[1]*t[2]*q - t[0]*s; - ElementAt(1,3) = 0; - ElementAt(2,0) = t[2]*t[0]*q -t[1]*s; - ElementAt(2,1) = t[2]*t[1]*q +t[0]*s; - ElementAt(2,2) = t[2]*t[2]*q +c; - ElementAt(2,3) = 0; - ElementAt(3,0) = 0; - ElementAt(3,1) = 0; - ElementAt(3,2) = 0; - ElementAt(3,3) = 1; - return *this; -} - -/* Shear Matrixes -XY -1 k 0 0 x x+ky -0 1 0 0 y y -0 0 1 0 z z -0 0 0 1 1 1 - -1 0 k 0 x x+kz -0 1 0 0 y y -0 0 1 0 z z -0 0 0 1 1 1 - -1 1 0 0 x x -0 1 k 0 y y+kz -0 0 1 0 z z -0 0 0 1 1 1 - -*/ - - template Matrix44 & Matrix44::SetShearXY( const Scalar sh) {// shear the X coordinate as the Y coordinate change - Base::setIdentity(); - ElementAt(0,1) = sh; - return *this; - } - - template Matrix44 & Matrix44::SetShearXZ( const Scalar sh) {// shear the X coordinate as the Z coordinate change - Base::setIdentity(); - ElementAt(0,2) = sh; - return *this; - } - - template Matrix44 &Matrix44::SetShearYZ( const Scalar sh) {// shear the Y coordinate as the Z coordinate change - Base::setIdentity(); - ElementAt(1,2) = sh; - return *this; - } - - -/* -Given a non singular, non projective matrix (e.g. with the last row equal to [0,0,0,1] ) -This procedure decompose it in a sequence of - Scale,Shear,Rotation e Translation - -- ScaleV and Tranv are obiviously scaling and translation. -- ShearV contains three scalars with, respectively - ShearXY, ShearXZ e ShearYZ -- RotateV contains the rotations (in degree!) around the x,y,z axis - The input matrix is modified leaving inside it a simple roto translation. - - To obtain the original matrix the above transformation have to be applied in the strict following way: - - OriginalMatrix = Trn * Rtx*Rty*Rtz * ShearYZ*ShearXZ*ShearXY * Scl - -Example Code: -double srv() { return (double(rand()%40)-20)/2.0; } // small random value - - srand(time(0)); - Point3d ScV(10+srv(),10+srv(),10+srv()),ScVOut(-1,-1,-1); - Point3d ShV(srv(),srv(),srv()),ShVOut(-1,-1,-1); - Point3d RtV(10+srv(),srv(),srv()),RtVOut(-1,-1,-1); - Point3d TrV(srv(),srv(),srv()),TrVOut(-1,-1,-1); - - Matrix44d Scl; Scl.SetScale(ScV); - Matrix44d Sxy; Sxy.SetShearXY(ShV[0]); - Matrix44d Sxz; Sxz.SetShearXZ(ShV[1]); - Matrix44d Syz; Syz.SetShearYZ(ShV[2]); - Matrix44d Rtx; Rtx.SetRotate(math::ToRad(RtV[0]),Point3d(1,0,0)); - Matrix44d Rty; Rty.SetRotate(math::ToRad(RtV[1]),Point3d(0,1,0)); - Matrix44d Rtz; Rtz.SetRotate(math::ToRad(RtV[2]),Point3d(0,0,1)); - Matrix44d Trn; Trn.SetTranslate(TrV); - - Matrix44d StartM = Trn * Rtx*Rty*Rtz * Syz*Sxz*Sxy *Scl; - Matrix44d ResultM=StartM; - Decompose(ResultM,ScVOut,ShVOut,RtVOut,TrVOut); - - Scl.SetScale(ScVOut); - Sxy.SetShearXY(ShVOut[0]); - Sxz.SetShearXZ(ShVOut[1]); - Syz.SetShearYZ(ShVOut[2]); - Rtx.SetRotate(math::ToRad(RtVOut[0]),Point3d(1,0,0)); - Rty.SetRotate(math::ToRad(RtVOut[1]),Point3d(0,1,0)); - Rtz.SetRotate(math::ToRad(RtVOut[2]),Point3d(0,0,1)); - Trn.SetTranslate(TrVOut); - - // Now Rebuild is equal to StartM - Matrix44d RebuildM = Trn * Rtx*Rty*Rtz * Syz*Sxz*Sxy * Scl ; -*/ -template -bool Decompose(Matrix44 &M, Point3 &ScaleV, Point3 &ShearV, Point3 &RotV,Point3 &TranV) -{ - if(!(M(3,0)==0 && M(3,1)==0 && M(3,2)==0 && M(3,3)==1) ) // the matrix is projective - return false; - if(math::Abs(M.Determinant())<1e-10) return false; // matrix should be at least invertible... - - // First Step recover the traslation - TranV=M.GetColumn3(3); - - // Second Step Recover Scale and Shearing interleaved - ScaleV[0]=Norm(M.GetColumn3(0)); - Point3 R[3]; - R[0]=M.GetColumn3(0); - R[0].Normalize(); - - ShearV[0]=R[0].dot(M.GetColumn3(1)); // xy shearing - R[1]= M.GetColumn3(1)-R[0]*ShearV[0]; - assert(math::Abs(R[1].dot(R[0]))<1e-10); - ScaleV[1]=Norm(R[1]); // y scaling - R[1]=R[1]/ScaleV[1]; - ShearV[0]=ShearV[0]/ScaleV[1]; - - ShearV[1]=R[0].dot(M.GetColumn3(2)); // xz shearing - R[2]= M.GetColumn3(2)-R[0]*ShearV[1]; - assert(math::Abs(R[2].dot(R[0]))<1e-10); - - R[2] = R[2]-R[1]*(R[2].dot(R[1])); - assert(math::Abs(R[2].dot(R[1]))<1e-10); - assert(math::Abs(R[2].dot(R[0]))<1e-10); - - ScaleV[2]=Norm(R[2]); - ShearV[1]=ShearV[1]/ScaleV[2]; - R[2]=R[2]/ScaleV[2]; - assert(math::Abs(R[2].dot(R[1]))<1e-10); - assert(math::Abs(R[2].dot(R[0]))<1e-10); - - ShearV[2]=R[1].dot(M.GetColumn3(2)); // yz shearing - ShearV[2]=ShearV[2]/ScaleV[2]; - int i,j; - for(i=0;i<3;++i) - for(j=0;j<3;++j) - M(i,j)=R[j][i]; - - // Third and last step: Recover the rotation - //now the matrix should be a pure rotation matrix so its determinant is +-1 - double det=M.Determinant(); - if(math::Abs(det)<1e-10) return false; // matrix should be at least invertible... - assert(math::Abs(math::Abs(det)-1.0)<1e-10); // it should be +-1... - if(det<0) { - ScaleV *= -1; - M *= -1; - } - - double alpha,beta,gamma; // rotations around the x,y and z axis - beta=asin( M(0,2)); - double cosbeta=cos(beta); - if(math::Abs(cosbeta) > 1e-5) - { - alpha=asin(-M(1,2)/cosbeta); - if((M(2,2)/cosbeta) < 0 ) alpha=M_PI-alpha; - gamma=asin(-M(0,1)/cosbeta); - if((M(0,0)/cosbeta)<0) gamma = M_PI-gamma; - } - else - { - alpha=asin(-M(1,0)); - if(M(1,1)<0) alpha=M_PI-alpha; - gamma=0; - } - - RotV[0]=math::ToDeg(alpha); - RotV[1]=math::ToDeg(beta); - RotV[2]=math::ToDeg(gamma); - - return true; -} - -/* -To invert a matrix you can -either invert the matrix inplace calling - -vcg::Invert(yourMatrix); - -or get the inverse matrix of a given matrix without touching it: - -invertedMatrix = vcg::Inverse(untouchedMatrix); - -*/ -template Matrix44 & Invert(Matrix44 &m) { - return m = m.lu().inverse(); -} - -template Matrix44 Inverse(const Matrix44 &m) { - return m.lu().inverse(); -} - -template -struct ei_matrix44_product_impl -{ - typedef typename Other::Scalar Scalar; - typedef typename Eigen::ProductReturnType::Base,Other>::Type ResultType; - static ResultType run(const Matrix44& tr, const Other& other) - { return (static_cast::Base&>(tr)) * other; } -}; - -template -struct ei_matrix44_product_impl -{ - typedef typename Other::Scalar Scalar; - typedef Eigen::Matrix ResultType; - static ResultType run(const Matrix44& tr, const Other& p) - { - Scalar w; - Eigen::Matrix s; - s[0] = tr.ElementAt(0, 0)*p[0] + tr.ElementAt(0, 1)*p[1] + tr.ElementAt(0, 2)*p[2] + tr.ElementAt(0, 3); - s[1] = tr.ElementAt(1, 0)*p[0] + tr.ElementAt(1, 1)*p[1] + tr.ElementAt(1, 2)*p[2] + tr.ElementAt(1, 3); - s[2] = tr.ElementAt(2, 0)*p[0] + tr.ElementAt(2, 1)*p[1] + tr.ElementAt(2, 2)*p[2] + tr.ElementAt(2, 3); - w = tr.ElementAt(3, 0)*p[0] + tr.ElementAt(3, 1)*p[1] + tr.ElementAt(3, 2)*p[2] + tr.ElementAt(3, 3); - if(w!= 0) s /= w; - return s; - } -}; - -} //namespace -#endif - -#endif From 341148b961028a5381c934caf3aa2965562bd1a7 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Tue, 19 Oct 2021 14:16:53 +0200 Subject: [PATCH 071/117] fix matrix44, remove memset from octree.h --- vcg/math/matrix44.h | 1 + vcg/space/index/octree.h | 14 ++++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/vcg/math/matrix44.h b/vcg/math/matrix44.h index bd9d3a69..9bcc0e30 100644 --- a/vcg/math/matrix44.h +++ b/vcg/math/matrix44.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include diff --git a/vcg/space/index/octree.h b/vcg/space/index/octree.h index 25df7310..328ae419 100644 --- a/vcg/space/index/octree.h +++ b/vcg/space/index/octree.h @@ -25,6 +25,7 @@ #define VCG_SPACE_INDEX_OCTREE_H #include +#include #ifdef __glut_h__ #include @@ -212,11 +213,11 @@ namespace vcg public: Octree() { - marks=0; + //marks=0; } ~Octree() { - if(marks) delete []marks; + //if(marks) delete []marks; int node_count = TemplatedOctree::NodeCount(); for (int i=0; i()); std::vector< NodePointer > filled_leaves(placeholder_count); @@ -537,7 +539,7 @@ OBJECT_RETRIEVER: /*! * Markers used to avoid duplication of the same result during a query */ - unsigned char *marks; + std::vector marks; unsigned char global_mark; /*! @@ -561,7 +563,7 @@ OBJECT_RETRIEVER: global_mark = (global_mark+1)%255; if (global_mark == 0) { - memset(&marks[0], 0, sizeof(unsigned char)*int(sorted_dataset.size())); + std::fill(marks.begin(), marks.begin() + sorted_dataset.size(), 0); global_mark++; } };//end of IncrementMark From 0bb69855d96724d781d6a93804eee646d427ec29 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Tue, 19 Oct 2021 14:33:26 +0200 Subject: [PATCH 072/117] removed other memset --- vcg/space/index/octree.h | 1 - vcg/space/index/octree_template.h | 9 ++++++--- wrap/io_trimesh/export_idtf.h | 9 +++++---- wrap/io_trimesh/import_raw.h | 4 +++- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/vcg/space/index/octree.h b/vcg/space/index/octree.h index 328ae419..6815fcd8 100644 --- a/vcg/space/index/octree.h +++ b/vcg/space/index/octree.h @@ -310,7 +310,6 @@ public: global_mark = 1; marks.resize(placeholder_count); std::fill(marks.begin(), marks.end(), 0); - //memset(&marks[0], 0, sizeof(unsigned char)*placeholder_count); std::sort(placeholders.begin(), placeholders.end(), ObjectSorter< NodeType >()); std::vector< NodePointer > filled_leaves(placeholder_count); diff --git a/vcg/space/index/octree_template.h b/vcg/space/index/octree_template.h index 7a2f1d71..96aca827 100644 --- a/vcg/space/index/octree_template.h +++ b/vcg/space/index/octree_template.h @@ -28,6 +28,8 @@ #include #include #include +#include +#include namespace vcg @@ -111,7 +113,7 @@ protected: InnerNode() : Node() {} InnerNode(NodePointer parent, int level) : Node(parent, level) { - memset(&sons[0], 0, 8*sizeof(Node*)); + sons.fill(nullptr); } inline NodePointer &Son(int sonIndex) @@ -125,7 +127,7 @@ protected: return false; } - NodePointer sons[8]; + std::array sons; }; /* @@ -598,7 +600,8 @@ public: assert( boundingBox.min.Y()<=p.Y() && p.Y()<=boundingBox.max.Y() ); assert( boundingBox.min.Z()<=p.Z() && p.Z()<=boundingBox.max.Z() ); - memset(route, NULL, maximumDepth*sizeof(NodePointer)); + for (unsigned int i = 0; i < maximumDepth; ++i) + route[i] = nullptr; CenterType path = CenterType::Construct(Interize(p)); int shift = maximumDepth-1; diff --git a/wrap/io_trimesh/export_idtf.h b/wrap/io_trimesh/export_idtf.h index ac393c40..e711ee61 100644 --- a/wrap/io_trimesh/export_idtf.h +++ b/wrap/io_trimesh/export_idtf.h @@ -159,7 +159,8 @@ public: tga.colourmaptype = 0; tga.imagetype = 2; - memset(tga.colormapspecs,0,5); + for (unsigned int i = 0; i < 5; ++i) + tga.colormapspecs[i] = '\0'; tga.xstart = (short) im.offset().x(); tga.ystart = (short) im.offset().y(); tga.height = (short) im.height(); @@ -180,10 +181,10 @@ public: //is a 8-digits binary number code // always 0 0 | mirroring | bits //(future uses)| image | for alpha-channel - //-------------------------------------------- - // 7 6 | 5 4 | 3 2 1 0 //-------------------------------------------- - // 0 0 | 1 0 | 1 0 0 0 + // 7 6 | 5 4 | 3 2 1 0 + //-------------------------------------------- + // 0 0 | 1 0 | 1 0 0 0 tga.descriptor = (char) 40; tga.bits = (char) 32; } diff --git a/wrap/io_trimesh/import_raw.h b/wrap/io_trimesh/import_raw.h index 44773f55..a617a954 100644 --- a/wrap/io_trimesh/import_raw.h +++ b/wrap/io_trimesh/import_raw.h @@ -347,7 +347,9 @@ static int Open( MESH_TYPE &m, const char * filename, bool triangulate=false, in //read a new line ii=0; - memset( rawline, 0, 512); + for (unsigned int i = 0; i < 512; ++i) + rawline[i] = 0; + //memset( rawline, 0, 512); fread(&(rawline[ii++]),sizeof(char),1,fp); while( (rawline[ii-1] != '\n') && (ii<512) ) { From 9cb1a267fa97f5248092171854672bbbb7999185 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Tue, 19 Oct 2021 14:37:57 +0200 Subject: [PATCH 073/117] fix octree.h, char -> unsigned char --- vcg/space/index/octree.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vcg/space/index/octree.h b/vcg/space/index/octree.h index 6815fcd8..076f0eab 100644 --- a/vcg/space/index/octree.h +++ b/vcg/space/index/octree.h @@ -538,7 +538,7 @@ OBJECT_RETRIEVER: /*! * Markers used to avoid duplication of the same result during a query */ - std::vector marks; + std::vector marks; unsigned char global_mark; /*! From b8bb88063e52fe385f9c930587b3a4bf3212d5fa Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Tue, 19 Oct 2021 15:06:28 +0200 Subject: [PATCH 074/117] remove memcpy from point_matching_scale.h --- vcg/complex/algorithms/point_matching_scale.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/vcg/complex/algorithms/point_matching_scale.h b/vcg/complex/algorithms/point_matching_scale.h index 2acfb2a1..ca14fe38 100644 --- a/vcg/complex/algorithms/point_matching_scale.h +++ b/vcg/complex/algorithms/point_matching_scale.h @@ -93,7 +93,8 @@ public: // rtm = rototranslation RotoTranslation rt; vcg::Matrix44d rtm; - memcpy(&rt._v[0],&x[1],6*sizeof(double)); + for (unsigned int i = 0; i < 6; ++i) + rt._v[i] = x[i+1]; rt.toMatrix(rtm); // res= scaling w.r.t. barycenter @@ -122,7 +123,8 @@ public: RotoTranslation rt; vcg::Matrix44d m; - memcpy(&rt._v[0],&x[1],6*sizeof(double)); + for (unsigned int i = 0; i < 6; ++i) + rt._v[i] = x[i+1]; rt.toMatrix(m); for(; i != mov->end(); ++i,++ifix) { From 93538361062787586622bf0665e10550adfe83d8 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Tue, 19 Oct 2021 15:31:06 +0200 Subject: [PATCH 075/117] remove memcpy on allocate.h --- vcg/complex/allocate.h | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/vcg/complex/allocate.h b/vcg/complex/allocate.h index b4b337d6..ee96b2c9 100644 --- a/vcg/complex/allocate.h +++ b/vcg/complex/allocate.h @@ -2267,8 +2267,10 @@ public: for(size_t i = 0; i < m.vert.size(); ++i){ ATTR_TYPE * dest = &(*_handle)[i]; char * ptr = (char*)( ((SimpleTempDataBase *)pa._handle)->DataBegin()); - memcpy((void*)dest , - (void*) &(ptr[i * pa._sizeof ]) ,sizeof(ATTR_TYPE)); + ATTR_TYPE* attrptr = (ATTR_TYPE*)ptr; + *dest = attrptr[i * pa._sizeof ]; + //memcpy((void*)dest , + //(void*) &(ptr[i * pa._sizeof ]) ,sizeof(ATTR_TYPE)); } // remove the padded container @@ -2294,8 +2296,10 @@ public: for(size_t i = 0; i < m.edge.size(); ++i){ ATTR_TYPE * dest = &(*_handle)[i]; char * ptr = (char*)( ((SimpleTempDataBase *)pa._handle)->DataBegin()); - memcpy((void*)dest , - (void*) &(ptr[i * pa._sizeof ]) ,sizeof(ATTR_TYPE)); + ATTR_TYPE* attrptr = (ATTR_TYPE*)ptr; + *dest = attrptr[i * pa._sizeof ]; + //memcpy((void*)dest , + //(void*) &(ptr[i * pa._sizeof ]) ,sizeof(ATTR_TYPE)); } // remove the padded container @@ -2322,8 +2326,10 @@ public: for(size_t i = 0; i < m.face.size(); ++i){ ATTR_TYPE * dest = &(*_handle)[i]; char * ptr = (char*)( ((SimpleTempDataBase *)pa._handle)->DataBegin()); - memcpy((void*)dest , - (void*) &(ptr[i * pa._sizeof ]) ,sizeof(ATTR_TYPE)); + ATTR_TYPE* attrptr = (ATTR_TYPE*)ptr; + *dest = attrptr[i * pa._sizeof ]; + //memcpy((void*)dest , + // (void*) &(ptr[i * pa._sizeof ]) ,sizeof(ATTR_TYPE)); } // remove the padded container @@ -2352,8 +2358,10 @@ public: { ATTR_TYPE *dest = &(*_handle)[i]; char *ptr = (char *)(((SimpleTempDataBase *)pa._handle)->DataBegin()); - memcpy((void *)dest, - (void *)&(ptr[i * pa._sizeof]), sizeof(ATTR_TYPE)); + ATTR_TYPE* attrptr = (ATTR_TYPE*)ptr; + *dest = attrptr[i * pa._sizeof ]; + //memcpy((void *)dest, + //(void *)&(ptr[i * pa._sizeof]), sizeof(ATTR_TYPE)); } // remove the padded container @@ -2376,8 +2384,11 @@ public: Attribute * _handle = new Attribute(); // copy the padded container in the new one - char * ptr = (char*)( ((Attribute *)pa._handle)->DataBegin()); - memcpy((void*)_handle->DataBegin() ,(void*) &(ptr[0]) ,sizeof(ATTR_TYPE)); + ATTR_TYPE* dest = (ATTR_TYPE*)_handle->DataBegin(); + char* ptr = (char*)( ((Attribute *)pa._handle)->DataBegin()); + ATTR_TYPE* attrptr = (ATTR_TYPE*)ptr; + *dest = *attrptr; + //memcpy((void*)dest ,(void*) &(ptr[0]) ,sizeof(ATTR_TYPE)); // remove the padded container delete ( (Attribute *) pa._handle); From 9dccb764ed42a24fac1a6cb87f4fe33fd764d345 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Tue, 19 Oct 2021 15:46:14 +0200 Subject: [PATCH 076/117] remove memcpy on simple_temporary_data.h --- vcg/container/simple_temporary_data.h | 28 +++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/vcg/container/simple_temporary_data.h b/vcg/container/simple_temporary_data.h index 13db925e..f414bcd7 100644 --- a/vcg/container/simple_temporary_data.h +++ b/vcg/container/simple_temporary_data.h @@ -66,18 +66,22 @@ public: delete[] booldata; } - void reserve(size_t sz) - { - if (sz <= datareserve) - return; - bool *newdataLoc = new bool[sz]; - if (datasize != 0) - memcpy(newdataLoc, booldata, sizeof(bool) * sizeof(datasize)); - std::swap(booldata, newdataLoc); - if (newdataLoc != 0) - delete[] newdataLoc; - datareserve = sz; - } + void reserve(size_t sz) + { + if (sz <= datareserve) + return; + bool* newdataLoc = new bool[sz]; + if (datasize != 0) { + // memcpy(newdataLoc, booldata, sizeof(bool) * sizeof(datasize)); + for (unsigned int i = 0; i < datasize; ++i) + newdataLoc[i] = booldata[i]; + } + + std::swap(booldata, newdataLoc); + if (newdataLoc != 0) + delete[] newdataLoc; + datareserve = sz; + } void resize(size_t sz) { From 78cad04cb96f4c8778de907f64a4eda846048f9d Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Tue, 19 Oct 2021 17:44:19 +0200 Subject: [PATCH 077/117] remove sprintf from plymc.h --- vcg/complex/algorithms/create/plymc/plymc.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/vcg/complex/algorithms/create/plymc/plymc.h b/vcg/complex/algorithms/create/plymc/plymc.h index d01ed870..9d6f5dca 100644 --- a/vcg/complex/algorithms/create/plymc/plymc.h +++ b/vcg/complex/algorithms/create/plymc/plymc.h @@ -173,7 +173,7 @@ public: MeshProvider MP; Parameter p; Volume VV; - char errorMessage[1024]; + std::string errorMessage; /// PLYMC Methods @@ -193,7 +193,7 @@ public: { if(m.FN()==0) { - sprintf(errorMessage,"%sError: mesh has not per vertex normals\n",errorMessage); + errorMessage = "Error: mesh has not per vertex normals\n"; return false; } else @@ -214,7 +214,7 @@ public: tri::Allocator::CompactEveryVector(m); if(badNormalCnt > m.VN()/10) { - sprintf(errorMessage,"%sError: mesh has null normals\n",errorMessage); + errorMessage = "Error: mesh has null normals\n"; return false; } @@ -340,7 +340,7 @@ public: bool Process(vcg::CallBackPos *cb=0) { - sprintf(errorMessage,"%s", ""); + errorMessage = ""; printf("bbox scanning...\n"); fflush(stdout); Matrix44f Id; Id.SetIdentity(); MP.InitBBox(); @@ -419,7 +419,7 @@ bool Process(vcg::CallBackPos *cb=0) res = InitMesh(*sm,MP.MeshName(i).c_str(),MP.Tr(i)); if(!res) { - sprintf(errorMessage,"%sFailed Init of mesh %s\n",errorMessage,MP.MeshName(i).c_str()); + errorMessage = "Failed Init of mesh " +MP.MeshName(i); return false ; } } From 10e8502717ef68230f085affe797dc237dffd533 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Tue, 19 Oct 2021 18:25:28 +0200 Subject: [PATCH 078/117] remove sprintf from hole.h, plymc.h and volume.h --- vcg/complex/algorithms/create/plymc/plymc.h | 6 +++--- vcg/complex/algorithms/create/plymc/volume.h | 8 ++++---- vcg/complex/algorithms/hole.h | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/vcg/complex/algorithms/create/plymc/plymc.h b/vcg/complex/algorithms/create/plymc/plymc.h index 9d6f5dca..c90f233d 100644 --- a/vcg/complex/algorithms/create/plymc/plymc.h +++ b/vcg/complex/algorithms/create/plymc/plymc.h @@ -597,7 +597,6 @@ int MCSimplify( MeshType &m, float absoluteError, bool preserveBB, vcg::CallBack //qDebug("Simplifying at absoluteError=%f",absoluteError); float TargetError = absoluteError; - char buf[1024]; DeciSession.template Init< MyColl > (); pp.areaThr=TargetError*TargetError; @@ -605,8 +604,9 @@ int MCSimplify( MeshType &m, float absoluteError, bool preserveBB, vcg::CallBack if(TargetError < std::numeric_limits::max() ) DeciSession.SetTargetMetric(TargetError); while(DeciSession.DoOptimization() && DeciSession.currMetric < TargetError) { - sprintf(buf,"Simplyfing %7i err %9g \r",m.fn,DeciSession.currMetric); - if (cb) cb(int(100.0f*DeciSession.currMetric/TargetError),buf); + std::string buf = "Simplyfing " + std::to_string(m.fn) + " err " + std::to_string(DeciSession.currMetric) + " \r"; + if (cb) + cb(int(100.0f*DeciSession.currMetric/TargetError),buf.c_str()); } return 1; //success diff --git a/vcg/complex/algorithms/create/plymc/volume.h b/vcg/complex/algorithms/create/plymc/volume.h index 0a9ba7fc..8f654ee9 100644 --- a/vcg/complex/algorithms/create/plymc/volume.h +++ b/vcg/complex/algorithms/create/plymc/volume.h @@ -42,7 +42,7 @@ const char *SFormat( const char * f, ... ) static char buf[4096]; va_list marker; va_start( marker, f ); - vsprintf(buf,f,marker); + vsnprintf(buf,4096,f,marker); va_end( marker ); return buf; } @@ -301,9 +301,9 @@ public: void GetSubVolumeTag(std::string &subtag) { char buf[32]; - if (div[0]<= 10 && div[1]<= 10 && div[2]<= 10 ) sprintf(buf,"_%01d%01d%01d",pos[0],pos[1],pos[2]); - else if(div[0]<= 100 && div[1]<= 100 && div[2]<= 100 ) sprintf(buf,"_%02d%02d%02d",pos[0],pos[1],pos[2]); - else sprintf(buf,"_%03d%03d%03d",pos[0],pos[1],pos[2]); + if (div[0]<= 10 && div[1]<= 10 && div[2]<= 10 ) snprintf(buf,32,"_%01d%01d%01d",pos[0],pos[1],pos[2]); + else if(div[0]<= 100 && div[1]<= 100 && div[2]<= 100 ) snprintf(buf,32,"_%02d%02d%02d",pos[0],pos[1],pos[2]); + else snprintf(buf,32,"_%03d%03d%03d",pos[0],pos[1],pos[2]); subtag=buf; } diff --git a/vcg/complex/algorithms/hole.h b/vcg/complex/algorithms/hole.h index ecb2256b..70e6aae7 100644 --- a/vcg/complex/algorithms/hole.h +++ b/vcg/complex/algorithms/hole.h @@ -291,8 +291,8 @@ public: typename MESH::ScalarType aspectRatio; const char * Dump() { static char buf[200]; - if(this->IsConcave()) sprintf(buf,"Dihedral -(deg) %6.2f Quality %6.2f\n",math::ToDeg(dihedralRad),aspectRatio); - else sprintf(buf,"Dihedral (deg) %6.2f Quality %6.2f\n",math::ToDeg(dihedralRad),aspectRatio); + if(this->IsConcave()) snprintf(buf,200,"Dihedral -(deg) %6.2f Quality %6.2f\n",math::ToDeg(dihedralRad),aspectRatio); + else snprintf(buf,200,"Dihedral (deg) %6.2f Quality %6.2f\n",math::ToDeg(dihedralRad),aspectRatio); return buf; } From feb2f2c3bce2d3a44aac45d515ac57fada2193a8 Mon Sep 17 00:00:00 2001 From: Paolo Cignoni Date: Tue, 19 Oct 2021 18:56:48 +0200 Subject: [PATCH 079/117] removed memset from isosurfacing classes --- .../algorithms/create/mc_trivial_walker.h | 46 +++++------ vcg/complex/algorithms/create/resampler.h | 77 ++++++++++++------- 2 files changed, 69 insertions(+), 54 deletions(-) diff --git a/vcg/complex/algorithms/create/mc_trivial_walker.h b/vcg/complex/algorithms/create/mc_trivial_walker.h index 8a745560..ac670fe7 100644 --- a/vcg/complex/algorithms/create/mc_trivial_walker.h +++ b/vcg/complex/algorithms/create/mc_trivial_walker.h @@ -166,12 +166,11 @@ private: { _bbox = subbox; _slice_dimension = _bbox.DimX()*_bbox.DimZ(); - - _x_cs = new VertexIndex[ _slice_dimension ]; - _y_cs = new VertexIndex[ _slice_dimension ]; - _z_cs = new VertexIndex[ _slice_dimension ]; - _x_ns = new VertexIndex[ _slice_dimension ]; - _z_ns = new VertexIndex[ _slice_dimension ]; + _x_cs.resize(_slice_dimension); + _y_cs.resize(_slice_dimension); + _z_cs.resize(_slice_dimension); + _x_ns.resize(_slice_dimension); + _z_ns.resize(_slice_dimension); } TrivialWalker() @@ -321,23 +320,22 @@ protected: int _slice_dimension; int _current_slice; - - VertexIndex *_x_cs; // indici dell'intersezioni della superficie lungo gli Xedge della fetta corrente - VertexIndex *_y_cs; // indici dell'intersezioni della superficie lungo gli Yedge della fetta corrente - VertexIndex *_z_cs; // indici dell'intersezioni della superficie lungo gli Zedge della fetta corrente - VertexIndex *_x_ns; // indici dell'intersezioni della superficie lungo gli Xedge della prossima fetta - VertexIndex *_z_ns; // indici dell'intersezioni della superficie lungo gli Zedge della prossima fetta + + std::vector _x_cs; // indici dell'intersezioni della superficie lungo gli Xedge della fetta corrente + std::vector _y_cs; // indici dell'intersezioni della superficie lungo gli Yedge della fetta corrente + std::vector _z_cs; // indici dell'intersezioni della superficie lungo gli Zedge della fetta corrente + std::vector _x_ns; // indici dell'intersezioni della superficie lungo gli Xedge della prossima fetta + std::vector _z_ns; // indici dell'intersezioni della superficie lungo gli Zedge della prossima fetta MeshType *_mesh; VolumeType *_volume; - - float _thr; + + float _thr; void NextYSlice() { - memset(_x_cs, -1, _slice_dimension*sizeof(VertexIndex)); - memset(_y_cs, -1, _slice_dimension*sizeof(VertexIndex)); - memset(_z_cs, -1, _slice_dimension*sizeof(VertexIndex)); - + std::fill(_x_cs.begin(),_x_cs.end(),-1); + std::fill(_y_cs.begin(),_y_cs.end(),-1); + std::fill(_z_cs.begin(),_z_cs.end(),-1); std::swap(_x_cs, _x_ns); std::swap(_z_cs, _z_ns); @@ -347,13 +345,11 @@ protected: void Begin() { _current_slice = _bbox.min.Y(); - - memset(_x_cs, -1, _slice_dimension*sizeof(VertexIndex)); - memset(_y_cs, -1, _slice_dimension*sizeof(VertexIndex)); - memset(_z_cs, -1, _slice_dimension*sizeof(VertexIndex)); - memset(_x_ns, -1, _slice_dimension*sizeof(VertexIndex)); - memset(_z_ns, -1, _slice_dimension*sizeof(VertexIndex)); - + std::fill(_x_cs.begin(),_x_cs.end(),-1); + std::fill(_y_cs.begin(),_y_cs.end(),-1); + std::fill(_z_cs.begin(),_z_cs.end(),-1); + std::fill(_x_ns.begin(),_x_ns.end(),-1); + std::fill(_z_ns.begin(),_z_ns.end(),-1); } }; } // end namespace tri diff --git a/vcg/complex/algorithms/create/resampler.h b/vcg/complex/algorithms/create/resampler.h index edf9eae5..94a484ec 100644 --- a/vcg/complex/algorithms/create/resampler.h +++ b/vcg/complex/algorithms/create/resampler.h @@ -74,19 +74,22 @@ class Resampler : public BasicGrid //typedef tri::FaceTmark MarkerFace; typedef vcg::tri::EmptyTMark MarkerFace; MarkerFace markerFunctor; - - VertexIndex *_x_cs; // indici dell'intersezioni della superficie lungo gli Xedge della fetta corrente - VertexIndex *_y_cs; // indici dell'intersezioni della superficie lungo gli Yedge della fetta corrente - VertexIndex *_z_cs; // indici dell'intersezioni della superficie lungo gli Zedge della fetta corrente - VertexIndex *_x_ns; // indici dell'intersezioni della superficie lungo gli Xedge della prossima fetta - VertexIndex *_z_ns; // indici dell'intersezioni della superficie lungo gli Zedge della prossima fetta + + std::vector _x_cs; // indici dell'intersezioni della superficie lungo gli Xedge della fetta corrente + std::vector _y_cs; // indici dell'intersezioni della superficie lungo gli Yedge della fetta corrente + std::vector _z_cs; // indici dell'intersezioni della superficie lungo gli Zedge della fetta corrente + std::vector _x_ns; // indici dell'intersezioni della superficie lungo gli Xedge della prossima fetta + std::vector _z_ns; // indici dell'intersezioni della superficie lungo gli Zedge della prossima fetta //float *_v_cs;///values of distance fields for each direction in current slice //float *_v_ns;///values of distance fields for each direction in next slice typedef typename std::pair field_value; - field_value* _v_cs; - field_value* _v_ns; + std::vector _v_cs; + std::vector _v_ns; + +// field_value* _v_cs; +// field_value* _v_ns; NewMeshType *_newM; OldMeshType *_oldM; @@ -110,15 +113,22 @@ class Resampler : public BasicGrid DiscretizeFlag=false; MultiSampleFlag=false; AbsDistFlag=false; - - _x_cs = new VertexIndex[ SliceSize ]; - _y_cs = new VertexIndex[ SliceSize ]; - _z_cs = new VertexIndex[ SliceSize ]; - _x_ns = new VertexIndex[ SliceSize ]; - _z_ns = new VertexIndex[ SliceSize ]; - - _v_cs= new field_value[(this->siz.X()+1)*(this->siz.Z()+1)]; - _v_ns= new field_value[(this->siz.X()+1)*(this->siz.Z()+1)]; + + _x_cs.resize(SliceSize); + _y_cs.resize(SliceSize); + _z_cs.resize(SliceSize); + _x_ns.resize(SliceSize); + _z_ns.resize(SliceSize); +// _x_cs = new VertexIndex[ SliceSize ]; +// _y_cs = new VertexIndex[ SliceSize ]; +// _z_cs = new VertexIndex[ SliceSize ]; +// _x_ns = new VertexIndex[ SliceSize ]; +// _z_ns = new VertexIndex[ SliceSize ]; + + _v_cs.resize((this->siz.X()+1)*(this->siz.Z()+1)); + _v_ns.resize((this->siz.X()+1)*(this->siz.Z()+1)); +// _v_cs= new field_value[(this->siz.X()+1)*(this->siz.Z()+1)]; +// _v_ns= new field_value[(this->siz.X()+1)*(this->siz.Z()+1)]; }; @@ -232,7 +242,7 @@ class Resampler : public BasicGrid /// compute the values if an entire slice (per y) distances>dig of a cell are signed with double of /// the distance of the bb - void ComputeSliceValues(int slice,field_value *slice_values) + void ComputeSliceValues(int slice,std::vector &slice_values) { #pragma omp parallel for schedule(dynamic, 10) for (int i=0; i<=this->siz.X(); i++) @@ -252,7 +262,7 @@ class Resampler : public BasicGrid For some reasons it can happens that the sign of the computed distance could not correct. this function tries to correct these issues by flipping the isolated voxels with discordant sign */ - void ComputeConsensus(int /*slice*/, field_value *slice_values) + void ComputeConsensus(int /*slice*/, std::vector &slice_values) { float max_dist = min(min(this->voxel[0],this->voxel[1]),this->voxel[2]); int flippedCnt=0; @@ -363,10 +373,13 @@ class Resampler : public BasicGrid //swap slices , the initial value of distance fields ids set as double of bbox of space void NextSlice() { - - memset(_x_cs, -1, SliceSize*sizeof(VertexIndex)); - memset(_y_cs, -1, SliceSize*sizeof(VertexIndex)); - memset(_z_cs, -1, SliceSize*sizeof(VertexIndex)); + + std::fill(_x_cs.begin(),_x_cs.end(),-1); + std::fill(_y_cs.begin(),_y_cs.end(),-1); + std::fill(_z_cs.begin(),_z_cs.end(),-1); +// memset(_x_cs, -1, SliceSize*sizeof(VertexIndex)); +// memset(_y_cs, -1, SliceSize*sizeof(VertexIndex)); +// memset(_z_cs, -1, SliceSize*sizeof(VertexIndex)); std::swap(_x_cs, _x_ns); @@ -384,12 +397,18 @@ class Resampler : public BasicGrid { CurrentSlice = 0; - - memset(_x_cs, -1, SliceSize*sizeof(VertexIndex)); - memset(_y_cs, -1, SliceSize*sizeof(VertexIndex)); - memset(_z_cs, -1, SliceSize*sizeof(VertexIndex)); - memset(_x_ns, -1, SliceSize*sizeof(VertexIndex)); - memset(_z_ns, -1, SliceSize*sizeof(VertexIndex)); + + std::fill(_x_cs.begin(),_x_cs.end(),-1); + std::fill(_y_cs.begin(),_y_cs.end(),-1); + std::fill(_z_cs.begin(),_z_cs.end(),-1); + std::fill(_x_ns.begin(),_x_ns.end(),-1); + std::fill(_z_ns.begin(),_z_ns.end(),-1); + +// memset(_x_cs, -1, SliceSize*sizeof(VertexIndex)); +// memset(_y_cs, -1, SliceSize*sizeof(VertexIndex)); +// memset(_z_cs, -1, SliceSize*sizeof(VertexIndex)); +// memset(_x_ns, -1, SliceSize*sizeof(VertexIndex)); +// memset(_z_ns, -1, SliceSize*sizeof(VertexIndex)); ComputeSliceValues(CurrentSlice,_v_cs); ComputeSliceValues(CurrentSlice+1,_v_ns); From 875d659719024c64431d07046130d271be1f9ec2 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Wed, 20 Oct 2021 08:48:06 +0200 Subject: [PATCH 080/117] remove sprintf from edge collapse algorithms --- .../algorithms/local_optimization/quad_diag_collapse.h | 9 ++++++--- .../algorithms/local_optimization/tri_edge_collapse.h | 9 ++++++--- .../algorithms/local_optimization/tri_edge_flip.h | 9 ++++++--- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/vcg/complex/algorithms/local_optimization/quad_diag_collapse.h b/vcg/complex/algorithms/local_optimization/quad_diag_collapse.h index 94d65353..f2dea23a 100755 --- a/vcg/complex/algorithms/local_optimization/quad_diag_collapse.h +++ b/vcg/complex/algorithms/local_optimization/quad_diag_collapse.h @@ -358,9 +358,12 @@ namespace vcg{ virtual const char *Info(MeshType &m) { - static char buf[60]; - sprintf(buf,"(%d - %d) %g\n", hp->HVp()-&m.vert[0], hp->HNp()->HNp()->HVp()-&m.vert[0], -_priority); - return buf; + static std::string msg; + msg = + "(" + std::to_string(hp->HVp()-&m.vert[0]) + + " - " + std::to_string(hp->HNp()->HNp()->HVp()-&m.vert[0]) + + ") " + std::to_string(-_priority) + "\n"; + return msg.c_str(); } /*! diff --git a/vcg/complex/algorithms/local_optimization/tri_edge_collapse.h b/vcg/complex/algorithms/local_optimization/tri_edge_collapse.h index 309210da..0a4a8693 100644 --- a/vcg/complex/algorithms/local_optimization/tri_edge_collapse.h +++ b/vcg/complex/algorithms/local_optimization/tri_edge_collapse.h @@ -115,9 +115,12 @@ public: virtual const char *Info(TriMeshType &m) { mt = &m; - static char buf[60]; - sprintf(buf,"%i -> %i %g\n", int(pos.V(0)-&m.vert[0]), int(pos.V(1)-&m.vert[0]),-_priority); - return buf; + static std::string msg; + msg = + std::to_string(int(pos.V(0)-&m.vert[0])) + " -> " + + std::to_string(int(pos.V(1)-&m.vert[0])) + + " " + std::to_string(-_priority) + "\n"; + return msg.c_str(); } inline void Execute(TriMeshType &m, BaseParameterClass *) diff --git a/vcg/complex/algorithms/local_optimization/tri_edge_flip.h b/vcg/complex/algorithms/local_optimization/tri_edge_flip.h index 29f26b5f..2ad4d64e 100644 --- a/vcg/complex/algorithms/local_optimization/tri_edge_flip.h +++ b/vcg/complex/algorithms/local_optimization/tri_edge_flip.h @@ -283,9 +283,12 @@ public: */ const char* Info(TRIMESH_TYPE &m) { - static char dump[60]; - sprintf(dump,"%zu -> %zu %g\n", tri::Index(m,_pos.F()->V(0)), tri::Index(m,_pos.F()->V(1)),-_priority); - return dump; + static std::string msg; + msg = + std::to_string(tri::Index(m,_pos.F()->V(0))) + " -> " + + std::to_string(tri::Index(m,_pos.F()->V(1))) + + " " + std::to_string(-_priority) + "\n"; + return msg.c_str(); } /*! From 4d6c87c579ea022c7468f9525b1adffd9daa5ac4 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Wed, 20 Oct 2021 09:38:07 +0200 Subject: [PATCH 081/117] remove sprintf from meshtree and perfect_sparial_hashing --- vcg/complex/algorithms/meshtree.h | 26 ++++++++++++++--------- vcg/space/index/perfect_spatial_hashing.h | 2 +- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/vcg/complex/algorithms/meshtree.h b/vcg/complex/algorithms/meshtree.h index de9f12a8..42c21c2f 100644 --- a/vcg/complex/algorithms/meshtree.h +++ b/vcg/complex/algorithms/meshtree.h @@ -128,8 +128,9 @@ namespace vcg { void Process(vcg::AlignPair::Param& ap, MeshTree::Param& mtp) { std::array buf; - std::sprintf( + std::snprintf( buf.data(), + 1024, "Starting Processing of %i glued meshes out of %zu meshes\n", gluedNum(), nodeMap.size()); @@ -137,7 +138,7 @@ namespace vcg { /******* Occupancy Grid Computation *************/ buf.fill('\0'); - std::sprintf(buf.data(), "Computing Overlaps %i glued meshes...\n", gluedNum()); + std::snprintf(buf.data(), 1024, "Computing Overlaps %i glued meshes...\n", gluedNum()); cb(0, buf.data()); OG.Init( @@ -196,8 +197,9 @@ namespace vcg { // if there are no arcs at all complain and return if (totalArcNum == 0) { buf.fill('\0'); - std::sprintf( + std::snprintf( buf.data(), + 1024, "\n Failure. There are no overlapping meshes?\n No candidate alignment arcs. " "Nothing Done.\n"); cb(0, buf.data()); @@ -210,12 +212,12 @@ namespace vcg { num_max_thread = omp_get_max_threads(); #endif buf.fill('\0'); - std::sprintf( - buf.data(), "Arc with good overlap %6zu (on %6zu)\n", totalArcNum, OG.SVA.size()); + std::snprintf( + buf.data(), 1024,"Arc with good overlap %6zu (on %6zu)\n", totalArcNum, OG.SVA.size()); cb(0, buf.data()); buf.fill('\0'); - std::sprintf(buf.data(), " %6i preserved %i Recalc \n", preservedArcNum, recalcArcNum); + std::snprintf(buf.data(), 1024," %6i preserved %i Recalc \n", preservedArcNum, recalcArcNum); cb(0, buf.data()); bool hasValidAlign = false; @@ -244,8 +246,9 @@ namespace vcg { #pragma omp critical buf.fill('\0'); - std::sprintf( + std::snprintf( buf.data(), + 1024, "(%3i/%3zu) %2i -> %2i Aligned AvgErr dd=%f -> dd=%f \n", i + 1, totalArcNum, @@ -258,8 +261,9 @@ namespace vcg { else { #pragma omp critical buf.fill('\0'); - std::sprintf( + std::snprintf( buf.data(), + 1024, "(%3i/%3zu) %2i -> %2i Failed Alignment of one arc %s\n", i + 1, totalArcNum, @@ -274,8 +278,9 @@ namespace vcg { // if there are no valid arcs complain and return if (!hasValidAlign) { buf.fill('\0'); - std::sprintf( + std::snprintf( buf.data(), + 1024, "\n Failure. No successful arc among candidate Alignment arcs. Nothing " "Done.\n"); cb(0, buf.data()); @@ -289,8 +294,9 @@ namespace vcg { } buf.fill('\0'); - std::sprintf( + std::snprintf( buf.data(), + 1024, "Completed Mesh-Mesh Alignment: Avg Err %5.3f; Median %5.3f; 90%% %5.3f\n", H.Avg(), H.Percentile(0.5f), diff --git a/vcg/space/index/perfect_spatial_hashing.h b/vcg/space/index/perfect_spatial_hashing.h index bbcbdef9..cf253bc0 100644 --- a/vcg/space/index/perfect_spatial_hashing.h +++ b/vcg/space/index/perfect_spatial_hashing.h @@ -1462,7 +1462,7 @@ namespace vcg m_OffsetTable.GetPreImageSortedPerCardinality(preimage_slots); char msg[128]; - sprintf(msg, "Building offset table of resolution %d", m_OffsetTable.GetSize()); + snprintf(msg, 128, "Building offset table of resolution %d", m_OffsetTable.GetSize()); int step = int(preimage_slots.size())/100; int number_of_slots = int(preimage_slots.size()); int perc = 0; From 412c904a179357d52d511fa6fb2b1503eab77a7d Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Wed, 20 Oct 2021 10:29:25 +0200 Subject: [PATCH 082/117] remove fscanf from outline2_packer.h --- vcg/space/outline2_packer.h | 41 ++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/vcg/space/outline2_packer.h b/vcg/space/outline2_packer.h index 5343ad0b..384bfda6 100644 --- a/vcg/space/outline2_packer.h +++ b/vcg/space/outline2_packer.h @@ -1,4 +1,4 @@ -/**************************************************************************** +/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * @@ -24,6 +24,7 @@ #define __VCG_OUTLINE2_PACKER_H__ #include +#include #include #include #include @@ -212,26 +213,24 @@ static bool WritePolyVec(const std::vector< std::vector > &polyVec, con static bool ReadPolyVec(std::vector< std::vector > &polyVec, const char *filename) { - FILE *fp=fopen(filename,"r"); - if(!fp) return false; - int sz; - fscanf(fp,"%i\n",&sz); - polyVec.clear(); - polyVec.resize(sz); - for(size_t i=0;i> sz; + polyVec.resize(sz); + for (std::size_t i = 0; i < sz; ++i){ + int isz; + ifs >> isz; + polyVec[i].resize(isz); + for (std::size_t j = 0; j < isz; ++j){ + float x, y; + ifs >> x >> y; + polyVec[i][j].X() = x; + polyVec[i][j].Y() = y; + } + } + ifs.close(); + return true; } From 18e841e3d029e195efd850b45b96225bfbffe401 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Wed, 20 Oct 2021 11:27:02 +0200 Subject: [PATCH 083/117] fix import_dae, see #24 --- wrap/io_trimesh/import_dae.h | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/wrap/io_trimesh/import_dae.h b/wrap/io_trimesh/import_dae.h index b4e0e09b..0dcaaa6f 100644 --- a/wrap/io_trimesh/import_dae.h +++ b/wrap/io_trimesh/import_dae.h @@ -397,14 +397,33 @@ namespace io { } // ind_txt = indexTextureByImgNode(*(info.doc),txt_node); } - int faceAttributeNum = triNodeList.at(tript).toElement().elementsByTagName("input").size(); + int triangleNumber = triNodeList.at(tript).toElement().attribute("count").toInt(); + + // A triangle can have multiple inputs that share a common offset. Therefore it's + // not sufficient to take the number of input to derive the stride from triangle to + // triangle. Instead, this heuristic uses the maximal offset found among inputs. + QDomNodeList attributes = triNodeList.at(tript).toElement().elementsByTagName("input"); + int numTriangleAttributeIndices = 0; + for (int i = 0; i < attributes.size(); ++i) { + QDomNode attr = attributes.at(i); + int offset = attr.toElement().attribute("offset", "-1").toInt(); + numTriangleAttributeIndices = std::max(numTriangleAttributeIndices, offset+1); + } QStringList face; valueStringList(face,triNodeList.at(tript),"p"); + + // Ensure that the

array size is consistent with the number of triangles and the + // exprected stride. + if (face.size() != 3 * triangleNumber * numTriangleAttributeIndices) { + QDEBUG("********* ERROR triangle count is inconsistent with input offsets and face index list"); + return E_INCOMPATIBLECOLLADA141FORMAT; + } + int offsetface = (int)m.face.size(); if (face.size() != 0) { - vcg::tri::Allocator::AddFaces(m,face.size() / (faceAttributeNum * 3)); + vcg::tri::Allocator::AddFaces(m, triangleNumber); WedgeAttribute wa; FindStandardWedgeAttributes(wa,triNodeList.at(tript),*(info.doc)); @@ -430,7 +449,7 @@ namespace io { WedgeTextureAttribute(m,face,ind_txt,wa.wt,wa.wtsrc,ff,jj + wa.offtx,tt,wa.stridetx); } - jj += faceAttributeNum; + jj += numTriangleAttributeIndices; } if( ! ( (m.face[ff].V(0) != m.face[ff].V(1)) && (m.face[ff].V(0) != m.face[ff].V(2)) && @@ -589,8 +608,13 @@ namespace io { } } - if (isTri && tripatch.isEmpty()) + if (isTri && tripatch.isEmpty()) { tripatch=polylist; + // Clear the polylist. Otherwise faces are loaded twice, once by + // LoadTriangularMesh and another time by LoadPolygonalListMesh. + polylist = QDomNodeList(); + } + if (tripatch.isEmpty() && polypatch.isEmpty() && polylist.isEmpty()) return E_NOPOLYGONALMESH; From 91dcfaa3062089b83cc7efcea14939daf5a02813 Mon Sep 17 00:00:00 2001 From: Christian Rauch Date: Tue, 19 Oct 2021 20:14:18 +0100 Subject: [PATCH 084/117] fix typo in PLY loader error message --- wrap/io_trimesh/export_ply.h | 2 +- wrap/io_trimesh/import_ply.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/wrap/io_trimesh/export_ply.h b/wrap/io_trimesh/export_ply.h index 3823c337..95d52350 100644 --- a/wrap/io_trimesh/export_ply.h +++ b/wrap/io_trimesh/export_ply.h @@ -923,7 +923,7 @@ public: ply_error_msg[PlyInfo::E_NO_VERTEX ]="No vertex field found"; ply_error_msg[PlyInfo::E_NO_FACE ]="No face field found"; - ply_error_msg[PlyInfo::E_SHORTFILE ]="Unespected eof"; + ply_error_msg[PlyInfo::E_SHORTFILE ]="Unexpected EOF"; ply_error_msg[PlyInfo::E_NO_3VERTINFACE ]="Face with more than 3 vertices"; ply_error_msg[PlyInfo::E_BAD_VERT_INDEX ]="Bad vertex index in face"; ply_error_msg[PlyInfo::E_NO_6TCOORD ]="Face with no 6 texture coordinates"; diff --git a/wrap/io_trimesh/import_ply.h b/wrap/io_trimesh/import_ply.h index d94dc5fa..ab6bda9c 100644 --- a/wrap/io_trimesh/import_ply.h +++ b/wrap/io_trimesh/import_ply.h @@ -328,7 +328,7 @@ public: ply_error_msg[PlyInfo::E_NO_VERTEX ]="No vertex field found"; ply_error_msg[PlyInfo::E_NO_FACE ]="No face field found"; - ply_error_msg[PlyInfo::E_SHORTFILE ]="Unespected eof"; + ply_error_msg[PlyInfo::E_SHORTFILE ]="Unexpected EOF"; ply_error_msg[PlyInfo::E_NO_3VERTINFACE ]="Face with more than 3 vertices"; ply_error_msg[PlyInfo::E_BAD_VERT_INDEX ]="Bad vertex index in face"; ply_error_msg[PlyInfo::E_BAD_VERT_INDEX_EDGE ]="Bad vertex index in edge"; From 8e7ec453bb0e6f62cc10e1d79ce8536ffa376a14 Mon Sep 17 00:00:00 2001 From: Christian Rauch Date: Tue, 19 Oct 2021 20:30:42 +0100 Subject: [PATCH 085/117] fix typos in pull request template --- .github/pull_request_template.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index e81cb6a9..1b246c9a 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,4 +1,4 @@ -## Thank you for sending a Pull Request to the VCGLib! +## Thank you for sending a Pull Request to the VCGLib! VCGLib is fully owned by CNR, and all the VCGLib contributors that do not work at the VCLab of CNR must first sign the contributor license agreement that you can find at the following link: https://github.com/cnr-isti-vclab/vcglib/blob/devel/docs/ContributorLicenseAgreement.pdf @@ -6,9 +6,9 @@ If you will sign the CLA, then we will be able to merge your pull request after Please send the signed document to muntoni.alessandro@gmail.com and paolo.cignoni@isti.cnr.it . If you will not sign the CLA, we will review and then apply your changes as soon as possible. -Before opening the PR, please leave the follwing form with a check for your particluar case: +Before opening the PR, please leave the following form with a check for your particular case: ##### Check with `[x]` what is your case: - [ ] I already signed and sent via email the CLA; -- [ ] I wil sign and send the CLA via email as soon as possible; -- [ ] I don't want to sign the CLA. \ No newline at end of file +- [ ] I will sign and send the CLA via email as soon as possible; +- [ ] I don't want to sign the CLA. From 08487711d6b43d6a6a3cffc972ed49fc954069db Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Wed, 20 Oct 2021 18:36:34 +0200 Subject: [PATCH 086/117] better copy in simple temporary data --- vcg/container/simple_temporary_data.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/vcg/container/simple_temporary_data.h b/vcg/container/simple_temporary_data.h index f414bcd7..8fd50011 100644 --- a/vcg/container/simple_temporary_data.h +++ b/vcg/container/simple_temporary_data.h @@ -72,9 +72,8 @@ public: return; bool* newdataLoc = new bool[sz]; if (datasize != 0) { + std::copy(booldata, booldata+datasize, newdataLoc); // memcpy(newdataLoc, booldata, sizeof(bool) * sizeof(datasize)); - for (unsigned int i = 0; i < datasize; ++i) - newdataLoc[i] = booldata[i]; } std::swap(booldata, newdataLoc); From 138b35eb06edd937954b295cc66b93c1afccfcb1 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Thu, 21 Oct 2021 17:00:03 +0200 Subject: [PATCH 087/117] update CLA --- docs/ContributorLicenseAgreement.md | 7 ++----- docs/ContributorLicenseAgreement.pdf | Bin 45779 -> 45891 bytes 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/docs/ContributorLicenseAgreement.md b/docs/ContributorLicenseAgreement.md index 994c4e2f..20215eef 100644 --- a/docs/ContributorLicenseAgreement.md +++ b/docs/ContributorLicenseAgreement.md @@ -8,7 +8,7 @@ The following terms are used throughout this agreement: * **Submitted** - conveyed to a Project via a pull request, commit, issue, or any form of electronic, written, or verbal communication with GitHub, contributors or maintainers. ## 1. Grant of Copyright License. -Subject to the terms and conditions of this agreement, You grant to the Projects’ maintainers and to VCLab a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute Your contributions and such derivative works. Except for this license, You reserve all rights, title, and interest in your contributions. +Subject to the terms and conditions of this agreement, You grant to the Projects’ maintainers and to VCLab a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute Your contributions and such derivative works. Except for this license, You reserve all rights, title, and interest in your contributions. You agree that your perpetual licensing grant will be applied to all Your contributions to VCLab's Projects during the validity (two years) of this agreement. ## 2. Grant of Patent License. Subject to the terms and conditions of this agreement, You grant to the Projects’ maintainers and to VCLab a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer your contributions, where such license applies only to those patent claims licensable by you that are necessarily infringed by your contribution or by combination of your contribution with the project to which this contribution was submitted. @@ -25,9 +25,7 @@ Your contribution is either your original creation, based upon previous work tha   |   **Email** | **Physical home/office address**  |  -**Date of birth** | **Place of birth** -  |   -**github Project Contributed** | **Contribution** (id of the pull request) +**Date of birth** | **Place of birth**   |   @@ -37,4 +35,3 @@ Signature Date --- - diff --git a/docs/ContributorLicenseAgreement.pdf b/docs/ContributorLicenseAgreement.pdf index daa1cefc65b5e2f74186378d976d29bbc7d54fe0..c56c6392a9977b31d62ac6bc3f91565aea6ddfd5 100644 GIT binary patch delta 39679 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 aV*>K Date: Thu, 21 Oct 2021 17:14:44 +0200 Subject: [PATCH 088/117] update PR template --- .github/pull_request_template.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 1b246c9a..15f9de14 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -3,6 +3,7 @@ VCGLib is fully owned by CNR, and all the VCGLib contributors that do not work at the VCLab of CNR must first sign the contributor license agreement that you can find at the following link: https://github.com/cnr-isti-vclab/vcglib/blob/devel/docs/ContributorLicenseAgreement.pdf If you will sign the CLA, then we will be able to merge your pull request after reviewing it. +The validity of the CLA is two years, therefore after signing it your PRs for the next two years can be merged without further actions. Please send the signed document to muntoni.alessandro@gmail.com and paolo.cignoni@isti.cnr.it . If you will not sign the CLA, we will review and then apply your changes as soon as possible. From 2fbc872228f782ae451cae312ab13de7d0576040 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Fri, 22 Oct 2021 12:36:41 +0200 Subject: [PATCH 089/117] delete old travis and appveyor yml files --- .appveyor.yml | 59 --------------------------------------------------- .travis.yml | 49 ------------------------------------------ 2 files changed, 108 deletions(-) delete mode 100644 .appveyor.yml delete mode 100644 .travis.yml diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index f378c89d..00000000 --- a/.appveyor.yml +++ /dev/null @@ -1,59 +0,0 @@ -branches: - only: - - devel - -# Build worker image (VM template) -image: Visual Studio 2015 - -# clone directory -clone_folder: c:\projects\vcglib -# Build Configuration, i.e. Debug, Release, etc. -configuration: - - release -# - debug - -environment: - matrix: - # MinGW 32bit - - QTDIR: C:\Qt\5.6\mingw49_32 - SPEC: win32-g++ - COMPILER: mingw32-make - #ARTIFACT: $(APPVEYOR_PROJECT_NAME)-%APPVEYOR_REPO_TAG_NAME%.%APPVEYOR_BUILD_NUMBER%-win32.zip - #ARTIFACT: $(APPVEYOR_PROJECT_NAME)-%APPVEYOR_REPO_TAG_NAME%-win32.zip - # Microsoft Visual Studio 64bit - - QTDIR: C:\Qt\5.6\msvc2015_64 - VSVER: 14.0 - SPEC: win32-msvc2015 - COMPILER: nmake - #ARTIFACT: $(APPVEYOR_PROJECT_NAME)-%APPVEYOR_REPO_TAG_NAME%.%APPVEYOR_BUILD_NUMBER%-win64.zip - #ARTIFACT: $(APPVEYOR_PROJECT_NAME)-%APPVEYOR_REPO_TAG_NAME%-win64.zip - - - -# Set paths, etc. -before_build: - # Set paths - #- '%QTDIR%\bin\qtenv2.bat' - - call "%QTDIR%\bin\qtenv2.bat" - # Show qmake and make version - - qmake -v - - if %COMPILER%==mingw32-make call %COMPILER% -v - # Detect architecture (32bit or 64bit) - - if %QTDIR:_64=%==%QTDIR% (set ARCH=x86) else (set ARCH=x64) - # Set more... if Microsoft Visual Studio - - if %COMPILER%==nmake call "%ProgramFiles(x86)%\Microsoft Visual Studio %VSVER%\VC\vcvarsall.bat" %ARCH% - # Show build folder - #- echo %APPVEYOR_BUILD_FOLDER% - #- echo %CONFIGURATION% - -# To run your custom scripts instead of automatic MSBuild -build_script: - # Go to clone directory - - cd %APPVEYOR_BUILD_FOLDER% - - cd apps - - cd sample - # Run qmake - - qmake sample.pro -r -spec %SPEC% "CONFIG+=%CONFIGURATION%" - # Run compiler - #- '%COMPILER%' - - call %COMPILER% diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 9c7935a6..00000000 --- a/.travis.yml +++ /dev/null @@ -1,49 +0,0 @@ - -# Enable C++ support -language: cpp - -os: - - linux - - osx - - -# Compiler selection -compiler: - - clang - - gcc - -addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - gcc-4.8 - - g++-4.8 - - clang - -matrix: - exclude: - - os: osx - compiler: gcc - - -install: -# Linux Setup - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then wget --no-check-certificate http://cmake.org/files/v3.1/cmake-3.1.3-Linux-x86_64.tar.gz ;fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then tar -xzf cmake-3.1.3-Linux-x86_64.tar.gz ;fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then if [ "$CXX" = "g++" ]; then export CXX="g++-4.8" CC="gcc-4.8" ;fi ;fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then export PATH=$PWD/cmake-3.1.3-Linux-x86_64/bin:$PATH ;fi -# OSX Setup - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then which cmake ;fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then wget --no-check-certificate http://cmake.org/files/v3.7/cmake-3.7.2-Darwin-x86_64.tar.gz ;fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then tar -xzf cmake-3.7.2-Darwin-x86_64.tar.gz ;fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export PATH=$PWD/cmake-3.1.3-Darwin-x86_64/CMake.app/Contents/bin:$PATH ;fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then which cmake ;fi - -# Build steps -script: - - cd apps - - mkdir build - - cd build - - cmake .. - - make From a0e7ed3d0a557332398879920db74eaae9b3498c Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Tue, 26 Oct 2021 10:57:18 +0200 Subject: [PATCH 090/117] solve bug for uninitialized public members in ply lib --- wrap/io_trimesh/io_ply.h | 1 + wrap/ply/plylib.h | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/wrap/io_trimesh/io_ply.h b/wrap/io_trimesh/io_ply.h index 05c25cab..56e7822f 100644 --- a/wrap/io_trimesh/io_ply.h +++ b/wrap/io_trimesh/io_ply.h @@ -75,6 +75,7 @@ public: PropDescriptor p; p.propname=propName; + p.islist = false; p.stotype1 = propertyType; p.memtype1 = propertyType; diff --git a/wrap/ply/plylib.h b/wrap/ply/plylib.h index 0162ae00..da64940e 100644 --- a/wrap/ply/plylib.h +++ b/wrap/ply/plylib.h @@ -116,18 +116,18 @@ typedef FILE * GZFILE; class PropDescriptor { public: - std::string elemname; // name of the element (e.g. vertex) - std::string propname; // name of the property (e.g. x, y, red...) - int stotype1; // Type of the property in the file - int memtype1; // Type of the property in memory - size_t offset1; // Offset in memory - bool islist; // true if the property is a list - bool alloclist; // 1 se alloca lista, 0 se preallocata - int stotype2; // Type of the number of elements of the list in the file - int memtype2; // Type of the number of elements of the list in memory - size_t offset2; // Offset valore memoria + std::string elemname = ""; // name of the element (e.g. vertex) + std::string propname = ""; // name of the property (e.g. x, y, red...) + int stotype1 = -1; // Type of the property in the file + int memtype1 = -1; // Type of the property in memory + size_t offset1 = 0; // Offset in memory + bool islist = false; // true if the property is a list + bool alloclist = false; // 1 se alloca lista, 0 se preallocata + int stotype2 = -1; // Type of the number of elements of the list in the file + int memtype2 = -1; // Type of the number of elements of the list in memory + size_t offset2 = 0; // Offset valore memoria - int format; // duplicazione del formato + int format = -1; // duplicazione del formato size_t stotypesize() const; // per sapere quanto e'grande un dato descrittore sul file size_t memtypesize() const; // per sapere quanto e'grande un dato descrittore in memoria From 476d1c2d5176b9d48f0c55dc37ef913de4099a5a Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Tue, 26 Oct 2021 11:22:20 +0200 Subject: [PATCH 091/117] make plylib bugfix build also on gcc and clang --- wrap/ply/plylib.cpp | 2 +- wrap/ply/plylib.h | 32 +++++++++++++++++++++++++++++--- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/wrap/ply/plylib.cpp b/wrap/ply/plylib.cpp index c4657fd6..78bb2ccd 100644 --- a/wrap/ply/plylib.cpp +++ b/wrap/ply/plylib.cpp @@ -3695,6 +3695,6 @@ void interpret_texture_name(const char*a, const char*fn, char*output){ output[io++]=a[ia++]; }; output[io]=0; -}; +} } } diff --git a/wrap/ply/plylib.h b/wrap/ply/plylib.h index da64940e..a068ac4c 100644 --- a/wrap/ply/plylib.h +++ b/wrap/ply/plylib.h @@ -116,9 +116,35 @@ typedef FILE * GZFILE; class PropDescriptor { public: - std::string elemname = ""; // name of the element (e.g. vertex) - std::string propname = ""; // name of the property (e.g. x, y, red...) - int stotype1 = -1; // Type of the property in the file + PropDescriptor() {} + PropDescriptor + (std::string elemname, + std::string propname, + int stotype1, + int memtype1, + size_t offset1, + bool islist, + bool alloclist, + int stotype2, + int memtype2, + size_t offset2, + int format) : + elemname(elemname), + propname(propname), + stotype1(stotype1), + memtype1(memtype1), + offset1(offset1), + islist(islist), + alloclist(alloclist), + stotype2(stotype2), + memtype2(memtype2), + offset2(offset2), + format(format) + { + } + std::string elemname; // name of the element (e.g. vertex) + std::string propname; // name of the property (e.g. x, y, red...) + int stotype1 = -1; // Type of the property in the file int memtype1 = -1; // Type of the property in memory size_t offset1 = 0; // Offset in memory bool islist = false; // true if the property is a list From 7cce9f185f2e4056c4ca2b6d92ae7c9bc9cc7961 Mon Sep 17 00:00:00 2001 From: Paolo Cignoni Date: Thu, 28 Oct 2021 13:24:24 +0200 Subject: [PATCH 092/117] Update export_ply.h --- wrap/io_trimesh/export_ply.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/wrap/io_trimesh/export_ply.h b/wrap/io_trimesh/export_ply.h index 95d52350..c69106b2 100644 --- a/wrap/io_trimesh/export_ply.h +++ b/wrap/io_trimesh/export_ply.h @@ -579,7 +579,7 @@ public: fprintf(fpout,"%.*g ",DGTVR,vp->R()); if( HasPerVertexTexCoord(m) && (pi.mask & Mask::IOM_VERTTEXCOORD) ) - fprintf(fpout,"%.*g %.*g",DGTVT,vp->T().u(),vp->T().v()); + fprintf(fpout,"%.*g %.*g",DGTVT,vp->T().u(),DGTVT,vp->T().v()); for(size_t i=0;iVN()*2); for(int k=0;kVN();++k) fprintf(fpout,"%.*g %.*g " - ,DGTFT - ,fp->V(k)->T().u() - ,fp->V(k)->T().v() + ,DGTFT,fp->V(k)->T().u() + ,DGTFT,fp->V(k)->T().v() ); } else if( HasPerWedgeTexCoord(m) && (pi.mask & Mask::IOM_WEDGTEXCOORD) ) From 448c340d3a57f0d3617306b543c6b9f8a03a60d1 Mon Sep 17 00:00:00 2001 From: Paolo Cignoni Date: Thu, 28 Oct 2021 21:21:15 +0200 Subject: [PATCH 093/117] removed useless selection count call in append --- vcg/complex/append.h | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/vcg/complex/append.h b/vcg/complex/append.h index bba38581..33229da3 100644 --- a/vcg/complex/append.h +++ b/vcg/complex/append.h @@ -299,9 +299,10 @@ static void MeshAppendConst( // vertex remap.vert.resize(mr.vert.size(), Remap::InvalidIndex()); VertexIteratorLeft vp; - size_t svn = UpdateSelection::VertexCount(mr); - if(selected) + if(selected){ + size_t svn = UpdateSelection::VertexCount(mr); vp=Allocator::AddVertices(ml,int(svn)); + } else vp=Allocator::AddVertices(ml,mr.vn); @@ -317,8 +318,10 @@ static void MeshAppendConst( // edge remap.edge.resize(mr.edge.size(), Remap::InvalidIndex()); EdgeIteratorLeft ep; - size_t sen = UpdateSelection::EdgeCount(mr); - if(selected) ep=Allocator::AddEdges(ml,sen); + if(selected) { + size_t sen = UpdateSelection::EdgeCount(mr); + ep=Allocator::AddEdges(ml,sen); + } else ep=Allocator::AddEdges(ml,mr.en); ForEachEdge(mr, [&](const EdgeRight& e) @@ -333,8 +336,10 @@ static void MeshAppendConst( // face remap.face.resize(mr.face.size(), Remap::InvalidIndex()); FaceIteratorLeft fp; - size_t sfn = UpdateSelection::FaceCount(mr); - if(selected) fp=Allocator::AddFaces(ml,sfn); + if(selected) { + size_t sfn = UpdateSelection::FaceCount(mr); + fp=Allocator::AddFaces(ml,sfn); + } else fp=Allocator::AddFaces(ml,mr.fn); ForEachFace(mr, [&](const FaceRight& f) From a0d239ec268014aad46a95fe3510b240f3446fb4 Mon Sep 17 00:00:00 2001 From: Paolo Cignoni Date: Thu, 28 Oct 2021 21:22:19 +0200 Subject: [PATCH 094/117] improved behaviour of distribution/histogram in presence of NaN --- vcg/complex/algorithms/stat.h | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/vcg/complex/algorithms/stat.h b/vcg/complex/algorithms/stat.h index f0e8502e..c9b0e7cb 100644 --- a/vcg/complex/algorithms/stat.h +++ b/vcg/complex/algorithms/stat.h @@ -299,11 +299,14 @@ public: static void ComputePerVertexQualityDistribution(const MeshType & m, Distribution & h, bool selectionOnly = false) // V1.0 { tri::RequirePerVertexQuality(m); + h.Clear(); for(ConstVertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi) if(!(*vi).IsD() && ((!selectionOnly) || (*vi).IsS()) ) { - assert(!math::IsNAN((*vi).Q()) && "You should never try to compute Histogram with Invalid Floating points numbers (NaN)"); - h.Add((*vi).Q()); + if(!math::IsNAN((*vi).Q())) + h.Add((*vi).Q()); + else + assert( "You should never try to compute Histogram with Invalid Floating points numbers (NaN)"); } } @@ -311,11 +314,14 @@ public: bool selectionOnly = false) // V1.0 { tri::RequirePerFaceQuality(m); + h.Clear(); for(ConstFaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi) if(!(*fi).IsD() && ((!selectionOnly) || (*fi).IsS()) ) { - assert(!math::IsNAN((*fi).Q()) && "You should never try to compute Histogram with Invalid Floating points numbers (NaN)"); - h.Add((*fi).Q()); + if(!math::IsNAN((*fi).Q())) + h.Add((*fi).Q()); + else + assert( "You should never try to compute Histogram with Invalid Floating points numbers (NaN)"); } } From b6110a93df2258a1f7a3e8f7a210b8b15d1cdb6f Mon Sep 17 00:00:00 2001 From: Paolo Cignoni Date: Thu, 28 Oct 2021 21:22:42 +0200 Subject: [PATCH 095/117] removed useless var --- vcg/complex/algorithms/update/curvature_fitting.h | 1 - 1 file changed, 1 deletion(-) diff --git a/vcg/complex/algorithms/update/curvature_fitting.h b/vcg/complex/algorithms/update/curvature_fitting.h index 9de9fe3e..332b3d36 100644 --- a/vcg/complex/algorithms/update/curvature_fitting.h +++ b/vcg/complex/algorithms/update/curvature_fitting.h @@ -633,7 +633,6 @@ class Quadric if (cb && ((i%1024)==00)) { (*cb)(int(100.0f * (float)i / (float)mesh.vn),"Vertices Analysis"); } - int count; expandSphereLocal (mesh, &*vi, radiusSphere, 5, &vv); assert (vv.size() >= 5); From 49c8678ec3583f4eb7d0d7ff147a4a32584e3d00 Mon Sep 17 00:00:00 2001 From: Paolo Cignoni Date: Fri, 29 Oct 2021 14:26:00 +0200 Subject: [PATCH 096/117] removed useless HG components from the vertex component set Replaced by much simpler attributes --- vcg/complex/base.h | 3 -- vcg/simplex/vertex/component.h | 49 ------------------------------ vcg/simplex/vertex/component_ocf.h | 44 --------------------------- 3 files changed, 96 deletions(-) diff --git a/vcg/complex/base.h b/vcg/complex/base.h index befda76c..b59e26e6 100644 --- a/vcg/complex/base.h +++ b/vcg/complex/base.h @@ -666,7 +666,6 @@ template < class VertexType> bool VertexVectorHasPerVertexColor (const std template < class VertexType> bool VertexVectorHasPerVertexMark (const std::vector &) { return VertexType::HasMark (); } template < class VertexType> bool VertexVectorHasPerVertexFlags (const std::vector &) { return VertexType::HasFlags (); } template < class VertexType> bool VertexVectorHasPerVertexRadius (const std::vector &) { return VertexType::HasRadius (); } -template < class VertexType> bool VertexVectorHasPerVertexCurvature (const std::vector &) { return VertexType::HasCurvature (); } template < class VertexType> bool VertexVectorHasPerVertexCurvatureDir(const std::vector &) { return VertexType::HasCurvatureDir(); } template < class VertexType> bool VertexVectorHasPerVertexTexCoord (const std::vector &) { return VertexType::HasTexCoord (); } @@ -676,7 +675,6 @@ template < class TriMeshType> bool HasPerVertexColor (const TriMeshType &m template < class TriMeshType> bool HasPerVertexMark (const TriMeshType &m) { return tri::VertexVectorHasPerVertexMark (m.vert); } template < class TriMeshType> bool HasPerVertexFlags (const TriMeshType &m) { return tri::VertexVectorHasPerVertexFlags (m.vert); } template < class TriMeshType> bool HasPerVertexRadius (const TriMeshType &m) { return tri::VertexVectorHasPerVertexRadius (m.vert); } -template < class TriMeshType> bool HasPerVertexCurvature (const TriMeshType &m) { return tri::VertexVectorHasPerVertexCurvature (m.vert); } template < class TriMeshType> bool HasPerVertexCurvatureDir(const TriMeshType &m) { return tri::VertexVectorHasPerVertexCurvatureDir(m.vert); } template < class TriMeshType> bool HasPerVertexTexCoord (const TriMeshType &m) { return tri::VertexVectorHasPerVertexTexCoord (m.vert); } @@ -877,7 +875,6 @@ template void RequirePerVertexColor (const MeshType &m) { template void RequirePerVertexMark (const MeshType &m) { if(!tri::HasPerVertexMark (m)) throw vcg::MissingComponentException("PerVertexMark "); } template void RequirePerVertexFlags (const MeshType &m) { if(!tri::HasPerVertexFlags (m)) throw vcg::MissingComponentException("PerVertexFlags "); } template void RequirePerVertexRadius (const MeshType &m) { if(!tri::HasPerVertexRadius (m)) throw vcg::MissingComponentException("PerVertexRadius "); } -template void RequirePerVertexCurvature (const MeshType &m) { if(!tri::HasPerVertexCurvature (m)) throw vcg::MissingComponentException("PerVertexCurvature "); } template void RequirePerVertexCurvatureDir(const MeshType &m) { if(!tri::HasPerVertexCurvatureDir(m)) throw vcg::MissingComponentException("PerVertexCurvatureDir"); } template void RequirePerVertexTexCoord (const MeshType &m) { if(!tri::HasPerVertexTexCoord (m)) throw vcg::MissingComponentException("PerVertexTexCoord "); } diff --git a/vcg/simplex/vertex/component.h b/vcg/simplex/vertex/component.h index dab25640..37f27f93 100644 --- a/vcg/simplex/vertex/component.h +++ b/vcg/simplex/vertex/component.h @@ -158,15 +158,8 @@ public: static bool HasVHAdjacency() { return false; } typedef float CurScalarType; - typedef float ScalarTypeCur; typedef Point3f CurVecType; typedef Point2f CurvatureType; - float &Kh() { static float dummy = 0.f; assert(0);return dummy;} - float &Kg() { static float dummy = 0.f; assert(0);return dummy;} - float Kh() const { static float dummy = 0.f; assert(0); return dummy;} - float Kg() const { static float dummy = 0.f; assert(0); return dummy;} - float cKh() const { static float dummy = 0.f; assert(0); return dummy;} - float cKg() const { static float dummy = 0.f; assert(0); return dummy;} typedef CurvatureDirBaseType CurvatureDirType; CurVecType &PD1() {static CurVecType v(0,0,0); assert(0);return v;} @@ -183,9 +176,7 @@ public: CurScalarType cK1() const {static ScalarType v = 0.0;assert(0);return v;} CurScalarType cK2() const {static ScalarType v = 0.0;assert(0);return v;} - static bool HasCurvature() { return false; } static bool HasCurvatureDir() { return false; } - inline bool IsCurvatureEnabled() const { return TT::VertexType::HasCurvature();} inline bool IsCurvatureDirEnabled() const { return TT::VertexType::HasCurvatureDir();} template < class RightValueType> @@ -428,46 +419,6 @@ template class Qualityd: public Quality { public: static void Name(std::vector & name){name.push_back(std::string("Qualityd"));TT::Name(name);} }; - /*-------------------------- Curvature ----------------------------------*/ - - /*! \brief \em Component: Per vertex basic \b curvature - This component keeps the mean an gaussian curvature for a vertex. Used by some of the algorithms of vcg::tri::UpdateCurvature to store the computed curvatures. - */ - template class Curvature: public TT { - public: - typedef Point2 CurvatureType; - typedef typename CurvatureType::ScalarType ScalarTypeCur; - const ScalarTypeCur &Kh() const { return _hk[0]; } - const ScalarTypeCur &Kg() const { return _hk[1]; } - ScalarTypeCur &Kh() { return _hk[0]; } - ScalarTypeCur &Kg() { return _hk[1]; } - ScalarTypeCur cKh() const { return _hk[0]; } - ScalarTypeCur cKg() const { return _hk[1]; } - - template < class RightValueType> - void ImportData(const RightValueType & rVert ) { - if(rVert.IsCurvatureEnabled()) { - Kh() = rVert.cKh(); - Kg() = rVert.cKg(); - } - TT::ImportData( rVert); - } - - static bool HasCurvature() { return true; } - static void Name(std::vector & name){name.push_back(std::string("Curvature"));TT::Name(name);} - - private: - Point2 _hk; - }; - - - template class Curvaturef: public Curvature< float, T> { - public: static void Name(std::vector & name){name.push_back(std::string("Curvaturef"));T::Name(name);} - }; - template class Curvatured: public Curvature { - public: static void Name(std::vector & name){name.push_back(std::string("Curvatured"));T::Name(name);} - }; - /*-------------------------- Curvature Direction ----------------------------------*/ /*! \brief \em Component: Per vertex \b curvature \b directions diff --git a/vcg/simplex/vertex/component_ocf.h b/vcg/simplex/vertex/component_ocf.h index 8750066c..4ad90edb 100644 --- a/vcg/simplex/vertex/component_ocf.h +++ b/vcg/simplex/vertex/component_ocf.h @@ -432,50 +432,6 @@ public: }; -///*-------------------------- CURVATURE ----------------------------------*/ - -template class CurvatureOcf: public TT { -public: - typedef Point2 CurvatureType; - typedef typename CurvatureType::ScalarType ScalarTypeCur; - - ScalarTypeCur &Kh(){ assert((*this).Base().CurvatureEnabled); return (*this).Base().CuV[(*this).Index()][0]; } - ScalarTypeCur &Kg(){ assert((*this).Base().CurvatureEnabled); return (*this).Base().CuV[(*this).Index()][1]; } - ScalarTypeCur cKh() const - { - assert((*this).Base().CurvatureEnabled); - return (*this).Base().CuV[(*this).Index()][0]; - } - - ScalarTypeCur cKg() const - { - assert((*this).Base().CurvatureEnabled); - return (*this).Base().CuV[(*this).Index()][1]; - } - - template - void ImportData(const RightVertexType & rightV){ - if((*this).IsCurvatureEnabled() && rightV.IsCurvatureEnabled()) - { - (*this).Base().CuV[(*this).Index()][0] = rightV.cKh(); - (*this).Base().CuV[(*this).Index()][1] = rightV.cKg(); - } - TT::ImportData(rightV); - } - - inline bool IsCurvatureEnabled( ) const - { - return this->Base().IsCurvatureEnabled(); - } - - static bool HasCurvature() { return true; } - static bool HasCurvatureOcf() { return true; } -}; - -template class CurvaturefOcf: public CurvatureOcf {public: static void Name(std::vector & name){name.push_back(std::string("CurvaturefOcf"));T::Name(name);} }; -template class CurvaturedOcf: public CurvatureOcf {public: static void Name(std::vector & name){name.push_back(std::string("CurvaturedOcf"));T::Name(name);} }; - - ///*-------------------------- CURVATURE DIR ----------------------------------*/ template From 11b7b362ec96ef14d9c575bb4317e5c61e06f888 Mon Sep 17 00:00:00 2001 From: Paolo Cignoni Date: Fri, 29 Oct 2021 14:26:38 +0200 Subject: [PATCH 097/117] Updated curvature and quality function to do not use components but attributes --- vcg/complex/algorithms/update/curvature.h | 126 ++++++++++++---------- vcg/complex/algorithms/update/quality.h | 54 +++++----- 2 files changed, 96 insertions(+), 84 deletions(-) diff --git a/vcg/complex/algorithms/update/curvature.h b/vcg/complex/algorithms/update/curvature.h index 5b9a5364..e61e2ce8 100644 --- a/vcg/complex/algorithms/update/curvature.h +++ b/vcg/complex/algorithms/update/curvature.h @@ -400,7 +400,6 @@ For further details, please, refer to: \n static void MeanAndGaussian(MeshType & m) { tri::RequireFFAdjacency(m); - tri::RequirePerVertexCurvature(m); float area0, area1, area2, angle0, angle1, angle2; FaceIterator fi; @@ -411,13 +410,16 @@ static void MeanAndGaussian(MeshType & m) SimpleTempData TDContr(m.vert); vcg::tri::UpdateNormal::PerVertexNormalized(m); + auto KH = vcg::tri::Allocator:: template GetPerVertexAttribute (m, std::string("KH")); + auto KG = vcg::tri::Allocator:: template GetPerVertexAttribute (m, std::string("KG")); + //Compute AreaMix in H (vale anche per K) for(vi=m.vert.begin(); vi!=m.vert.end(); ++vi) if(!(*vi).IsD()) { (TDAreaPtr)[*vi].A = 0.0; (TDContr)[*vi] =typename MeshType::CoordType(0.0,0.0,0.0); - (*vi).Kh() = 0.0; - (*vi).Kg() = (float)(2.0 * M_PI); + KH[*vi] = 0.0; + KG[*vi] = (ScalarType)(2.0 * M_PI); } for(fi=m.face.begin();fi!=m.face.end();++fi) if( !(*fi).IsD()) @@ -482,10 +484,10 @@ static void MeanAndGaussian(MeshType & m) TDContr[(*fi).V(0)] += ( e20v * (1.0/tan(angle1)) - e01v * (1.0/tan(angle2)) ) / 4.0; TDContr[(*fi).V(1)] += ( e01v * (1.0/tan(angle2)) - e12v * (1.0/tan(angle0)) ) / 4.0; TDContr[(*fi).V(2)] += ( e12v * (1.0/tan(angle0)) - e20v * (1.0/tan(angle1)) ) / 4.0; - - (*fi).V(0)->Kg() -= angle0; - (*fi).V(1)->Kg() -= angle1; - (*fi).V(2)->Kg() -= angle2; + + KG[(*fi).V(0)] -= angle0; + KG[(*fi).V(1)] -= angle1; + KG[(*fi).V(2)] -= angle2; for(int i=0;i<3;i++) @@ -501,7 +503,7 @@ static void MeanAndGaussian(MeshType & m) hp1.FlipV(); hp1.NextB(); e2=hp1.v->cP() - hp.v->cP(); - (*fi).V(i)->Kg() -= math::Abs(Angle(e1,e2)); + KG[(*fi).V(i)] -= math::Abs(Angle(e1,e2)); } } } @@ -510,13 +512,13 @@ static void MeanAndGaussian(MeshType & m) { if((TDAreaPtr)[*vi].A<=std::numeric_limits::epsilon()) { - (*vi).Kh() = 0; - (*vi).Kg() = 0; + KH[(*vi)] = 0; + KG[(*vi)] = 0; } else { - (*vi).Kh() = (((TDContr)[*vi].dot((*vi).cN())>0)?1.0:-1.0)*((TDContr)[*vi] / (TDAreaPtr) [*vi].A).Norm(); - (*vi).Kg() /= (TDAreaPtr)[*vi].A; + KH[(*vi)] = (((TDContr)[*vi].dot((*vi).cN())>0)?1.0:-1.0)*((TDContr)[*vi] / (TDAreaPtr) [*vi].A).Norm(); + KG[(*vi)] /= (TDAreaPtr)[*vi].A; } } } @@ -526,78 +528,86 @@ static void MeanAndGaussian(MeshType & m) /** The function uses the VF adiacency to walk around the vertex. - \return It will return the voronoi area around the vertex. If (norm == true) the mean and the gaussian curvature are normalized. - Based on the paper "Optimizing 3d triangulations using discrete curvature analysis" - */ - - static float ComputeSingleVertexCurvature(VertexPointer v, bool norm = true) + + Based on the paper + "Optimizing 3d triangulations using discrete curvature analysis" + it compute an approximation of the gaussian and of the absolute mean curvature + */ +static void PerVertexAbsoluteMeanAndGaussian(MeshType & m) +{ + tri::RequireVFAdjacency(m); + tri::RequireCompactness(m); + const bool areaNormalize = true; + const bool barycentricArea=false; + auto KH = vcg::tri::Allocator:: template GetPerVertexAttribute (m, std::string("KH")); + auto KG = vcg::tri::Allocator:: template GetPerVertexAttribute (m, std::string("KG")); + int faceCnt=0; + for(VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi) { + VertexPointer v=&*vi; VFIteratorType vfi(v); - float A = 0; + ScalarType A = 0; - v->Kh() = 0; - v->Kg() = 2 * M_PI; + KH[v] = 0; + ScalarType AngleDefect = (ScalarType)(2.0 * M_PI);; while (!vfi.End()) { - if (!vfi.F()->IsD()) { + faceCnt++; FacePointer f = vfi.F(); CoordType nf = TriangleNormal(*f); int i = vfi.I(); VertexPointer v0 = f->V0(i), v1 = f->V1(i), v2 = f->V2(i); + assert (v==v0); - float ang0 = math::Abs(Angle(v1->P() - v0->P(), v2->P() - v0->P() )); - float ang1 = math::Abs(Angle(v0->P() - v1->P(), v2->P() - v1->P() )); - float ang2 = M_PI - ang0 - ang1; + ScalarType ang0 = math::Abs(Angle(v1->P() - v0->P(), v2->P() - v0->P() )); + ScalarType ang1 = math::Abs(Angle(v0->P() - v1->P(), v2->P() - v1->P() )); + ScalarType ang2 = M_PI - ang0 - ang1; - float s01 = SquaredDistance(v1->P(), v0->P()); - float s02 = SquaredDistance(v2->P(), v0->P()); + ScalarType s01 = SquaredDistance(v1->P(), v0->P()); + ScalarType s02 = SquaredDistance(v2->P(), v0->P()); // voronoi cell of current vertex - if (ang0 >= M_PI/2) - A += (0.5f * DoubleArea(*f) - (s01 * tan(ang1) + s02 * tan(ang2)) / 8.0 ); - else if (ang1 >= M_PI/2) - A += (s01 * tan(ang0)) / 8.0; - else if (ang2 >= M_PI/2) - A += (s02 * tan(ang0)) / 8.0; - else // non obctuse triangle - A += ((s02 / tan(ang1)) + (s01 / tan(ang2))) / 8.0; - + if(barycentricArea) + A+=vcg::DoubleArea(*f)/6.0; + else + { + if (ang0 >= M_PI/2) + A += (0.5f * DoubleArea(*f) - (s01 * tan(ang1) + s02 * tan(ang2)) / 8.0 ); + else if (ang1 >= M_PI/2) + A += (s01 * tan(ang0)) / 8.0; + else if (ang2 >= M_PI/2) + A += (s02 * tan(ang0)) / 8.0; + else // non obctuse triangle + A += ((s02 / tan(ang1)) + (s01 / tan(ang2))) / 8.0; + } // gaussian curvature update - v->Kg() -= ang0; + AngleDefect -= ang0; // mean curvature update - ang1 = math::Abs(Angle(nf, v1->N())); - ang2 = math::Abs(Angle(nf, v2->N())); - v->Kh() += ( (math::Sqrt(s01) / 2.0) * ang1 + - (math::Sqrt(s02) / 2.0) * ang2 ); - } - + // Note that the standard abs mean curvature approximation would require + // to sum all the edges*diehedralAngle. Here with just VF adjacency + // we make a rough approximation that 1/2 of the edge len plus something + // that is half of the diedral angle + ang1 = math::Abs(Angle(nf, v1->N()+v0->N())); + ang2 = math::Abs(Angle(nf, v2->N()+v0->N())); + KH[v] += math::Sqrt(s01)*ang1 + math::Sqrt(s02)*ang2 ; ++vfi; } - v->Kh() /= 4.0f; + KH[v] /= 4.0; - if(norm) { + if(areaNormalize) { if(A <= std::numeric_limits::epsilon()) { - v->Kh() = 0; - v->Kg() = 0; + KH[v] = 0; + KG[v] = 0; } else { - v->Kh() /= A; - v->Kg() /= A; + KH[v] /= A; + KG[v] = AngleDefect / A; } } - - return A; - } - - static void PerVertex(MeshType & m) - { - tri::RequireVFAdjacency(m); - - for(VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi) - ComputeSingleVertexCurvature(&*vi,false); } +} diff --git a/vcg/complex/algorithms/update/quality.h b/vcg/complex/algorithms/update/quality.h index 728c6e5f..cdb0c223 100644 --- a/vcg/complex/algorithms/update/quality.h +++ b/vcg/complex/algorithms/update/quality.h @@ -224,6 +224,15 @@ static void VertexFromAttributeHandle(MeshType &m, typename MeshType::template P (*vi).Q()=VertexQualityType(h[vi]); } +static void VertexFromAttributeName(MeshType &m, const std::string &AttrName) +{ + tri::RequirePerVertexQuality(m); + auto KH = tri::Allocator:: template FindPerVertexAttribute (m, AttrName); + if(!tri::Allocator::template IsValidHandle(m, KH)) throw vcg::MissingPreconditionException("Required Attribute is non existent"); + for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) + (*vi).Q() = KH[vi]; +} + template static void FaceFromAttributeHandle(MeshType &m, typename MeshType::template PerFaceAttributeHandle &h) { @@ -232,6 +241,15 @@ static void FaceFromAttributeHandle(MeshType &m, typename MeshType::template Per (*fi).Q() =FaceQualityType(h[fi]); } +static void FaceFromAttributeName(MeshType &m, const std::string &AttrName) +{ + tri::RequirePerFaceQuality(m); + auto KH = tri::Allocator:: template FindPerFaceAttribute (m, AttrName); + if(!tri::Allocator::template IsValidHandle(m, KH)) throw vcg::MissingPreconditionException("Required Attribute is non existent"); + for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD()) + (*fi).Q() =FaceQualityType(KH[fi]); +} + static void FaceFromVertex( MeshType &m) { tri::RequirePerFaceQuality(m); @@ -252,22 +270,6 @@ static void VertexFromPlane(MeshType &m, const Plane3 &pl) (*vi).Q() =SignedDistancePlanePoint(pl,(*vi).cP()); } -static void VertexFromGaussianCurvatureHG(MeshType &m) -{ - tri::RequirePerVertexQuality(m); - tri::RequirePerVertexCurvature(m); - for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) - (*vi).Q() = (*vi).Kg(); -} - -static void VertexFromMeanCurvatureHG(MeshType &m) -{ - tri::RequirePerVertexQuality(m); - tri::RequirePerVertexCurvature(m); - for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) - (*vi).Q() = (*vi).Kh(); -} - static void VertexFromGaussianCurvatureDir(MeshType &m) { tri::RequirePerVertexQuality(m); @@ -364,14 +366,14 @@ static void VertexFromCurvednessCurvatureDir(MeshType &m) static void VertexFromAbsoluteCurvature(MeshType &m) { tri::RequirePerVertexQuality(m); - tri::RequirePerVertexCurvature(m); - VertexIterator vi; - for(vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) + auto KH = vcg::tri::Allocator:: template GetPerVertexAttribute (m, std::string("KH")); + auto KG = vcg::tri::Allocator:: template GetPerVertexAttribute (m, std::string("KG")); + for(auto vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) { - if((*vi).Kg() >= 0) - (*vi).Q() = math::Abs( 2*(*vi).Kh() ); + if(KG[vi] >= 0) + (*vi).Q() = math::Abs( 2.0*KH[vi] ); else - (*vi).Q() = 2*math::Sqrt(math::Abs( (*vi).Kh()*(*vi).Kh() - (*vi).Kg())); + (*vi).Q() = 2*math::Sqrt(math::Abs( KH[vi]*KH[vi] - KG[vi])); } } @@ -385,10 +387,10 @@ static void VertexFromAbsoluteCurvature(MeshType &m) static void VertexFromRMSCurvature(MeshType &m) { tri::RequirePerVertexQuality(m); - tri::RequirePerVertexCurvature(m); - VertexIterator vi; - for(vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) - (*vi).Q() = math::Sqrt(math::Abs( 4*(*vi).Kh()*(*vi).Kh() - 2*(*vi).Kg())); + auto KH = vcg::tri::Allocator:: template GetPerVertexAttribute (m, std::string("KH")); + auto KG = vcg::tri::Allocator:: template GetPerVertexAttribute (m, std::string("KG")); + for(auto vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) + (*vi).Q() = math::Sqrt(math::Abs( 4*KH[vi]*KH[vi] - 2*KG[vi])); } /* From 442a289bf6f43efeaf54e6dc566aa9acb0655a97 Mon Sep 17 00:00:00 2001 From: Paolo Cignoni Date: Fri, 29 Oct 2021 14:58:18 +0200 Subject: [PATCH 098/117] renamed curvature extracting method for sake of coherence --- vcg/complex/algorithms/update/quality.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/vcg/complex/algorithms/update/quality.h b/vcg/complex/algorithms/update/quality.h index cdb0c223..51e8237b 100644 --- a/vcg/complex/algorithms/update/quality.h +++ b/vcg/complex/algorithms/update/quality.h @@ -270,7 +270,7 @@ static void VertexFromPlane(MeshType &m, const Plane3 &pl) (*vi).Q() =SignedDistancePlanePoint(pl,(*vi).cP()); } -static void VertexFromGaussianCurvatureDir(MeshType &m) +static void VertexGaussianFromCurvatureDir(MeshType &m) { tri::RequirePerVertexQuality(m); tri::RequirePerVertexCurvatureDir(m); @@ -278,21 +278,21 @@ static void VertexFromGaussianCurvatureDir(MeshType &m) (*vi).Q() = (*vi).K1()*(*vi).K2(); } -static void VertexFromMeanCurvatureDir(MeshType &m) +static void VertexMeanFromCurvatureDir(MeshType &m) { tri::RequirePerVertexQuality(m); tri::RequirePerVertexCurvatureDir(m); for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) (*vi).Q() = ((*vi).K1()+(*vi).K2())/2.0f; } -static void VertexFromMinCurvatureDir(MeshType &m) +static void VertexMinCurvFromCurvatureDir(MeshType &m) { tri::RequirePerVertexQuality(m); tri::RequirePerVertexCurvatureDir(m); for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) (*vi).Q() = (*vi).K1(); } -static void VertexFromMaxCurvatureDir(MeshType &m) +static void VertexMaxCurvFromCurvatureDir(MeshType &m) { tri::RequirePerVertexQuality(m); tri::RequirePerVertexCurvatureDir(m); @@ -301,7 +301,7 @@ static void VertexFromMaxCurvatureDir(MeshType &m) } /** - * @brief VertexFromShapeIndexCurvatureDir + * @brief VertexShapeIndexFromCurvatureDir * Compute from the current Curvature Direction the Shape Index S as defined by [Koenderink 1992] * and store it in the per-vertex Quality. * S = 2/pi atan(k1+k2/k1-k2) @@ -311,7 +311,7 @@ static void VertexFromMaxCurvatureDir(MeshType &m) * Image and vision computing, 10(8):557–565, 1992. */ -static void VertexFromShapeIndexCurvatureDir(MeshType &m) +static void VertexShapeIndexFromCurvatureDir(MeshType &m) { tri::RequirePerVertexQuality(m); tri::RequirePerVertexCurvatureDir(m); @@ -324,7 +324,7 @@ static void VertexFromShapeIndexCurvatureDir(MeshType &m) } } /** - * @brief VertexFromCurvednessCurvatureDir + * @brief VertexCurvednessFromCurvatureDir * Compute from the current Curvature Direction the Curvedness as defined by [Koenderink 1992] * and store it in the per-vertex Quality. * C = Sqrt((k1*k1+k2*k2)/2.0) @@ -333,7 +333,7 @@ static void VertexFromShapeIndexCurvatureDir(MeshType &m) * Surface shape and curvature scales. * Image and vision computing, 10(8):557–565, 1992. */ -static void VertexFromCurvednessCurvatureDir(MeshType &m) +static void VertexCurvednessFromCurvatureDir(MeshType &m) { tri::RequirePerVertexQuality(m); tri::RequirePerVertexCurvatureDir(m); @@ -363,7 +363,7 @@ static void VertexFromCurvednessCurvatureDir(MeshType &m) * N Dyn, K Hormann, SJ Kim, D Levin - Mathematical Methods for Curves and Surfaces: Oslo, 2000 */ -static void VertexFromAbsoluteCurvature(MeshType &m) +static void VertexAbsoluteCurvatureFromHGAttribute(MeshType &m) { tri::RequirePerVertexQuality(m); auto KH = vcg::tri::Allocator:: template GetPerVertexAttribute (m, std::string("KH")); @@ -384,7 +384,7 @@ static void VertexFromAbsoluteCurvature(MeshType &m) * Improved curvature estimation for watershed segmentation of 3-dimensional meshes * S Pulla, A Razdan, G Farin - Arizona State University, Tech. Rep, 2001 */ -static void VertexFromRMSCurvature(MeshType &m) +static void VertexRMSCurvatureFromHGAttribute(MeshType &m) { tri::RequirePerVertexQuality(m); auto KH = vcg::tri::Allocator:: template GetPerVertexAttribute (m, std::string("KH")); From 72200b9d9b9a90e1f57846a2bbaf86b2ea38da39 Mon Sep 17 00:00:00 2001 From: Paolo Cignoni Date: Fri, 29 Oct 2021 16:11:50 +0200 Subject: [PATCH 099/117] Updated curvature sample to the last changes --- .../trimesh_curvature/trimesh_curvature.cpp | 72 ++++++++++++++----- .../trimesh_curvature/trimesh_curvature.pro | 2 +- 2 files changed, 57 insertions(+), 17 deletions(-) diff --git a/apps/sample/trimesh_curvature/trimesh_curvature.cpp b/apps/sample/trimesh_curvature/trimesh_curvature.cpp index 8569c6e5..47104819 100644 --- a/apps/sample/trimesh_curvature/trimesh_curvature.cpp +++ b/apps/sample/trimesh_curvature/trimesh_curvature.cpp @@ -23,46 +23,86 @@ /*! \file trimesh_curvature.cpp \ingroup code_sample -\brief an example showing the various techniques for computing curvatures +\brief an example showing various techniques for computing curvatures */ #include #include #include +#include -#include +#include -class MyEdge; class MyFace; class MyVertex; struct MyUsedTypes : public vcg::UsedTypes< vcg::Use ::AsVertexType, - vcg::Use ::AsEdgeType, vcg::Use ::AsFaceType>{}; -class MyVertex : public vcg::Vertex{}; -class MyFace : public vcg::Face< MyUsedTypes, vcg::face::FFAdj, vcg::face::VFAdj, vcg::face::VertexRef, vcg::face::BitFlags > {}; -class MyEdge : public vcg::Edge{}; -class MyMesh : public vcg::tri::TriMesh< std::vector, std::vector , std::vector > {}; +class MyVertex : public vcg::Vertex{}; +class MyFace : public vcg::Face< MyUsedTypes, vcg::face::FFAdj, vcg::face::VFAdj, vcg::face::Normal3f, vcg::face::VertexRef, vcg::face::BitFlags > {}; +class MyMesh : public vcg::tri::TriMesh< std::vector, std::vector > {}; int main( int /*argc*/, char **/*argv*/ ) { MyMesh m; - vcg::tri::Torus(m,30,10); + // in a torus with radii 1 and 4 + // on the outside the principal curvature should be 1 and 1/5 + // and internally the principal curvature should be 1 and -1/3 + // Gaussian range -0.333 .. 0.200 + // mean range 0.333 .. 0.600 + //vcg::tri::Torus(m,4,1,32,16); + + + // in a sphere of radius 2 the curvature is everywhere 0.5 + // Gaussian 0.25 + // Mean 0.5 + vcg::tri::Sphere(m,5); + vcg::tri::UpdatePosition::Scale(m, 2.0); vcg::tri::UpdateTopology::FaceFace(m); vcg::tri::UpdateTopology::VertexFace(m); + vcg::tri::UpdateNormal::PerVertexNormalizedPerFaceNormalized(m); + vcg::Distribution distr; + printf("Starting mesh vn:%i fn:%i\n",m.VN(),m.FN()); - // Two different techniques for computing Discrete Gaussian and Mean Curvature - // they require the presence of the vertex::Curvature component - vcg::tri::UpdateCurvature::PerVertex(m); + // Method 1 (discrete - Optimizing 3d triangulations using discrete curvature analysis 2003) + vcg::tri::UpdateCurvature::PerVertexAbsoluteMeanAndGaussian(m); + vcg::tri::UpdateQuality::VertexFromAttributeName(m,"KG"); + vcg::tri::Stat::ComputePerVertexQualityDistribution(m,distr); + printf("Gaussian Curvature method 1 Min %f Max %f\n",distr.Min(),distr.Max()); + vcg::tri::UpdateQuality::VertexFromAttributeName(m,"KH"); + vcg::tri::Stat::ComputePerVertexQualityDistribution(m,distr); + printf("Mean Curvature method 1 Min %f Max %f\n",distr.Min(),distr.Max()); + + // Method 2 (discrete - Discrete Differential-Geometry Operators for Triangulated 2-Manifolds 2002) vcg::tri::UpdateCurvature::MeanAndGaussian(m); + vcg::tri::UpdateQuality::VertexFromAttributeName(m,"KG"); + vcg::tri::Stat::ComputePerVertexQualityDistribution(m,distr); + printf("Gaussian Curvature method 2 Min %f Max %f\n",distr.Min(),distr.Max()); + vcg::tri::UpdateQuality::VertexFromAttributeName(m,"KH"); + vcg::tri::Stat::ComputePerVertexQualityDistribution(m,distr); + printf("Mean Curvature method 2 Min %f Max %f\n",distr.Min(),distr.Max()); + vcg::tri::io::ExporterPLY::Save(m,"Torus_Discrete_Mean2.ply",vcg::tri::io::Mask::IOM_VERTQUALITY); - // Two different techniques for computing Principal Curvature Directions - // they require the presence of the vertex::CurvatureDir component + // Method 3 (directions - Estimating the Tensor of Curvature of a Surface from a Polyhedral Approximation - 1995) vcg::tri::UpdateCurvature::PrincipalDirections(m); + vcg::tri::UpdateQuality::VertexGaussianFromCurvatureDir(m); + vcg::tri::Stat::ComputePerVertexQualityDistribution(m,distr); + printf("Gaussian Curvature method 3 Min %f Max %f\n",distr.Min(),distr.Max()); + vcg::tri::UpdateQuality::VertexMeanFromCurvatureDir(m); + vcg::tri::Stat::ComputePerVertexQualityDistribution(m,distr); + printf("Mean Curvature method 3 Min %f Max %f\n",distr.Min(),distr.Max()); + + // Method 4 (directions - Restricted delaunay triangulations and normal cycle ) vcg::tri::UpdateCurvature::PrincipalDirectionsNormalCycle(m); - printf("Input mesh vn:%i fn:%i\n",m.VN(),m.FN()); - + vcg::tri::UpdateQuality::VertexGaussianFromCurvatureDir(m); + vcg::tri::Stat::ComputePerVertexQualityDistribution(m,distr); + printf("Gaussian Curvature method 4 Min %f Max %f\n",distr.Min(),distr.Max()); + vcg::tri::UpdateQuality::VertexMeanFromCurvatureDir(m); + vcg::tri::Stat::ComputePerVertexQualityDistribution(m,distr); + printf("Mean Curvature method 4 Min %f Max %f\n",distr.Min(),distr.Max()); + + return 0; } diff --git a/apps/sample/trimesh_curvature/trimesh_curvature.pro b/apps/sample/trimesh_curvature/trimesh_curvature.pro index 8342dfa4..343a355e 100644 --- a/apps/sample/trimesh_curvature/trimesh_curvature.pro +++ b/apps/sample/trimesh_curvature/trimesh_curvature.pro @@ -1,3 +1,3 @@ include(../common.pri) TARGET = trimesh_curvature -SOURCES += trimesh_curvature.cpp +SOURCES += trimesh_curvature.cpp ../../../wrap/ply/plylib.cpp From d1d106a4ce3a46d42fdfa665bb3e17b0c6ba61bd Mon Sep 17 00:00:00 2001 From: Paolo Cignoni Date: Fri, 29 Oct 2021 16:36:17 +0200 Subject: [PATCH 100/117] Updated cmakelist --- apps/sample/trimesh_curvature/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/sample/trimesh_curvature/CMakeLists.txt b/apps/sample/trimesh_curvature/CMakeLists.txt index a09fe6e1..57265ce7 100644 --- a/apps/sample/trimesh_curvature/CMakeLists.txt +++ b/apps/sample/trimesh_curvature/CMakeLists.txt @@ -3,7 +3,8 @@ project(trimesh_curvature) if (VCG_HEADER_ONLY) set(SOURCES - trimesh_curvature.cpp) + trimesh_curvature.cpp + ${VCG_INCLUDE_DIRS}/wrap/ply/plylib.cpp) endif() add_executable(trimesh_curvature From 23a24290a28ca0096c77544ff59d2df841d3b568 Mon Sep 17 00:00:00 2001 From: Luigi Malomo Date: Wed, 3 Nov 2021 14:19:44 +0100 Subject: [PATCH 101/117] commented out per vertex curvature property (todo: decide how to handle complete removal) --- wrap/nanoply/include/nanoply.hpp | 12 ++--- wrap/nanoply/include/nanoplyWrapper.hpp | 60 ++++++++++++------------- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/wrap/nanoply/include/nanoply.hpp b/wrap/nanoply/include/nanoply.hpp index 5a213560..e4110928 100644 --- a/wrap/nanoply/include/nanoply.hpp +++ b/wrap/nanoply/include/nanoply.hpp @@ -104,8 +104,8 @@ namespace nanoply NNP_BITFLAG = 0x00040000, /**< Bit flags. */ NNP_K1 = 0x00080000, /**< Main curvaure value k1. */ NNP_K2 = 0x00100000, /**< Main curvaure value k2. */ - NNP_KG = 0x00200000, /**< Gaussian curvature value. */ - NNP_KH = 0x00400000, /**< Mean curvature value. */ +// NNP_KG = 0x00200000, /**< Gaussian curvature value. */ +// NNP_KH = 0x00400000, /**< Mean curvature value. */ NNP_K1DIR = 0x00800000, /**< Curvature direction k1. */ NNP_K2DIR = 0x01000000, /**< Curvature direction k2. */ NNP_EDGE_V1 = 0x02000000, /**< Index of the first vertex of the edge. */ @@ -242,8 +242,8 @@ namespace nanoply { PlyEntity::NNP_BITFLAG, NameVector({ "flags" }) }, { PlyEntity::NNP_K1, NameVector({ "k1" }) }, { PlyEntity::NNP_K2, NameVector({ "k2" }) }, - { PlyEntity::NNP_KG, NameVector({ "k" }) }, - { PlyEntity::NNP_KH, NameVector({ "h" }) }, +// { PlyEntity::NNP_KG, NameVector({ "k" }) }, +// { PlyEntity::NNP_KH, NameVector({ "h" }) }, { PlyEntity::NNP_K1DIR, NameVector({ "k1dir" }) }, { PlyEntity::NNP_K2DIR, NameVector({ "k2dir" }) }, { PlyEntity::NNP_EDGE_V1, NameVector({ "vertex1", "v1" }) }, @@ -738,8 +738,8 @@ namespace nanoply case NNP_BITFLAG: return "NNP_BITFLAG "; case NNP_K1: return "NNP_K1 "; case NNP_K2: return "NNP_K2 "; - case NNP_KG: return "NNP_K "; - case NNP_KH: return "NNP_H "; +// case NNP_KG: return "NNP_K "; +// case NNP_KH: return "NNP_H "; case NNP_K1DIR: return "NNP_K1DIR "; case NNP_K2DIR: return "NNP_K2DIR "; case NNP_EDGE_V1: return "NNP_EDGE_V1 "; diff --git a/wrap/nanoply/include/nanoplyWrapper.hpp b/wrap/nanoply/include/nanoplyWrapper.hpp index abab3417..800b3427 100644 --- a/wrap/nanoply/include/nanoplyWrapper.hpp +++ b/wrap/nanoply/include/nanoplyWrapper.hpp @@ -856,8 +856,8 @@ namespace nanoply case NNP_DENSITY: mask |= BitMask::IO_VERTRADIUS; break; case NNP_TEXTURE2D: case NNP_TEXTURE3D: mask |= BitMask::IO_VERTTEXCOORD; break; - case NNP_KH: - case NNP_KG: mask |= BitMask::IO_VERTCURV; break; +// case NNP_KH: +// case NNP_KG: mask |= BitMask::IO_VERTCURV; break; case NNP_K1: case NNP_K2: case NNP_K1DIR: @@ -1012,21 +1012,21 @@ namespace nanoply else vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_TEXTURE2D, (*mesh.vert.begin()).T().P().V())); } - if ((bitMask & BitMask::IO_VERTCURV) && vcg::tri::HasPerVertexCurvature(mesh)) - { - if (ocfVertexMask & BitMask::IO_VERTCURV) - { - vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_KG, &(*mesh.vert.begin()).Kg())); - vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_KH, &(*mesh.vert.begin()).Kh())); - } - else - { - vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_KG, &(*mesh.vert.begin()).Kg())); - vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_KH, &(*mesh.vert.begin()).Kh())); - } - } - if ((bitMask & BitMask::IO_VERTCURVDIR) && vcg::tri::HasPerVertexCurvatureDir(mesh)) - { +// if ((bitMask & BitMask::IO_VERTCURV) && vcg::tri::HasPerVertexCurvature(mesh)) +// { +// if (ocfVertexMask & BitMask::IO_VERTCURV) +// { +// vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_KG, &(*mesh.vert.begin()).Kg())); +// vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_KH, &(*mesh.vert.begin()).Kh())); +// } +// else +// { +// vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_KG, &(*mesh.vert.begin()).Kg())); +// vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_KH, &(*mesh.vert.begin()).Kh())); +// } +// } + if ((bitMask & BitMask::IO_VERTCURVDIR) && vcg::tri::HasPerVertexCurvatureDir(mesh)) + { if (ocfVertexMask & BitMask::IO_VERTCURVDIR) { vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K1, &(*mesh.vert.begin()).K1())); @@ -1380,19 +1380,19 @@ namespace nanoply else PushDescriport(vertexProp, vertexDescr, NNP_TEXTURE2D, (*mesh.vert.begin()).T().P().V()); } - if ((bitMask & BitMask::IO_VERTCURV) && vcg::tri::HasPerVertexCurvature(mesh)) - { - if (ocfVertexMask & BitMask::IO_VERTTEXCOORD) - { - PushDescriport(vertexProp, vertexDescr, NNP_KG, &(*mesh.vert.begin()).Kg()); - PushDescriport(vertexProp, vertexDescr, NNP_KH, &(*mesh.vert.begin()).Kh()); - } - else - { - PushDescriport(vertexProp, vertexDescr, NNP_KG, &(*mesh.vert.begin()).Kg()); - PushDescriport(vertexProp, vertexDescr, NNP_KH, &(*mesh.vert.begin()).Kh()); - } - } +// if ((bitMask & BitMask::IO_VERTCURV) && vcg::tri::HasPerVertexCurvature(mesh)) +// { +// if (ocfVertexMask & BitMask::IO_VERTTEXCOORD) +// { +// PushDescriport(vertexProp, vertexDescr, NNP_KG, &(*mesh.vert.begin()).Kg()); +// PushDescriport(vertexProp, vertexDescr, NNP_KH, &(*mesh.vert.begin()).Kh()); +// } +// else +// { +// PushDescriport(vertexProp, vertexDescr, NNP_KG, &(*mesh.vert.begin()).Kg()); +// PushDescriport(vertexProp, vertexDescr, NNP_KH, &(*mesh.vert.begin()).Kh()); +// } +// } if ((bitMask & BitMask::IO_VERTCURVDIR) && vcg::tri::HasPerVertexCurvatureDir(mesh)) { if (ocfVertexMask & BitMask::IO_VERTCURVDIR) From 97a521fd23772ac2561dad3128f02c354ee1f0ca Mon Sep 17 00:00:00 2001 From: jmespadero Date: Fri, 5 Nov 2021 10:43:29 +0100 Subject: [PATCH 102/117] Edge orientation coherence Sort edges in output of IntersectionPlaneMesh() to remove duplicate vertex and maintain orientation coherence in the edges. Before this change, the vertex list contains duplicates and the edge list is not sorted, so there is no easy way to build the polylines of the cut. Calling RemoveDuplicateVertex() will produce a edge list with no coherence, like this example: ``` edge [0 1] goes from [0.12843863 0.38690682 0.1] to [0.13383933 0.3839188 0.1] edge [2 3] goes from [0.14307424 0.38100217 0.1] to [0.13592989 0.38318165 0.1] edge [3 1] goes from [0.13592989 0.38318165 0.1] to [0.13383933 0.3839188 0.1] ``` The output is correct, but somehow confusing because edges in the polyline(s) are not in order. After the proposed change, the output will be: ``` edge [0 1] goes from [0.12843863 0.38690682 0.1] to [0.13383933 0.3839188 0.1] edge [1 3] goes from [0.13383933 0.3839188 0.1] to [0.13592989 0.38318165 0.1] edge [3 2] goes from [0.13592989 0.38318165 0.1] to [0.14307424 0.38100217 0.1] ``` --- vcg/complex/algorithms/intersection.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/vcg/complex/algorithms/intersection.h b/vcg/complex/algorithms/intersection.h index b0c8cab9..3277ee5a 100644 --- a/vcg/complex/algorithms/intersection.h +++ b/vcg/complex/algorithms/intersection.h @@ -195,6 +195,26 @@ bool IntersectionPlaneMesh(TriMeshType & m, } tri::Allocator :: template DeletePerVertexAttribute < ScalarType >(m,qH); + //Clean-up: Remove duplicate vertex + tri::Clean::RemoveDuplicateVertex(em); + + //Clean-up: Sort edges ensuring orientation coherence + for(size_t j=1; j < em.edge.size(); j++) + { + auto &n=em.edge[j-1].V(1); + for(size_t i=j; i< em.edge.size(); i++) + { + auto & ei=em.edge[i]; + if (ei.V(1) == n) + std::swap(ei.V(0), ei.V(1)); + if (ei.V(0) == n) + { + std::swap(em.edge[j], em.edge[i]); + break; + } + } + } + return true; } From 117daf1a76b80ef4da6e6eddb8ee1051f83e7b4b Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Fri, 5 Nov 2021 12:24:52 +0100 Subject: [PATCH 103/117] obj materials importer less restrictive when reads something unexpected --- wrap/io_trimesh/import_obj.h | 78 +++++++++++++++--------------------- 1 file changed, 33 insertions(+), 45 deletions(-) diff --git a/wrap/io_trimesh/import_obj.h b/wrap/io_trimesh/import_obj.h index 0a3a6347..5b8ab94d 100644 --- a/wrap/io_trimesh/import_obj.h +++ b/wrap/io_trimesh/import_obj.h @@ -985,20 +985,16 @@ public: currentMaterial.illum = 2; bool first = true; - while (!stream.eof()) - { + while (!stream.eof()) { tokens.clear(); TokenizeNextLine(stream, tokens, line, 0); - if (tokens.size() > 0) - { + if (tokens.size() > 0) { header.clear(); header = tokens[0]; - if (header.compare("newmtl")==0) - { - if (!first) - { + if (header.compare("newmtl")==0) { + if (!first) { materials.push_back(currentMaterial); currentMaterial = Material(); currentMaterial.index = (unsigned int)(-1); @@ -1013,43 +1009,39 @@ public: else currentMaterial.materialName = line.substr(7); //space in the name, get everything after "newmtl " } - else if (header.compare("Ka")==0) - { - if (tokens.size() < 4) return false; - currentMaterial.Ka = Point3fFrom3Tokens(tokens,1); + else if (header.compare("Ka")==0) { + if (tokens.size() < 4) { + currentMaterial.Ka = Point3fFrom3Tokens(tokens,1); + } } - else if (header.compare("Kd")==0) - { - if (tokens.size() < 4) return false; - currentMaterial.Kd = Point3fFrom3Tokens(tokens,1); + else if (header.compare("Kd")==0) { + if (tokens.size() < 4) { + currentMaterial.Kd = Point3fFrom3Tokens(tokens,1); + } } - else if (header.compare("Ks")==0) - { - if (tokens.size() < 4) return false; - currentMaterial.Ks = Point3fFrom3Tokens(tokens,1); + else if (header.compare("Ks")==0) { + if (tokens.size() < 4) { + currentMaterial.Ks = Point3fFrom3Tokens(tokens,1); + } } - else if ( (header.compare("d")==0) || - (header.compare("Tr")==0) ) // alpha - { - if (tokens.size() < 2) return false; - currentMaterial.Tr = (float) atof(tokens[1].c_str()); + else if ((header.compare("d")==0) || (header.compare("Tr")==0)) { // alpha + if (tokens.size() < 2) { + currentMaterial.Tr = (float) atof(tokens[1].c_str()); + } } - else if (header.compare("Ns")==0) // shininess - { - if (tokens.size() < 2) return false; - currentMaterial.Ns = float(atoi(tokens[1].c_str())); + else if (header.compare("Ns")==0) { // shininess + if (tokens.size() < 2) { + currentMaterial.Ns = float(atoi(tokens[1].c_str())); + } } - else if (header.compare("illum")==0) // specular illumination on/off - { - if (tokens.size() < 2) return false; - currentMaterial.illum = atoi(tokens[1].c_str());; + else if (header.compare("illum")==0) { // specular illumination on/off + if (tokens.size() < 2) { + currentMaterial.illum = atoi(tokens[1].c_str()); + } } - else if(header.compare("map_Kd")==0) // texture name - { + else if(header.compare("map_Kd")==0) { // texture name std::string textureName; - if (tokens.size() < 2) - return false; - else { + if (tokens.size() == 2) { //the tex name is the last one (after any option) textureName = tokens[tokens.size()-1]; } @@ -1074,19 +1066,15 @@ public: stream.close(); // Sometimes some materials have texture and no texture // in this case for sake of uniformity we just use the first texture. - if(!textures.empty()) - { - for(size_t i=0;i Date: Thu, 28 Oct 2021 13:24:24 +0200 Subject: [PATCH 104/117] Update export_ply.h --- wrap/io_trimesh/export_ply.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/wrap/io_trimesh/export_ply.h b/wrap/io_trimesh/export_ply.h index 95d52350..c69106b2 100644 --- a/wrap/io_trimesh/export_ply.h +++ b/wrap/io_trimesh/export_ply.h @@ -579,7 +579,7 @@ public: fprintf(fpout,"%.*g ",DGTVR,vp->R()); if( HasPerVertexTexCoord(m) && (pi.mask & Mask::IOM_VERTTEXCOORD) ) - fprintf(fpout,"%.*g %.*g",DGTVT,vp->T().u(),vp->T().v()); + fprintf(fpout,"%.*g %.*g",DGTVT,vp->T().u(),DGTVT,vp->T().v()); for(size_t i=0;iVN()*2); for(int k=0;kVN();++k) fprintf(fpout,"%.*g %.*g " - ,DGTFT - ,fp->V(k)->T().u() - ,fp->V(k)->T().v() + ,DGTFT,fp->V(k)->T().u() + ,DGTFT,fp->V(k)->T().v() ); } else if( HasPerWedgeTexCoord(m) && (pi.mask & Mask::IOM_WEDGTEXCOORD) ) From 63a227dd92d8bd14861a23997b51d0c81ea2ba69 Mon Sep 17 00:00:00 2001 From: Paolo Cignoni Date: Thu, 28 Oct 2021 21:21:15 +0200 Subject: [PATCH 105/117] removed useless selection count call in append --- vcg/complex/append.h | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/vcg/complex/append.h b/vcg/complex/append.h index bba38581..33229da3 100644 --- a/vcg/complex/append.h +++ b/vcg/complex/append.h @@ -299,9 +299,10 @@ static void MeshAppendConst( // vertex remap.vert.resize(mr.vert.size(), Remap::InvalidIndex()); VertexIteratorLeft vp; - size_t svn = UpdateSelection::VertexCount(mr); - if(selected) + if(selected){ + size_t svn = UpdateSelection::VertexCount(mr); vp=Allocator::AddVertices(ml,int(svn)); + } else vp=Allocator::AddVertices(ml,mr.vn); @@ -317,8 +318,10 @@ static void MeshAppendConst( // edge remap.edge.resize(mr.edge.size(), Remap::InvalidIndex()); EdgeIteratorLeft ep; - size_t sen = UpdateSelection::EdgeCount(mr); - if(selected) ep=Allocator::AddEdges(ml,sen); + if(selected) { + size_t sen = UpdateSelection::EdgeCount(mr); + ep=Allocator::AddEdges(ml,sen); + } else ep=Allocator::AddEdges(ml,mr.en); ForEachEdge(mr, [&](const EdgeRight& e) @@ -333,8 +336,10 @@ static void MeshAppendConst( // face remap.face.resize(mr.face.size(), Remap::InvalidIndex()); FaceIteratorLeft fp; - size_t sfn = UpdateSelection::FaceCount(mr); - if(selected) fp=Allocator::AddFaces(ml,sfn); + if(selected) { + size_t sfn = UpdateSelection::FaceCount(mr); + fp=Allocator::AddFaces(ml,sfn); + } else fp=Allocator::AddFaces(ml,mr.fn); ForEachFace(mr, [&](const FaceRight& f) From f2400770c1077d7e3499800aa22a6d0361e0a205 Mon Sep 17 00:00:00 2001 From: Paolo Cignoni Date: Thu, 28 Oct 2021 21:22:19 +0200 Subject: [PATCH 106/117] improved behaviour of distribution/histogram in presence of NaN --- vcg/complex/algorithms/stat.h | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/vcg/complex/algorithms/stat.h b/vcg/complex/algorithms/stat.h index f0e8502e..c9b0e7cb 100644 --- a/vcg/complex/algorithms/stat.h +++ b/vcg/complex/algorithms/stat.h @@ -299,11 +299,14 @@ public: static void ComputePerVertexQualityDistribution(const MeshType & m, Distribution & h, bool selectionOnly = false) // V1.0 { tri::RequirePerVertexQuality(m); + h.Clear(); for(ConstVertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi) if(!(*vi).IsD() && ((!selectionOnly) || (*vi).IsS()) ) { - assert(!math::IsNAN((*vi).Q()) && "You should never try to compute Histogram with Invalid Floating points numbers (NaN)"); - h.Add((*vi).Q()); + if(!math::IsNAN((*vi).Q())) + h.Add((*vi).Q()); + else + assert( "You should never try to compute Histogram with Invalid Floating points numbers (NaN)"); } } @@ -311,11 +314,14 @@ public: bool selectionOnly = false) // V1.0 { tri::RequirePerFaceQuality(m); + h.Clear(); for(ConstFaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi) if(!(*fi).IsD() && ((!selectionOnly) || (*fi).IsS()) ) { - assert(!math::IsNAN((*fi).Q()) && "You should never try to compute Histogram with Invalid Floating points numbers (NaN)"); - h.Add((*fi).Q()); + if(!math::IsNAN((*fi).Q())) + h.Add((*fi).Q()); + else + assert( "You should never try to compute Histogram with Invalid Floating points numbers (NaN)"); } } From e07681039431d8e09b79322a9e3296d4e594b1bd Mon Sep 17 00:00:00 2001 From: Paolo Cignoni Date: Thu, 28 Oct 2021 21:22:42 +0200 Subject: [PATCH 107/117] removed useless var --- vcg/complex/algorithms/update/curvature_fitting.h | 1 - 1 file changed, 1 deletion(-) diff --git a/vcg/complex/algorithms/update/curvature_fitting.h b/vcg/complex/algorithms/update/curvature_fitting.h index 9de9fe3e..332b3d36 100644 --- a/vcg/complex/algorithms/update/curvature_fitting.h +++ b/vcg/complex/algorithms/update/curvature_fitting.h @@ -633,7 +633,6 @@ class Quadric if (cb && ((i%1024)==00)) { (*cb)(int(100.0f * (float)i / (float)mesh.vn),"Vertices Analysis"); } - int count; expandSphereLocal (mesh, &*vi, radiusSphere, 5, &vv); assert (vv.size() >= 5); From 0aac58999664d93b077080373edcc4aed348d3db Mon Sep 17 00:00:00 2001 From: Paolo Cignoni Date: Fri, 29 Oct 2021 14:26:00 +0200 Subject: [PATCH 108/117] removed useless HG components from the vertex component set Replaced by much simpler attributes --- vcg/complex/base.h | 3 -- vcg/simplex/vertex/component.h | 49 ------------------------------ vcg/simplex/vertex/component_ocf.h | 44 --------------------------- 3 files changed, 96 deletions(-) diff --git a/vcg/complex/base.h b/vcg/complex/base.h index befda76c..b59e26e6 100644 --- a/vcg/complex/base.h +++ b/vcg/complex/base.h @@ -666,7 +666,6 @@ template < class VertexType> bool VertexVectorHasPerVertexColor (const std template < class VertexType> bool VertexVectorHasPerVertexMark (const std::vector &) { return VertexType::HasMark (); } template < class VertexType> bool VertexVectorHasPerVertexFlags (const std::vector &) { return VertexType::HasFlags (); } template < class VertexType> bool VertexVectorHasPerVertexRadius (const std::vector &) { return VertexType::HasRadius (); } -template < class VertexType> bool VertexVectorHasPerVertexCurvature (const std::vector &) { return VertexType::HasCurvature (); } template < class VertexType> bool VertexVectorHasPerVertexCurvatureDir(const std::vector &) { return VertexType::HasCurvatureDir(); } template < class VertexType> bool VertexVectorHasPerVertexTexCoord (const std::vector &) { return VertexType::HasTexCoord (); } @@ -676,7 +675,6 @@ template < class TriMeshType> bool HasPerVertexColor (const TriMeshType &m template < class TriMeshType> bool HasPerVertexMark (const TriMeshType &m) { return tri::VertexVectorHasPerVertexMark (m.vert); } template < class TriMeshType> bool HasPerVertexFlags (const TriMeshType &m) { return tri::VertexVectorHasPerVertexFlags (m.vert); } template < class TriMeshType> bool HasPerVertexRadius (const TriMeshType &m) { return tri::VertexVectorHasPerVertexRadius (m.vert); } -template < class TriMeshType> bool HasPerVertexCurvature (const TriMeshType &m) { return tri::VertexVectorHasPerVertexCurvature (m.vert); } template < class TriMeshType> bool HasPerVertexCurvatureDir(const TriMeshType &m) { return tri::VertexVectorHasPerVertexCurvatureDir(m.vert); } template < class TriMeshType> bool HasPerVertexTexCoord (const TriMeshType &m) { return tri::VertexVectorHasPerVertexTexCoord (m.vert); } @@ -877,7 +875,6 @@ template void RequirePerVertexColor (const MeshType &m) { template void RequirePerVertexMark (const MeshType &m) { if(!tri::HasPerVertexMark (m)) throw vcg::MissingComponentException("PerVertexMark "); } template void RequirePerVertexFlags (const MeshType &m) { if(!tri::HasPerVertexFlags (m)) throw vcg::MissingComponentException("PerVertexFlags "); } template void RequirePerVertexRadius (const MeshType &m) { if(!tri::HasPerVertexRadius (m)) throw vcg::MissingComponentException("PerVertexRadius "); } -template void RequirePerVertexCurvature (const MeshType &m) { if(!tri::HasPerVertexCurvature (m)) throw vcg::MissingComponentException("PerVertexCurvature "); } template void RequirePerVertexCurvatureDir(const MeshType &m) { if(!tri::HasPerVertexCurvatureDir(m)) throw vcg::MissingComponentException("PerVertexCurvatureDir"); } template void RequirePerVertexTexCoord (const MeshType &m) { if(!tri::HasPerVertexTexCoord (m)) throw vcg::MissingComponentException("PerVertexTexCoord "); } diff --git a/vcg/simplex/vertex/component.h b/vcg/simplex/vertex/component.h index dab25640..37f27f93 100644 --- a/vcg/simplex/vertex/component.h +++ b/vcg/simplex/vertex/component.h @@ -158,15 +158,8 @@ public: static bool HasVHAdjacency() { return false; } typedef float CurScalarType; - typedef float ScalarTypeCur; typedef Point3f CurVecType; typedef Point2f CurvatureType; - float &Kh() { static float dummy = 0.f; assert(0);return dummy;} - float &Kg() { static float dummy = 0.f; assert(0);return dummy;} - float Kh() const { static float dummy = 0.f; assert(0); return dummy;} - float Kg() const { static float dummy = 0.f; assert(0); return dummy;} - float cKh() const { static float dummy = 0.f; assert(0); return dummy;} - float cKg() const { static float dummy = 0.f; assert(0); return dummy;} typedef CurvatureDirBaseType CurvatureDirType; CurVecType &PD1() {static CurVecType v(0,0,0); assert(0);return v;} @@ -183,9 +176,7 @@ public: CurScalarType cK1() const {static ScalarType v = 0.0;assert(0);return v;} CurScalarType cK2() const {static ScalarType v = 0.0;assert(0);return v;} - static bool HasCurvature() { return false; } static bool HasCurvatureDir() { return false; } - inline bool IsCurvatureEnabled() const { return TT::VertexType::HasCurvature();} inline bool IsCurvatureDirEnabled() const { return TT::VertexType::HasCurvatureDir();} template < class RightValueType> @@ -428,46 +419,6 @@ template class Qualityd: public Quality { public: static void Name(std::vector & name){name.push_back(std::string("Qualityd"));TT::Name(name);} }; - /*-------------------------- Curvature ----------------------------------*/ - - /*! \brief \em Component: Per vertex basic \b curvature - This component keeps the mean an gaussian curvature for a vertex. Used by some of the algorithms of vcg::tri::UpdateCurvature to store the computed curvatures. - */ - template class Curvature: public TT { - public: - typedef Point2 CurvatureType; - typedef typename CurvatureType::ScalarType ScalarTypeCur; - const ScalarTypeCur &Kh() const { return _hk[0]; } - const ScalarTypeCur &Kg() const { return _hk[1]; } - ScalarTypeCur &Kh() { return _hk[0]; } - ScalarTypeCur &Kg() { return _hk[1]; } - ScalarTypeCur cKh() const { return _hk[0]; } - ScalarTypeCur cKg() const { return _hk[1]; } - - template < class RightValueType> - void ImportData(const RightValueType & rVert ) { - if(rVert.IsCurvatureEnabled()) { - Kh() = rVert.cKh(); - Kg() = rVert.cKg(); - } - TT::ImportData( rVert); - } - - static bool HasCurvature() { return true; } - static void Name(std::vector & name){name.push_back(std::string("Curvature"));TT::Name(name);} - - private: - Point2 _hk; - }; - - - template class Curvaturef: public Curvature< float, T> { - public: static void Name(std::vector & name){name.push_back(std::string("Curvaturef"));T::Name(name);} - }; - template class Curvatured: public Curvature { - public: static void Name(std::vector & name){name.push_back(std::string("Curvatured"));T::Name(name);} - }; - /*-------------------------- Curvature Direction ----------------------------------*/ /*! \brief \em Component: Per vertex \b curvature \b directions diff --git a/vcg/simplex/vertex/component_ocf.h b/vcg/simplex/vertex/component_ocf.h index 8750066c..4ad90edb 100644 --- a/vcg/simplex/vertex/component_ocf.h +++ b/vcg/simplex/vertex/component_ocf.h @@ -432,50 +432,6 @@ public: }; -///*-------------------------- CURVATURE ----------------------------------*/ - -template class CurvatureOcf: public TT { -public: - typedef Point2 CurvatureType; - typedef typename CurvatureType::ScalarType ScalarTypeCur; - - ScalarTypeCur &Kh(){ assert((*this).Base().CurvatureEnabled); return (*this).Base().CuV[(*this).Index()][0]; } - ScalarTypeCur &Kg(){ assert((*this).Base().CurvatureEnabled); return (*this).Base().CuV[(*this).Index()][1]; } - ScalarTypeCur cKh() const - { - assert((*this).Base().CurvatureEnabled); - return (*this).Base().CuV[(*this).Index()][0]; - } - - ScalarTypeCur cKg() const - { - assert((*this).Base().CurvatureEnabled); - return (*this).Base().CuV[(*this).Index()][1]; - } - - template - void ImportData(const RightVertexType & rightV){ - if((*this).IsCurvatureEnabled() && rightV.IsCurvatureEnabled()) - { - (*this).Base().CuV[(*this).Index()][0] = rightV.cKh(); - (*this).Base().CuV[(*this).Index()][1] = rightV.cKg(); - } - TT::ImportData(rightV); - } - - inline bool IsCurvatureEnabled( ) const - { - return this->Base().IsCurvatureEnabled(); - } - - static bool HasCurvature() { return true; } - static bool HasCurvatureOcf() { return true; } -}; - -template class CurvaturefOcf: public CurvatureOcf {public: static void Name(std::vector & name){name.push_back(std::string("CurvaturefOcf"));T::Name(name);} }; -template class CurvaturedOcf: public CurvatureOcf {public: static void Name(std::vector & name){name.push_back(std::string("CurvaturedOcf"));T::Name(name);} }; - - ///*-------------------------- CURVATURE DIR ----------------------------------*/ template From fa5f92979e59f70e08ccfc8a00772c89f5d06d68 Mon Sep 17 00:00:00 2001 From: Paolo Cignoni Date: Fri, 29 Oct 2021 14:26:38 +0200 Subject: [PATCH 109/117] Updated curvature and quality function to do not use components but attributes --- vcg/complex/algorithms/update/curvature.h | 126 ++++++++++++---------- vcg/complex/algorithms/update/quality.h | 54 +++++----- 2 files changed, 96 insertions(+), 84 deletions(-) diff --git a/vcg/complex/algorithms/update/curvature.h b/vcg/complex/algorithms/update/curvature.h index 5b9a5364..e61e2ce8 100644 --- a/vcg/complex/algorithms/update/curvature.h +++ b/vcg/complex/algorithms/update/curvature.h @@ -400,7 +400,6 @@ For further details, please, refer to: \n static void MeanAndGaussian(MeshType & m) { tri::RequireFFAdjacency(m); - tri::RequirePerVertexCurvature(m); float area0, area1, area2, angle0, angle1, angle2; FaceIterator fi; @@ -411,13 +410,16 @@ static void MeanAndGaussian(MeshType & m) SimpleTempData TDContr(m.vert); vcg::tri::UpdateNormal::PerVertexNormalized(m); + auto KH = vcg::tri::Allocator:: template GetPerVertexAttribute (m, std::string("KH")); + auto KG = vcg::tri::Allocator:: template GetPerVertexAttribute (m, std::string("KG")); + //Compute AreaMix in H (vale anche per K) for(vi=m.vert.begin(); vi!=m.vert.end(); ++vi) if(!(*vi).IsD()) { (TDAreaPtr)[*vi].A = 0.0; (TDContr)[*vi] =typename MeshType::CoordType(0.0,0.0,0.0); - (*vi).Kh() = 0.0; - (*vi).Kg() = (float)(2.0 * M_PI); + KH[*vi] = 0.0; + KG[*vi] = (ScalarType)(2.0 * M_PI); } for(fi=m.face.begin();fi!=m.face.end();++fi) if( !(*fi).IsD()) @@ -482,10 +484,10 @@ static void MeanAndGaussian(MeshType & m) TDContr[(*fi).V(0)] += ( e20v * (1.0/tan(angle1)) - e01v * (1.0/tan(angle2)) ) / 4.0; TDContr[(*fi).V(1)] += ( e01v * (1.0/tan(angle2)) - e12v * (1.0/tan(angle0)) ) / 4.0; TDContr[(*fi).V(2)] += ( e12v * (1.0/tan(angle0)) - e20v * (1.0/tan(angle1)) ) / 4.0; - - (*fi).V(0)->Kg() -= angle0; - (*fi).V(1)->Kg() -= angle1; - (*fi).V(2)->Kg() -= angle2; + + KG[(*fi).V(0)] -= angle0; + KG[(*fi).V(1)] -= angle1; + KG[(*fi).V(2)] -= angle2; for(int i=0;i<3;i++) @@ -501,7 +503,7 @@ static void MeanAndGaussian(MeshType & m) hp1.FlipV(); hp1.NextB(); e2=hp1.v->cP() - hp.v->cP(); - (*fi).V(i)->Kg() -= math::Abs(Angle(e1,e2)); + KG[(*fi).V(i)] -= math::Abs(Angle(e1,e2)); } } } @@ -510,13 +512,13 @@ static void MeanAndGaussian(MeshType & m) { if((TDAreaPtr)[*vi].A<=std::numeric_limits::epsilon()) { - (*vi).Kh() = 0; - (*vi).Kg() = 0; + KH[(*vi)] = 0; + KG[(*vi)] = 0; } else { - (*vi).Kh() = (((TDContr)[*vi].dot((*vi).cN())>0)?1.0:-1.0)*((TDContr)[*vi] / (TDAreaPtr) [*vi].A).Norm(); - (*vi).Kg() /= (TDAreaPtr)[*vi].A; + KH[(*vi)] = (((TDContr)[*vi].dot((*vi).cN())>0)?1.0:-1.0)*((TDContr)[*vi] / (TDAreaPtr) [*vi].A).Norm(); + KG[(*vi)] /= (TDAreaPtr)[*vi].A; } } } @@ -526,78 +528,86 @@ static void MeanAndGaussian(MeshType & m) /** The function uses the VF adiacency to walk around the vertex. - \return It will return the voronoi area around the vertex. If (norm == true) the mean and the gaussian curvature are normalized. - Based on the paper "Optimizing 3d triangulations using discrete curvature analysis" - */ - - static float ComputeSingleVertexCurvature(VertexPointer v, bool norm = true) + + Based on the paper + "Optimizing 3d triangulations using discrete curvature analysis" + it compute an approximation of the gaussian and of the absolute mean curvature + */ +static void PerVertexAbsoluteMeanAndGaussian(MeshType & m) +{ + tri::RequireVFAdjacency(m); + tri::RequireCompactness(m); + const bool areaNormalize = true; + const bool barycentricArea=false; + auto KH = vcg::tri::Allocator:: template GetPerVertexAttribute (m, std::string("KH")); + auto KG = vcg::tri::Allocator:: template GetPerVertexAttribute (m, std::string("KG")); + int faceCnt=0; + for(VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi) { + VertexPointer v=&*vi; VFIteratorType vfi(v); - float A = 0; + ScalarType A = 0; - v->Kh() = 0; - v->Kg() = 2 * M_PI; + KH[v] = 0; + ScalarType AngleDefect = (ScalarType)(2.0 * M_PI);; while (!vfi.End()) { - if (!vfi.F()->IsD()) { + faceCnt++; FacePointer f = vfi.F(); CoordType nf = TriangleNormal(*f); int i = vfi.I(); VertexPointer v0 = f->V0(i), v1 = f->V1(i), v2 = f->V2(i); + assert (v==v0); - float ang0 = math::Abs(Angle(v1->P() - v0->P(), v2->P() - v0->P() )); - float ang1 = math::Abs(Angle(v0->P() - v1->P(), v2->P() - v1->P() )); - float ang2 = M_PI - ang0 - ang1; + ScalarType ang0 = math::Abs(Angle(v1->P() - v0->P(), v2->P() - v0->P() )); + ScalarType ang1 = math::Abs(Angle(v0->P() - v1->P(), v2->P() - v1->P() )); + ScalarType ang2 = M_PI - ang0 - ang1; - float s01 = SquaredDistance(v1->P(), v0->P()); - float s02 = SquaredDistance(v2->P(), v0->P()); + ScalarType s01 = SquaredDistance(v1->P(), v0->P()); + ScalarType s02 = SquaredDistance(v2->P(), v0->P()); // voronoi cell of current vertex - if (ang0 >= M_PI/2) - A += (0.5f * DoubleArea(*f) - (s01 * tan(ang1) + s02 * tan(ang2)) / 8.0 ); - else if (ang1 >= M_PI/2) - A += (s01 * tan(ang0)) / 8.0; - else if (ang2 >= M_PI/2) - A += (s02 * tan(ang0)) / 8.0; - else // non obctuse triangle - A += ((s02 / tan(ang1)) + (s01 / tan(ang2))) / 8.0; - + if(barycentricArea) + A+=vcg::DoubleArea(*f)/6.0; + else + { + if (ang0 >= M_PI/2) + A += (0.5f * DoubleArea(*f) - (s01 * tan(ang1) + s02 * tan(ang2)) / 8.0 ); + else if (ang1 >= M_PI/2) + A += (s01 * tan(ang0)) / 8.0; + else if (ang2 >= M_PI/2) + A += (s02 * tan(ang0)) / 8.0; + else // non obctuse triangle + A += ((s02 / tan(ang1)) + (s01 / tan(ang2))) / 8.0; + } // gaussian curvature update - v->Kg() -= ang0; + AngleDefect -= ang0; // mean curvature update - ang1 = math::Abs(Angle(nf, v1->N())); - ang2 = math::Abs(Angle(nf, v2->N())); - v->Kh() += ( (math::Sqrt(s01) / 2.0) * ang1 + - (math::Sqrt(s02) / 2.0) * ang2 ); - } - + // Note that the standard abs mean curvature approximation would require + // to sum all the edges*diehedralAngle. Here with just VF adjacency + // we make a rough approximation that 1/2 of the edge len plus something + // that is half of the diedral angle + ang1 = math::Abs(Angle(nf, v1->N()+v0->N())); + ang2 = math::Abs(Angle(nf, v2->N()+v0->N())); + KH[v] += math::Sqrt(s01)*ang1 + math::Sqrt(s02)*ang2 ; ++vfi; } - v->Kh() /= 4.0f; + KH[v] /= 4.0; - if(norm) { + if(areaNormalize) { if(A <= std::numeric_limits::epsilon()) { - v->Kh() = 0; - v->Kg() = 0; + KH[v] = 0; + KG[v] = 0; } else { - v->Kh() /= A; - v->Kg() /= A; + KH[v] /= A; + KG[v] = AngleDefect / A; } } - - return A; - } - - static void PerVertex(MeshType & m) - { - tri::RequireVFAdjacency(m); - - for(VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi) - ComputeSingleVertexCurvature(&*vi,false); } +} diff --git a/vcg/complex/algorithms/update/quality.h b/vcg/complex/algorithms/update/quality.h index 728c6e5f..cdb0c223 100644 --- a/vcg/complex/algorithms/update/quality.h +++ b/vcg/complex/algorithms/update/quality.h @@ -224,6 +224,15 @@ static void VertexFromAttributeHandle(MeshType &m, typename MeshType::template P (*vi).Q()=VertexQualityType(h[vi]); } +static void VertexFromAttributeName(MeshType &m, const std::string &AttrName) +{ + tri::RequirePerVertexQuality(m); + auto KH = tri::Allocator:: template FindPerVertexAttribute (m, AttrName); + if(!tri::Allocator::template IsValidHandle(m, KH)) throw vcg::MissingPreconditionException("Required Attribute is non existent"); + for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) + (*vi).Q() = KH[vi]; +} + template static void FaceFromAttributeHandle(MeshType &m, typename MeshType::template PerFaceAttributeHandle &h) { @@ -232,6 +241,15 @@ static void FaceFromAttributeHandle(MeshType &m, typename MeshType::template Per (*fi).Q() =FaceQualityType(h[fi]); } +static void FaceFromAttributeName(MeshType &m, const std::string &AttrName) +{ + tri::RequirePerFaceQuality(m); + auto KH = tri::Allocator:: template FindPerFaceAttribute (m, AttrName); + if(!tri::Allocator::template IsValidHandle(m, KH)) throw vcg::MissingPreconditionException("Required Attribute is non existent"); + for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD()) + (*fi).Q() =FaceQualityType(KH[fi]); +} + static void FaceFromVertex( MeshType &m) { tri::RequirePerFaceQuality(m); @@ -252,22 +270,6 @@ static void VertexFromPlane(MeshType &m, const Plane3 &pl) (*vi).Q() =SignedDistancePlanePoint(pl,(*vi).cP()); } -static void VertexFromGaussianCurvatureHG(MeshType &m) -{ - tri::RequirePerVertexQuality(m); - tri::RequirePerVertexCurvature(m); - for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) - (*vi).Q() = (*vi).Kg(); -} - -static void VertexFromMeanCurvatureHG(MeshType &m) -{ - tri::RequirePerVertexQuality(m); - tri::RequirePerVertexCurvature(m); - for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) - (*vi).Q() = (*vi).Kh(); -} - static void VertexFromGaussianCurvatureDir(MeshType &m) { tri::RequirePerVertexQuality(m); @@ -364,14 +366,14 @@ static void VertexFromCurvednessCurvatureDir(MeshType &m) static void VertexFromAbsoluteCurvature(MeshType &m) { tri::RequirePerVertexQuality(m); - tri::RequirePerVertexCurvature(m); - VertexIterator vi; - for(vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) + auto KH = vcg::tri::Allocator:: template GetPerVertexAttribute (m, std::string("KH")); + auto KG = vcg::tri::Allocator:: template GetPerVertexAttribute (m, std::string("KG")); + for(auto vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) { - if((*vi).Kg() >= 0) - (*vi).Q() = math::Abs( 2*(*vi).Kh() ); + if(KG[vi] >= 0) + (*vi).Q() = math::Abs( 2.0*KH[vi] ); else - (*vi).Q() = 2*math::Sqrt(math::Abs( (*vi).Kh()*(*vi).Kh() - (*vi).Kg())); + (*vi).Q() = 2*math::Sqrt(math::Abs( KH[vi]*KH[vi] - KG[vi])); } } @@ -385,10 +387,10 @@ static void VertexFromAbsoluteCurvature(MeshType &m) static void VertexFromRMSCurvature(MeshType &m) { tri::RequirePerVertexQuality(m); - tri::RequirePerVertexCurvature(m); - VertexIterator vi; - for(vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) - (*vi).Q() = math::Sqrt(math::Abs( 4*(*vi).Kh()*(*vi).Kh() - 2*(*vi).Kg())); + auto KH = vcg::tri::Allocator:: template GetPerVertexAttribute (m, std::string("KH")); + auto KG = vcg::tri::Allocator:: template GetPerVertexAttribute (m, std::string("KG")); + for(auto vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) + (*vi).Q() = math::Sqrt(math::Abs( 4*KH[vi]*KH[vi] - 2*KG[vi])); } /* From 5e9cd474f5b17394e87732b91812f12fc86926c1 Mon Sep 17 00:00:00 2001 From: Paolo Cignoni Date: Fri, 29 Oct 2021 14:58:18 +0200 Subject: [PATCH 110/117] renamed curvature extracting method for sake of coherence --- vcg/complex/algorithms/update/quality.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/vcg/complex/algorithms/update/quality.h b/vcg/complex/algorithms/update/quality.h index cdb0c223..51e8237b 100644 --- a/vcg/complex/algorithms/update/quality.h +++ b/vcg/complex/algorithms/update/quality.h @@ -270,7 +270,7 @@ static void VertexFromPlane(MeshType &m, const Plane3 &pl) (*vi).Q() =SignedDistancePlanePoint(pl,(*vi).cP()); } -static void VertexFromGaussianCurvatureDir(MeshType &m) +static void VertexGaussianFromCurvatureDir(MeshType &m) { tri::RequirePerVertexQuality(m); tri::RequirePerVertexCurvatureDir(m); @@ -278,21 +278,21 @@ static void VertexFromGaussianCurvatureDir(MeshType &m) (*vi).Q() = (*vi).K1()*(*vi).K2(); } -static void VertexFromMeanCurvatureDir(MeshType &m) +static void VertexMeanFromCurvatureDir(MeshType &m) { tri::RequirePerVertexQuality(m); tri::RequirePerVertexCurvatureDir(m); for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) (*vi).Q() = ((*vi).K1()+(*vi).K2())/2.0f; } -static void VertexFromMinCurvatureDir(MeshType &m) +static void VertexMinCurvFromCurvatureDir(MeshType &m) { tri::RequirePerVertexQuality(m); tri::RequirePerVertexCurvatureDir(m); for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) (*vi).Q() = (*vi).K1(); } -static void VertexFromMaxCurvatureDir(MeshType &m) +static void VertexMaxCurvFromCurvatureDir(MeshType &m) { tri::RequirePerVertexQuality(m); tri::RequirePerVertexCurvatureDir(m); @@ -301,7 +301,7 @@ static void VertexFromMaxCurvatureDir(MeshType &m) } /** - * @brief VertexFromShapeIndexCurvatureDir + * @brief VertexShapeIndexFromCurvatureDir * Compute from the current Curvature Direction the Shape Index S as defined by [Koenderink 1992] * and store it in the per-vertex Quality. * S = 2/pi atan(k1+k2/k1-k2) @@ -311,7 +311,7 @@ static void VertexFromMaxCurvatureDir(MeshType &m) * Image and vision computing, 10(8):557–565, 1992. */ -static void VertexFromShapeIndexCurvatureDir(MeshType &m) +static void VertexShapeIndexFromCurvatureDir(MeshType &m) { tri::RequirePerVertexQuality(m); tri::RequirePerVertexCurvatureDir(m); @@ -324,7 +324,7 @@ static void VertexFromShapeIndexCurvatureDir(MeshType &m) } } /** - * @brief VertexFromCurvednessCurvatureDir + * @brief VertexCurvednessFromCurvatureDir * Compute from the current Curvature Direction the Curvedness as defined by [Koenderink 1992] * and store it in the per-vertex Quality. * C = Sqrt((k1*k1+k2*k2)/2.0) @@ -333,7 +333,7 @@ static void VertexFromShapeIndexCurvatureDir(MeshType &m) * Surface shape and curvature scales. * Image and vision computing, 10(8):557–565, 1992. */ -static void VertexFromCurvednessCurvatureDir(MeshType &m) +static void VertexCurvednessFromCurvatureDir(MeshType &m) { tri::RequirePerVertexQuality(m); tri::RequirePerVertexCurvatureDir(m); @@ -363,7 +363,7 @@ static void VertexFromCurvednessCurvatureDir(MeshType &m) * N Dyn, K Hormann, SJ Kim, D Levin - Mathematical Methods for Curves and Surfaces: Oslo, 2000 */ -static void VertexFromAbsoluteCurvature(MeshType &m) +static void VertexAbsoluteCurvatureFromHGAttribute(MeshType &m) { tri::RequirePerVertexQuality(m); auto KH = vcg::tri::Allocator:: template GetPerVertexAttribute (m, std::string("KH")); @@ -384,7 +384,7 @@ static void VertexFromAbsoluteCurvature(MeshType &m) * Improved curvature estimation for watershed segmentation of 3-dimensional meshes * S Pulla, A Razdan, G Farin - Arizona State University, Tech. Rep, 2001 */ -static void VertexFromRMSCurvature(MeshType &m) +static void VertexRMSCurvatureFromHGAttribute(MeshType &m) { tri::RequirePerVertexQuality(m); auto KH = vcg::tri::Allocator:: template GetPerVertexAttribute (m, std::string("KH")); From 009ea9e67115e5a8cfdc4c029bf8a9331c9ac541 Mon Sep 17 00:00:00 2001 From: Paolo Cignoni Date: Fri, 29 Oct 2021 16:11:50 +0200 Subject: [PATCH 111/117] Updated curvature sample to the last changes --- .../trimesh_curvature/trimesh_curvature.cpp | 72 ++++++++++++++----- .../trimesh_curvature/trimesh_curvature.pro | 2 +- 2 files changed, 57 insertions(+), 17 deletions(-) diff --git a/apps/sample/trimesh_curvature/trimesh_curvature.cpp b/apps/sample/trimesh_curvature/trimesh_curvature.cpp index 8569c6e5..47104819 100644 --- a/apps/sample/trimesh_curvature/trimesh_curvature.cpp +++ b/apps/sample/trimesh_curvature/trimesh_curvature.cpp @@ -23,46 +23,86 @@ /*! \file trimesh_curvature.cpp \ingroup code_sample -\brief an example showing the various techniques for computing curvatures +\brief an example showing various techniques for computing curvatures */ #include #include #include +#include -#include +#include -class MyEdge; class MyFace; class MyVertex; struct MyUsedTypes : public vcg::UsedTypes< vcg::Use ::AsVertexType, - vcg::Use ::AsEdgeType, vcg::Use ::AsFaceType>{}; -class MyVertex : public vcg::Vertex{}; -class MyFace : public vcg::Face< MyUsedTypes, vcg::face::FFAdj, vcg::face::VFAdj, vcg::face::VertexRef, vcg::face::BitFlags > {}; -class MyEdge : public vcg::Edge{}; -class MyMesh : public vcg::tri::TriMesh< std::vector, std::vector , std::vector > {}; +class MyVertex : public vcg::Vertex{}; +class MyFace : public vcg::Face< MyUsedTypes, vcg::face::FFAdj, vcg::face::VFAdj, vcg::face::Normal3f, vcg::face::VertexRef, vcg::face::BitFlags > {}; +class MyMesh : public vcg::tri::TriMesh< std::vector, std::vector > {}; int main( int /*argc*/, char **/*argv*/ ) { MyMesh m; - vcg::tri::Torus(m,30,10); + // in a torus with radii 1 and 4 + // on the outside the principal curvature should be 1 and 1/5 + // and internally the principal curvature should be 1 and -1/3 + // Gaussian range -0.333 .. 0.200 + // mean range 0.333 .. 0.600 + //vcg::tri::Torus(m,4,1,32,16); + + + // in a sphere of radius 2 the curvature is everywhere 0.5 + // Gaussian 0.25 + // Mean 0.5 + vcg::tri::Sphere(m,5); + vcg::tri::UpdatePosition::Scale(m, 2.0); vcg::tri::UpdateTopology::FaceFace(m); vcg::tri::UpdateTopology::VertexFace(m); + vcg::tri::UpdateNormal::PerVertexNormalizedPerFaceNormalized(m); + vcg::Distribution distr; + printf("Starting mesh vn:%i fn:%i\n",m.VN(),m.FN()); - // Two different techniques for computing Discrete Gaussian and Mean Curvature - // they require the presence of the vertex::Curvature component - vcg::tri::UpdateCurvature::PerVertex(m); + // Method 1 (discrete - Optimizing 3d triangulations using discrete curvature analysis 2003) + vcg::tri::UpdateCurvature::PerVertexAbsoluteMeanAndGaussian(m); + vcg::tri::UpdateQuality::VertexFromAttributeName(m,"KG"); + vcg::tri::Stat::ComputePerVertexQualityDistribution(m,distr); + printf("Gaussian Curvature method 1 Min %f Max %f\n",distr.Min(),distr.Max()); + vcg::tri::UpdateQuality::VertexFromAttributeName(m,"KH"); + vcg::tri::Stat::ComputePerVertexQualityDistribution(m,distr); + printf("Mean Curvature method 1 Min %f Max %f\n",distr.Min(),distr.Max()); + + // Method 2 (discrete - Discrete Differential-Geometry Operators for Triangulated 2-Manifolds 2002) vcg::tri::UpdateCurvature::MeanAndGaussian(m); + vcg::tri::UpdateQuality::VertexFromAttributeName(m,"KG"); + vcg::tri::Stat::ComputePerVertexQualityDistribution(m,distr); + printf("Gaussian Curvature method 2 Min %f Max %f\n",distr.Min(),distr.Max()); + vcg::tri::UpdateQuality::VertexFromAttributeName(m,"KH"); + vcg::tri::Stat::ComputePerVertexQualityDistribution(m,distr); + printf("Mean Curvature method 2 Min %f Max %f\n",distr.Min(),distr.Max()); + vcg::tri::io::ExporterPLY::Save(m,"Torus_Discrete_Mean2.ply",vcg::tri::io::Mask::IOM_VERTQUALITY); - // Two different techniques for computing Principal Curvature Directions - // they require the presence of the vertex::CurvatureDir component + // Method 3 (directions - Estimating the Tensor of Curvature of a Surface from a Polyhedral Approximation - 1995) vcg::tri::UpdateCurvature::PrincipalDirections(m); + vcg::tri::UpdateQuality::VertexGaussianFromCurvatureDir(m); + vcg::tri::Stat::ComputePerVertexQualityDistribution(m,distr); + printf("Gaussian Curvature method 3 Min %f Max %f\n",distr.Min(),distr.Max()); + vcg::tri::UpdateQuality::VertexMeanFromCurvatureDir(m); + vcg::tri::Stat::ComputePerVertexQualityDistribution(m,distr); + printf("Mean Curvature method 3 Min %f Max %f\n",distr.Min(),distr.Max()); + + // Method 4 (directions - Restricted delaunay triangulations and normal cycle ) vcg::tri::UpdateCurvature::PrincipalDirectionsNormalCycle(m); - printf("Input mesh vn:%i fn:%i\n",m.VN(),m.FN()); - + vcg::tri::UpdateQuality::VertexGaussianFromCurvatureDir(m); + vcg::tri::Stat::ComputePerVertexQualityDistribution(m,distr); + printf("Gaussian Curvature method 4 Min %f Max %f\n",distr.Min(),distr.Max()); + vcg::tri::UpdateQuality::VertexMeanFromCurvatureDir(m); + vcg::tri::Stat::ComputePerVertexQualityDistribution(m,distr); + printf("Mean Curvature method 4 Min %f Max %f\n",distr.Min(),distr.Max()); + + return 0; } diff --git a/apps/sample/trimesh_curvature/trimesh_curvature.pro b/apps/sample/trimesh_curvature/trimesh_curvature.pro index 8342dfa4..343a355e 100644 --- a/apps/sample/trimesh_curvature/trimesh_curvature.pro +++ b/apps/sample/trimesh_curvature/trimesh_curvature.pro @@ -1,3 +1,3 @@ include(../common.pri) TARGET = trimesh_curvature -SOURCES += trimesh_curvature.cpp +SOURCES += trimesh_curvature.cpp ../../../wrap/ply/plylib.cpp From 5c63ade13d7bb8315e53ece36812fabd126b67da Mon Sep 17 00:00:00 2001 From: Paolo Cignoni Date: Fri, 29 Oct 2021 16:36:17 +0200 Subject: [PATCH 112/117] Updated cmakelist --- apps/sample/trimesh_curvature/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/sample/trimesh_curvature/CMakeLists.txt b/apps/sample/trimesh_curvature/CMakeLists.txt index a09fe6e1..57265ce7 100644 --- a/apps/sample/trimesh_curvature/CMakeLists.txt +++ b/apps/sample/trimesh_curvature/CMakeLists.txt @@ -3,7 +3,8 @@ project(trimesh_curvature) if (VCG_HEADER_ONLY) set(SOURCES - trimesh_curvature.cpp) + trimesh_curvature.cpp + ${VCG_INCLUDE_DIRS}/wrap/ply/plylib.cpp) endif() add_executable(trimesh_curvature From 7eaeb7bece61addc18d16bf6197fad67e4cd3579 Mon Sep 17 00:00:00 2001 From: Luigi Malomo Date: Wed, 3 Nov 2021 14:19:44 +0100 Subject: [PATCH 113/117] commented out per vertex curvature property (todo: decide how to handle complete removal) --- wrap/nanoply/include/nanoply.hpp | 12 ++--- wrap/nanoply/include/nanoplyWrapper.hpp | 60 ++++++++++++------------- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/wrap/nanoply/include/nanoply.hpp b/wrap/nanoply/include/nanoply.hpp index 5a213560..e4110928 100644 --- a/wrap/nanoply/include/nanoply.hpp +++ b/wrap/nanoply/include/nanoply.hpp @@ -104,8 +104,8 @@ namespace nanoply NNP_BITFLAG = 0x00040000, /**< Bit flags. */ NNP_K1 = 0x00080000, /**< Main curvaure value k1. */ NNP_K2 = 0x00100000, /**< Main curvaure value k2. */ - NNP_KG = 0x00200000, /**< Gaussian curvature value. */ - NNP_KH = 0x00400000, /**< Mean curvature value. */ +// NNP_KG = 0x00200000, /**< Gaussian curvature value. */ +// NNP_KH = 0x00400000, /**< Mean curvature value. */ NNP_K1DIR = 0x00800000, /**< Curvature direction k1. */ NNP_K2DIR = 0x01000000, /**< Curvature direction k2. */ NNP_EDGE_V1 = 0x02000000, /**< Index of the first vertex of the edge. */ @@ -242,8 +242,8 @@ namespace nanoply { PlyEntity::NNP_BITFLAG, NameVector({ "flags" }) }, { PlyEntity::NNP_K1, NameVector({ "k1" }) }, { PlyEntity::NNP_K2, NameVector({ "k2" }) }, - { PlyEntity::NNP_KG, NameVector({ "k" }) }, - { PlyEntity::NNP_KH, NameVector({ "h" }) }, +// { PlyEntity::NNP_KG, NameVector({ "k" }) }, +// { PlyEntity::NNP_KH, NameVector({ "h" }) }, { PlyEntity::NNP_K1DIR, NameVector({ "k1dir" }) }, { PlyEntity::NNP_K2DIR, NameVector({ "k2dir" }) }, { PlyEntity::NNP_EDGE_V1, NameVector({ "vertex1", "v1" }) }, @@ -738,8 +738,8 @@ namespace nanoply case NNP_BITFLAG: return "NNP_BITFLAG "; case NNP_K1: return "NNP_K1 "; case NNP_K2: return "NNP_K2 "; - case NNP_KG: return "NNP_K "; - case NNP_KH: return "NNP_H "; +// case NNP_KG: return "NNP_K "; +// case NNP_KH: return "NNP_H "; case NNP_K1DIR: return "NNP_K1DIR "; case NNP_K2DIR: return "NNP_K2DIR "; case NNP_EDGE_V1: return "NNP_EDGE_V1 "; diff --git a/wrap/nanoply/include/nanoplyWrapper.hpp b/wrap/nanoply/include/nanoplyWrapper.hpp index abab3417..800b3427 100644 --- a/wrap/nanoply/include/nanoplyWrapper.hpp +++ b/wrap/nanoply/include/nanoplyWrapper.hpp @@ -856,8 +856,8 @@ namespace nanoply case NNP_DENSITY: mask |= BitMask::IO_VERTRADIUS; break; case NNP_TEXTURE2D: case NNP_TEXTURE3D: mask |= BitMask::IO_VERTTEXCOORD; break; - case NNP_KH: - case NNP_KG: mask |= BitMask::IO_VERTCURV; break; +// case NNP_KH: +// case NNP_KG: mask |= BitMask::IO_VERTCURV; break; case NNP_K1: case NNP_K2: case NNP_K1DIR: @@ -1012,21 +1012,21 @@ namespace nanoply else vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_TEXTURE2D, (*mesh.vert.begin()).T().P().V())); } - if ((bitMask & BitMask::IO_VERTCURV) && vcg::tri::HasPerVertexCurvature(mesh)) - { - if (ocfVertexMask & BitMask::IO_VERTCURV) - { - vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_KG, &(*mesh.vert.begin()).Kg())); - vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_KH, &(*mesh.vert.begin()).Kh())); - } - else - { - vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_KG, &(*mesh.vert.begin()).Kg())); - vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_KH, &(*mesh.vert.begin()).Kh())); - } - } - if ((bitMask & BitMask::IO_VERTCURVDIR) && vcg::tri::HasPerVertexCurvatureDir(mesh)) - { +// if ((bitMask & BitMask::IO_VERTCURV) && vcg::tri::HasPerVertexCurvature(mesh)) +// { +// if (ocfVertexMask & BitMask::IO_VERTCURV) +// { +// vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_KG, &(*mesh.vert.begin()).Kg())); +// vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_KH, &(*mesh.vert.begin()).Kh())); +// } +// else +// { +// vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_KG, &(*mesh.vert.begin()).Kg())); +// vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_KH, &(*mesh.vert.begin()).Kh())); +// } +// } + if ((bitMask & BitMask::IO_VERTCURVDIR) && vcg::tri::HasPerVertexCurvatureDir(mesh)) + { if (ocfVertexMask & BitMask::IO_VERTCURVDIR) { vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K1, &(*mesh.vert.begin()).K1())); @@ -1380,19 +1380,19 @@ namespace nanoply else PushDescriport(vertexProp, vertexDescr, NNP_TEXTURE2D, (*mesh.vert.begin()).T().P().V()); } - if ((bitMask & BitMask::IO_VERTCURV) && vcg::tri::HasPerVertexCurvature(mesh)) - { - if (ocfVertexMask & BitMask::IO_VERTTEXCOORD) - { - PushDescriport(vertexProp, vertexDescr, NNP_KG, &(*mesh.vert.begin()).Kg()); - PushDescriport(vertexProp, vertexDescr, NNP_KH, &(*mesh.vert.begin()).Kh()); - } - else - { - PushDescriport(vertexProp, vertexDescr, NNP_KG, &(*mesh.vert.begin()).Kg()); - PushDescriport(vertexProp, vertexDescr, NNP_KH, &(*mesh.vert.begin()).Kh()); - } - } +// if ((bitMask & BitMask::IO_VERTCURV) && vcg::tri::HasPerVertexCurvature(mesh)) +// { +// if (ocfVertexMask & BitMask::IO_VERTTEXCOORD) +// { +// PushDescriport(vertexProp, vertexDescr, NNP_KG, &(*mesh.vert.begin()).Kg()); +// PushDescriport(vertexProp, vertexDescr, NNP_KH, &(*mesh.vert.begin()).Kh()); +// } +// else +// { +// PushDescriport(vertexProp, vertexDescr, NNP_KG, &(*mesh.vert.begin()).Kg()); +// PushDescriport(vertexProp, vertexDescr, NNP_KH, &(*mesh.vert.begin()).Kh()); +// } +// } if ((bitMask & BitMask::IO_VERTCURVDIR) && vcg::tri::HasPerVertexCurvatureDir(mesh)) { if (ocfVertexMask & BitMask::IO_VERTCURVDIR) From d3acb9bd69ae540153f7d503979fd83bb23c875e Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Fri, 5 Nov 2021 12:24:52 +0100 Subject: [PATCH 114/117] obj materials importer less restrictive when reads something unexpected --- wrap/io_trimesh/import_obj.h | 78 +++++++++++++++--------------------- 1 file changed, 33 insertions(+), 45 deletions(-) diff --git a/wrap/io_trimesh/import_obj.h b/wrap/io_trimesh/import_obj.h index 0a3a6347..5b8ab94d 100644 --- a/wrap/io_trimesh/import_obj.h +++ b/wrap/io_trimesh/import_obj.h @@ -985,20 +985,16 @@ public: currentMaterial.illum = 2; bool first = true; - while (!stream.eof()) - { + while (!stream.eof()) { tokens.clear(); TokenizeNextLine(stream, tokens, line, 0); - if (tokens.size() > 0) - { + if (tokens.size() > 0) { header.clear(); header = tokens[0]; - if (header.compare("newmtl")==0) - { - if (!first) - { + if (header.compare("newmtl")==0) { + if (!first) { materials.push_back(currentMaterial); currentMaterial = Material(); currentMaterial.index = (unsigned int)(-1); @@ -1013,43 +1009,39 @@ public: else currentMaterial.materialName = line.substr(7); //space in the name, get everything after "newmtl " } - else if (header.compare("Ka")==0) - { - if (tokens.size() < 4) return false; - currentMaterial.Ka = Point3fFrom3Tokens(tokens,1); + else if (header.compare("Ka")==0) { + if (tokens.size() < 4) { + currentMaterial.Ka = Point3fFrom3Tokens(tokens,1); + } } - else if (header.compare("Kd")==0) - { - if (tokens.size() < 4) return false; - currentMaterial.Kd = Point3fFrom3Tokens(tokens,1); + else if (header.compare("Kd")==0) { + if (tokens.size() < 4) { + currentMaterial.Kd = Point3fFrom3Tokens(tokens,1); + } } - else if (header.compare("Ks")==0) - { - if (tokens.size() < 4) return false; - currentMaterial.Ks = Point3fFrom3Tokens(tokens,1); + else if (header.compare("Ks")==0) { + if (tokens.size() < 4) { + currentMaterial.Ks = Point3fFrom3Tokens(tokens,1); + } } - else if ( (header.compare("d")==0) || - (header.compare("Tr")==0) ) // alpha - { - if (tokens.size() < 2) return false; - currentMaterial.Tr = (float) atof(tokens[1].c_str()); + else if ((header.compare("d")==0) || (header.compare("Tr")==0)) { // alpha + if (tokens.size() < 2) { + currentMaterial.Tr = (float) atof(tokens[1].c_str()); + } } - else if (header.compare("Ns")==0) // shininess - { - if (tokens.size() < 2) return false; - currentMaterial.Ns = float(atoi(tokens[1].c_str())); + else if (header.compare("Ns")==0) { // shininess + if (tokens.size() < 2) { + currentMaterial.Ns = float(atoi(tokens[1].c_str())); + } } - else if (header.compare("illum")==0) // specular illumination on/off - { - if (tokens.size() < 2) return false; - currentMaterial.illum = atoi(tokens[1].c_str());; + else if (header.compare("illum")==0) { // specular illumination on/off + if (tokens.size() < 2) { + currentMaterial.illum = atoi(tokens[1].c_str()); + } } - else if(header.compare("map_Kd")==0) // texture name - { + else if(header.compare("map_Kd")==0) { // texture name std::string textureName; - if (tokens.size() < 2) - return false; - else { + if (tokens.size() == 2) { //the tex name is the last one (after any option) textureName = tokens[tokens.size()-1]; } @@ -1074,19 +1066,15 @@ public: stream.close(); // Sometimes some materials have texture and no texture // in this case for sake of uniformity we just use the first texture. - if(!textures.empty()) - { - for(size_t i=0;i Date: Thu, 11 Nov 2021 11:37:57 +0100 Subject: [PATCH 115/117] Point3::normalized() is const and does not modify components --- vcg/space/deprecated_point3.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/vcg/space/deprecated_point3.h b/vcg/space/deprecated_point3.h index a5e75494..3362a633 100644 --- a/vcg/space/deprecated_point3.h +++ b/vcg/space/deprecated_point3.h @@ -379,7 +379,12 @@ public: } // for compatibility with eigen port - inline Point3 & normalized() { return Normalize(); } + inline Point3 normalized() const + { + Point3 p = *this; + p.Normalize(); + return p; + } /** * Convert to polar coordinates from cartesian coordinates. From aee9055ffee0971a2dc6c1a44eb42ab8eaf9bfc5 Mon Sep 17 00:00:00 2001 From: alemuntoni Date: Fri, 12 Nov 2021 14:21:53 +0100 Subject: [PATCH 116/117] fix append: polygonal faces with more than 3 vertices have always maximum 3 wedges... --- vcg/complex/append.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vcg/complex/append.h b/vcg/complex/append.h index 33229da3..1ee99c1d 100644 --- a/vcg/complex/append.h +++ b/vcg/complex/append.h @@ -460,7 +460,7 @@ static void MeshAppendConst( } fl.ImportData(f); if(wedgeTexFlag) { - for(int i = 0; i < fl.VN(); ++i){ + for(int i = 0; i < 3; ++i){ if (size_t(f.WT(i).n()) < mappingTextures.size()){ //standard case: the texture is contained in the mesh fl.WT(i).n() = mappingTextures[f.WT(i).n()]; From ba3e4370bb904228a02e5622bdc3689294065559 Mon Sep 17 00:00:00 2001 From: Luigi Malomo Date: Fri, 12 Nov 2021 19:27:30 +0100 Subject: [PATCH 117/117] added scalar * point operators + added correct normalize/normalized functions to points + some code cleaning --- vcg/space/deprecated_point2.h | 55 +++++++++--- vcg/space/deprecated_point3.h | 152 ++++++++++++++++++---------------- vcg/space/deprecated_point4.h | 45 ++++++++-- 3 files changed, 160 insertions(+), 92 deletions(-) diff --git a/vcg/space/deprecated_point2.h b/vcg/space/deprecated_point2.h index 6241e78d..5db300a3 100644 --- a/vcg/space/deprecated_point2.h +++ b/vcg/space/deprecated_point2.h @@ -193,12 +193,19 @@ public: _v[1] *= s; return *this; } + inline Point2 & operator /= ( const ScalarType s ) { _v[0] /= s; _v[1] /= s; return *this; } + + inline Point2 operator - (void) const + { + return Point2(-_v[0], -_v[1]); + } + //@} /// returns the norm (Euclidian) inline ScalarType Norm( void ) const @@ -216,7 +223,8 @@ public: _v[1] *= sy; return * this; } - /// normalizes, and returns itself as result + + /// normalizes, and returns itself as result (nonsense) inline Point2 & Normalize( void ) { ScalarType n = math::Sqrt(_v[0]*_v[0] + _v[1]*_v[1]); @@ -225,6 +233,19 @@ public: } return *this; } + + inline void normalize(void) + { + this->Normalize(); + } + + inline Point2 normalized(void) const + { + Point2 p = *this; + p.normalize(); + return p; + } + /// points equality inline bool operator == ( const Point2 & p ) const { @@ -374,42 +395,50 @@ inline T Angle( Point2 const & p0, Point2 const & p1 ) } template -inline Point2 operator - ( Point2 const & p ){ - return Point2( -p[0], -p[1] ); -} - -template -inline Point2 operator * ( const T s, Point2 const & p ){ +inline Point2 operator * ( const T s, Point2 const & p ) +{ return Point2( p[0] * s, p[1] * s ); } template -inline T Norm( Point2 const & p ){ +inline T Norm( Point2 const & p ) +{ return p.Norm(); } template -inline T SquaredNorm( Point2 const & p ){ +inline T SquaredNorm( Point2 const & p ) +{ return p.SquaredNorm(); } template -inline Point2 & Normalize( Point2 & p ){ +inline Point2 & Normalize( Point2 & p ) +{ return p.Normalize(); } +template +inline Point2 Normalized(const Point2 & p ) +{ + return p.normalized(); +} + template -inline T Distance( Point2 const & p1,Point2 const & p2 ){ +inline T Distance( Point2 const & p1,Point2 const & p2 ) +{ return Norm(p1-p2); } template -inline T SquaredDistance( Point2 const & p1,Point2 const & p2 ){ +inline T SquaredDistance( Point2 const & p1,Point2 const & p2 ) +{ return SquaredNorm(p1-p2); } template -inline Point2 Abs(const Point2 & p) { +inline Point2 Abs(const Point2 & p) +{ return (Point2(math::Abs(p[0]), math::Abs(p[1]))); } diff --git a/vcg/space/deprecated_point3.h b/vcg/space/deprecated_point3.h index 3362a633..81e67862 100644 --- a/vcg/space/deprecated_point3.h +++ b/vcg/space/deprecated_point3.h @@ -277,12 +277,9 @@ public: assert(i>=0 && i<3); return _v[i]; } -//@} -//@{ - /** @name Classical overloading of operators - Note - **/ + /** @name Classical overloading of operators + **/ inline Point3 operator + ( Point3 const & p) const { @@ -306,7 +303,7 @@ public: return ( _v[0]*p._v[0] + _v[1]*p._v[1] + _v[2]*p._v[2] ); } inline P3ScalarType dot( const Point3 & p ) const { return (*this) * p; } - /// Cross product + /// Cross product inline Point3 operator ^ ( Point3 const & p ) const { return Point3 @@ -345,7 +342,8 @@ public: _v[2] /= s; return *this; } - // Norme + + // Norms inline P3ScalarType Norm() const { return math::Sqrt( _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] ); @@ -370,67 +368,69 @@ public: return *this; } - // Normalizzazione - inline Point3 & Normalize() - { - P3ScalarType n = P3ScalarType(math::Sqrt(_v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2])); - if (n > P3ScalarType(0)) { _v[0] /= n; _v[1] /= n; _v[2] /= n; } - return *this; - } + // Normalization + inline Point3 & Normalize() + { + P3ScalarType n = P3ScalarType(math::Sqrt(_v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2])); + if (n > P3ScalarType(0)) { _v[0] /= n; _v[1] /= n; _v[2] /= n; } + return *this; + } - // for compatibility with eigen port - inline Point3 normalized() const - { - Point3 p = *this; - p.Normalize(); - return p; - } + inline void normalize(void) + { + this->Normalize(); + } - /** - * Convert to polar coordinates from cartesian coordinates. - * - * Theta is the azimuth angle and ranges between [0, 2PI) degrees. - * Phi is the elevation angle (not the polar angle) and ranges between [-PI/2, PI/2] degrees. - * - * /note Note that instead of the classical polar angle, which ranges between - * 0 and PI degrees we opt for the elevation angle to obtain a more - * intuitive spherical coordinate system. - */ - void ToPolarRad(P3ScalarType &ro, P3ScalarType &theta, P3ScalarType &phi) const - { - ro = Norm(); - theta = (P3ScalarType)atan2(_v[2], _v[0]); - phi = (P3ScalarType)asin(_v[1]/ro); - } + inline Point3 normalized(void) const + { + Point3 p = *this; + p.normalize(); + return p; + } - /** - * Convert from polar coordinates to cartesian coordinates. - * - * Theta is the azimuth angle and ranges between [0, 2PI) radians. - * Phi is the elevation angle (not the polar angle) and ranges between [-PI/2, PI/2] radians. - * - * \note Note that instead of the classical polar angle, which ranges between - * 0 and PI degrees, we opt for the elevation angle to obtain a more - * intuitive spherical coordinate system. - */ - void FromPolarRad(const P3ScalarType &ro, const P3ScalarType &theta, const P3ScalarType &phi) - { - _v[0]= ro*cos(theta)*cos(phi); - _v[1]= ro*sin(phi); - _v[2]= ro*sin(theta)*cos(phi); - } + /** + * Convert to polar coordinates from cartesian coordinates. + * + * Theta is the azimuth angle and ranges between [0, 2PI) degrees. + * Phi is the elevation angle (not the polar angle) and ranges between [-PI/2, PI/2] degrees. + * + * /note Note that instead of the classical polar angle, which ranges between + * 0 and PI degrees we opt for the elevation angle to obtain a more + * intuitive spherical coordinate system. + */ + void ToPolarRad(P3ScalarType &ro, P3ScalarType &theta, P3ScalarType &phi) const + { + ro = Norm(); + theta = (P3ScalarType)atan2(_v[2], _v[0]); + phi = (P3ScalarType)asin(_v[1]/ro); + } - Box3 GetBBox(Box3 &bb) const; -//@} -//@{ + /** + * Convert from polar coordinates to cartesian coordinates. + * + * Theta is the azimuth angle and ranges between [0, 2PI) radians. + * Phi is the elevation angle (not the polar angle) and ranges between [-PI/2, PI/2] radians. + * + * \note Note that instead of the classical polar angle, which ranges between + * 0 and PI degrees, we opt for the elevation angle to obtain a more + * intuitive spherical coordinate system. + */ + void FromPolarRad(const P3ScalarType &ro, const P3ScalarType &theta, const P3ScalarType &phi) + { + _v[0]= ro*cos(theta)*cos(phi); + _v[1]= ro*sin(phi); + _v[2]= ro*sin(theta)*cos(phi); + } - size_t MaxCoeffId() const - { - if (_v[0]>_v[1]) - return _v[0]>_v[2] ? 0 : 2; - else - return _v[1]>_v[2] ? 1 : 2; - } + Box3 GetBBox(Box3 &bb) const; + + size_t MaxCoeffId() const + { + if (_v[0]>_v[1]) + return _v[0]>_v[2] ? 0 : 2; + else + return _v[1]>_v[2] ? 1 : 2; + } /** @name Comparison Operators. Note that the reverse z prioritized ordering, useful in many situations. **/ @@ -468,8 +468,7 @@ inline bool operator == ( Point3 const & p ) const (_v[0]>=p._v[0]); } - - inline Point3 operator - () const + inline Point3 operator - (void) const { return Point3 ( -_v[0], -_v[1], -_v[2] ); } @@ -505,32 +504,37 @@ inline P3ScalarType AngleN( Point3 const & p1, Point3 inline P3ScalarType Norm( Point3 const & p ) { - return p.Norm(); + return p.Norm(); } template inline P3ScalarType SquaredNorm( Point3 const & p ) { - return p.SquaredNorm(); + return p.SquaredNorm(); } template inline Point3 & Normalize( Point3 & p ) { - p.Normalize(); - return p; + return p.Normalize(); +} + +template +inline Point3 Normalized(const Point3 & p) +{ + return p.normalized(); } template inline P3ScalarType Distance( Point3 const & p1,Point3 const & p2 ) { - return (p1-p2).Norm(); + return (p1-p2).Norm(); } template inline P3ScalarType SquaredDistance( Point3 const & p1,Point3 const & p2 ) { - return (p1-p2).SquaredNorm(); + return (p1-p2).SquaredNorm(); } template @@ -632,6 +636,12 @@ inline Point3 LowClampToZero(const Point3 & p) { return (Point3(std::max(p[0], (SCALARTYPE)0), std::max(p[1], (SCALARTYPE)0), std::max(p[2], (SCALARTYPE)0))); } +template +inline Point3 operator*(const Scalar s, const Point3 & p) +{ + return (p * s); +} + typedef Point3 Point3s; typedef Point3 Point3i; typedef Point3 Point3f; diff --git a/vcg/space/deprecated_point4.h b/vcg/space/deprecated_point4.h index 39b5d135..2b1b0410 100644 --- a/vcg/space/deprecated_point4.h +++ b/vcg/space/deprecated_point4.h @@ -274,21 +274,44 @@ public: return _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] + _v[3]*_v[3]; } /// Euclidian normalization - inline Point4 & Normalize() + inline Point4 & Normalize() { T n = sqrt(_v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] + _v[3]*_v[3] ); if(n>0.0) { _v[0] /= n; _v[1] /= n; _v[2] /= n; _v[3] /= n; } return *this; } - /// Homogeneous normalization (division by W) - inline Point4 & HomoNormalize(){ - if (_v[3]!=0.0) { _v[0] /= _v[3]; _v[1] /= _v[3]; _v[2] /= _v[3]; _v[3]=1.0; } - return *this; - }; -//@} + inline void normalize(void) + { + this->Normalize(); + } + + inline Point4 normalized(void) const + { + Point4 p = *this; + p.normalize(); + return p; + } + + /// Homogeneous normalization (division by W) + inline Point4 & HomoNormalize() + { + if (_v[3]!=0.0) { _v[0] /= _v[3]; _v[1] /= _v[3]; _v[2] /= _v[3]; _v[3]=1.0; } + return *this; + }; + + inline void homoNormalize(void) + { + this->HomoNormalize(); + }; + + inline Point4 homoNormalized(void) const + { + Point4 p = *this; + p.homoNormalize(); + return p; + } -//@{ /** @name Comparison operators (lexicographical order) **/ inline bool operator == ( const Point4& p ) const @@ -409,6 +432,12 @@ double StableDot ( Point4 const & p0, Point4 const & p1 ) return p0.StableDot(p1); } +template +inline Point4 operator*(const Scalar s, const Point4 & p) +{ + return (p * s); +} + typedef Point4 Point4s; typedef Point4 Point4i; typedef Point4 Point4f;