From b1d2e9ff07fbb0d3597dd11495dc6da6b87c4fcc Mon Sep 17 00:00:00 2001 From: Nick Sharp Date: Wed, 17 Jul 2019 07:23:11 -0400 Subject: [PATCH] permute template args --- include/polyscope/point_cloud.h | 2 +- include/polyscope/point_cloud.ipp | 4 +- include/polyscope/standardize_data_array.h | 47 ++++++++++++---------- include/polyscope/surface_mesh.h | 2 +- include/polyscope/surface_mesh.ipp | 22 +++++----- 5 files changed, 40 insertions(+), 37 deletions(-) diff --git a/include/polyscope/point_cloud.h b/include/polyscope/point_cloud.h index a11ab63b..9859e7ea 100644 --- a/include/polyscope/point_cloud.h +++ b/include/polyscope/point_cloud.h @@ -114,7 +114,7 @@ class PointCloud : public QuantityStructure { // Implementation of templated constructor template PointCloud::PointCloud(std::string name, const T& points_) - : QuantityStructure(name), points(standardizeVectorArray(points_)) { + : QuantityStructure(name), points(standardizeVectorArray(points_)) { initialBaseColor = getNextUniqueColor(); pointColor = initialBaseColor; diff --git a/include/polyscope/point_cloud.ipp b/include/polyscope/point_cloud.ipp index a50fb999..0547f282 100644 --- a/include/polyscope/point_cloud.ipp +++ b/include/polyscope/point_cloud.ipp @@ -5,7 +5,7 @@ namespace polyscope { template PointCloudColorQuantity* PointCloud::addColorQuantity(std::string name, const T& colors) { validateSize(colors, nPoints(), "point cloud color quantity " + name); - return addColorQuantityImpl(name, standardizeVectorArray(colors)); + return addColorQuantityImpl(name, standardizeVectorArray(colors)); } @@ -18,7 +18,7 @@ PointCloudScalarQuantity* PointCloud::addScalarQuantity(std::string name, const template PointCloudVectorQuantity* PointCloud::addVectorQuantity(std::string name, const T& vectors, VectorType vectorType) { validateSize(vectors, nPoints(), "point cloud vector quantity " + name); - return addVectorQuantityImpl(name, standardizeVectorArray(vectors), vectorType); + return addVectorQuantityImpl(name, standardizeVectorArray(vectors), vectorType); } diff --git a/include/polyscope/standardize_data_array.h b/include/polyscope/standardize_data_array.h index 092f0e8f..e7b0d26e 100644 --- a/include/polyscope/standardize_data_array.h +++ b/include/polyscope/standardize_data_array.h @@ -14,13 +14,16 @@ // == "How the heck do these work", abridged version: // +// Nicholas Sharp (nsharp@cs.cmu.edu) +// // (This is Nick's best attempt to explain these functions, during a glorious -// few days in July 2019 when he sorta understood how they work. An actual -// C++ expert could certainly give a better explanation. Pardon misued -// terminology.) +// few days after writing them in July 2019 when he sorta understood how they +// work. An actual C++ expert could certainly give a better explanation. Pardon +// misused terminology.) // // These templates abuse C++ to consider many version of a function, and pick -// the one which will compile. +// the one which will compile. We use technique to heuristically convert +// unknown user types to a standard format. // // This isn't really something it seems like the language supports, but // technically you can do it, thanks to a "feature" called SFINAE @@ -47,7 +50,7 @@ // ambiguous function calls. // // We utilize SFINAE by ensuring that versions of a function which are not -// applicable get discarded during step (2). There are a few ways to do this +// applicable get discarded during step (2). There are a few ways to do this, // but we'll do it by adding extra template types with default values that // fail to resolve. // @@ -93,7 +96,7 @@ // (recall, if ::type doesn't exist, it'll halt substitution as // we discussed in (2) above). // -// Putting these two together we can require that a function doStuff() +// Putting these two together we can require that a function x.doStuff() // return an int with a recipe like // // template in every functions argument list, with a distinct -// value of N. Our Preference // is implicitly convertible to -// PreferenceT. So if our initial function call uses +// Our mechanism to do so will be including an extra dummpy parameter +// PreferenceT in every function's argument list, with a distinct +// value of N. Our Preference is implicitly convertible to +// PreferenceT (and so on). So if our initial function call uses // PreferenceT{}, it will match any of the overloads with lower- -// numbered PreferenceT<> templates. However, since these lower-numbered +// numbered PreferenceT<> parameters. However, since these lower-numbered // functions involve implicit conversions, they will always have a lower // priority and not be ambiguous! @@ -162,7 +165,7 @@ struct InnerType { // Note: this dummy function is defined so the non-dependent user function name will always resolve to something; // some compilers will throw an error if the name doesn't resolve. -void adaptorF_custom_size(void* dont_use) { +inline void adaptorF_custom_size(void* dont_use) { // dummy function } @@ -225,7 +228,7 @@ size_t adaptorF_size(const T& inputData) { // and S. // // Note: it might be tempting to instead abstract via a function which which accesses the i'th element of the array, -// but that would require that array types be random-accessable. By going to a std::vector, we open the door to +// but that would require that array types be random-accessible. By going to a std::vector, we open the door to // non-random-accessible input types like iterables. // // The following hierarchy of strategies will be attempted, with decreasing precedence: @@ -237,13 +240,13 @@ size_t adaptorF_size(const T& inputData) { // Note: this dummy function is defined so the non-dependent user function name will always resolve to something; // some compilers will throw an error if the name doesn't resolve. -void adaptorF_custom_convertToStdVector(void* dont_use) { +inline void adaptorF_custom_convertToStdVector(void* dont_use) { // dummy function } // Highest priority: user-specified function template ::value>::type> std::vector adaptorF_convertToStdVectorImpl(PreferenceT<4>, const T& inputData) { @@ -351,7 +354,7 @@ std::vector adaptorF_convertToStdVector(const T& inputData) { // Note: this dummy function is defined so the non-dependent user function name will always resolve to something; // some compilers will throw an error if the name doesn't resolve. -void adaptorF_custom_accessVector2Value(void* dont_use) { +inline void adaptorF_custom_accessVector2Value(void* dont_use) { // dummy function } @@ -466,7 +469,7 @@ S adaptorF_accessVector2Value(const T& inVal) { // Note: this dummy function is defined so the non-dependent user function name will always resolve to something; // some compilers will throw an error if the name doesn't resolve. -void adaptorF_custom_accessVector3Value(void* dont_use) { +inline void adaptorF_custom_accessVector3Value(void* dont_use) { // dummy function } @@ -566,7 +569,7 @@ S adaptorF_accessVector3Value(const T& inVal) { // Note: this dummy function is defined so the non-dependent user function name will always resolve to something; // some compilers will throw an error if the name doesn't resolve. -void adaptorF_custom_convertArrayOfVectorToStdVector(void* dont_use) { +inline void adaptorF_custom_convertArrayOfVectorToStdVector(void* dont_use) { // dummy function } @@ -634,7 +637,7 @@ std::vector adaptorF_convertArrayOfVectorToStdVectorImpl(PreferenceT<6>, cons // Next: bracketed array of anything adaptable to vector3 template ::type, /* helper type: inner type of output O */ typename C_RES = typename InnerType::type, @@ -658,7 +661,7 @@ std::vector adaptorF_convertArrayOfVectorToStdVectorImpl(PreferenceT<5>, cons // Next: bracketed array of anything adaptable to vector2 template ::type, /* helper type: inner type of output O */ typename C_RES = typename InnerType::type, @@ -805,7 +808,7 @@ std::vector adaptorF_convertArrayOfVectorToStdVector(const T& inputData) { // Note: this dummy function is defined so the non-dependent name adaptorF_custom_convertArrayOfVectorToStdVector will // always resolve to something; some compilers will throw an error if the name doesn't resolve. -void adaptorF_custom_convertNestedArrayToStdVector(void* dont_use) { +inline void adaptorF_custom_convertNestedArrayToStdVector(void* dont_use) { // dummy function } @@ -1019,7 +1022,7 @@ std::vector standardizeArray(const T& inputData) { } // Convert an array of vector types -// class O: output inner vector type to put the result in. Will be bracked-indexed. +// class O: output inner vector type to put the result in. Will be bracket-indexed. // (Polyscope pretty much always uses glm::vec2/3, std::vector<>, or std::array<>) // unsigned int D: dimension of inner vector type // class T: input array type diff --git a/include/polyscope/surface_mesh.h b/include/polyscope/surface_mesh.h index 794d509f..91a63acd 100644 --- a/include/polyscope/surface_mesh.h +++ b/include/polyscope/surface_mesh.h @@ -365,7 +365,7 @@ inline SurfaceMesh* getSurfaceMesh(std::string name = "") { // Implementation of templated constructor template SurfaceMesh::SurfaceMesh(std::string name, const V& vertexPositions, const F& faceIndices) - : QuantityStructure(name), vertices(standardizeVectorArray(vertexPositions)), + : QuantityStructure(name), vertices(standardizeVectorArray(vertexPositions)), faces(standardizeNestedList(faceIndices)) { computeCounts(); diff --git a/include/polyscope/surface_mesh.ipp b/include/polyscope/surface_mesh.ipp index 5d127d8d..a7dfe00a 100644 --- a/include/polyscope/surface_mesh.ipp +++ b/include/polyscope/surface_mesh.ipp @@ -102,14 +102,14 @@ void SurfaceMesh::setAllPermutations(const std::array, 5>& template SurfaceVertexColorQuantity* SurfaceMesh::addVertexColorQuantity(std::string name, const T& colors) { validateSize(colors, vertexDataSize, "vertex color quantity " + name); - return addVertexColorQuantityImpl(name, standardizeVectorArray(colors)); + return addVertexColorQuantityImpl(name, standardizeVectorArray(colors)); } template SurfaceFaceColorQuantity* SurfaceMesh::addFaceColorQuantity(std::string name, const T& colors) { validateSize(colors, faceDataSize, "face color quantity " + name); - return addFaceColorQuantityImpl(name, standardizeVectorArray(colors)); + return addFaceColorQuantityImpl(name, standardizeVectorArray(colors)); } @@ -163,8 +163,8 @@ SurfaceDistanceQuantity* SurfaceMesh::addVertexSignedDistanceQuantity(std::strin template SurfaceGraphQuantity* SurfaceMesh::addSurfaceGraphQuantity(std::string name, const P& nodes, const E& edges) { - return addSurfaceGraphQuantityImpl(name, standardizeVectorArray(nodes), - standardizeVectorArray, E, 2>(edges)); + return addSurfaceGraphQuantityImpl(name, standardizeVectorArray(nodes), + standardizeVectorArray, 2>(edges)); } @@ -173,7 +173,7 @@ template SurfaceCornerParameterizationQuantity* SurfaceMesh::addParameterizationQuantity(std::string name, const T& coords, ParamCoordsType type) { validateSize(coords, cornerDataSize, "parameterization quantity " + name); - return addParameterizationQuantityImpl(name, standardizeVectorArray(coords), type); + return addParameterizationQuantityImpl(name, standardizeVectorArray(coords), type); } // Parameterization defined at vertices, rather than corners @@ -181,7 +181,7 @@ template SurfaceVertexParameterizationQuantity* SurfaceMesh::addVertexParameterizationQuantity(std::string name, const T& coords, ParamCoordsType type) { validateSize(coords, vertexDataSize, "parameterization (at vertices) quantity " + name); - return addVertexParameterizationQuantityImpl(name, standardizeVectorArray(coords), type); + return addVertexParameterizationQuantityImpl(name, standardizeVectorArray(coords), type); } // "local" parameterization defined at vertices. has different presets: type is WORLD and style is LOCAL @@ -189,7 +189,7 @@ template SurfaceVertexParameterizationQuantity* SurfaceMesh::addLocalParameterizationQuantity(std::string name, const T& coords, ParamCoordsType type) { validateSize(coords, vertexDataSize, "parameterization (at vertices) quantity " + name); - return addLocalParameterizationQuantityImpl(name, standardizeVectorArray(coords), type); + return addLocalParameterizationQuantityImpl(name, standardizeVectorArray(coords), type); } @@ -222,21 +222,21 @@ template SurfaceVertexVectorQuantity* SurfaceMesh::addVertexVectorQuantity(std::string name, const T& vectors, VectorType vectorType) { validateSize(vectors, vertexDataSize, "vertex vector quantity " + name); - return addVertexVectorQuantityImpl(name, standardizeVectorArray(vectors), vectorType); + return addVertexVectorQuantityImpl(name, standardizeVectorArray(vectors), vectorType); } template SurfaceFaceVectorQuantity* SurfaceMesh::addFaceVectorQuantity(std::string name, const T& vectors, VectorType vectorType) { validateSize(vectors, faceDataSize, "face vector quantity " + name); - return addFaceVectorQuantityImpl(name, standardizeVectorArray(vectors), vectorType); + return addFaceVectorQuantityImpl(name, standardizeVectorArray(vectors), vectorType); } template SurfaceFaceIntrinsicVectorQuantity* SurfaceMesh::addFaceIntrinsicVectorQuantity(std::string name, const T& vectors, int nSym, VectorType vectorType) { validateSize(vectors, faceDataSize, "face intrinsic vector quantity " + name); - return addFaceIntrinsicVectorQuantityImpl(name, standardizeVectorArray(vectors), nSym, vectorType); + return addFaceIntrinsicVectorQuantityImpl(name, standardizeVectorArray(vectors), nSym, vectorType); } @@ -244,7 +244,7 @@ template SurfaceVertexIntrinsicVectorQuantity* SurfaceMesh::addVertexIntrinsicVectorQuantity(std::string name, const T& vectors, int nSym, VectorType vectorType) { validateSize(vectors, vertexDataSize, "vertex intrinsic vector quantity " + name); - return addVertexIntrinsicVectorQuantityImpl(name, standardizeVectorArray(vectors), nSym, vectorType); + return addVertexIntrinsicVectorQuantityImpl(name, standardizeVectorArray(vectors), nSym, vectorType); } // Orientations is `true` if the canonical orientation of the edge points from the lower-indexed vertex to the