OpenSubdiv/opensubdiv/osd/cpuSmoothNormalContext.h
jcowles 392e5e8bed Remove #pragma once
While this may be worth revisiting, we should first quantify the benefits and
identify the compilers that support it. Ultimately, we may never use pragma
once in favor of strictly using standard C++.
2015-05-20 09:59:18 -07:00

180 lines
5.5 KiB
C++

//
// Copyright 2013 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
#ifndef OPENSUBDIV3_OSD_CPU_SMOOTHNORMAL_CONTEXT_H
#define OPENSUBDIV3_OSD_CPU_SMOOTHNORMAL_CONTEXT_H
#include "../version.h"
#include "../osd/nonCopyable.h"
#include "../osd/vertexDescriptor.h"
#include "../far/types.h"
#include <vector>
namespace OpenSubdiv {
namespace OPENSUBDIV_VERSION {
namespace Far {
class TopologyRefiner;
}
namespace Osd {
class CpuSmoothNormalContext : private NonCopyable<CpuSmoothNormalContext> {
public:
/// Creates an CpuComputeContext instance
///
/// @param refiner The uniformly refined Far::TopologyRefiner
///
/// @param level Refinement level used to generate normals
///
/// @param resetMemory Set to true if the target vertex buffer needs its
/// memory reset before accumulating the averaged normals.
/// If the SmoothNormal Controller runs after a Computer
/// Controller, then the vertex buffer will already have
/// been reset and this step can be skipped to save time.
///
static CpuSmoothNormalContext * Create(
Far::TopologyRefiner const & refiner, int level, bool resetMemory=false);
/// Binds a vertex and a varying data buffers to the context. Binding ensures
/// that data buffers are properly inter-operated between Contexts and
/// Controllers operating across multiple devices.
///
/// @param in a buffer containing input vertex-interpolated primvar data
///
/// @param iOfs offset to the buffer element describing the vertex position
///
/// @param out a buffer where the smooth normals will be output
///
/// @param oOfs offset to the buffer element describing the normal position
///
template<class VERTEX_BUFFER>
void Bind(VERTEX_BUFFER * in, int iOfs,
VERTEX_BUFFER * out, int oOfs) {
assert( ((iOfs+3)<=in->GetNumElements()) and
((oOfs+3)<=out->GetNumElements()) and
out->GetNumVertices()>=in->GetNumVertices());
_iBuffer = in ? in->BindCpuBuffer() : 0;
_oBuffer = out ? out->BindCpuBuffer() : 0;
_iDesc = VertexBufferDescriptor( iOfs, 3, in->GetNumElements() );
_oDesc = VertexBufferDescriptor( oOfs, 3, out->GetNumElements() );
_numVertices = out->GetNumVertices();
}
/// Unbinds any previously bound vertex and varying data buffers.
void Unbind() {
_iBuffer = _oBuffer = 0;
_iDesc.Reset();
_oDesc.Reset();
_numVertices = 0;
}
Far::Index const * GetFaceVertices() const {
return &_faceVerts[0];
}
int GetNumFaces() const {
return (int)_faceVerts.size()/4;
}
/// Returns the number of vertices in output vertex buffer
int GetNumVertices() const {
return _numVertices;
}
/// Returns a pointer to the data of the input buffer
float const * GetCurrentInputVertexBuffer() const {
return _iBuffer;
}
/// Returns a pointer to the data of the output buffer
float * GetCurrentOutputVertexBuffer() {
return _oBuffer;
}
/// Returns an VertexDescriptor for the input vertex data
VertexBufferDescriptor const & GetInputVertexDescriptor() const {
return _iDesc;
}
/// Returns an VertexDescriptor for the buffer where the normals data
/// will be stored
VertexBufferDescriptor const & GetOutputVertexDescriptor() const {
return _oDesc;
}
/// Returns whether the controller needs to reset the vertex buffer before
/// accumulating smooth normals
bool GetResetMemory() const {
return _resetMemory;
}
/// Set to true if the controller needs to reset the vertex buffer before
/// accumulating smooth normals
void SetResetMemory(bool resetMemory) {
_resetMemory = resetMemory;
}
protected:
// Constructor
explicit CpuSmoothNormalContext(Far::TopologyRefiner const & refiner,
int level, bool resetMemory);
private:
// Topology data for a mesh
std::vector<Far::Index> _faceVerts; // patch control vertices
VertexBufferDescriptor _iDesc,
_oDesc;
int _numVertices;
float * _iBuffer,
* _oBuffer;
bool _resetMemory; // set to true if the output buffer needs to be reset to 0
};
} // end namespace Osd
} // end namespace OPENSUBDIV_VERSION
using namespace OPENSUBDIV_VERSION;
} // end namespace OpenSubdiv
#endif // OPENSUBDIV3_OSD_CPU_SMOOTHNORMAL_CONTEXT_H