<commit_before>// ======================================================================== //
// Copyright 2009-2018 Intel Corporation                                    //
//                                                                          //
// Licensed under the Apache License, Version 2.0 (the "License");          //
// you may not use this file except in compliance with the License.         //
// You may obtain a copy of the License at                                  //
//                                                                          //
//     http://www.apache.org/licenses/LICENSE-2.0                           //
//                                                                          //
// Unless required by applicable law or agreed to in writing, software      //
// distributed under the License is distributed on an "AS IS" BASIS,        //
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
// See the License for the specific language governing permissions and      //
// limitations under the License.                                           //
// ======================================================================== //

#pragma once

#include "geometry.h"
#include "buffer.h"
#include "../subdiv/half_edge.h"
#include "../subdiv/tessellation_cache.h"
#include "../subdiv/catmullclark_coefficients.h"
#include "../subdiv/patch.h"
#include "../../common/algorithms/parallel_map.h"
#include "../../common/algorithms/parallel_set.h"

namespace embree
{
  class SubdivMesh : public Geometry
  {
    ALIGNED_CLASS_(16);
  public:

    typedef HalfEdge::Edge Edge;
    
    /*! type of this geometry */
    static const Geometry::GTypeMask geom_type = Geometry::MTY_SUBDIV_MESH;

    /*! structure used to sort half edges using radix sort by their key */
    struct KeyHalfEdge 
    {
      KeyHalfEdge() {}
      
      KeyHalfEdge (uint64_t key, HalfEdge* edge) 
      : key(key), edge(edge) {}
      
      __forceinline operator uint64_t() const { 
	return key; 
      }

      friend __forceinline bool operator<(const KeyHalfEdge& e0, const KeyHalfEdge& e1) {
        return e0.key < e1.key;
      }
      
    public:
      uint64_t key;
      HalfEdge* edge;
    };

  public:

    /*! subdiv mesh construction */
    SubdivMesh(Device* device);

  public:
    void enabling();
    void disabling();
    void setMask (unsigned mask);
    void setSubdivisionMode (unsigned int topologyID, RTCSubdivisionMode mode);
    void setVertexAttributeTopology(unsigned int vertexAttribID, unsigned int topologyID);
    void setNumTimeSteps (unsigned int numTimeSteps);
    void setVertexAttributeCount (unsigned int N);
    void setTopologyCount (unsigned int N);
    void setBuffer(RTCBufferType type, unsigned int slot, RTCFormat format, const Ref<Buffer>& buffer, size_t offset, size_t stride, unsigned int num);
    void* getBuffer(RTCBufferType type, unsigned int slot);
    void updateBuffer(RTCBufferType type, unsigned int slot);
    void setTessellationRate(float N);
    bool verify();
    void commit();
    void setDisplacementFunction (RTCDisplacementFunctionN func);
    unsigned int getFirstHalfEdge(unsigned int faceID);
    unsigned int getFace(unsigned int edgeID);
    unsigned int getOppositeHalfEdge(unsigned int topologyID, unsigned int edgeID);
    unsigned int getNextHalfEdge(unsigned int topologyID, unsigned int edgeID);
    unsigned int getPreviousHalfEdge(unsigned int topologyID, unsigned int edgeID);

  public:

    /*! return the number of faces */
    size_t numFaces() const { 
      return faceVertices.size(); 
    }

    /*! return the number of edges */
    size_t numEdges() const { 
      return topology[0].vertexIndices.size(); 
    }

    /*! return the number of vertices */
    size_t numVertices() const { 
      return vertices[0].size(); 
    }

    /*! calculates the bounds of the i'th subdivision patch at the j'th timestep */
    __forceinline BBox3fa bounds(size_t i, size_t j = 0) const {
      return topology[0].getHalfEdge(i)->bounds(vertices[j]);
    }

    /*! check if the i'th primitive is valid */
    __forceinline bool valid(size_t i) const {
      return topology[0].valid(i) && !invalidFace(i);
    }

    /*! check if the i'th primitive is valid for the j'th time range */
    __forceinline bool valid(size_t i, size_t j) const {
      return topology[0].valid(i) && !invalidFace(i,j);
    }

    /*! prints some statistics */
    void printStatistics();

    /*! initializes the half edge data structure */
    void initializeHalfEdgeStructures ();
 
  public:

    /*! returns the vertex buffer for some time step */
    __forceinline const BufferView<Vec3fa>& getVertexBuffer( const size_t t = 0 ) const {
      return vertices[t];
    }

    /* returns tessellation level of edge */
    __forceinline float getEdgeLevel(const size_t i) const
    {
      if (levels) return clamp(levels[i],1.0f,4096.0f); // FIXME: do we want to limit edge level?
      else return clamp(tessellationRate,1.0f,4096.0f); // FIXME: do we want to limit edge level?
    }

  public:
    RTCDisplacementFunctionN displFunc;    //!< displacement function

    /*! all buffers in this section are provided by the application */
  public:
    
    /*! the topology contains all data that may differ when
     *  interpolating different user data buffers */
    struct Topology
    {
    public:

      /*! Default topology construction */
      Topology () : halfEdges(nullptr,0) {}

      /*! Topology initialization */
      Topology (SubdivMesh* mesh);

      /*! make the class movable */
    public: 
      Topology (Topology&& other) // FIXME: this is only required to workaround compilation issues under Windows
        : mesh(std::move(other.mesh)), 
          vertexIndices(std::move(other.vertexIndices)),
          subdiv_mode(std::move(other.subdiv_mode)),
          halfEdges(std::move(other.halfEdges)),
          halfEdges0(std::move(other.halfEdges0)),
          halfEdges1(std::move(other.halfEdges1)) {}
      
      Topology& operator= (Topology&& other) // FIXME: this is only required to workaround compilation issues under Windows
      {
        mesh = std::move(other.mesh); 
        vertexIndices = std::move(other.vertexIndices);
        subdiv_mode = std::move(other.subdiv_mode);
        halfEdges = std::move(other.halfEdges);
        halfEdges0 = std::move(other.halfEdges0);
        halfEdges1 = std::move(other.halfEdges1);
        return *this;
      }

    public:
      /*! check if the i'th primitive is valid in this topology */
      __forceinline bool valid(size_t i) const 
      {
        if (unlikely(subdiv_mode == RTC_SUBDIVISION_MODE_NO_BOUNDARY)) {
          if (getHalfEdge(i)->faceHasBorder()) return false;<commit_msg>Removed move constructor and assignment operator from SubdivMesh::Topology class. This was a workaround for some Windows compile issues with VS2012.<commit_after>// ======================================================================== //
// Copyright 2009-2018 Intel Corporation                                    //
//                                                                          //
// Licensed under the Apache License, Version 2.0 (the "License");          //
// you may not use this file except in compliance with the License.         //
// You may obtain a copy of the License at                                  //
//                                                                          //
//     http://www.apache.org/licenses/LICENSE-2.0                           //
//                                                                          //
// Unless required by applicable law or agreed to in writing, software      //
// distributed under the License is distributed on an "AS IS" BASIS,        //
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
// See the License for the specific language governing permissions and      //
// limitations under the License.                                           //
// ======================================================================== //

#pragma once

#include "geometry.h"
#include "buffer.h"
#include "../subdiv/half_edge.h"
#include "../subdiv/tessellation_cache.h"
#include "../subdiv/catmullclark_coefficients.h"
#include "../subdiv/patch.h"
#include "../../common/algorithms/parallel_map.h"
#include "../../common/algorithms/parallel_set.h"

namespace embree
{
  class SubdivMesh : public Geometry
  {
    ALIGNED_CLASS_(16);
  public:

    typedef HalfEdge::Edge Edge;
    
    /*! type of this geometry */
    static const Geometry::GTypeMask geom_type = Geometry::MTY_SUBDIV_MESH;

    /*! structure used to sort half edges using radix sort by their key */
    struct KeyHalfEdge 
    {
      KeyHalfEdge() {}
      
      KeyHalfEdge (uint64_t key, HalfEdge* edge) 
      : key(key), edge(edge) {}
      
      __forceinline operator uint64_t() const { 
	return key; 
      }

      friend __forceinline bool operator<(const KeyHalfEdge& e0, const KeyHalfEdge& e1) {
        return e0.key < e1.key;
      }
      
    public:
      uint64_t key;
      HalfEdge* edge;
    };

  public:

    /*! subdiv mesh construction */
    SubdivMesh(Device* device);

  public:
    void enabling();
    void disabling();
    void setMask (unsigned mask);
    void setSubdivisionMode (unsigned int topologyID, RTCSubdivisionMode mode);
    void setVertexAttributeTopology(unsigned int vertexAttribID, unsigned int topologyID);
    void setNumTimeSteps (unsigned int numTimeSteps);
    void setVertexAttributeCount (unsigned int N);
    void setTopologyCount (unsigned int N);
    void setBuffer(RTCBufferType type, unsigned int slot, RTCFormat format, const Ref<Buffer>& buffer, size_t offset, size_t stride, unsigned int num);
    void* getBuffer(RTCBufferType type, unsigned int slot);
    void updateBuffer(RTCBufferType type, unsigned int slot);
    void setTessellationRate(float N);
    bool verify();
    void commit();
    void setDisplacementFunction (RTCDisplacementFunctionN func);
    unsigned int getFirstHalfEdge(unsigned int faceID);
    unsigned int getFace(unsigned int edgeID);
    unsigned int getOppositeHalfEdge(unsigned int topologyID, unsigned int edgeID);
    unsigned int getNextHalfEdge(unsigned int topologyID, unsigned int edgeID);
    unsigned int getPreviousHalfEdge(unsigned int topologyID, unsigned int edgeID);

  public:

    /*! return the number of faces */
    size_t numFaces() const { 
      return faceVertices.size(); 
    }

    /*! return the number of edges */
    size_t numEdges() const { 
      return topology[0].vertexIndices.size(); 
    }

    /*! return the number of vertices */
    size_t numVertices() const { 
      return vertices[0].size(); 
    }

    /*! calculates the bounds of the i'th subdivision patch at the j'th timestep */
    __forceinline BBox3fa bounds(size_t i, size_t j = 0) const {
      return topology[0].getHalfEdge(i)->bounds(vertices[j]);
    }

    /*! check if the i'th primitive is valid */
    __forceinline bool valid(size_t i) const {
      return topology[0].valid(i) && !invalidFace(i);
    }

    /*! check if the i'th primitive is valid for the j'th time range */
    __forceinline bool valid(size_t i, size_t j) const {
      return topology[0].valid(i) && !invalidFace(i,j);
    }

    /*! prints some statistics */
    void printStatistics();

    /*! initializes the half edge data structure */
    void initializeHalfEdgeStructures ();
 
  public:

    /*! returns the vertex buffer for some time step */
    __forceinline const BufferView<Vec3fa>& getVertexBuffer( const size_t t = 0 ) const {
      return vertices[t];
    }

    /* returns tessellation level of edge */
    __forceinline float getEdgeLevel(const size_t i) const
    {
      if (levels) return clamp(levels[i],1.0f,4096.0f); // FIXME: do we want to limit edge level?
      else return clamp(tessellationRate,1.0f,4096.0f); // FIXME: do we want to limit edge level?
    }

  public:
    RTCDisplacementFunctionN displFunc;    //!< displacement function

    /*! all buffers in this section are provided by the application */
  public:
    
    /*! the topology contains all data that may differ when
     *  interpolating different user data buffers */
    struct Topology
    {
    public:

      /*! Default topology construction */
      Topology () : halfEdges(nullptr,0) {}

      /*! Topology initialization */
      Topology (SubdivMesh* mesh);

    public:
      /*! check if the i'th primitive is valid in this topology */
      __forceinline bool valid(size_t i) const 
      {
        if (unlikely(subdiv_mode == RTC_SUBDIVISION_MODE_NO_BOUNDARY)) {
          if (getHalfEdge(i)->faceHasBorder()) return false;
{'fraction_non_alphanumeric': 0.11929549902152642, 'fraction_numerical': 0.008454011741682975, 'mean_word_length': 2.4371805219262845, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 26, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6520538', 'n_tokens_mistral': 3557, 'n_tokens_neox': 3329, 'n_words': 1088}