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,
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);
61 Index sourceIndex()
const { assert(*
this);
return mSource; }
62 Index targetIndex()
const { assert(*
this);
return mIt; }
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);
100 set.reset(
new AttributeSet(AttributeSet::Descriptor::create(sourceDescriptor.type(ppos))));
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));
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
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);
228 assert(idxHandle.size() == total);
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,
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
std::unique_ptr< Handle > UniquePtr
PointDataGridT::Ptr replicate(const PointDataGridT &source, const Index multiplier, const std::vector< std::string > &attributes, const std::string &scaleAttribute, const std::string &replicationIndex)
std::shared_ptr< Descriptor > DescriptorPtr
GLdouble GLdouble GLint GLint const GLdouble * points
Write-able version of AttributeHandle.
OIIO_UTIL_API bool copy(string_view from, string_view to, std::string &err)
GLsizei const GLchar *const * string
std::shared_ptr< AttributeSet > Ptr
#define OPENVDB_USE_VERSION_NAMESPACE
void expand(bool fill=true)
If this array is uniform, replace it with an array of length size().
GA_API const UT_StringHolder scale
float Round(float x)
Return x rounded to the nearest integer.
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...
GLsizei GLsizei GLchar * source
GLuint const GLchar * name
typename RootNodeType::LeafNodeType LeafNodeType
Typed class for storing attribute data.
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
Ordered collection of uniquely-named attribute arrays.
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
ValueType get(Index n, Index m=0) const
FMT_CONSTEXPR auto find(Ptr first, Ptr last, T value, Ptr &out) -> bool