| 
									
										
										
										
											2021-05-20 12:49:33 +02:00
										 |  |  | // Copyright 2009-2021 Intel Corporation
 | 
					
						
							| 
									
										
										
										
											2021-04-20 18:38:09 +02:00
										 |  |  | // SPDX-License-Identifier: Apache-2.0
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "scene_triangle_mesh.h"
 | 
					
						
							|  |  |  | #include "scene.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace embree | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #if defined(EMBREE_LOWEST_ISA)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   TriangleMesh::TriangleMesh (Device* device) | 
					
						
							|  |  |  |     : Geometry(device,GTY_TRIANGLE_MESH,0,1) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     vertices.resize(numTimeSteps); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void TriangleMesh::setMask (unsigned mask)  | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     this->mask = mask;  | 
					
						
							|  |  |  |     Geometry::update(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void TriangleMesh::setNumTimeSteps (unsigned int numTimeSteps) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     vertices.resize(numTimeSteps); | 
					
						
							|  |  |  |     Geometry::setNumTimeSteps(numTimeSteps); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void TriangleMesh::setVertexAttributeCount (unsigned int N) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     vertexAttribs.resize(N); | 
					
						
							|  |  |  |     Geometry::update(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   void TriangleMesh::setBuffer(RTCBufferType type, unsigned int slot, RTCFormat format, const Ref<Buffer>& buffer, size_t offset, size_t stride, unsigned int num) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     /* verify that all accesses are 4 bytes aligned */ | 
					
						
							|  |  |  |     if (((size_t(buffer->getPtr()) + offset) & 0x3) || (stride & 0x3))  | 
					
						
							|  |  |  |       throw_RTCError(RTC_ERROR_INVALID_OPERATION, "data must be 4 bytes aligned"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (type == RTC_BUFFER_TYPE_VERTEX) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (format != RTC_FORMAT_FLOAT3) | 
					
						
							|  |  |  |         throw_RTCError(RTC_ERROR_INVALID_OPERATION, "invalid vertex buffer format"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /* if buffer is larger than 16GB the premultiplied index optimization does not work */ | 
					
						
							|  |  |  |       if (stride*num > 16ll*1024ll*1024ll*1024ll) | 
					
						
							|  |  |  |         throw_RTCError(RTC_ERROR_INVALID_OPERATION, "vertex buffer can be at most 16GB large"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (slot >= vertices.size()) | 
					
						
							|  |  |  |         throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid vertex buffer slot"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       vertices[slot].set(buffer, offset, stride, num, format); | 
					
						
							|  |  |  |       vertices[slot].checkPadding16(); | 
					
						
							|  |  |  |       vertices0 = vertices[0]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (type == RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (format < RTC_FORMAT_FLOAT || format > RTC_FORMAT_FLOAT16) | 
					
						
							|  |  |  |         throw_RTCError(RTC_ERROR_INVALID_OPERATION, "invalid vertex attribute buffer format"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (slot >= vertexAttribs.size()) | 
					
						
							|  |  |  |         throw_RTCError(RTC_ERROR_INVALID_OPERATION, "invalid vertex attribute buffer slot"); | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |       vertexAttribs[slot].set(buffer, offset, stride, num, format); | 
					
						
							|  |  |  |       vertexAttribs[slot].checkPadding16(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (type == RTC_BUFFER_TYPE_INDEX) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (slot != 0) | 
					
						
							|  |  |  |         throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid buffer slot"); | 
					
						
							|  |  |  |       if (format != RTC_FORMAT_UINT3) | 
					
						
							|  |  |  |         throw_RTCError(RTC_ERROR_INVALID_OPERATION, "invalid index buffer format"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       triangles.set(buffer, offset, stride, num, format); | 
					
						
							|  |  |  |       setNumPrimitives(num); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else  | 
					
						
							|  |  |  |       throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "unknown buffer type"); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void* TriangleMesh::getBuffer(RTCBufferType type, unsigned int slot) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     if (type == RTC_BUFFER_TYPE_INDEX) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (slot != 0) | 
					
						
							|  |  |  |         throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid buffer slot"); | 
					
						
							|  |  |  |       return triangles.getPtr(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (type == RTC_BUFFER_TYPE_VERTEX) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (slot >= vertices.size()) | 
					
						
							|  |  |  |         throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid buffer slot"); | 
					
						
							|  |  |  |       return vertices[slot].getPtr(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (type == RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (slot >= vertexAttribs.size()) | 
					
						
							|  |  |  |         throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid buffer slot"); | 
					
						
							|  |  |  |       return vertexAttribs[slot].getPtr(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "unknown buffer type"); | 
					
						
							|  |  |  |       return nullptr; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void TriangleMesh::updateBuffer(RTCBufferType type, unsigned int slot) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     if (type == RTC_BUFFER_TYPE_INDEX) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (slot != 0) | 
					
						
							|  |  |  |         throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid buffer slot"); | 
					
						
							|  |  |  |       triangles.setModified(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (type == RTC_BUFFER_TYPE_VERTEX) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (slot >= vertices.size()) | 
					
						
							|  |  |  |         throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid buffer slot"); | 
					
						
							|  |  |  |       vertices[slot].setModified(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (type == RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (slot >= vertexAttribs.size()) | 
					
						
							|  |  |  |         throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid buffer slot"); | 
					
						
							|  |  |  |       vertexAttribs[slot].setModified(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "unknown buffer type"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Geometry::update(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void TriangleMesh::commit()  | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     /* verify that stride of all time steps are identical */ | 
					
						
							|  |  |  |     for (unsigned int t=0; t<numTimeSteps; t++) | 
					
						
							|  |  |  |       if (vertices[t].getStride() != vertices[0].getStride()) | 
					
						
							|  |  |  |         throw_RTCError(RTC_ERROR_INVALID_OPERATION,"stride of vertex buffers have to be identical for each time step"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Geometry::commit(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void TriangleMesh::addElementsToCount (GeometryCounts & counts) const  | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     if (numTimeSteps == 1) counts.numTriangles += numPrimitives; | 
					
						
							|  |  |  |     else                   counts.numMBTriangles += numPrimitives; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   bool TriangleMesh::verify()  | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     /*! verify size of vertex arrays */ | 
					
						
							|  |  |  |     if (vertices.size() == 0) return false; | 
					
						
							|  |  |  |     for (const auto& buffer : vertices) | 
					
						
							|  |  |  |       if (buffer.size() != numVertices()) | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*! verify size of user vertex arrays */ | 
					
						
							|  |  |  |     for (const auto& buffer : vertexAttribs) | 
					
						
							|  |  |  |       if (buffer.size() != numVertices()) | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*! verify triangle indices */ | 
					
						
							|  |  |  |     for (size_t i=0; i<size(); i++) {      | 
					
						
							|  |  |  |       if (triangles[i].v[0] >= numVertices()) return false;  | 
					
						
							|  |  |  |       if (triangles[i].v[1] >= numVertices()) return false;  | 
					
						
							|  |  |  |       if (triangles[i].v[2] >= numVertices()) return false;  | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*! verify vertices */ | 
					
						
							|  |  |  |     for (const auto& buffer : vertices) | 
					
						
							|  |  |  |       for (size_t i=0; i<buffer.size(); i++) | 
					
						
							|  |  |  | 	if (!isvalid(buffer[i]))  | 
					
						
							|  |  |  | 	  return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-05-20 12:49:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   void TriangleMesh::interpolate(const RTCInterpolateArguments* const args) { | 
					
						
							|  |  |  |     interpolate_impl<4>(args); | 
					
						
							| 
									
										
										
										
											2021-04-20 18:38:09 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-05-20 12:49:33 +02:00
										 |  |  |   | 
					
						
							| 
									
										
										
										
											2021-04-20 18:38:09 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2021-05-20 12:49:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-20 18:38:09 +02:00
										 |  |  |   namespace isa | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     TriangleMesh* createTriangleMesh(Device* device) { | 
					
						
							|  |  |  |       return new TriangleMeshISA(device); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } |