246 lines
14 KiB
C++
246 lines
14 KiB
C++
/*###############################################################################
|
|
#
|
|
# Copyright 2021 NVIDIA Corporation
|
|
#
|
|
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
# this software and associated documentation files (the "Software"), to deal in
|
|
# the Software without restriction, including without limitation the rights to
|
|
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
# the Software, and to permit persons to whom the Software is furnished to do so,
|
|
# subject to the following conditions:
|
|
#
|
|
# The above copyright notice and this permission notice shall be included in all
|
|
# copies or substantial portions of the Software.
|
|
#
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
#
|
|
###############################################################################*/
|
|
#ifndef __SIMPLE_FACE_MODEL__
|
|
#define __SIMPLE_FACE_MODEL__
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <vector>
|
|
#include <string>
|
|
|
|
#include "FaceIO.h"
|
|
#include "nvAR_defs.h"
|
|
|
|
/********************************************************************************
|
|
* SimpleFaceModel
|
|
********************************************************************************/
|
|
|
|
|
|
struct SimpleFaceModel {
|
|
std::vector<NvAR_Point3f> shapeMean;
|
|
std::vector<NvAR_Vector3f> shapeModes; /* shapeMean.size() * numModes */
|
|
std::vector<float> shapeEigenValues;
|
|
std::vector<NvAR_Vector3u16> triangles;
|
|
struct BlendShape {
|
|
std::string name;
|
|
std::vector<NvAR_Vector3f> shape;
|
|
};
|
|
std::vector<BlendShape> blendShapes;
|
|
struct Partition {
|
|
unsigned partitionIndex; ///< The index of the partition.
|
|
unsigned faceIndex; ///< The index of the first face in the partition.
|
|
unsigned numFaces; ///< The number of faces in the partition.
|
|
unsigned vertexIndex; ///< The index of the first topological vertex in the partition.
|
|
unsigned numVertexIndices; ///< The number of topological vertices in the partition.
|
|
int smoothingGroup; ///< Smoothing group > 0; no smoothing == 0; undefined < 0.
|
|
std::string name; ///< The name of the partition.
|
|
std::string materialName; ///< The name of the material assigned to the partition.
|
|
void set(unsigned partIx, unsigned firstFaceIndex, unsigned lastFaceIndex,
|
|
unsigned firstVertexIndex, unsigned lastVertexIndex, int smooth,
|
|
const char* partName = nullptr, const char* mtrlName = nullptr) {
|
|
partitionIndex = partIx;
|
|
smoothingGroup = smooth;
|
|
faceIndex = firstFaceIndex;
|
|
numFaces = lastFaceIndex - firstFaceIndex + 1;
|
|
vertexIndex = firstVertexIndex;
|
|
numVertexIndices = lastVertexIndex - firstVertexIndex + 1;
|
|
if (partName) name = partName;
|
|
if (mtrlName) materialName = mtrlName;
|
|
}
|
|
Partition(unsigned partIx, unsigned firstFaceIndex, unsigned lastFaceIndex,
|
|
unsigned firstVertexIndex, unsigned lastVertexIndex, int smooth,
|
|
const char* partName, const char* mtrlName) {
|
|
set(partIx, firstFaceIndex, lastFaceIndex, firstVertexIndex, lastVertexIndex, smooth, partName, mtrlName);
|
|
}
|
|
Partition() { set(0, 0, 0, 0, 0, -1, nullptr, nullptr); }
|
|
};
|
|
std::vector<Partition> partitions;
|
|
std::vector<unsigned short> ibugLandmarkMappings; /* 68 */
|
|
const unsigned short ibugRightContour[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
|
|
const unsigned short ibugLeftContour[8] = { 10, 11, 12, 13, 14, 15, 16, 17 };
|
|
std::vector<unsigned short> modelRightContour;
|
|
std::vector<unsigned short> modelLeftContour;
|
|
std::vector<unsigned short> adjacentFaces;
|
|
std::vector<unsigned short> adjacentVertices;
|
|
std::vector<unsigned short> nvlmLandmarks;
|
|
std::vector<unsigned short> nvlmRightContour;
|
|
std::vector<unsigned short> nvlmLeftContour;
|
|
|
|
void appendMode(const NvAR_Point3f* pts) {
|
|
size_t n = shapeMean.size(),
|
|
off = shapeModes.size();
|
|
shapeModes.resize(off + n);
|
|
float *to = shapeModes[off].vec; // Delta mode vector
|
|
const float *fr = &pts->x; // Mode points
|
|
const float *mn = &shapeMean[0].x; // Mean points
|
|
for (n *= 3; n--;) // 3D points
|
|
*to++ = *fr++ - *mn++; // Delta shape
|
|
}
|
|
|
|
void setBlendShape(unsigned i, const std::string& name, const NvAR_Point3f* pts) {
|
|
size_t n = shapeMean.size();
|
|
blendShapes[i].name = name;
|
|
blendShapes[i].shape.resize(n);
|
|
float *to = blendShapes[i].shape.data()->vec; // Delta mode vector
|
|
const float *fr = &pts->x; // Blendshape points
|
|
const float *mn = &shapeMean[0].x; // Mean points
|
|
for (n *= 3; n--;) // 3D points
|
|
*to++ = *fr++ - *mn++; // Delta shape
|
|
}
|
|
};
|
|
|
|
|
|
/********************************************************************************
|
|
* SimpleFaceModelAdapter
|
|
********************************************************************************/
|
|
|
|
class SimpleFaceModelAdapter : public FaceIOAdapter {
|
|
public:
|
|
SimpleFaceModel fm;
|
|
|
|
uint32_t getShapeMeanSize() const override { return unsigned(fm.shapeMean.size()) * 3; }
|
|
uint32_t getShapeModesSize() const override { return unsigned(fm.shapeModes.size()) * 3; }
|
|
uint32_t getShapeNumModes() const override { return unsigned(fm.shapeModes.size() / fm.shapeMean.size()); }
|
|
uint32_t getShapeEigenvaluesSize()const override { return unsigned(fm.shapeEigenValues.size()); }
|
|
float* getShapeMean(uint32_t size) override { if (size) fm.shapeMean.resize(size / 3);
|
|
return &fm.shapeMean.data()->x; };
|
|
float* getShapeModes(uint32_t modeSize, uint32_t numModes) override {
|
|
if (modeSize) fm.shapeModes.resize(modeSize / 3 * numModes); return fm.shapeModes.data()->vec; }
|
|
float* getShapeEigenvalues(uint32_t numModes) override { if (numModes) fm.shapeEigenValues.resize(numModes);
|
|
return fm.shapeEigenValues.data(); }
|
|
|
|
uint32_t getColorMeanSize() const override { return 0; }
|
|
uint32_t getColorModesSize() const override { return 0; }
|
|
uint32_t getColorNumModes() const override { return 0; }
|
|
uint32_t getColorEigenvaluesSize() const override { return 0; }
|
|
float* getColorMean(uint32_t /*size*/) override { return nullptr; }
|
|
float* getColorModes(uint32_t /*modeSize*/, uint32_t /*numModes*/) override { return nullptr; }
|
|
float* getColorEigenvalues(uint32_t /*numModes*/) override { return nullptr; }
|
|
|
|
void setTriangleListSize(uint32_t size) override { fm.triangles.resize(size / 3); }
|
|
uint32_t getTriangleListSize() const override { return unsigned(fm.triangles.size()) * 3; }
|
|
uint16_t* getTriangleList(uint32_t size) override { if (size) fm.triangles.resize(size / 3);
|
|
return fm.triangles.data()->vec; }
|
|
|
|
void setTextureCoordinatesSize(uint32_t /*size*/) override {}
|
|
uint32_t getTextureCoordinatesSize() const override { return 0; }
|
|
float* getTextureCoordinates(uint32_t /*size*/) override { return nullptr; }
|
|
|
|
void setNumBlendShapes(uint32_t n) override { fm.blendShapes.resize(n); }
|
|
void setBlendShapeName(uint32_t i, const char* name) override { fm.blendShapes[i].name = name; }
|
|
uint32_t getNumBlendShapes() const override { return unsigned(fm.blendShapes.size()); }
|
|
const char* getBlendShapeName(uint32_t i) const override { return fm.blendShapes[i].name.c_str(); }
|
|
uint32_t getBlendShapeSize(uint32_t i) const override { return unsigned((fm.blendShapes[i].shape.size()) * 3); }
|
|
float* getBlendShape(uint32_t i, uint32_t size) override { if (size) fm.blendShapes[i].shape.resize(size / 3);
|
|
return fm.blendShapes[i].shape.data()->vec; }
|
|
|
|
void setIbugLandmarkMappingsSize(uint32_t n) override { fm.ibugLandmarkMappings.resize(n); }
|
|
uint32_t getIbugLandmarkMappingsSize() const override { return unsigned(fm.ibugLandmarkMappings.size()); }
|
|
uint16_t* getIbugLandmarkMappings(uint32_t size) override { if (size) fm.ibugLandmarkMappings.resize(size);
|
|
return fm.ibugLandmarkMappings.data(); }
|
|
void appendIbugLandmarkMapping(uint16_t i) override { fm.ibugLandmarkMappings.push_back(i); }
|
|
void appendIbugLandmarkMapping(uint16_t i, uint16_t j) override { fm.ibugLandmarkMappings.push_back(i);
|
|
fm.ibugLandmarkMappings.push_back(j); }
|
|
|
|
void setIbugRightContourSize(uint32_t /*n*/) override {}
|
|
uint32_t getIbugRightContourSize() const override {
|
|
return sizeof(fm.ibugRightContour) / sizeof(fm.ibugRightContour[0]); }
|
|
uint16_t* getIbugRightContour(uint32_t /*size*/) override { return const_cast<uint16_t*>(fm.ibugRightContour); }
|
|
void appendIbugRightContour(uint16_t /*i*/) override {}
|
|
|
|
void setIbugLeftContourSize(uint32_t /*n*/) override {}
|
|
uint32_t getIbugLeftContourSize() const override { return sizeof(fm.ibugLeftContour)/sizeof(fm.ibugLeftContour[0]);}
|
|
uint16_t* getIbugLeftContour(uint32_t /*size*/) override { return const_cast<uint16_t*>(fm.ibugLeftContour); }
|
|
void appendIbugLeftContour(uint16_t /*i*/) override {}
|
|
|
|
void setModelRightContourSize(uint32_t n) override { fm.modelRightContour.resize(n); }
|
|
uint32_t getModelRightContourSize() const override { return unsigned(fm.modelRightContour.size()); }
|
|
uint16_t* getModelRightContour(uint32_t size) override { if (size) fm.modelRightContour.resize(size);
|
|
return fm.modelRightContour.data(); }
|
|
void appendModelRightContour(uint16_t i) override { fm.modelRightContour.push_back(i); }
|
|
|
|
void setModelLeftContourSize(uint32_t n) override { fm.modelLeftContour.resize(n); }
|
|
uint32_t getModelLeftContourSize() const override { return unsigned(fm.modelLeftContour.size()); }
|
|
uint16_t* getModelLeftContour(uint32_t size) override { if (size) fm.modelLeftContour.resize(size);
|
|
return fm.modelLeftContour.data(); }
|
|
void appendModelLeftContour(uint16_t i) override { fm.modelLeftContour.push_back(i); }
|
|
|
|
void setAdjacentFacesSize(uint32_t n) override { fm.adjacentFaces.resize(n); }
|
|
uint32_t getAdjacentFacesSize() const override { return unsigned(fm.adjacentFaces.size()); }
|
|
uint16_t* getAdjacentFaces(uint32_t size) override { if (size) fm.adjacentFaces.resize(size);
|
|
return fm.adjacentFaces.data(); }
|
|
void appendAdjacentFace(uint16_t i) override { fm.adjacentFaces.push_back(i); }
|
|
void appendAdjacentFaces(uint16_t i, uint16_t j) override { fm.adjacentFaces.push_back(i);
|
|
fm.adjacentFaces.push_back(j); }
|
|
|
|
void setAdjacentVerticesSize(uint32_t n) override { fm.adjacentVertices.resize(n); }
|
|
uint32_t getAdjacentVerticesSize() const override { return unsigned(fm.adjacentVertices.size()); }
|
|
uint16_t* getAdjacentVertices(uint32_t size) override { if (size) fm.adjacentVertices.resize(size);
|
|
return fm.adjacentVertices.data(); }
|
|
void appendAdjacentVertex(uint16_t i) override { fm.adjacentVertices.push_back(i); }
|
|
void appendAdjacentVertices(uint16_t i, uint16_t j) override { fm.adjacentVertices.push_back(i);
|
|
fm.adjacentVertices.push_back(j); }
|
|
|
|
void setNvlmLandmarksSize(uint32_t n) override { fm.nvlmLandmarks.resize(n); }
|
|
uint32_t getNvlmLandmarksSize() const override { return (uint32_t)fm.nvlmLandmarks.size(); }
|
|
uint16_t* getNvlmLandmarks(uint32_t size) override { if (size) fm.nvlmLandmarks.resize(size);
|
|
return fm.nvlmLandmarks.data(); }
|
|
void appendNvlmLandmark(uint16_t i) override { fm.nvlmLandmarks.push_back(i); }
|
|
|
|
void setNvlmRightContourSize(uint32_t n) override { fm.nvlmRightContour.resize(n); }
|
|
uint32_t getNvlmRightContourSize() const override { return (uint32_t)fm.nvlmRightContour.size(); }
|
|
uint16_t* getNvlmRightContour(uint32_t size) override { if (size) fm.nvlmRightContour.resize(size);
|
|
return fm.nvlmRightContour.data(); }
|
|
void appendNvlmRightContour(uint16_t i) override { fm.nvlmRightContour.push_back(i); }
|
|
|
|
void setNvlmLeftContourSize(uint32_t n) override { fm.nvlmLeftContour.resize(n); }
|
|
uint32_t getNvlmLeftContourSize() const override { return (uint32_t)fm.nvlmLeftContour.size(); }
|
|
uint16_t* getNvlmLeftContour(uint32_t size) override { if (size) fm.nvlmLeftContour.resize(size);
|
|
return fm.nvlmLeftContour.data(); }
|
|
void appendNvlmLeftContour(uint16_t i) override { fm.nvlmLeftContour.push_back(i); }
|
|
|
|
void setNumPartitions(uint32_t n) override { fm.partitions.resize(n); }
|
|
void setPartitionName(uint32_t i, const char* name) override { fm.partitions.at(i).name = name; }
|
|
void setPartitionMaterialName(uint32_t i, const char* name) override { fm.partitions.at(i).materialName = name;}
|
|
void setPartition(uint32_t i, uint32_t faceIndex, uint32_t numFaces, uint32_t vertexIndex, uint32_t numVertices,
|
|
int32_t smoothingGroup) override {
|
|
fm.partitions.at(i).set(i, faceIndex, faceIndex + numFaces - 1, vertexIndex,
|
|
vertexIndex + numVertices - 1, smoothingGroup);
|
|
}
|
|
uint32_t getNumPartitions() const override { return (uint32_t)fm.partitions.size(); }
|
|
const char* getPartitionName(uint32_t i) const override { return fm.partitions.at(i).name.c_str(); }
|
|
const char* getPartitionMaterialName(uint32_t i) const override { return fm.partitions.at(i).materialName.c_str(); }
|
|
int16_t getPartition(uint32_t i, uint32_t* faceIndex, uint32_t* numFaces, uint32_t* vertexIndex,
|
|
uint32_t* numVertices, int32_t* smoothingGroup) const override {
|
|
const SimpleFaceModel::Partition& pt = fm.partitions.at(i);
|
|
if (faceIndex) *faceIndex = pt.faceIndex;
|
|
if (numFaces) *numFaces = pt.numFaces;
|
|
if (vertexIndex) *vertexIndex = pt.vertexIndex;
|
|
if (numVertices) *numVertices = pt.numVertexIndices;
|
|
if (smoothingGroup) *smoothingGroup = pt.smoothingGroup;
|
|
return (int16_t)pt.partitionIndex;
|
|
}
|
|
};
|
|
|
|
#endif // __SIMPLE_FACE_MODEL__
|