Path: blob/master/thirdparty/embree/kernels/subdiv/bspline_patch.h
9913 views
// Copyright 2009-2021 Intel Corporation1// SPDX-License-Identifier: Apache-2.023#pragma once45#include "catmullclark_patch.h"6#include "bspline_curve.h"78namespace embree9{10template<typename Vertex, typename Vertex_t = Vertex>11class __aligned(64) BSplinePatchT12{13typedef CatmullClark1RingT<Vertex,Vertex_t> CatmullClarkRing;14typedef CatmullClarkPatchT<Vertex,Vertex_t> CatmullClarkPatch;1516public:1718__forceinline BSplinePatchT () {}1920__forceinline BSplinePatchT (const CatmullClarkPatch& patch) {21init(patch);22}2324__forceinline BSplinePatchT(const CatmullClarkPatch& patch,25const BezierCurveT<Vertex>* border0,26const BezierCurveT<Vertex>* border1,27const BezierCurveT<Vertex>* border2,28const BezierCurveT<Vertex>* border3)29{30init(patch);31}3233__forceinline BSplinePatchT (const HalfEdge* edge, const char* vertices, size_t stride) {34init(edge,vertices,stride);35}3637__forceinline Vertex hard_corner(const Vertex& v01, const Vertex& v02,38const Vertex& v10, const Vertex& v11, const Vertex& v12,39const Vertex& v20, const Vertex& v21, const Vertex& v22)40{41return 4.0f*v11 - 2.0f*(v12+v21) + v22;42}4344__forceinline Vertex soft_convex_corner( const Vertex& v01, const Vertex& v02,45const Vertex& v10, const Vertex& v11, const Vertex& v12,46const Vertex& v20, const Vertex& v21, const Vertex& v22)47{48return -8.0f*v11 + 4.0f*(v12+v21) + v22;49}5051__forceinline Vertex convex_corner(const float vertex_crease_weight,52const Vertex& v01, const Vertex& v02,53const Vertex& v10, const Vertex& v11, const Vertex& v12,54const Vertex& v20, const Vertex& v21, const Vertex& v22)55{56if (std::isinf(vertex_crease_weight)) return hard_corner(v01,v02,v10,v11,v12,v20,v21,v22);57else return soft_convex_corner(v01,v02,v10,v11,v12,v20,v21,v22);58}5960__forceinline Vertex load(const HalfEdge* edge, const char* vertices, size_t stride) {61return Vertex_t::loadu(vertices+edge->getStartVertexIndex()*stride);62}6364__forceinline void init_border(const CatmullClarkRing& edge0,65Vertex& v01, Vertex& v02,66const Vertex& v11, const Vertex& v12,67const Vertex& v21, const Vertex& v22)68{69if (likely(edge0.has_opposite_back(0)))70{71v01 = edge0.back(2);72v02 = edge0.back(1);73} else {74v01 = 2.0f*v11-v21;75v02 = 2.0f*v12-v22;76}77}7879__forceinline void init_corner(const CatmullClarkRing& edge0,80Vertex& v00, const Vertex& v01, const Vertex& v02,81const Vertex& v10, const Vertex& v11, const Vertex& v12,82const Vertex& v20, const Vertex& v21, const Vertex& v22)83{84const bool MAYBE_UNUSED has_back1 = edge0.has_opposite_back(1);85const bool has_back0 = edge0.has_opposite_back(0);86const bool has_front1 = edge0.has_opposite_front(1);87const bool MAYBE_UNUSED has_front2 = edge0.has_opposite_front(2);8889if (likely(has_back0)) {90if (likely(has_front1)) { assert(has_back1 && has_front2); v00 = edge0.back(3); }91else { assert(!has_back1); v00 = 2.0f*v01-v02; }92}93else {94if (likely(has_front1)) { assert(!has_front2); v00 = 2.0f*v10-v20; }95else v00 = convex_corner(edge0.vertex_crease_weight,v01,v02,v10,v11,v12,v20,v21,v22);96}97}9899void init(const CatmullClarkPatch& patch)100{101/* fill inner vertices */102const Vertex v11 = v[1][1] = patch.ring[0].vtx;103const Vertex v12 = v[1][2] = patch.ring[1].vtx;104const Vertex v22 = v[2][2] = patch.ring[2].vtx;105const Vertex v21 = v[2][1] = patch.ring[3].vtx;106107/* fill border vertices */108init_border(patch.ring[0],v[0][1],v[0][2],v11,v12,v21,v22);109init_border(patch.ring[1],v[1][3],v[2][3],v12,v22,v11,v21);110init_border(patch.ring[2],v[3][2],v[3][1],v22,v21,v12,v11);111init_border(patch.ring[3],v[2][0],v[1][0],v21,v11,v22,v12);112113/* fill corner vertices */114init_corner(patch.ring[0],v[0][0],v[0][1],v[0][2],v[1][0],v11,v12,v[2][0],v21,v22);115init_corner(patch.ring[1],v[0][3],v[1][3],v[2][3],v[0][2],v12,v22,v[0][1],v11,v21);116init_corner(patch.ring[2],v[3][3],v[3][2],v[3][1],v[2][3],v22,v21,v[1][3],v12,v11);117init_corner(patch.ring[3],v[3][0],v[2][0],v[1][0],v[3][1],v21,v11,v[3][2],v22,v12);118}119120void init_border(const HalfEdge* edge0, const char* vertices, size_t stride,121Vertex& v01, Vertex& v02,122const Vertex& v11, const Vertex& v12,123const Vertex& v21, const Vertex& v22)124{125if (likely(edge0->hasOpposite()))126{127const HalfEdge* e = edge0->opposite()->next()->next();128v01 = load(e,vertices,stride);129v02 = load(e->next(),vertices,stride);130} else {131v01 = 2.0f*v11-v21;132v02 = 2.0f*v12-v22;133}134}135136void init_corner(const HalfEdge* edge0, const char* vertices, size_t stride,137Vertex& v00, const Vertex& v01, const Vertex& v02,138const Vertex& v10, const Vertex& v11, const Vertex& v12,139const Vertex& v20, const Vertex& v21, const Vertex& v22)140{141const bool has_back0 = edge0->hasOpposite();142const bool has_front1 = edge0->prev()->hasOpposite();143144if (likely(has_back0))145{146const HalfEdge* e = edge0->opposite()->next();147if (likely(has_front1))148{149assert(e->hasOpposite());150assert(edge0->prev()->opposite()->prev()->hasOpposite());151v00 = load(e->opposite()->prev(),vertices,stride);152}153else {154assert(!e->hasOpposite());155v00 = 2.0f*v01-v02;156}157}158else159{160if (likely(has_front1)) {161assert(!edge0->prev()->opposite()->prev()->hasOpposite());162v00 = 2.0f*v10-v20;163}164else {165assert(edge0->vertex_crease_weight == 0.0f || std::isinf(edge0->vertex_crease_weight));166v00 = convex_corner(edge0->vertex_crease_weight,v01,v02,v10,v11,v12,v20,v21,v22);167}168}169}170171void init(const HalfEdge* edge0, const char* vertices, size_t stride)172{173assert( edge0->isRegularFace() );174175/* fill inner vertices */176const Vertex v11 = v[1][1] = load(edge0,vertices,stride); const HalfEdge* edge1 = edge0->next();177const Vertex v12 = v[1][2] = load(edge1,vertices,stride); const HalfEdge* edge2 = edge1->next();178const Vertex v22 = v[2][2] = load(edge2,vertices,stride); const HalfEdge* edge3 = edge2->next();179const Vertex v21 = v[2][1] = load(edge3,vertices,stride); assert(edge0 == edge3->next());180181/* fill border vertices */182init_border(edge0,vertices,stride,v[0][1],v[0][2],v11,v12,v21,v22);183init_border(edge1,vertices,stride,v[1][3],v[2][3],v12,v22,v11,v21);184init_border(edge2,vertices,stride,v[3][2],v[3][1],v22,v21,v12,v11);185init_border(edge3,vertices,stride,v[2][0],v[1][0],v21,v11,v22,v12);186187/* fill corner vertices */188init_corner(edge0,vertices,stride,v[0][0],v[0][1],v[0][2],v[1][0],v11,v12,v[2][0],v21,v22);189init_corner(edge1,vertices,stride,v[0][3],v[1][3],v[2][3],v[0][2],v12,v22,v[0][1],v11,v21);190init_corner(edge2,vertices,stride,v[3][3],v[3][2],v[3][1],v[2][3],v22,v21,v[1][3],v12,v11);191init_corner(edge3,vertices,stride,v[3][0],v[2][0],v[1][0],v[3][1],v21,v11,v[3][2],v22,v12);192}193194__forceinline BBox<Vertex> bounds() const195{196const Vertex* const cv = &v[0][0];197BBox<Vertex> bounds (cv[0]);198for (size_t i=1; i<16 ; i++)199bounds.extend( cv[i] );200return bounds;201}202203__forceinline Vertex eval(const float uu, const float vv) const204{205const Vec4f v_n = BSplineBasis::eval(vv);206const Vertex_t curve0 = madd(v_n[0],v[0][0],madd(v_n[1],v[1][0],madd(v_n[2],v[2][0],v_n[3] * v[3][0])));207const Vertex_t curve1 = madd(v_n[0],v[0][1],madd(v_n[1],v[1][1],madd(v_n[2],v[2][1],v_n[3] * v[3][1])));208const Vertex_t curve2 = madd(v_n[0],v[0][2],madd(v_n[1],v[1][2],madd(v_n[2],v[2][2],v_n[3] * v[3][2])));209const Vertex_t curve3 = madd(v_n[0],v[0][3],madd(v_n[1],v[1][3],madd(v_n[2],v[2][3],v_n[3] * v[3][3])));210211const Vec4f u_n = BSplineBasis::eval(uu);212return madd(u_n[0],curve0,madd(u_n[1],curve1,madd(u_n[2],curve2,u_n[3] * curve3)));213}214215__forceinline Vertex eval_du(const float uu, const float vv) const216{217const Vec4f v_n = BSplineBasis::eval(vv);218const Vertex_t curve0 = madd(v_n[0],v[0][0],madd(v_n[1],v[1][0],madd(v_n[2],v[2][0],v_n[3] * v[3][0])));219const Vertex_t curve1 = madd(v_n[0],v[0][1],madd(v_n[1],v[1][1],madd(v_n[2],v[2][1],v_n[3] * v[3][1])));220const Vertex_t curve2 = madd(v_n[0],v[0][2],madd(v_n[1],v[1][2],madd(v_n[2],v[2][2],v_n[3] * v[3][2])));221const Vertex_t curve3 = madd(v_n[0],v[0][3],madd(v_n[1],v[1][3],madd(v_n[2],v[2][3],v_n[3] * v[3][3])));222223const Vec4f u_n = BSplineBasis::derivative(uu);224return madd(u_n[0],curve0,madd(u_n[1],curve1,madd(u_n[2],curve2,u_n[3] * curve3)));225}226227__forceinline Vertex eval_dv(const float uu, const float vv) const228{229const Vec4f v_n = BSplineBasis::derivative(vv);230const Vertex_t curve0 = madd(v_n[0],v[0][0],madd(v_n[1],v[1][0],madd(v_n[2],v[2][0],v_n[3] * v[3][0])));231const Vertex_t curve1 = madd(v_n[0],v[0][1],madd(v_n[1],v[1][1],madd(v_n[2],v[2][1],v_n[3] * v[3][1])));232const Vertex_t curve2 = madd(v_n[0],v[0][2],madd(v_n[1],v[1][2],madd(v_n[2],v[2][2],v_n[3] * v[3][2])));233const Vertex_t curve3 = madd(v_n[0],v[0][3],madd(v_n[1],v[1][3],madd(v_n[2],v[2][3],v_n[3] * v[3][3])));234235const Vec4f u_n = BSplineBasis::eval(uu);236return madd(u_n[0],curve0,madd(u_n[1],curve1,madd(u_n[2],curve2,u_n[3] * curve3)));237}238239__forceinline Vertex eval_dudu(const float uu, const float vv) const240{241const Vec4f v_n = BSplineBasis::eval(vv);242const Vertex_t curve0 = madd(v_n[0],v[0][0],madd(v_n[1],v[1][0],madd(v_n[2],v[2][0],v_n[3] * v[3][0])));243const Vertex_t curve1 = madd(v_n[0],v[0][1],madd(v_n[1],v[1][1],madd(v_n[2],v[2][1],v_n[3] * v[3][1])));244const Vertex_t curve2 = madd(v_n[0],v[0][2],madd(v_n[1],v[1][2],madd(v_n[2],v[2][2],v_n[3] * v[3][2])));245const Vertex_t curve3 = madd(v_n[0],v[0][3],madd(v_n[1],v[1][3],madd(v_n[2],v[2][3],v_n[3] * v[3][3])));246247const Vec4f u_n = BSplineBasis::derivative2(uu);248return madd(u_n[0],curve0,madd(u_n[1],curve1,madd(u_n[2],curve2,u_n[3] * curve3)));249}250251__forceinline Vertex eval_dvdv(const float uu, const float vv) const252{253const Vec4f v_n = BSplineBasis::derivative2(vv);254const Vertex_t curve0 = madd(v_n[0],v[0][0],madd(v_n[1],v[1][0],madd(v_n[2],v[2][0],v_n[3] * v[3][0])));255const Vertex_t curve1 = madd(v_n[0],v[0][1],madd(v_n[1],v[1][1],madd(v_n[2],v[2][1],v_n[3] * v[3][1])));256const Vertex_t curve2 = madd(v_n[0],v[0][2],madd(v_n[1],v[1][2],madd(v_n[2],v[2][2],v_n[3] * v[3][2])));257const Vertex_t curve3 = madd(v_n[0],v[0][3],madd(v_n[1],v[1][3],madd(v_n[2],v[2][3],v_n[3] * v[3][3])));258259const Vec4f u_n = BSplineBasis::eval(uu);260return madd(u_n[0],curve0,madd(u_n[1],curve1,madd(u_n[2],curve2,u_n[3] * curve3)));261}262263__forceinline Vertex eval_dudv(const float uu, const float vv) const264{265const Vec4f v_n = BSplineBasis::derivative(vv);266const Vertex_t curve0 = madd(v_n[0],v[0][0],madd(v_n[1],v[1][0],madd(v_n[2],v[2][0],v_n[3] * v[3][0])));267const Vertex_t curve1 = madd(v_n[0],v[0][1],madd(v_n[1],v[1][1],madd(v_n[2],v[2][1],v_n[3] * v[3][1])));268const Vertex_t curve2 = madd(v_n[0],v[0][2],madd(v_n[1],v[1][2],madd(v_n[2],v[2][2],v_n[3] * v[3][2])));269const Vertex_t curve3 = madd(v_n[0],v[0][3],madd(v_n[1],v[1][3],madd(v_n[2],v[2][3],v_n[3] * v[3][3])));270271const Vec4f u_n = BSplineBasis::derivative(uu);272return madd(u_n[0],curve0,madd(u_n[1],curve1,madd(u_n[2],curve2,u_n[3] * curve3)));273}274275__forceinline Vertex normal(const float uu, const float vv) const276{277const Vertex tu = eval_du(uu,vv);278const Vertex tv = eval_dv(uu,vv);279return cross(tu,tv);280}281282template<typename T>283__forceinline Vec3<T> eval(const T& uu, const T& vv, const Vec4<T>& u_n, const Vec4<T>& v_n) const284{285const T curve0_x = madd(v_n[0],T(v[0][0].x),madd(v_n[1],T(v[1][0].x),madd(v_n[2],T(v[2][0].x),v_n[3] * T(v[3][0].x))));286const T curve1_x = madd(v_n[0],T(v[0][1].x),madd(v_n[1],T(v[1][1].x),madd(v_n[2],T(v[2][1].x),v_n[3] * T(v[3][1].x))));287const T curve2_x = madd(v_n[0],T(v[0][2].x),madd(v_n[1],T(v[1][2].x),madd(v_n[2],T(v[2][2].x),v_n[3] * T(v[3][2].x))));288const T curve3_x = madd(v_n[0],T(v[0][3].x),madd(v_n[1],T(v[1][3].x),madd(v_n[2],T(v[2][3].x),v_n[3] * T(v[3][3].x))));289const T x = madd(u_n[0],curve0_x,madd(u_n[1],curve1_x,madd(u_n[2],curve2_x,u_n[3] * curve3_x)));290291const T curve0_y = madd(v_n[0],T(v[0][0].y),madd(v_n[1],T(v[1][0].y),madd(v_n[2],T(v[2][0].y),v_n[3] * T(v[3][0].y))));292const T curve1_y = madd(v_n[0],T(v[0][1].y),madd(v_n[1],T(v[1][1].y),madd(v_n[2],T(v[2][1].y),v_n[3] * T(v[3][1].y))));293const T curve2_y = madd(v_n[0],T(v[0][2].y),madd(v_n[1],T(v[1][2].y),madd(v_n[2],T(v[2][2].y),v_n[3] * T(v[3][2].y))));294const T curve3_y = madd(v_n[0],T(v[0][3].y),madd(v_n[1],T(v[1][3].y),madd(v_n[2],T(v[2][3].y),v_n[3] * T(v[3][3].y))));295const T y = madd(u_n[0],curve0_y,madd(u_n[1],curve1_y,madd(u_n[2],curve2_y,u_n[3] * curve3_y)));296297const T curve0_z = madd(v_n[0],T(v[0][0].z),madd(v_n[1],T(v[1][0].z),madd(v_n[2],T(v[2][0].z),v_n[3] * T(v[3][0].z))));298const T curve1_z = madd(v_n[0],T(v[0][1].z),madd(v_n[1],T(v[1][1].z),madd(v_n[2],T(v[2][1].z),v_n[3] * T(v[3][1].z))));299const T curve2_z = madd(v_n[0],T(v[0][2].z),madd(v_n[1],T(v[1][2].z),madd(v_n[2],T(v[2][2].z),v_n[3] * T(v[3][2].z))));300const T curve3_z = madd(v_n[0],T(v[0][3].z),madd(v_n[1],T(v[1][3].z),madd(v_n[2],T(v[2][3].z),v_n[3] * T(v[3][3].z))));301const T z = madd(u_n[0],curve0_z,madd(u_n[1],curve1_z,madd(u_n[2],curve2_z,u_n[3] * curve3_z)));302303return Vec3<T>(x,y,z);304}305306template<typename T>307__forceinline Vec3<T> eval(const T& uu, const T& vv) const308{309const Vec4<T> u_n = BSplineBasis::eval(uu);310const Vec4<T> v_n = BSplineBasis::eval(vv);311return eval(uu,vv,u_n,v_n);312}313314template<typename T>315__forceinline Vec3<T> eval_du(const T& uu, const T& vv) const316{317const Vec4<T> u_n = BSplineBasis::derivative(uu);318const Vec4<T> v_n = BSplineBasis::eval(vv);319return eval(uu,vv,u_n,v_n);320}321322template<typename T>323__forceinline Vec3<T> eval_dv(const T& uu, const T& vv) const324{325const Vec4<T> u_n = BSplineBasis::eval(uu);326const Vec4<T> v_n = BSplineBasis::derivative(vv);327return eval(uu,vv,u_n,v_n);328}329330template<typename T>331__forceinline Vec3<T> eval_dudu(const T& uu, const T& vv) const332{333const Vec4<T> u_n = BSplineBasis::derivative2(uu);334const Vec4<T> v_n = BSplineBasis::eval(vv);335return eval(uu,vv,u_n,v_n);336}337338template<typename T>339__forceinline Vec3<T> eval_dvdv(const T& uu, const T& vv) const340{341const Vec4<T> u_n = BSplineBasis::eval(uu);342const Vec4<T> v_n = BSplineBasis::derivative2(vv);343return eval(uu,vv,u_n,v_n);344}345346template<typename T>347__forceinline Vec3<T> eval_dudv(const T& uu, const T& vv) const348{349const Vec4<T> u_n = BSplineBasis::derivative(uu);350const Vec4<T> v_n = BSplineBasis::derivative(vv);351return eval(uu,vv,u_n,v_n);352}353354template<typename T>355__forceinline Vec3<T> normal(const T& uu, const T& vv) const {356return cross(eval_du(uu,vv),eval_dv(uu,vv));357}358359void eval(const float u, const float v,360Vertex* P, Vertex* dPdu, Vertex* dPdv, Vertex* ddPdudu, Vertex* ddPdvdv, Vertex* ddPdudv,361const float dscale = 1.0f) const362{363if (P) {364*P = eval(u,v);365}366if (dPdu) {367assert(dPdu); *dPdu = eval_du(u,v)*dscale;368assert(dPdv); *dPdv = eval_dv(u,v)*dscale;369}370if (ddPdudu) {371assert(ddPdudu); *ddPdudu = eval_dudu(u,v)*sqr(dscale);372assert(ddPdvdv); *ddPdvdv = eval_dvdv(u,v)*sqr(dscale);373assert(ddPdudv); *ddPdudv = eval_dudv(u,v)*sqr(dscale);374}375}376377template<class vfloat>378__forceinline vfloat eval(const size_t i, const vfloat& uu, const vfloat& vv, const Vec4<vfloat>& u_n, const Vec4<vfloat>& v_n) const379{380const vfloat curve0_x = madd(v_n[0],vfloat(v[0][0][i]),madd(v_n[1],vfloat(v[1][0][i]),madd(v_n[2],vfloat(v[2][0][i]),v_n[3] * vfloat(v[3][0][i]))));381const vfloat curve1_x = madd(v_n[0],vfloat(v[0][1][i]),madd(v_n[1],vfloat(v[1][1][i]),madd(v_n[2],vfloat(v[2][1][i]),v_n[3] * vfloat(v[3][1][i]))));382const vfloat curve2_x = madd(v_n[0],vfloat(v[0][2][i]),madd(v_n[1],vfloat(v[1][2][i]),madd(v_n[2],vfloat(v[2][2][i]),v_n[3] * vfloat(v[3][2][i]))));383const vfloat curve3_x = madd(v_n[0],vfloat(v[0][3][i]),madd(v_n[1],vfloat(v[1][3][i]),madd(v_n[2],vfloat(v[2][3][i]),v_n[3] * vfloat(v[3][3][i]))));384return madd(u_n[0],curve0_x,madd(u_n[1],curve1_x,madd(u_n[2],curve2_x,u_n[3] * curve3_x)));385}386387template<typename vbool, typename vfloat>388void eval(const vbool& valid, const vfloat& uu, const vfloat& vv,389float* P, float* dPdu, float* dPdv, float* ddPdudu, float* ddPdvdv, float* ddPdudv,390const float dscale, const size_t dstride, const size_t N) const391{392if (P) {393const Vec4<vfloat> u_n = BSplineBasis::eval(uu);394const Vec4<vfloat> v_n = BSplineBasis::eval(vv);395for (size_t i=0; i<N; i++) vfloat::store(valid,P+i*dstride,eval(i,uu,vv,u_n,v_n));396}397if (dPdu)398{399{400assert(dPdu);401const Vec4<vfloat> u_n = BSplineBasis::derivative(uu);402const Vec4<vfloat> v_n = BSplineBasis::eval(vv);403for (size_t i=0; i<N; i++) vfloat::store(valid,dPdu+i*dstride,eval(i,uu,vv,u_n,v_n)*dscale);404}405{406assert(dPdv);407const Vec4<vfloat> u_n = BSplineBasis::eval(uu);408const Vec4<vfloat> v_n = BSplineBasis::derivative(vv);409for (size_t i=0; i<N; i++) vfloat::store(valid,dPdv+i*dstride,eval(i,uu,vv,u_n,v_n)*dscale);410}411}412if (ddPdudu)413{414{415assert(ddPdudu);416const Vec4<vfloat> u_n = BSplineBasis::derivative2(uu);417const Vec4<vfloat> v_n = BSplineBasis::eval(vv);418for (size_t i=0; i<N; i++) vfloat::store(valid,ddPdudu+i*dstride,eval(i,uu,vv,u_n,v_n)*sqr(dscale));419}420{421assert(ddPdvdv);422const Vec4<vfloat> u_n = BSplineBasis::eval(uu);423const Vec4<vfloat> v_n = BSplineBasis::derivative2(vv);424for (size_t i=0; i<N; i++) vfloat::store(valid,ddPdvdv+i*dstride,eval(i,uu,vv,u_n,v_n)*sqr(dscale));425}426{427assert(ddPdudv);428const Vec4<vfloat> u_n = BSplineBasis::derivative(uu);429const Vec4<vfloat> v_n = BSplineBasis::derivative(vv);430for (size_t i=0; i<N; i++) vfloat::store(valid,ddPdudv+i*dstride,eval(i,uu,vv,u_n,v_n)*sqr(dscale));431}432}433}434435friend __forceinline embree_ostream operator<<(embree_ostream o, const BSplinePatchT& p)436{437for (size_t y=0; y<4; y++)438for (size_t x=0; x<4; x++)439o << "[" << y << "][" << x << "] " << p.v[y][x] << embree_endl;440return o;441}442443public:444Vertex v[4][4];445};446447typedef BSplinePatchT<Vec3fa,Vec3fa_t> BSplinePatch3fa;448}449450451