示例#1
0
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;
        }
      }
    });
  }
示例#3
0
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();
  }