OpenVDB: openvdb_houdini/GeometryUtil.h Source File

OpenVDB 12.1.1

Loading...
Searching...
No Matches
GeometryUtil.h
Go to the documentation of this file.
1// Copyright Contributors to the OpenVDB Project
2// SPDX-License-Identifier: Apache-2.0
3//
4/// @file GeometryUtil.h
5/// @author FX R&D Simulation team
6/// @brief Utility methods and tools for geometry processing
7
8#ifndef OPENVDB_HOUDINI_GEOMETRY_UTIL_HAS_BEEN_INCLUDED
9#define OPENVDB_HOUDINI_GEOMETRY_UTIL_HAS_BEEN_INCLUDED
10
11#include <openvdb/openvdb.h>
12#include <openvdb/tools/MeshToVolume.h> // for openvdb::tools::MeshToVoxelEdgeData
13#include <openvdb/tree/LeafManager.h>
14#include <openvdb/util/NullInterrupter.h>
15#include <openvdb/util/Util.h> // for openvdb::util::COORD_OFFSETS
16
17#include <OBJ/OBJ_Camera.h>
18#include <GU/GU_Detail.h>
19#include <GEO/GEO_Primitive.h>
20#include <UT/UT_Version.h>
21
22#include <algorithm> // for std::max/min()
23#include <memory>
24#include <string>
25#include <vector>
26
27
28class GA_SplittableRange;
29class OP_Context;
30class OP_Node;
31
32
33#ifdef SESI_OPENVDB
34 #ifdef OPENVDB_HOUDINI_API
35 #undef OPENVDB_HOUDINI_API
36 #define OPENVDB_HOUDINI_API
37 #endif
38#endif
39
40
41namespace openvdb_houdini {
42
43class Interrupter;
44
45
46/// Add geometry to the given detail to indicate the extents of a frustum transform.
47 OPENVDB_HOUDINI_API
48void
49drawFrustum(GU_Detail&, const openvdb::math::Transform&,
50 const UT_Vector3* boxColor, const UT_Vector3* tickColor,
51 bool shaded, bool drawTicks = true);
52
53
54/// Construct a frustum transform from a Houdini camera.
55#if SYS_VERSION_MAJOR_INT >= 21
56openvdb::math::Transform::Ptr
57 frustumTransformFromCamera(
58 const OBJ_CameraParms&, const UT_Matrix4D&,
59 float offset, float nearPlaneDist, float farPlaneDist,
60 float voxelDepthSize = 1.0, int voxelCountX = 100);
61#else
62 OPENVDB_HOUDINI_API
63openvdb::math::Transform::Ptr
64frustumTransformFromCamera(
65 OP_Node&, OP_Context&, OBJ_Camera&,
66 float offset, float nearPlaneDist, float farPlaneDist,
67 float voxelDepthSize = 1.0, int voxelCountX = 100);
68#endif
69
70////////////////////////////////////////
71
72
73/// @brief Return @c true if the point at the given offset is referenced
74/// by primitives from a certain primitive group.
75 OPENVDB_HOUDINI_API
76bool
77pointInPrimGroup(GA_Offset ptnOffset, GU_Detail&, const GA_PrimitiveGroup&);
78
79
80////////////////////////////////////////
81
82
83/// @brief Convert geometry to quads and triangles.
84/// @return a pointer to a new GU_Detail object if the geometry was
85/// converted or subdivided, otherwise a null pointer
86 OPENVDB_HOUDINI_API
87std::unique_ptr<GU_Detail>
88convertGeometry(const GU_Detail&, std::string& warning, openvdb::util::NullInterrupter*);
89
90
91 OPENVDB_DEPRECATED_MESSAGE("openvdb_houdini::Interrupter has been deprecated, use openvdb_houdini::HoudiniInterrupter")
92 OPENVDB_HOUDINI_API
93 std::unique_ptr<GU_Detail>
94 convertGeometry(const GU_Detail& detail, std::string& warning, Interrupter* boss);
95
96
97////////////////////////////////////////
98
99
100/// TBB body object for threaded world to voxel space transformation and copy of points
101class OPENVDB_HOUDINI_API TransformOp
102{
103public:
104 TransformOp(GU_Detail const * const gdp,
105 const openvdb::math::Transform& transform,
106 std::vector<openvdb::Vec3s>& pointList);
107
108 void operator()(const GA_SplittableRange&) const;
109
110private:
111 GU_Detail const * const mGdp;
112 const openvdb::math::Transform& mTransform;
113 std::vector<openvdb::Vec3s>* const mPointList;
114};
115
116
117////////////////////////////////////////
118
119
120/// @brief TBB body object for threaded primitive copy
121/// @details Produces a primitive-vertex index list.
122 class OPENVDB_HOUDINI_API PrimCpyOp
123{
124public:
125 PrimCpyOp(GU_Detail const * const gdp, std::vector<openvdb::Vec4I>& primList);
126 void operator()(const GA_SplittableRange&) const;
127
128private:
129 GU_Detail const * const mGdp;
130 std::vector<openvdb::Vec4I>* const mPrimList;
131};
132
133
134////////////////////////////////////////
135
136
137/// @brief TBB body object for threaded vertex normal generation
138/// @details Averages face normals from all similarly oriented primitives,
139/// that share the same vertex-point, to maintain sharp features.
140 class OPENVDB_HOUDINI_API VertexNormalOp
141{
142public:
143 VertexNormalOp(GU_Detail&, const GA_PrimitiveGroup* interiorPrims=nullptr, float angle=0.7f);
144 void operator()(const GA_SplittableRange&) const;
145
146private:
147 bool isInteriorPrim(GA_Offset primOffset) const
148 {
149 return mInteriorPrims && mInteriorPrims->containsIndex(
150 mDetail.primitiveIndex(primOffset));
151 }
152
153 const GU_Detail& mDetail;
154 const GA_PrimitiveGroup* mInteriorPrims;
155 GA_RWHandleV3 mNormalHandle;
156 const float mAngle;
157};
158
159
160////////////////////////////////////////
161
162
163/// TBB body object for threaded sharp feature construction
164 class OPENVDB_HOUDINI_API SharpenFeaturesOp
165{
166public:
167 using EdgeData = openvdb::tools::MeshToVoxelEdgeData;
168
169 SharpenFeaturesOp(GU_Detail& meshGeo, const GU_Detail& refGeo, EdgeData& edgeData,
170 const openvdb::math::Transform& xform, const GA_PrimitiveGroup* surfacePrims = nullptr,
171 const openvdb::BoolTree* mask = nullptr);
172
173 void operator()(const GA_SplittableRange&) const;
174
175private:
176 GU_Detail& mMeshGeo;
177 const GU_Detail& mRefGeo;
178 EdgeData& mEdgeData;
179 const openvdb::math::Transform& mXForm;
180 const GA_PrimitiveGroup* mSurfacePrims;
181 const openvdb::BoolTree* mMaskTree;
182};
183
184
185////////////////////////////////////////
186
187
188/// TBB body object for threaded sharp feature construction
189template<typename IndexTreeType, typename BoolTreeType>
190 class GenAdaptivityMaskOp
191{
192public:
193 using BoolLeafManager = openvdb::tree::LeafManager<BoolTreeType>;
194
195 GenAdaptivityMaskOp(const GU_Detail& refGeo,
196 const IndexTreeType& indexTree, BoolLeafManager&, float edgetolerance = 0.0);
197
198 void run(bool threaded = true);
199
200 void operator()(const tbb::blocked_range<size_t>&) const;
201
202private:
203 const GU_Detail& mRefGeo;
204 const IndexTreeType& mIndexTree;
205 BoolLeafManager& mLeafs;
206 float mEdgeTolerance;
207};
208
209
210template<typename IndexTreeType, typename BoolTreeType>
211GenAdaptivityMaskOp<IndexTreeType, BoolTreeType>::GenAdaptivityMaskOp(const GU_Detail& refGeo,
212 const IndexTreeType& indexTree, BoolLeafManager& leafMgr, float edgetolerance)
213 : mRefGeo(refGeo)
214 , mIndexTree(indexTree)
215 , mLeafs(leafMgr)
216 , mEdgeTolerance(edgetolerance)
217{
218 mEdgeTolerance = std::max(0.0f, mEdgeTolerance);
219 mEdgeTolerance = std::min(1.0f, mEdgeTolerance);
220}
221
222
223template<typename IndexTreeType, typename BoolTreeType>
224void
225GenAdaptivityMaskOp<IndexTreeType, BoolTreeType>::run(bool threaded)
226{
227 if (threaded) {
228 tbb::parallel_for(mLeafs.getRange(), *this);
229 } else {
230 (*this)(mLeafs.getRange());
231 }
232}
233
234
235template<typename IndexTreeType, typename BoolTreeType>
236void
237GenAdaptivityMaskOp<IndexTreeType, BoolTreeType>::operator()(
238 const tbb::blocked_range<size_t>& range) const
239{
240 using IndexAccessorType = typename openvdb::tree::ValueAccessor<const IndexTreeType>;
241 IndexAccessorType idxAcc(mIndexTree);
242
243 UT_Vector3 tmpN, normal;
244 GA_Offset primOffset;
245 int tmpIdx;
246
247 openvdb::Coord ijk, nijk;
248 typename BoolTreeType::LeafNodeType::ValueOnIter iter;
249
250 for (size_t n = range.begin(); n < range.end(); ++n) {
251 iter = mLeafs.leaf(n).beginValueOn();
252 for (; iter; ++iter) {
253 ijk = iter.getCoord();
254
255 bool edgeVoxel = false;
256
257 int idx = idxAcc.getValue(ijk);
258
259 primOffset = mRefGeo.primitiveOffset(idx);
260 normal = mRefGeo.getGEOPrimitive(primOffset)->computeNormal();
261
262 for (size_t i = 0; i < 18; ++i) {
263 nijk = ijk + openvdb::util::COORD_OFFSETS[i];
264 if (idxAcc.probeValue(nijk, tmpIdx) && tmpIdx != idx) {
265 primOffset = mRefGeo.primitiveOffset(tmpIdx);
266 tmpN = mRefGeo.getGEOPrimitive(primOffset)->computeNormal();
267
268 if (normal.dot(tmpN) < mEdgeTolerance) {
269 edgeVoxel = true;
270 break;
271 }
272 }
273 }
274
275 if (!edgeVoxel) iter.setValueOff();
276 }
277 }
278}
279
280
281} // namespace openvdb_houdini
282
283
284////////////////////////////////////////
285
286
287#endif // OPENVDB_HOUDINI_GEOMETRY_UTIL_HAS_BEEN_INCLUDED
LeafManager.h
A LeafManager manages a linear array of pointers to a given tree's leaf nodes, as well as optional au...
MeshToVolume.h
Convert polygonal meshes that consist of quads and/or triangles into signed or unsigned distance fiel...
NullInterrupter.h
OPENVDB_HOUDINI_API
#define OPENVDB_HOUDINI_API
Definition Platform.h:299
OPENVDB_DEPRECATED_MESSAGE
#define OPENVDB_DEPRECATED_MESSAGE(msg)
Definition Platform.h:171
openvdb::v12_1::math::Coord
Signed (x, y, z) 32-bit integer coordinates.
Definition Coord.h:26
openvdb_houdini::GenAdaptivityMaskOp::run
void run(bool threaded=true)
Definition GeometryUtil.h:225
openvdb_houdini::GenAdaptivityMaskOp::operator()
void operator()(const tbb::blocked_range< size_t > &) const
Definition GeometryUtil.h:237
openvdb_houdini::GenAdaptivityMaskOp::BoolLeafManager
openvdb::tree::LeafManager< BoolTreeType > BoolLeafManager
Definition GeometryUtil.h:193
openvdb_houdini::GenAdaptivityMaskOp::GenAdaptivityMaskOp
GenAdaptivityMaskOp(const GU_Detail &refGeo, const IndexTreeType &indexTree, BoolLeafManager &, float edgetolerance=0.0)
Definition GeometryUtil.h:211
openvdb_houdini::Interrupter
Deprecated wrapper class with the same interface as HoudiniInterrupter, however it does not derive fr...
Definition Utils.h:218
openvdb_houdini::PrimCpyOp::operator()
void operator()(const GA_SplittableRange &) const
openvdb_houdini::PrimCpyOp::PrimCpyOp
PrimCpyOp(GU_Detail const *const gdp, std::vector< openvdb::Vec4I > &primList)
openvdb_houdini::SharpenFeaturesOp::operator()
void operator()(const GA_SplittableRange &) const
openvdb_houdini::SharpenFeaturesOp::SharpenFeaturesOp
SharpenFeaturesOp(GU_Detail &meshGeo, const GU_Detail &refGeo, EdgeData &edgeData, const openvdb::math::Transform &xform, const GA_PrimitiveGroup *surfacePrims=nullptr, const openvdb::BoolTree *mask=nullptr)
openvdb_houdini::SharpenFeaturesOp::EdgeData
openvdb::tools::MeshToVoxelEdgeData EdgeData
Definition GeometryUtil.h:167
openvdb_houdini::TransformOp::operator()
void operator()(const GA_SplittableRange &) const
openvdb_houdini::TransformOp::TransformOp
TransformOp(GU_Detail const *const gdp, const openvdb::math::Transform &transform, std::vector< openvdb::Vec3s > &pointList)
openvdb_houdini::VertexNormalOp::operator()
void operator()(const GA_SplittableRange &) const
openvdb_houdini::VertexNormalOp::VertexNormalOp
VertexNormalOp(GU_Detail &, const GA_PrimitiveGroup *interiorPrims=nullptr, float angle=0.7f)
detail
Definition VoxToNanoVDB.h:15
openvdb::v12_1::BoolTree
tree::Tree4< bool, 5, 4, 3 >::Type BoolTree
Common tree types.
Definition openvdb.h:53
openvdb_houdini
Definition AttributeTransferUtil.h:34
openvdb_houdini::pointInPrimGroup
OPENVDB_HOUDINI_API bool pointInPrimGroup(GA_Offset ptnOffset, GU_Detail &, const GA_PrimitiveGroup &)
Return true if the point at the given offset is referenced by primitives from a certain primitive gro...
openvdb_houdini::drawFrustum
OPENVDB_HOUDINI_API void drawFrustum(GU_Detail &, const openvdb::math::Transform &, const UT_Vector3 *boxColor, const UT_Vector3 *tickColor, bool shaded, bool drawTicks=true)
Add geometry to the given detail to indicate the extents of a frustum transform.
openvdb_houdini::convertGeometry
OPENVDB_HOUDINI_API std::unique_ptr< GU_Detail > convertGeometry(const GU_Detail &, std::string &warning, openvdb::util::NullInterrupter *)
Convert geometry to quads and triangles.
openvdb_houdini::frustumTransformFromCamera
OPENVDB_HOUDINI_API openvdb::math::Transform::Ptr frustumTransformFromCamera(OP_Node &, OP_Context &, OBJ_Camera &, float offset, float nearPlaneDist, float farPlaneDist, float voxelDepthSize=1.0, int voxelCountX=100)
Construct a frustum transform from a Houdini camera.
std
Definition Coord.h:590
Util.h
openvdb.h