OpenVDB  12.1.0
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
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 
28 class GA_SplittableRange;
29 class OP_Context;
30 class 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 
41 namespace openvdb_houdini {
42 
43 class Interrupter;
44 
45 
46 /// Add geometry to the given detail to indicate the extents of a frustum transform.
48 void
49 drawFrustum(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
56 openvdb::math::Transform::Ptr
58  const OBJ_CameraParms&, const UT_Matrix4D&,
59  float offset, float nearPlaneDist, float farPlaneDist,
60  float voxelDepthSize = 1.0, int voxelCountX = 100);
61 #else
63 openvdb::math::Transform::Ptr
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.
76 bool
77 pointInPrimGroup(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
87 std::unique_ptr<GU_Detail>
88 convertGeometry(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")
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
102 {
103 public:
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 
110 private:
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.
123 {
124 public:
125  PrimCpyOp(GU_Detail const * const gdp, std::vector<openvdb::Vec4I>& primList);
126  void operator()(const GA_SplittableRange&) const;
127 
128 private:
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.
141 {
142 public:
143  VertexNormalOp(GU_Detail&, const GA_PrimitiveGroup* interiorPrims=nullptr, float angle=0.7f);
144  void operator()(const GA_SplittableRange&) const;
145 
146 private:
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
165 {
166 public:
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 
175 private:
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
189 template<typename IndexTreeType, typename BoolTreeType>
191 {
192 public:
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 
202 private:
203  const GU_Detail& mRefGeo;
204  const IndexTreeType& mIndexTree;
205  BoolLeafManager& mLeafs;
206  float mEdgeTolerance;
207 };
208 
209 
210 template<typename IndexTreeType, typename BoolTreeType>
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 
223 template<typename IndexTreeType, typename BoolTreeType>
224 void
226 {
227  if (threaded) {
228  tbb::parallel_for(mLeafs.getRange(), *this);
229  } else {
230  (*this)(mLeafs.getRange());
231  }
232 }
233 
234 
235 template<typename IndexTreeType, typename BoolTreeType>
236 void
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
TBB body object for threaded primitive copy.
Definition: GeometryUtil.h:122
TBB body object for threaded vertex normal generation.
Definition: GeometryUtil.h:140
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.
#define OPENVDB_HOUDINI_API
Definition: Platform.h:299
OPENVDB_AX_API void run(const char *ax, openvdb::GridBase &grid, const AttributeBindings &bindings={})
Run a full AX pipeline (parse, compile and execute) on a single OpenVDB Grid.
TBB body object for threaded world to voxel space transformation and copy of points.
Definition: GeometryUtil.h:101
Definition: Coord.h:590
void run(bool threaded=true)
Definition: GeometryUtil.h:225
GenAdaptivityMaskOp(const GU_Detail &refGeo, const IndexTreeType &indexTree, BoolLeafManager &, float edgetolerance=0.0)
Definition: GeometryUtil.h:211
TBB body object for threaded sharp feature construction.
Definition: GeometryUtil.h:164
TBB body object for threaded sharp feature construction.
Definition: GeometryUtil.h:190
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_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.
Definition: VoxToNanoVDB.h:15
OutGridT XformOp bool threaded
Definition: ValueTransformer.h:140
const std::enable_if<!VecTraits< T >::IsVec, T >::type & min(const T &a, const T &b)
Definition: Composite.h:106
Convert polygonal meshes that consist of quads and/or triangles into signed or unsigned distance fiel...
constexpr Coord COORD_OFFSETS[26]
coordinate offset table for neighboring voxels
Definition: Util.h:22
T angle(const Vec2< T > &v1, const Vec2< T > &v2)
Definition: Vec2.h:446
Definition: AttributeTransferUtil.h:34
openvdb::tools::MeshToVoxelEdgeData EdgeData
Definition: GeometryUtil.h:167
OPENVDB_HOUDINI_API std::unique_ptr< GU_Detail > convertGeometry(const GU_Detail &, std::string &warning, openvdb::util::NullInterrupter *)
Convert geometry to quads and triangles.
A LeafManager manages a linear array of pointers to a given tree&#39;s leaf nodes, as well as optional au...
openvdb::tree::LeafManager< BoolTreeType > BoolLeafManager
Definition: GeometryUtil.h:193
void operator()(const tbb::blocked_range< size_t > &) const
Definition: GeometryUtil.h:237
#define OPENVDB_DEPRECATED_MESSAGE(msg)
Definition: Platform.h:171
const std::enable_if<!VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:110
Definition: Tree.h:194