9 #ifndef OPENVDB_POINTS_POINT_REPLICATE_IMPL_HAS_BEEN_INCLUDED 10 #define OPENVDB_POINTS_POINT_REPLICATE_IMPL_HAS_BEEN_INCLUDED 17 template <
typename Po
intDataGr
idT>
18 typename PointDataGridT::Ptr
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();
77 if (!iter)
return points;
79 const AttributeSet::Descriptor& sourceDescriptor =
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);
100 set.reset(
new AttributeSet(AttributeSet::Descriptor::create(sourceDescriptor.type(ppos))));
103 if (!replicationIndex.empty()) {
106 const size_t replIdxIdx = sourceDescriptor.find(replicationIndex);
107 if (replIdxIdx != AttributeSet::INVALID_POS) attribsToDrop.emplace_back(replIdxIdx);
109 set->dropAttributes(attribsToDrop);
113 size_t replicationIdx = AttributeSet::INVALID_POS;
114 if (!replicationIndex.empty()) {
116 replicationIdx =
set->descriptor().find(replicationIndex);
121 const size_t scaleIdx = !scaleAttribute.empty() ?
122 sourceDescriptor.find(scaleAttribute) : AttributeSet::INVALID_POS;
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;
140 bool useScale = scaleIdx != AttributeSet::INVALID_POS;
142 scaleHandle = std::make_unique<AttributeHandle<float>>
143 (sourceLeaf.constAttributeArray(scaleIdx));
148 auto getPointsToGenerate = [&](
const Index index) ->
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;
224 if (replicationIdx != AttributeSet::INVALID_POS && total > 0) {
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()) {
260 template <
typename Po
intDataGr
idT>
261 typename PointDataGridT::Ptr
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);
287 #endif // OPENVDB_POINTS_POINT_REPLICATE_IMPL_HAS_BEEN_INCLUDED bool isUniform() const
Definition: AttributeArray.h:2087
uint64_t Index64
Definition: Types.h:53
typename RootNodeType::ValueType ValueType
Definition: Tree.h:201
typename RootNodeType::LeafNodeType LeafNodeType
Definition: Tree.h:203
std::unique_ptr< Handle > UniquePtr
Definition: AttributeArray.h:768
const AttributeArray * getConst(const std::string &name) const
Return a pointer to the attribute array whose name is name or a null pointer if no match is found...
Index32 Index
Definition: Types.h:54
ValueType get(Index n, Index m=0) const
Definition: AttributeArray.h:2061
#define OPENVDB_ASSERT(X)
Definition: Assert.h:41
MatType scale(const Vec3< typename MatType::value_type > &s)
Return a matrix that scales by s.
Definition: Mat.h:615
SharedPtr< Grid > Ptr
Definition: Grid.h:573
Write-able version of AttributeHandle.
Definition: AttributeArray.h:834
Definition: Exceptions.h:13
std::shared_ptr< AttributeSet > Ptr
Definition: AttributeSet.h:44
std::shared_ptr< Descriptor > DescriptorPtr
Definition: AttributeSet.h:50
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
Ordered collection of uniquely-named attribute arrays.
Definition: AttributeSet.h:39
void expand(bool fill=true)
If this array is uniform, replace it with an array of length size().
Definition: AttributeArray.h:2130
float Round(float x)
Return x rounded to the nearest integer.
Definition: Math.h:819
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:121
Typed class for storing attribute data.
Definition: AttributeArray.h:511
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:218