Created
October 9, 2023 22:38
-
-
Save mtao/f2b75163df5f1a13bbd86a0a12807afa to your computer and use it in GitHub Desktop.
concatenates IGL style std::vectors.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Eigen/Core> | |
#include <numeric> | |
#include <tuple> | |
#include <iterator> | |
#include <algorithm> | |
#include <iostream> | |
template <typename BeginIt, typename EndIt> | |
auto vstack_iter(BeginIt beginit, EndIt endit) { | |
using CDerived = typename std::decay_t<decltype(*beginit)>; | |
constexpr static int CCols = CDerived::ColsAtCompileTime; | |
using Index = typename CDerived::Scalar; | |
using RetCells = Eigen::Matrix<Index,Eigen::Dynamic,CCols>; | |
int ccols = 0; | |
int crows = 0; | |
for(auto it = beginit; it != endit; ++it) { | |
auto&& c = *it; | |
if(c.size() > 0) { | |
ccols = std::max<int>(ccols,c.cols()); | |
crows += c.rows(); | |
} | |
} | |
RetCells mC(crows,ccols); | |
crows = 0; | |
for(auto it = beginit; it != endit; ++it) { | |
auto&& c = *it; | |
if(c.size() > 0) { | |
mC.block(crows,0,c.rows(),c.cols()) = c; | |
crows += c.rows(); | |
} | |
} | |
return mC; | |
} | |
// currently copies Fs to update indices. could change to a rval to indicate it takes ownership, or modify vstack to take in an offset | |
template <typename VSVector, typename FSVector> | |
auto stack_meshes(const VSVector& Vs, FSVector Fs) { | |
std::vector<int> sizes; | |
sizes.reserve(Vs.size()+1); | |
std::transform(Vs.begin(),Vs.end(), std::back_inserter(sizes), [](const auto& V) -> int { return V.rows(); }); | |
std::vector<int> offsets; | |
offsets.reserve(sizes.size()+1); | |
offsets.emplace_back(0); | |
std::partial_sum(sizes.begin(),sizes.end(), std::back_inserter(offsets) ); | |
for(size_t index = 0; index < Fs.size(); ++index) { | |
auto& F = Fs[index]; | |
auto FA = F.array(); | |
FA = FA + offsets[index];; | |
} | |
return std::make_tuple(vstack_iter(Vs.begin(),Vs.end()), vstack_iter(Fs.begin(),Fs.end())); | |
} | |
int main(int argc, char * argv[]) { | |
std::vector<Eigen::MatrixXd> Vs(3); | |
std::vector<Eigen::MatrixXi> Fs(3); | |
Eigen::MatrixXd& V0 = Vs[0]; | |
Eigen::MatrixXi& F0 = Fs[0]; | |
Eigen::MatrixXd& V1 = Vs[1]; | |
Eigen::MatrixXi& F1 = Fs[1]; | |
Eigen::MatrixXd& V2 = Vs[2]; | |
Eigen::MatrixXi& F2 = Fs[2]; | |
// set F column i be all i to see that concat worked | |
V0.setRandom(10,3); | |
V0.col(0).setConstant(0); | |
V1.setRandom(3,3); | |
V1.col(1).setConstant(1); | |
V2.setRandom(20,3); | |
V2.col(2).setConstant(2); | |
// set F to be 100 diff so we can catch 0 indices offset by 0 -> 10 -> 13 | |
F0.setConstant(3,3,0); | |
F1.setConstant(5,3,100); | |
F2.setConstant(7,3,200); | |
auto [V,F] = stack_meshes(Vs,Fs); | |
std::cout << V << std::endl; | |
std::cout << std::endl; | |
std::cout << F << std::endl; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment