20          const Index multiplier,
 
   21          const std::vector<std::string>& attributes,
 
   22          const std::string& scaleAttribute,
 
   23          const std::string& replicationIndex)
 
   31        _Pragma(
"clang diagnostic push")
 
   32        _Pragma(
"clang diagnostic ignored \"-Wunused-local-typedef\"")
 
   33        using GetIncrementCB = std::function<
Index(
const Index)>;
 
   34        _Pragma(
"clang diagnostic pop")
 
   36        using GetIncrementCB = std::function<
Index(
const Index)>;
 
   39        CopyIter(
const Index end, 
const GetIncrementCB& cb)
 
   40            : mIt(0), mEnd(0), mSource(0), mSourceEnd(end), mCallback(cb) {
 
   41            mEnd = mCallback(mSource);
 
   44        operator bool()
 const { 
return mSource < mSourceEnd; }
 
   46        CopyIter& operator++()
 
   54                if (*
this) mEnd += mCallback(mSource);
 
   65        Index mIt, mEnd, mSource;
 
   66        const Index mSourceEnd;
 
   67        const GetIncrementCB mCallback;
 
   76    auto iter = source.tree().cbeginLeaf();
 
   80        iter->attributeSet().descriptor();
 
   84    const size_t ppos = sourceDescriptor.
find(
"P");
 
   90    std::vector<size_t> attribsToDrop;
 
   91    if (!attributes.empty()) {
 
   92        for (
const auto& nameIdxPair : sourceDescriptor.
map()) {
 
   93            if (std::find(attributes.begin(), attributes.end(), nameIdxPair.first) != attributes.end()) 
continue;
 
   94            if (nameIdxPair.first == 
"P") 
continue;
 
   95            attribsToDrop.emplace_back(nameIdxPair.second);
 
  103    if (!replicationIndex.empty()) {
 
  106        const size_t replIdxIdx = sourceDescriptor.
find(replicationIndex);
 
  109    set->dropAttributes(attribsToDrop);
 
  114    if (!replicationIndex.empty()) {
 
  116        replicationIdx = set->descriptor().find(replicationIndex);
 
  121    const size_t scaleIdx = !scaleAttribute.empty() ?
 
  124    openvdb::tree::LeafManager<const PointDataTree> sourceManager(source.tree());
 
  125    openvdb::tree::LeafManager<openvdb::points::PointDataTree> manager(
points->tree());
 
  132        const auto& sourceLeaf = sourceManager.leaf(pos);
 
  136        const Index sourceCount = 
static_cast<Index>(sourceLeaf.pointCount());
 
  138        Index uniformMultiplier = multiplier;
 
  142            scaleHandle = std::make_unique<AttributeHandle<float>>
 
  143                (sourceLeaf.constAttributeArray(scaleIdx));
 
  149            const float scale = std::max(0.0f, scaleHandle->
get(
index));
 
  150            return static_cast<Index> 
  151                (
math::Round(
static_cast<float>(multiplier) * scale));
 
  156        if (useScale && scaleHandle->
isUniform()) {
 
  157            uniformMultiplier = getPointsToGenerate(0);
 
  169            for (
auto iter = sourceLeaf.cbeginValueAll(); iter; ++iter) {
 
  170                for (
auto piter = sourceLeaf.beginIndexVoxel(iter.getCoord());
 
  171                     piter; ++piter) { total += getPointsToGenerate(*piter); }
 
  172                leaf.setOffsetOnly(iter.pos(), total);
 
  176            total = uniformMultiplier * sourceCount;
 
  179            auto* data = leaf.buffer().data();
 
  180            for (
size_t i = 0; i < leaf.buffer().size(); ++i) {
 
  181                const ValueType::IntType value = data[i];
 
  182                data[i] = value * uniformMultiplier;
 
  187        leaf.updateValueMask();
 
  188        const AttributeSet& sourceSet = sourceLeaf.attributeSet();
 
  190        std::unique_ptr<openvdb::points::AttributeSet> newSet
 
  193        auto copy = [&](
const std::string& name)
 
  195            const auto* sourceArray = sourceSet.
getConst(name);
 
  201            auto* array = newSet->get(name);
 
  203            array->expand(
false);
 
  206                const CopyIter iter(sourceCount, [&](
const Index i) { 
return getPointsToGenerate(i); });
 
  207                array->copyValues(*sourceArray, iter);
 
  210                const CopyIter iter(sourceCount, [&](
const Index) { 
return uniformMultiplier; });
 
  211                array->copyValues(*sourceArray, iter);
 
  216        for (
const auto& iter : descriptor->map()) {
 
  217            if (iter.first == 
"P")              
continue;
 
  218            if (iter.first == replicationIndex) 
continue;
 
  226                idxHandle(*newSet->get(replicationIdx), 
false);
 
  234                for (
Index i = 0; i < sourceCount; ++i) {
 
  235                    const Index pointRepCount = getPointsToGenerate(i);
 
  236                    for (
Index j = 0; j < pointRepCount; ++j) {
 
  237                        idxHandle.
set(offset++, j);
 
  242                while (offset < total) {
 
  243                    for (
Index j = 0; j < uniformMultiplier; ++j) {
 
  244                        idxHandle.
set(offset++, j);
 
  250        leaf.replaceAttributeSet(newSet.release(), 
true);
 
  253    if (!scaleAttribute.empty()) {
 
 
  263          const Index multiplier,
 
  264          const std::string& scaleAttribute,
 
  265          const std::string& replicationIndex)
 
  267    auto iter = source.tree().cbeginLeaf();
 
  268    if (!iter) 
return source.deepCopy();
 
  270    const openvdb::points::AttributeSet::Descriptor& sourceDescriptor =
 
  271        iter->attributeSet().descriptor();
 
  273    std::vector<std::string> attribs;
 
  274    attribs.reserve(sourceDescriptor.map().size());
 
  275    for (
const auto& namepos : sourceDescriptor.map()) {
 
  276        attribs.emplace_back(namepos.first);
 
  279    return replicate(source, multiplier, attribs, scaleAttribute, replicationIndex);
 
 
PointDataGridT::Ptr replicate(const PointDataGridT &source, const Index multiplier, const std::vector< std::string > &attributes, const std::string &scaleAttribute="", const std::string &replicationIndex="")
Replicates points provided in a source grid into a new grid, transfering and creating attributes foun...
Definition PointReplicateImpl.h:19