KHalfEdgeMeshPrivate::FaceIndex KHalfEdgeMeshPrivate::addFace(index_array &v1, index_array &v2, index_array &v3) { // Normalize Indices size_t size = m_vertices.size() + 1; // Normalize Indices normalizeIndex(v1[0], size); normalizeIndex(v2[0], size); normalizeIndex(v3[0], size); // Create edges HalfEdgeIndex edgeA = getHalfEdge(v1, v2); HalfEdgeIndex edgeB = getHalfEdge(v2, v3); HalfEdgeIndex edgeC = getHalfEdge(v3, v1); // Create Face m_faces.emplace_back(edgeA); FaceIndex faceIdx = FaceIndex(static_cast<index_type>(m_faces.size())); // Initialize Inner Half Edges initializeInnerHalfEdge(edgeA, faceIdx, edgeB); initializeInnerHalfEdge(edgeB, faceIdx, edgeC); initializeInnerHalfEdge(edgeC, faceIdx, edgeA); // Set Vertex half edges if (vertex(v1[0])->to == 0) vertex(v1[0])->to = edgeA; if (vertex(v2[0])->to == 0) vertex(v2[0])->to = edgeB; if (vertex(v3[0])->to == 0) vertex(v3[0])->to = edgeC; return faceIdx; }
void SubdivMeshAVX::interpolateHelper(const vbool& valid1, const vint& primID, const vfloat& uu, const vfloat& vv, size_t numUVs, RTCBufferType buffer, float* P, float* dPdu, float* dPdv, float* ddPdudu, float* ddPdvdv, float* ddPdudv, size_t numFloats) { /* calculate base pointer and stride */ assert((buffer >= RTC_VERTEX_BUFFER0 && buffer <= RTC_VERTEX_BUFFER1) || (buffer >= RTC_USER_VERTEX_BUFFER0 && buffer <= RTC_USER_VERTEX_BUFFER1)); const char* src = nullptr; size_t stride = 0; size_t bufID = buffer&0xFFFF; std::vector<SharedLazyTessellationCache::CacheEntry>* baseEntry = nullptr; if (buffer >= RTC_USER_VERTEX_BUFFER0) { src = userbuffers[bufID]->getPtr(); stride = userbuffers[bufID]->getStride(); baseEntry = &user_buffer_tags[bufID]; } else { src = vertices[bufID].getPtr(); stride = vertices[bufID].getStride(); baseEntry = &vertex_buffer_tags[bufID]; } foreach_unique(valid1,primID,[&](const vbool& valid1, const int primID) { for (size_t j=0,slot=0; j<numFloats; slot++) { if (j+4 >= numFloats) { const size_t M = min(size_t(4),numFloats-j); isa::PatchEvalSimd<vbool,vint,vfloat,vfloat4>(baseEntry->at(interpolationSlot(primID,slot,stride)),parent->commitCounterSubdiv, getHalfEdge(primID),src+j*sizeof(float),stride,valid1,uu,vv, P ? P+j*numUVs : nullptr, dPdu ? dPdu+j*numUVs : nullptr, dPdv ? dPdv+j*numUVs : nullptr, ddPdudu ? ddPdudu+j*numUVs : nullptr, ddPdvdv ? ddPdvdv+j*numUVs : nullptr, ddPdudv ? ddPdudv+j*numUVs : nullptr, numUVs,M); j+=4; } else { const size_t M = min(size_t(8),numFloats-j); isa::PatchEvalSimd<vbool,vint,vfloat,vfloat8>(baseEntry->at(interpolationSlot(primID,slot,stride)),parent->commitCounterSubdiv, getHalfEdge(primID),src+j*sizeof(float),stride,valid1,uu,vv, P ? P+j*numUVs : nullptr, dPdu ? dPdu+j*numUVs : nullptr, dPdv ? dPdv+j*numUVs : nullptr, ddPdudu ? ddPdudu+j*numUVs : nullptr, ddPdvdv ? ddPdvdv+j*numUVs : nullptr, ddPdudv ? ddPdudv+j*numUVs : nullptr, numUVs,M); j+=8; } } }); }
int Mesh::splitFace(Face *f, Vertex *p1, Vertex *p2) { // Find halfedges pointing to p1 and p2 HalfEdge *he_p1 = p1->halfEdge; while(he_p1->vertex != p1) he_p1 = he_p1->next; HalfEdge *he_p2 = he_p1; while(he_p2->vertex != p2) he_p2 = he_p2->next; // Create two new halfedges on the split line int he1 = addHalfEdge(p2, he_p2->next, 0, 0); int he2 = addHalfEdge(p1, he_p1->next, 0, 0); HalfEdge *pHE1 = getHalfEdge(he1); HalfEdge *pHE2 = getHalfEdge(he2); // Create a new face int newFace = addFace(pHE1, f->normal); Face *pNewFace = getFace(newFace); // Point he1 to the new face, and he2 to the old one pHE1->face = pNewFace; pHE2->face = f; // Point the new face to he1, and the old face to he2 pNewFace->halfEdge = pHE1; f->halfEdge = pHE2; // Point p1 to he1 and p2 to he2 p1->halfEdge = pHE1; p2->halfEdge = pHE2; // Fix the next pointers for he_p1 and he_p2 he_p1->next = pHE1; he_p2->next = pHE2; // he1 and he2 are symmetric to each other pHE1->sym = pHE2; pHE2->sym = pHE1; // We *should* be done now (assuming I remembered all the pointers! :-)) - return the index of the new face return newFace; }
void SubdivMeshAVX::interpolate(unsigned primID, float u, float v, RTCBufferType buffer, float* P, float* dPdu, float* dPdv, float* ddPdudu, float* ddPdvdv, float* ddPdudv, size_t numFloats) { #if defined(DEBUG) if ((parent->aflags & RTC_INTERPOLATE) == 0) throw_RTCError(RTC_INVALID_OPERATION,"rtcInterpolate can only get called when RTC_INTERPOLATE is enabled for the scene"); #endif /* calculate base pointer and stride */ assert((buffer >= RTC_VERTEX_BUFFER0 && buffer <= RTC_VERTEX_BUFFER1) || (buffer >= RTC_USER_VERTEX_BUFFER0 && buffer <= RTC_USER_VERTEX_BUFFER1)); const char* src = nullptr; size_t stride = 0; size_t bufID = buffer&0xFFFF; std::vector<SharedLazyTessellationCache::CacheEntry>* baseEntry = nullptr; if (buffer >= RTC_USER_VERTEX_BUFFER0) { src = userbuffers[buffer&0xFFFF]->getPtr(); stride = userbuffers[buffer&0xFFFF]->getStride(); baseEntry = &user_buffer_tags[bufID]; } else { src = vertices[buffer&0xFFFF].getPtr(); stride = vertices[buffer&0xFFFF].getStride(); baseEntry = &vertex_buffer_tags[bufID]; } for (size_t i=0,slot=0; i<numFloats; slot++) { if (i+4 >= numFloats) { vfloat4 Pt, dPdut, dPdvt, ddPdudut, ddPdvdvt, ddPdudvt;; isa::PatchEval<vfloat4>(baseEntry->at(interpolationSlot(primID,slot,stride)),parent->commitCounterSubdiv, getHalfEdge(primID),src+i*sizeof(float),stride,u,v, P ? &Pt : nullptr, dPdu ? &dPdut : nullptr, dPdv ? &dPdvt : nullptr, ddPdudu ? &ddPdudut : nullptr, ddPdvdv ? &ddPdvdvt : nullptr, ddPdudv ? &ddPdudvt : nullptr); if (P) { for (size_t j=i; j<min(i+4,numFloats); j++) P[j] = Pt[j-i]; } if (dPdu) { for (size_t j=i; j<min(i+4,numFloats); j++) { dPdu[j] = dPdut[j-i]; dPdv[j] = dPdvt[j-i]; } } if (ddPdudu) { for (size_t j=i; j<min(i+4,numFloats); j++) { ddPdudu[j] = ddPdudut[j-i]; ddPdvdv[j] = ddPdvdvt[j-i]; ddPdudv[j] = ddPdudvt[j-i]; } } i+=4; } else { vfloat8 Pt, dPdut, dPdvt, ddPdudut, ddPdvdvt, ddPdudvt; isa::PatchEval<vfloat8>(baseEntry->at(interpolationSlot(primID,slot,stride)),parent->commitCounterSubdiv, getHalfEdge(primID),src+i*sizeof(float),stride,u,v, P ? &Pt : nullptr, dPdu ? &dPdut : nullptr, dPdv ? &dPdvt : nullptr, ddPdudu ? &ddPdudut : nullptr, ddPdvdv ? &ddPdvdvt : nullptr, ddPdudv ? &ddPdudvt : nullptr); if (P) { for (size_t j=i; j<i+8; j++) P[j] = Pt[j-i]; } if (dPdu) { for (size_t j=i; j<i+8; j++) { dPdu[j] = dPdut[j-i]; dPdv[j] = dPdvt[j-i]; } } if (ddPdudu) { for (size_t j=i; j<i+8; j++) { ddPdudu[j] = ddPdudut[j-i]; ddPdvdv[j] = ddPdvdvt[j-i]; ddPdudv[j] = ddPdudvt[j-i]; } } i+=8; } } AVX_ZERO_UPPER(); }