mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2024-12-05 01:10:05 +00:00
186 lines
6.0 KiB
C++
186 lines
6.0 KiB
C++
//
|
|
// Copyright 2014 DreamWorks Animation LLC.
|
|
//
|
|
// 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.
|
|
//
|
|
#include "../far/topologyDescriptor.h"
|
|
#include "../far/topologyRefinerFactory.h"
|
|
#include "../far/topologyRefiner.h"
|
|
|
|
// Unfortunately necessary for error codes that should be more accessible...
|
|
#include "../vtr/level.h"
|
|
|
|
#include <cstdio>
|
|
#ifdef _MSC_VER
|
|
#define snprintf _snprintf
|
|
#endif
|
|
|
|
|
|
namespace OpenSubdiv {
|
|
namespace OPENSUBDIV_VERSION {
|
|
|
|
namespace Far {
|
|
|
|
//
|
|
// Definitions for TopologyDescriptor:
|
|
//
|
|
TopologyDescriptor::TopologyDescriptor() {
|
|
memset(this, 0, sizeof(TopologyDescriptor));
|
|
}
|
|
|
|
|
|
//
|
|
// Definitions/specializations for its RefinerFactory<TopologyDescriptor>:
|
|
//
|
|
template <>
|
|
bool
|
|
TopologyRefinerFactory<TopologyDescriptor>::resizeComponentTopology(
|
|
TopologyRefiner & refiner, TopologyDescriptor const & desc) {
|
|
|
|
setNumBaseVertices(refiner, desc.numVertices);
|
|
setNumBaseFaces(refiner, desc.numFaces);
|
|
|
|
for (int face=0; face<desc.numFaces; ++face) {
|
|
|
|
setNumBaseFaceVertices(refiner, face, desc.numVertsPerFace[face]);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
template <>
|
|
bool
|
|
TopologyRefinerFactory<TopologyDescriptor>::assignComponentTopology(
|
|
TopologyRefiner & refiner, TopologyDescriptor const & desc) {
|
|
|
|
for (int face=0, idx=0; face<desc.numFaces; ++face) {
|
|
|
|
IndexArray dstFaceVerts = getBaseFaceVertices(refiner, face);
|
|
|
|
if (desc.isLeftHanded) {
|
|
dstFaceVerts[0] = desc.vertIndicesPerFace[idx++];
|
|
for (int vert=dstFaceVerts.size()-1; vert > 0; --vert) {
|
|
|
|
dstFaceVerts[vert] = desc.vertIndicesPerFace[idx++];
|
|
}
|
|
} else {
|
|
for (int vert=0; vert<dstFaceVerts.size(); ++vert) {
|
|
|
|
dstFaceVerts[vert] = desc.vertIndicesPerFace[idx++];
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
template <>
|
|
bool
|
|
TopologyRefinerFactory<TopologyDescriptor>::assignComponentTags(
|
|
TopologyRefiner & refiner, TopologyDescriptor const & desc) {
|
|
|
|
if ((desc.numCreases>0) && desc.creaseVertexIndexPairs && desc.creaseWeights) {
|
|
|
|
int const * vertIndexPairs = desc.creaseVertexIndexPairs;
|
|
for (int edge=0; edge<desc.numCreases; ++edge, vertIndexPairs+=2) {
|
|
|
|
Index idx = findBaseEdge(refiner, vertIndexPairs[0], vertIndexPairs[1]);
|
|
|
|
if (idx!=INDEX_INVALID) {
|
|
setBaseEdgeSharpness(refiner, idx, desc.creaseWeights[edge]);
|
|
} else {
|
|
char msg[1024];
|
|
snprintf(msg, 1024, "Edge %d specified to be sharp does not exist (%d, %d)",
|
|
edge, vertIndexPairs[0], vertIndexPairs[1]);
|
|
reportInvalidTopology(Vtr::internal::Level::TOPOLOGY_INVALID_CREASE_EDGE, msg, desc);
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((desc.numCorners>0) && desc.cornerVertexIndices && desc.cornerWeights) {
|
|
|
|
for (int vert=0; vert<desc.numCorners; ++vert) {
|
|
|
|
int idx = desc.cornerVertexIndices[vert];
|
|
|
|
if (idx >= 0 && idx < getNumBaseVertices(refiner)) {
|
|
setBaseVertexSharpness(refiner, idx, desc.cornerWeights[vert]);
|
|
} else {
|
|
char msg[1024];
|
|
snprintf(msg, 1024, "Vertex %d specified to be sharp does not exist", idx);
|
|
reportInvalidTopology(Vtr::internal::Level::TOPOLOGY_INVALID_CREASE_VERT, msg, desc);
|
|
}
|
|
}
|
|
}
|
|
if (desc.numHoles>0) {
|
|
for (int i=0; i<desc.numHoles; ++i) {
|
|
setBaseFaceHole(refiner, desc.holeIndices[i], true);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
template <>
|
|
bool
|
|
TopologyRefinerFactory<TopologyDescriptor>::assignFaceVaryingTopology(
|
|
TopologyRefiner & refiner, TopologyDescriptor const & desc) {
|
|
|
|
if (desc.numFVarChannels>0) {
|
|
|
|
for (int channel=0; channel<desc.numFVarChannels; ++channel) {
|
|
|
|
int numFVarValues = desc.fvarChannels[channel].numValues;
|
|
int const* srcFVarValues = desc.fvarChannels[channel].valueIndices;
|
|
|
|
createBaseFVarChannel(refiner, numFVarValues);
|
|
|
|
for (int face = 0, srcNext = 0; face < desc.numFaces; ++face) {
|
|
|
|
IndexArray dstFaceFVarValues = getBaseFaceFVarValues(refiner, face, channel);
|
|
|
|
if (desc.isLeftHanded) {
|
|
dstFaceFVarValues[0] = srcFVarValues[srcNext++];
|
|
for (int vert = dstFaceFVarValues.size() - 1; vert > 0; --vert) {
|
|
|
|
dstFaceFVarValues[vert] = srcFVarValues[srcNext++];
|
|
}
|
|
} else {
|
|
for (int vert = 0; vert < dstFaceFVarValues.size(); ++vert) {
|
|
|
|
dstFaceFVarValues[vert] = srcFVarValues[srcNext++];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
template <>
|
|
void
|
|
TopologyRefinerFactory<TopologyDescriptor>::reportInvalidTopology(
|
|
TopologyError /* errCode */, char const * msg, TopologyDescriptor const& /* mesh */) {
|
|
Warning(msg);
|
|
}
|
|
|
|
} // end namespace Far
|
|
|
|
} // end namespace OPENSUBDIV_VERSION
|
|
} // end namespace OpenSubdiv
|