Skip to content

Instantly share code, notes, and snippets.

@mtao
Created October 9, 2023 22:38
Show Gist options
  • Save mtao/f2b75163df5f1a13bbd86a0a12807afa to your computer and use it in GitHub Desktop.
Save mtao/f2b75163df5f1a13bbd86a0a12807afa to your computer and use it in GitHub Desktop.
concatenates IGL style std::vectors.
#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