Path: blob/master/thirdparty/embree/kernels/common/scene_triangle_mesh.cpp
9905 views
// Copyright 2009-2021 Intel Corporation1// SPDX-License-Identifier: Apache-2.023#include "scene_triangle_mesh.h"4#include "scene.h"56namespace embree7{8#if defined(EMBREE_LOWEST_ISA)910TriangleMesh::TriangleMesh (Device* device)11: Geometry(device,GTY_TRIANGLE_MESH,0,1)12{13vertices.resize(numTimeSteps);14}1516void TriangleMesh::setMask (unsigned mask)17{18this->mask = mask;19Geometry::update();20}2122void TriangleMesh::setNumTimeSteps (unsigned int numTimeSteps)23{24vertices.resize(numTimeSteps);25Geometry::setNumTimeSteps(numTimeSteps);26}2728void TriangleMesh::setVertexAttributeCount (unsigned int N)29{30vertexAttribs.resize(N);31Geometry::update();32}3334void TriangleMesh::setBuffer(RTCBufferType type, unsigned int slot, RTCFormat format, const Ref<Buffer>& buffer, size_t offset, size_t stride, unsigned int num)35{36/* verify that all accesses are 4 bytes aligned */37if (((size_t(buffer->getHostPtr()) + offset) & 0x3) || (stride & 0x3))38throw_RTCError(RTC_ERROR_INVALID_OPERATION, "data must be 4 bytes aligned");3940if (type == RTC_BUFFER_TYPE_VERTEX)41{42if (format != RTC_FORMAT_FLOAT3)43throw_RTCError(RTC_ERROR_INVALID_OPERATION, "invalid vertex buffer format");4445/* if buffer is larger than 16GB the premultiplied index optimization does not work */46if (stride*num > 16ll*1024ll*1024ll*1024ll)47throw_RTCError(RTC_ERROR_INVALID_OPERATION, "vertex buffer can be at most 16GB large");4849if (slot >= vertices.size())50throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid vertex buffer slot");5152vertices[slot].set(buffer, offset, stride, num, format);53vertices[slot].checkPadding16();54vertices0 = vertices[0];55}56else if (type == RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE)57{58if (format < RTC_FORMAT_FLOAT || format > RTC_FORMAT_FLOAT16)59throw_RTCError(RTC_ERROR_INVALID_OPERATION, "invalid vertex attribute buffer format");6061if (slot >= vertexAttribs.size())62throw_RTCError(RTC_ERROR_INVALID_OPERATION, "invalid vertex attribute buffer slot");6364vertexAttribs[slot].set(buffer, offset, stride, num, format);65vertexAttribs[slot].checkPadding16();66}67else if (type == RTC_BUFFER_TYPE_INDEX)68{69if (slot != 0)70throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid buffer slot");71if (format != RTC_FORMAT_UINT3)72throw_RTCError(RTC_ERROR_INVALID_OPERATION, "invalid index buffer format");7374triangles.set(buffer, offset, stride, num, format);75setNumPrimitives(num);76}77else78throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "unknown buffer type");79}8081void* TriangleMesh::getBufferData(RTCBufferType type, unsigned int slot, BufferDataPointerType pointerType)82{83if (type == RTC_BUFFER_TYPE_INDEX)84{85if (slot != 0)86throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid buffer slot");87return triangles.getPtr(pointerType);88}89else if (type == RTC_BUFFER_TYPE_VERTEX)90{91if (slot >= vertices.size())92throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid buffer slot");93return vertices[slot].getPtr(pointerType);94}95else if (type == RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE)96{97if (slot >= vertexAttribs.size())98throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid buffer slot");99return vertexAttribs[slot].getPtr(pointerType);100}101else102{103throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "unknown buffer type");104return nullptr;105}106}107108void TriangleMesh::updateBuffer(RTCBufferType type, unsigned int slot)109{110if (type == RTC_BUFFER_TYPE_INDEX)111{112if (slot != 0)113throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid buffer slot");114triangles.setModified();115}116else if (type == RTC_BUFFER_TYPE_VERTEX)117{118if (slot >= vertices.size())119throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid buffer slot");120vertices[slot].setModified();121}122else if (type == RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE)123{124if (slot >= vertexAttribs.size())125throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "invalid buffer slot");126vertexAttribs[slot].setModified();127}128else129{130throw_RTCError(RTC_ERROR_INVALID_ARGUMENT, "unknown buffer type");131}132133Geometry::update();134}135136void TriangleMesh::commit()137{138/* verify that stride of all time steps are identical */139for (unsigned int t=0; t<numTimeSteps; t++) {140if (vertices[t].getStride() != vertices[0].getStride())141throw_RTCError(RTC_ERROR_INVALID_OPERATION,"stride of vertex buffers have to be identical for each time step");142if (vertices[t]) vertices[t].buffer->commitIfNeeded();143}144if (triangles) triangles.buffer->commitIfNeeded();145Geometry::commit();146}147148void TriangleMesh::addElementsToCount (GeometryCounts & counts) const149{150if (numTimeSteps == 1) counts.numTriangles += numPrimitives;151else counts.numMBTriangles += numPrimitives;152}153154bool TriangleMesh::verify()155{156/*! verify size of vertex arrays */157if (vertices.size() == 0) return false;158for (const auto& buffer : vertices)159if (buffer.size() != numVertices())160return false;161162/*! verify size of user vertex arrays */163for (const auto& buffer : vertexAttribs)164if (buffer.size() != numVertices())165return false;166167/*! verify triangle indices */168for (size_t i=0; i<size(); i++) {169if (triangles[i].v[0] >= numVertices()) return false;170if (triangles[i].v[1] >= numVertices()) return false;171if (triangles[i].v[2] >= numVertices()) return false;172}173174/*! verify vertices */175for (const auto& buffer : vertices)176for (size_t i=0; i<buffer.size(); i++)177if (!isvalid(buffer[i]))178return false;179180return true;181}182183void TriangleMesh::interpolate(const RTCInterpolateArguments* const args) {184interpolate_impl<4>(args);185}186187size_t TriangleMesh::getGeometryDataDeviceByteSize() const {188size_t byte_size = sizeof(TriangleMesh);189byte_size += numTimeSteps * sizeof(BufferView<Vec3fa>);190return 16 * ((byte_size + 15) / 16);191}192193void TriangleMesh::convertToDeviceRepresentation(size_t offset, char* data_host, char* data_device) const {194TriangleMesh* mesh = (TriangleMesh*)(data_host + offset);195std::memcpy(data_host + offset, (void*)this, sizeof(TriangleMesh));196offset += sizeof(TriangleMesh);197198// store offset for overriding vertices pointer with device pointer after copying199const size_t offsetVertices = offset;200// copy vertices BufferViews for each time step201for (size_t t = 0; t < numTimeSteps; ++t) {202std::memcpy(data_host + offset, &(vertices[t]), sizeof(BufferView<Vec3fa>));203offset += sizeof(BufferView<Vec3fa>);204}205// override vertices pointer with device ptr206mesh->vertices.setDataPtr((BufferView<Vec3fa>*)(data_device + offsetVertices));207}208209#endif210211namespace isa212{213TriangleMesh* createTriangleMesh(Device* device) {214return new TriangleMeshISA(device);215}216}217}218219220