geometry.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. // Copyright 2009-2021 Intel Corporation
  2. // SPDX-License-Identifier: Apache-2.0
  3. #include "geometry.h"
  4. #include "scene.h"
  5. namespace embree
  6. {
  7. const char* Geometry::gtype_names[Geometry::GTY_END] =
  8. {
  9. "flat_linear_curve",
  10. "round_linear_curve",
  11. "oriented_linear_curve",
  12. "",
  13. "flat_bezier_curve",
  14. "round_bezier_curve",
  15. "oriented_bezier_curve",
  16. "",
  17. "flat_bspline_curve",
  18. "round_bspline_curve",
  19. "oriented_bspline_curve",
  20. "",
  21. "flat_hermite_curve",
  22. "round_hermite_curve",
  23. "oriented_hermite_curve",
  24. "",
  25. "flat_catmull_rom_curve",
  26. "round_catmull_rom_curve",
  27. "oriented_catmull_rom_curve",
  28. "",
  29. "triangles",
  30. "quads",
  31. "grid",
  32. "subdivs",
  33. "",
  34. "sphere",
  35. "disc",
  36. "oriented_disc",
  37. "",
  38. "usergeom",
  39. "instance_cheap",
  40. "instance_expensive",
  41. };
  42. Geometry::Geometry (Device* device, GType gtype, unsigned int numPrimitives, unsigned int numTimeSteps)
  43. : device(device), userPtr(nullptr),
  44. numPrimitives(numPrimitives), numTimeSteps(unsigned(numTimeSteps)), fnumTimeSegments(float(numTimeSteps-1)), time_range(0.0f,1.0f),
  45. mask(1),
  46. gtype(gtype),
  47. gsubtype(GTY_SUBTYPE_DEFAULT),
  48. quality(RTC_BUILD_QUALITY_MEDIUM),
  49. state((unsigned)State::MODIFIED),
  50. enabled(true),
  51. argumentFilterEnabled(false),
  52. intersectionFilterN(nullptr), occlusionFilterN(nullptr), pointQueryFunc(nullptr)
  53. {
  54. device->refInc();
  55. }
  56. Geometry::~Geometry()
  57. {
  58. device->refDec();
  59. }
  60. void Geometry::setNumPrimitives(unsigned int numPrimitives_in)
  61. {
  62. if (numPrimitives_in == numPrimitives) return;
  63. numPrimitives = numPrimitives_in;
  64. Geometry::update();
  65. }
  66. void Geometry::setNumTimeSteps (unsigned int numTimeSteps_in)
  67. {
  68. if (numTimeSteps_in == numTimeSteps) {
  69. return;
  70. }
  71. numTimeSteps = numTimeSteps_in;
  72. fnumTimeSegments = float(numTimeSteps_in-1);
  73. Geometry::update();
  74. }
  75. void Geometry::setTimeRange (const BBox1f range)
  76. {
  77. time_range = range;
  78. Geometry::update();
  79. }
  80. BBox1f Geometry::getTimeRange () const
  81. {
  82. return time_range;
  83. }
  84. void Geometry::update()
  85. {
  86. ++modCounter_; // FIXME: required?
  87. state = (unsigned)State::MODIFIED;
  88. }
  89. void Geometry::commit()
  90. {
  91. ++modCounter_;
  92. state = (unsigned)State::COMMITTED;
  93. }
  94. void Geometry::preCommit()
  95. {
  96. if (State::MODIFIED == (State)state)
  97. throw_RTCError(RTC_ERROR_INVALID_OPERATION,"geometry not committed");
  98. }
  99. void Geometry::postCommit()
  100. {
  101. }
  102. void Geometry::enable ()
  103. {
  104. if (isEnabled())
  105. return;
  106. enabled = true;
  107. ++modCounter_;
  108. }
  109. void Geometry::disable ()
  110. {
  111. if (isDisabled())
  112. return;
  113. enabled = false;
  114. ++modCounter_;
  115. }
  116. void Geometry::setUserData (void* ptr)
  117. {
  118. userPtr = ptr;
  119. }
  120. void Geometry::setIntersectionFilterFunctionN (RTCFilterFunctionN filter)
  121. {
  122. if (!(getTypeMask() & (MTY_TRIANGLE_MESH | MTY_QUAD_MESH | MTY_CURVES | MTY_SUBDIV_MESH | MTY_USER_GEOMETRY | MTY_GRID_MESH)))
  123. throw_RTCError(RTC_ERROR_INVALID_OPERATION,"filter functions not supported for this geometry");
  124. intersectionFilterN = filter;
  125. }
  126. void Geometry::setOcclusionFilterFunctionN (RTCFilterFunctionN filter)
  127. {
  128. if (!(getTypeMask() & (MTY_TRIANGLE_MESH | MTY_QUAD_MESH | MTY_CURVES | MTY_SUBDIV_MESH | MTY_USER_GEOMETRY | MTY_GRID_MESH)))
  129. throw_RTCError(RTC_ERROR_INVALID_OPERATION,"filter functions not supported for this geometry");
  130. occlusionFilterN = filter;
  131. }
  132. void Geometry::setPointQueryFunction (RTCPointQueryFunction func)
  133. {
  134. pointQueryFunc = func;
  135. }
  136. void Geometry::interpolateN(const RTCInterpolateNArguments* const args)
  137. {
  138. const void* valid_i = args->valid;
  139. const unsigned* primIDs = args->primIDs;
  140. const float* u = args->u;
  141. const float* v = args->v;
  142. unsigned int N = args->N;
  143. RTCBufferType bufferType = args->bufferType;
  144. unsigned int bufferSlot = args->bufferSlot;
  145. float* P = args->P;
  146. float* dPdu = args->dPdu;
  147. float* dPdv = args->dPdv;
  148. float* ddPdudu = args->ddPdudu;
  149. float* ddPdvdv = args->ddPdvdv;
  150. float* ddPdudv = args->ddPdudv;
  151. unsigned int valueCount = args->valueCount;
  152. if (valueCount > 256) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"maximally 256 floating point values can be interpolated per vertex");
  153. const int* valid = (const int*) valid_i;
  154. __aligned(64) float P_tmp[256];
  155. __aligned(64) float dPdu_tmp[256];
  156. __aligned(64) float dPdv_tmp[256];
  157. __aligned(64) float ddPdudu_tmp[256];
  158. __aligned(64) float ddPdvdv_tmp[256];
  159. __aligned(64) float ddPdudv_tmp[256];
  160. float* Pt = P ? P_tmp : nullptr;
  161. float* dPdut = nullptr, *dPdvt = nullptr;
  162. if (dPdu) { dPdut = dPdu_tmp; dPdvt = dPdv_tmp; }
  163. float* ddPdudut = nullptr, *ddPdvdvt = nullptr, *ddPdudvt = nullptr;
  164. if (ddPdudu) { ddPdudut = ddPdudu_tmp; ddPdvdvt = ddPdvdv_tmp; ddPdudvt = ddPdudv_tmp; }
  165. for (unsigned int i=0; i<N; i++)
  166. {
  167. if (valid && !valid[i]) continue;
  168. RTCInterpolateArguments iargs;
  169. iargs.primID = primIDs[i];
  170. iargs.u = u[i];
  171. iargs.v = v[i];
  172. iargs.bufferType = bufferType;
  173. iargs.bufferSlot = bufferSlot;
  174. iargs.P = Pt;
  175. iargs.dPdu = dPdut;
  176. iargs.dPdv = dPdvt;
  177. iargs.ddPdudu = ddPdudut;
  178. iargs.ddPdvdv = ddPdvdvt;
  179. iargs.ddPdudv = ddPdudvt;
  180. iargs.valueCount = valueCount;
  181. interpolate(&iargs);
  182. if (likely(P)) {
  183. for (unsigned int j=0; j<valueCount; j++)
  184. P[j*N+i] = Pt[j];
  185. }
  186. if (likely(dPdu))
  187. {
  188. for (unsigned int j=0; j<valueCount; j++) {
  189. dPdu[j*N+i] = dPdut[j];
  190. dPdv[j*N+i] = dPdvt[j];
  191. }
  192. }
  193. if (likely(ddPdudu))
  194. {
  195. for (unsigned int j=0; j<valueCount; j++) {
  196. ddPdudu[j*N+i] = ddPdudut[j];
  197. ddPdvdv[j*N+i] = ddPdvdvt[j];
  198. ddPdudv[j*N+i] = ddPdudvt[j];
  199. }
  200. }
  201. }
  202. }
  203. bool Geometry::pointQuery(PointQuery* query, PointQueryContext* context)
  204. {
  205. assert(context->primID < size());
  206. RTCPointQueryFunctionArguments args;
  207. args.query = (RTCPointQuery*)context->query_ws;
  208. args.userPtr = context->userPtr;
  209. args.primID = context->primID;
  210. args.geomID = context->geomID;
  211. args.context = context->userContext;
  212. args.similarityScale = context->similarityScale;
  213. bool update = false;
  214. if(context->func) update |= context->func(&args);
  215. if(pointQueryFunc) update |= pointQueryFunc(&args);
  216. if (update && context->userContext->instStackSize > 0)
  217. {
  218. // update point query
  219. if (context->query_type == POINT_QUERY_TYPE_AABB) {
  220. context->updateAABB();
  221. } else {
  222. assert(context->similarityScale > 0.f);
  223. query->radius = context->query_ws->radius * context->similarityScale;
  224. }
  225. }
  226. return update;
  227. }
  228. }