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