scene.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. // Copyright 2009-2021 Intel Corporation
  2. // SPDX-License-Identifier: Apache-2.0
  3. #pragma once
  4. #include "default.h"
  5. #include "device.h"
  6. #include "builder.h"
  7. #include "../../common/algorithms/parallel_any_of.h"
  8. #include "scene_triangle_mesh.h"
  9. #include "scene_quad_mesh.h"
  10. #include "scene_user_geometry.h"
  11. #include "scene_instance.h"
  12. #include "scene_curves.h"
  13. #include "scene_line_segments.h"
  14. #include "scene_subdiv_mesh.h"
  15. #include "scene_grid_mesh.h"
  16. #include "scene_points.h"
  17. #include "../subdiv/tessellation_cache.h"
  18. #include "acceln.h"
  19. #include "geometry.h"
  20. namespace embree
  21. {
  22. /*! Base class all scenes are derived from */
  23. class Scene : public AccelN
  24. {
  25. ALIGNED_CLASS_(std::alignment_of<Scene>::value);
  26. public:
  27. template<typename Ty, bool mblur = false>
  28. class Iterator
  29. {
  30. public:
  31. Iterator () {}
  32. Iterator (Scene* scene, bool all = false)
  33. : scene(scene), all(all) {}
  34. __forceinline Ty* at(const size_t i)
  35. {
  36. Geometry* geom = scene->geometries[i].ptr;
  37. if (geom == nullptr) return nullptr;
  38. if (!all && !geom->isEnabled()) return nullptr;
  39. const size_t mask = geom->getTypeMask() & Ty::geom_type;
  40. if (!(mask)) return nullptr;
  41. if ((geom->numTimeSteps != 1) != mblur) return nullptr;
  42. return (Ty*) geom;
  43. }
  44. __forceinline Ty* operator[] (const size_t i) {
  45. return at(i);
  46. }
  47. __forceinline size_t size() const {
  48. return scene->size();
  49. }
  50. __forceinline size_t numPrimitives() const {
  51. return scene->getNumPrimitives(Ty::geom_type,mblur);
  52. }
  53. __forceinline size_t maxPrimitivesPerGeometry()
  54. {
  55. size_t ret = 0;
  56. for (size_t i=0; i<scene->size(); i++) {
  57. Ty* mesh = at(i);
  58. if (mesh == nullptr) continue;
  59. ret = max(ret,mesh->size());
  60. }
  61. return ret;
  62. }
  63. __forceinline unsigned int maxGeomID()
  64. {
  65. unsigned int ret = 0;
  66. for (size_t i=0; i<scene->size(); i++) {
  67. Ty* mesh = at(i);
  68. if (mesh == nullptr) continue;
  69. ret = max(ret,(unsigned int)i);
  70. }
  71. return ret;
  72. }
  73. __forceinline unsigned maxTimeStepsPerGeometry()
  74. {
  75. unsigned ret = 0;
  76. for (size_t i=0; i<scene->size(); i++) {
  77. Ty* mesh = at(i);
  78. if (mesh == nullptr) continue;
  79. ret = max(ret,mesh->numTimeSteps);
  80. }
  81. return ret;
  82. }
  83. private:
  84. Scene* scene;
  85. bool all;
  86. };
  87. class Iterator2
  88. {
  89. public:
  90. Iterator2 () {}
  91. Iterator2 (Scene* scene, Geometry::GTypeMask typemask, bool mblur)
  92. : scene(scene), typemask(typemask), mblur(mblur) {}
  93. __forceinline Geometry* at(const size_t i)
  94. {
  95. Geometry* geom = scene->geometries[i].ptr;
  96. if (geom == nullptr) return nullptr;
  97. if (!geom->isEnabled()) return nullptr;
  98. if (!(geom->getTypeMask() & typemask)) return nullptr;
  99. if ((geom->numTimeSteps != 1) != mblur) return nullptr;
  100. return geom;
  101. }
  102. __forceinline Geometry* operator[] (const size_t i) {
  103. return at(i);
  104. }
  105. __forceinline size_t size() const {
  106. return scene->size();
  107. }
  108. private:
  109. Scene* scene;
  110. Geometry::GTypeMask typemask;
  111. bool mblur;
  112. };
  113. public:
  114. /*! Scene construction */
  115. Scene (Device* device);
  116. /*! Scene destruction */
  117. ~Scene () noexcept;
  118. private:
  119. /*! class is non-copyable */
  120. Scene (const Scene& other) DELETED; // do not implement
  121. Scene& operator= (const Scene& other) DELETED; // do not implement
  122. public:
  123. void createTriangleAccel();
  124. void createTriangleMBAccel();
  125. void createQuadAccel();
  126. void createQuadMBAccel();
  127. void createHairAccel();
  128. void createHairMBAccel();
  129. void createSubdivAccel();
  130. void createSubdivMBAccel();
  131. void createUserGeometryAccel();
  132. void createUserGeometryMBAccel();
  133. void createInstanceAccel();
  134. void createInstanceMBAccel();
  135. void createInstanceExpensiveAccel();
  136. void createInstanceExpensiveMBAccel();
  137. void createGridAccel();
  138. void createGridMBAccel();
  139. /*! prints statistics about the scene */
  140. void printStatistics();
  141. /*! clears the scene */
  142. void clear();
  143. /*! detaches some geometry */
  144. void detachGeometry(size_t geomID);
  145. void setBuildQuality(RTCBuildQuality quality_flags);
  146. RTCBuildQuality getBuildQuality() const;
  147. void setSceneFlags(RTCSceneFlags scene_flags);
  148. RTCSceneFlags getSceneFlags() const;
  149. void commit (bool join);
  150. void commit_task ();
  151. void build () {}
  152. void updateInterface();
  153. /* return number of geometries */
  154. __forceinline size_t size() const { return geometries.size(); }
  155. /* bind geometry to the scene */
  156. unsigned int bind (unsigned geomID, Ref<Geometry> geometry);
  157. /* determines if scene is modified */
  158. __forceinline bool isModified() const { return modified; }
  159. /* sets modified flag */
  160. __forceinline void setModified(bool f = true) {
  161. modified = f;
  162. }
  163. __forceinline bool isGeometryModified(size_t geomID)
  164. {
  165. Ref<Geometry>& g = geometries[geomID];
  166. if (!g) return false;
  167. return g->getModCounter() > geometryModCounters_[geomID];
  168. }
  169. protected:
  170. __forceinline void checkIfModifiedAndSet ()
  171. {
  172. if (isModified ()) return;
  173. auto geometryIsModified = [this](size_t geomID)->bool {
  174. return isGeometryModified(geomID);
  175. };
  176. if (parallel_any_of (size_t(0), geometries.size (), geometryIsModified)) {
  177. setModified ();
  178. }
  179. }
  180. public:
  181. /* get mesh by ID */
  182. __forceinline Geometry* get(size_t i) { assert(i < geometries.size()); return geometries[i].ptr; }
  183. __forceinline const Geometry* get(size_t i) const { assert(i < geometries.size()); return geometries[i].ptr; }
  184. template<typename Mesh>
  185. __forceinline Mesh* get(size_t i) {
  186. assert(i < geometries.size());
  187. assert(geometries[i]->getTypeMask() & Mesh::geom_type);
  188. return (Mesh*)geometries[i].ptr;
  189. }
  190. template<typename Mesh>
  191. __forceinline const Mesh* get(size_t i) const {
  192. assert(i < geometries.size());
  193. assert(geometries[i]->getTypeMask() & Mesh::geom_type);
  194. return (Mesh*)geometries[i].ptr;
  195. }
  196. template<typename Mesh>
  197. __forceinline Mesh* getSafe(size_t i) {
  198. assert(i < geometries.size());
  199. if (geometries[i] == null) return nullptr;
  200. if (!(geometries[i]->getTypeMask() & Mesh::geom_type)) return nullptr;
  201. else return (Mesh*) geometries[i].ptr;
  202. }
  203. __forceinline Ref<Geometry> get_locked(size_t i) {
  204. Lock<SpinLock> lock(geometriesMutex);
  205. assert(i < geometries.size());
  206. return geometries[i];
  207. }
  208. /* flag decoding */
  209. __forceinline bool isFastAccel() const { return !isCompactAccel() && !isRobustAccel(); }
  210. __forceinline bool isCompactAccel() const { return scene_flags & RTC_SCENE_FLAG_COMPACT; }
  211. __forceinline bool isRobustAccel() const { return scene_flags & RTC_SCENE_FLAG_ROBUST; }
  212. __forceinline bool isStaticAccel() const { return !(scene_flags & RTC_SCENE_FLAG_DYNAMIC); }
  213. __forceinline bool isDynamicAccel() const { return scene_flags & RTC_SCENE_FLAG_DYNAMIC; }
  214. __forceinline bool hasContextFilterFunction() const {
  215. return scene_flags & RTC_SCENE_FLAG_CONTEXT_FILTER_FUNCTION;
  216. }
  217. __forceinline bool hasGeometryFilterFunction() {
  218. return world.numFilterFunctions != 0;
  219. }
  220. __forceinline bool hasFilterFunction() {
  221. return hasContextFilterFunction() || hasGeometryFilterFunction();
  222. }
  223. /* test if scene got already build */
  224. __forceinline bool isBuild() const { return is_build; }
  225. public:
  226. IDPool<unsigned,0xFFFFFFFE> id_pool;
  227. vector<Ref<Geometry>> geometries; //!< list of all user geometries
  228. vector<unsigned int> geometryModCounters_;
  229. vector<float*> vertices;
  230. public:
  231. Device* device;
  232. /* these are to detect if we need to recreate the acceleration structures */
  233. bool flags_modified;
  234. unsigned int enabled_geometry_types;
  235. RTCSceneFlags scene_flags;
  236. RTCBuildQuality quality_flags;
  237. MutexSys buildMutex;
  238. SpinLock geometriesMutex;
  239. bool is_build;
  240. private:
  241. bool modified; //!< true if scene got modified
  242. public:
  243. /*! global lock step task scheduler */
  244. #if defined(TASKING_INTERNAL)
  245. MutexSys schedulerMutex;
  246. Ref<TaskScheduler> scheduler;
  247. #elif defined(TASKING_TBB) && TASKING_TBB_USE_TASK_ISOLATION
  248. tbb::isolated_task_group group;
  249. #elif defined(TASKING_TBB)
  250. tbb::task_group group;
  251. #elif defined(TASKING_PPL)
  252. concurrency::task_group group;
  253. #endif
  254. public:
  255. struct BuildProgressMonitorInterface : public BuildProgressMonitor {
  256. BuildProgressMonitorInterface(Scene* scene)
  257. : scene(scene) {}
  258. void operator() (size_t dn) const { scene->progressMonitor(double(dn)); }
  259. private:
  260. Scene* scene;
  261. };
  262. BuildProgressMonitorInterface progressInterface;
  263. RTCProgressMonitorFunction progress_monitor_function;
  264. void* progress_monitor_ptr;
  265. std::atomic<size_t> progress_monitor_counter;
  266. void progressMonitor(double nprims);
  267. void setProgressMonitorFunction(RTCProgressMonitorFunction func, void* ptr);
  268. private:
  269. GeometryCounts world; //!< counts for geometry
  270. public:
  271. __forceinline size_t numPrimitives() const {
  272. return world.size();
  273. }
  274. __forceinline size_t getNumPrimitives(Geometry::GTypeMask mask, bool mblur) const
  275. {
  276. size_t count = 0;
  277. if (mask & Geometry::MTY_TRIANGLE_MESH)
  278. count += mblur ? world.numMBTriangles : world.numTriangles;
  279. if (mask & Geometry::MTY_QUAD_MESH)
  280. count += mblur ? world.numMBQuads : world.numQuads;
  281. if (mask & Geometry::MTY_CURVE2)
  282. count += mblur ? world.numMBLineSegments : world.numLineSegments;
  283. if (mask & Geometry::MTY_CURVE4)
  284. count += mblur ? world.numMBBezierCurves : world.numBezierCurves;
  285. if (mask & Geometry::MTY_POINTS)
  286. count += mblur ? world.numMBPoints : world.numPoints;
  287. if (mask & Geometry::MTY_SUBDIV_MESH)
  288. count += mblur ? world.numMBSubdivPatches : world.numSubdivPatches;
  289. if (mask & Geometry::MTY_USER_GEOMETRY)
  290. count += mblur ? world.numMBUserGeometries : world.numUserGeometries;
  291. if (mask & Geometry::MTY_INSTANCE_CHEAP)
  292. count += mblur ? world.numMBInstancesCheap : world.numInstancesCheap;
  293. if (mask & Geometry::MTY_INSTANCE_EXPENSIVE)
  294. count += mblur ? world.numMBInstancesExpensive : world.numInstancesExpensive;
  295. if (mask & Geometry::MTY_GRID_MESH)
  296. count += mblur ? world.numMBGrids : world.numGrids;
  297. return count;
  298. }
  299. template<typename Mesh, bool mblur>
  300. __forceinline unsigned getNumTimeSteps()
  301. {
  302. if (!mblur)
  303. return 1;
  304. Scene::Iterator<Mesh,mblur> iter(this);
  305. return iter.maxTimeStepsPerGeometry();
  306. }
  307. template<typename Mesh, bool mblur>
  308. __forceinline unsigned int getMaxGeomID()
  309. {
  310. Scene::Iterator<Mesh,mblur> iter(this);
  311. return iter.maxGeomID();
  312. }
  313. };
  314. }