Path: blob/master/thirdparty/embree/kernels/common/geometry.cpp
9905 views
// Copyright 2009-2021 Intel Corporation1// SPDX-License-Identifier: Apache-2.023#include "geometry.h"4#include "scene.h"56namespace embree7{8const char* Geometry::gtype_names[Geometry::GTY_END] =9{10"flat_linear_curve",11"round_linear_curve",12"oriented_linear_curve",13"",14"flat_bezier_curve",15"round_bezier_curve",16"oriented_bezier_curve",17"",18"flat_bspline_curve",19"round_bspline_curve",20"oriented_bspline_curve",21"",22"flat_hermite_curve",23"round_hermite_curve",24"oriented_hermite_curve",25"",26"flat_catmull_rom_curve",27"round_catmull_rom_curve",28"oriented_catmull_rom_curve",29"",30"triangles",31"quads",32"grid",33"subdivs",34"",35"sphere",36"disc",37"oriented_disc",38"",39"usergeom",40"instance_cheap",41"instance_expensive",42};4344Geometry::Geometry (Device* device, GType gtype, unsigned int numPrimitives, unsigned int numTimeSteps)45: device(device), userPtr(nullptr),46numPrimitives(numPrimitives), numTimeSteps(unsigned(numTimeSteps)), fnumTimeSegments(float(numTimeSteps-1)), time_range(0.0f,1.0f),47mask(1),48gtype(gtype),49gsubtype(GTY_SUBTYPE_DEFAULT),50quality(RTC_BUILD_QUALITY_MEDIUM),51state((unsigned)State::MODIFIED),52enabled(true),53argumentFilterEnabled(false),54intersectionFilterN(nullptr), occlusionFilterN(nullptr), pointQueryFunc(nullptr)55{56device->refInc();57}5859Geometry::~Geometry()60{61device->refDec();62}6364void Geometry::setNumPrimitives(unsigned int numPrimitives_in)65{66if (numPrimitives_in == numPrimitives) return;6768numPrimitives = numPrimitives_in;6970Geometry::update();71}7273void Geometry::setNumTimeSteps (unsigned int numTimeSteps_in)74{75if (numTimeSteps_in == numTimeSteps) {76return;77}7879numTimeSteps = numTimeSteps_in;80fnumTimeSegments = float(numTimeSteps_in-1);8182Geometry::update();83}8485void Geometry::setTimeRange (const BBox1f range)86{87time_range = range;88Geometry::update();89}9091BBox1f Geometry::getTimeRange () const92{93return time_range;94}9596void Geometry::update()97{98++modCounter_; // FIXME: required?99state = (unsigned)State::MODIFIED;100}101102void Geometry::commit()103{104++modCounter_;105state = (unsigned)State::COMMITTED;106}107108void Geometry::preCommit()109{110if (State::MODIFIED == (State)state)111throw_RTCError(RTC_ERROR_INVALID_OPERATION,"geometry not committed");112}113114void Geometry::postCommit()115{116}117118void Geometry::enable ()119{120if (isEnabled())121return;122123enabled = true;124++modCounter_;125}126127void Geometry::disable ()128{129if (isDisabled())130return;131132enabled = false;133++modCounter_;134}135136void Geometry::setUserData (void* ptr)137{138userPtr = ptr;139}140141void Geometry::setIntersectionFilterFunctionN (RTCFilterFunctionN filter)142{143if (!(getTypeMask() & (MTY_TRIANGLE_MESH | MTY_QUAD_MESH | MTY_CURVES | MTY_SUBDIV_MESH | MTY_USER_GEOMETRY | MTY_GRID_MESH)))144throw_RTCError(RTC_ERROR_INVALID_OPERATION,"filter functions not supported for this geometry");145146intersectionFilterN = filter;147}148149void Geometry::setOcclusionFilterFunctionN (RTCFilterFunctionN filter)150{151if (!(getTypeMask() & (MTY_TRIANGLE_MESH | MTY_QUAD_MESH | MTY_CURVES | MTY_SUBDIV_MESH | MTY_USER_GEOMETRY | MTY_GRID_MESH)))152throw_RTCError(RTC_ERROR_INVALID_OPERATION,"filter functions not supported for this geometry");153154occlusionFilterN = filter;155}156157void Geometry::setPointQueryFunction (RTCPointQueryFunction func)158{159pointQueryFunc = func;160}161162void Geometry::interpolateN(const RTCInterpolateNArguments* const args)163{164const void* valid_i = args->valid;165const unsigned* primIDs = args->primIDs;166const float* u = args->u;167const float* v = args->v;168unsigned int N = args->N;169RTCBufferType bufferType = args->bufferType;170unsigned int bufferSlot = args->bufferSlot;171float* P = args->P;172float* dPdu = args->dPdu;173float* dPdv = args->dPdv;174float* ddPdudu = args->ddPdudu;175float* ddPdvdv = args->ddPdvdv;176float* ddPdudv = args->ddPdudv;177unsigned int valueCount = args->valueCount;178179if (valueCount > 256) throw_RTCError(RTC_ERROR_INVALID_OPERATION,"maximally 256 floating point values can be interpolated per vertex");180const int* valid = (const int*) valid_i;181182__aligned(64) float P_tmp[256];183__aligned(64) float dPdu_tmp[256];184__aligned(64) float dPdv_tmp[256];185__aligned(64) float ddPdudu_tmp[256];186__aligned(64) float ddPdvdv_tmp[256];187__aligned(64) float ddPdudv_tmp[256];188189float* Pt = P ? P_tmp : nullptr;190float* dPdut = nullptr, *dPdvt = nullptr;191if (dPdu) { dPdut = dPdu_tmp; dPdvt = dPdv_tmp; }192float* ddPdudut = nullptr, *ddPdvdvt = nullptr, *ddPdudvt = nullptr;193if (ddPdudu) { ddPdudut = ddPdudu_tmp; ddPdvdvt = ddPdvdv_tmp; ddPdudvt = ddPdudv_tmp; }194195for (unsigned int i=0; i<N; i++)196{197if (valid && !valid[i]) continue;198199RTCInterpolateArguments iargs;200iargs.primID = primIDs[i];201iargs.u = u[i];202iargs.v = v[i];203iargs.bufferType = bufferType;204iargs.bufferSlot = bufferSlot;205iargs.P = Pt;206iargs.dPdu = dPdut;207iargs.dPdv = dPdvt;208iargs.ddPdudu = ddPdudut;209iargs.ddPdvdv = ddPdvdvt;210iargs.ddPdudv = ddPdudvt;211iargs.valueCount = valueCount;212interpolate(&iargs);213214if (likely(P)) {215for (unsigned int j=0; j<valueCount; j++)216P[j*N+i] = Pt[j];217}218if (likely(dPdu))219{220for (unsigned int j=0; j<valueCount; j++) {221dPdu[j*N+i] = dPdut[j];222dPdv[j*N+i] = dPdvt[j];223}224}225if (likely(ddPdudu))226{227for (unsigned int j=0; j<valueCount; j++) {228ddPdudu[j*N+i] = ddPdudut[j];229ddPdvdv[j*N+i] = ddPdvdvt[j];230ddPdudv[j*N+i] = ddPdudvt[j];231}232}233}234}235236bool Geometry::pointQuery(PointQuery* query, PointQueryContext* context)237{238assert(context->primID < size());239240RTCPointQueryFunctionArguments args;241args.query = (RTCPointQuery*)context->query_ws;242args.userPtr = context->userPtr;243args.primID = context->primID;244args.geomID = context->geomID;245args.context = context->userContext;246args.similarityScale = context->similarityScale;247248bool update = false;249if(context->func) update |= context->func(&args);250if(pointQueryFunc) update |= pointQueryFunc(&args);251252if (update && context->userContext->instStackSize > 0)253{254// update point query255if (context->query_type == POINT_QUERY_TYPE_AABB) {256context->updateAABB();257} else {258assert(context->similarityScale > 0.f);259query->radius = context->query_ws->radius * context->similarityScale;260}261}262return update;263}264}265266267