#include "PtexImporter.h"
#include "PtexPaintLayerImporter.h"
void PtexImporter::Import(
const QString &sFileName, Scene::LoadData & )
{
if (!pMesh)
return;
PtexPaintLayerImporter *pI = CreateInstance<PtexPaintLayerImporter>();
if (pI) {
pI->SetPtexImporter(this);
pI->Prepare( sFileName, pMesh, false, true );
pI->Import( sFileName, 0, pMesh, 0 );
}
if (m_FaceMap != 0) {
delete [] m_FaceMap;
m_FaceMap = 0;
}
if (m_ReverseFaceMap != 0) {
delete [] m_ReverseFaceMap;
m_ReverseFaceMap = 0;
}
}
Mesh *PtexImporter::CreateMeshFromPtex(
const QString &sFileName,
bool makeMesh, bool silent )
{
if (m_FaceMap != 0) {
delete [] m_FaceMap;
m_FaceMap = 0;
}
if (m_ReverseFaceMap != 0) {
delete [] m_ReverseFaceMap;
m_ReverseFaceMap = 0;
}
PtexTexture *pT = PtexTexture::open( a.
constData(),
s );
if (!pT) {
Kernel()->Interface()->HUDMessageShow( tr(
"Unable to open PTEX file. Mudbox cannot import it."),
Kernel()->Log(
QString(
"Unable to open PTEX file. Mudbox cannot import it.\n" ));
return false;
}
if (pT->meshType() != Ptex::mt_quad) {
Kernel()->Interface()->HUDMessageShow( tr(
"This PTEX file is not quadrangular. "
"Mudbox cannot import it."),
Kernel()->Log(
QString(
"This PTEX file is not quadrangular. Mudbox cannot import it.\n" ));
pT->release();
return false;
}
PtexMetaData *pM = pT->getMetaData();
if ( !pM )
{
Kernel()->Log(
QString(
"This PTEX file does not contain mesh information. Mudbox cannot import it."));
if (!silent) {
Kernel()->Interface()->HUDMessageShow( tr(
"This PTEX file does not contain mesh information. "
"Mudbox cannot import it."),
}
return NULL;
}
m_iFaceCount = 0;
const int *aFaceSizes = NULL;
pM->getValue(
NTR(
"PtexFaceVertCounts"), aFaceSizes, m_iFaceCount );
if ( aFaceSizes == NULL )
{
Kernel()->Log(
NTR(
"This PTEX file does not contain mesh information. "
"Mudbox cannot import it. (2)"));
if (!silent) {
Kernel()->Interface()->HUDMessageShow( tr(
"This PTEX file does not contain mesh information. "
"Mudbox cannot import it."),
}
return NULL;
}
int pTexSubFaceCount = pT->numFaces();
memset(m_hist, 0, sizeof(m_hist));
m_allQuads = true;
m_maxFaceSize = 0;
m_minFaceSize = INT_MAX;
m_iTotalTesselatedFaceCount = 0;
for ( int i = 0; i < m_iFaceCount; i++ ) {
int faceSize = aFaceSizes[i];
if (faceSize < MAX_EDGE_COUNT) {
++m_hist[faceSize];
} else {
Kernel()->Log(
NTRQ(
"Mudbox can only import PTEX files that "
"contain faces with less than %1 sides").arg(MAX_EDGE_COUNT));
if (!silent) {
Kernel()->Interface()->HUDMessageShow( tr(
"Mudbox can only import PTEX files "
"that contain faces with less than %1 sides")
.arg(MAX_EDGE_COUNT),
}
return NULL;
}
if (faceSize < 3) {
Kernel()->Log(
NTR(
"Mudbox can only import PTEX files that contain faces with at least 3 sides"));
if (!silent) {
Kernel()->Interface()->HUDMessageShow( tr(
"Mudbox can only import PTEX files that "
"contain faces with at least 3 sides"),
}
return NULL;
}
if (faceSize != 4) m_allQuads = false;
if (faceSize > m_maxFaceSize) m_maxFaceSize = faceSize;
if (faceSize < m_minFaceSize) m_minFaceSize = faceSize;
}
if (m_allQuads) {
m_iTotalTesselatedFaceCount = m_iFaceCount;
} else {
for (int i = 3; i < m_maxFaceSize+1; ++i) {
m_iTotalTesselatedFaceCount += (m_hist[i] * (i - 2));
}
}
Kernel()->Log(
"\nPTex Import VertexCount Histogram;\n");
for (int i = 0; i < MAX_EDGE_COUNT; ++i) {
if (m_hist[i] != 0) {
Kernel()->Log(
QString(
" Vertex Count %1, number of faces %2\n").arg(i).arg(m_hist[i]));
}
}
int iVertexDataSize = 0;
const float *aVertexPositions = NULL;
pM->getValue(
NTR(
"PtexVertPositions"), aVertexPositions, iVertexDataSize );
if ( iVertexDataSize%3 || aVertexPositions == NULL ) {
Kernel()->Log(
QString(
"Ptex: Vertex DataSize %1, \n").arg(iVertexDataSize));
return NULL;
}
int iFaceDataSize = 0;
const int *aFaceData = NULL;
pM->getValue(
NTR(
"PtexFaceVertIndices"), aFaceData, iFaceDataSize );
if ( aFaceData == NULL )
return NULL;
Kernel()->Log(
QString(
"Ptex: Max Face Size %5, VertexCount %3, FaceCount %1, "
"TesselatedFaceCount = %4, FakeTriangleCount %2\n\n").
arg(m_iFaceCount).arg(m_iTotalTesselatedFaceCount - m_iFaceCount).
arg(iVertexDataSize/3).
arg(m_iTotalTesselatedFaceCount).arg(m_maxFaceSize));
if (makeMesh) {
if (m_allQuads) {
pMesh =
Kernel()->Scene()->CreateMesh( Topology::typeQuadric );
} else {
pMesh =
Kernel()->Scene()->CreateMesh( Topology::typeTriangular );
}
}
MB_ASSERT(m_iTotalTesselatedFaceCount >= m_iFaceCount);
if (pMesh) {
for ( int i = 0; i < iVertexDataSize/3; i++ ) {
aVertexPositions[i*3+1],
aVertexPositions[i*3+2] ) );
}
if (!m_allQuads) {
}
pMesh->
SetName( cFileInfo.baseName().isEmpty() ?
NTR(
"PTEX_Mesh") : cFileInfo.baseName() );
}
int curTri = 0;
int curVertex = 0;
int curSubFaceID = 0;
m_FaceMap = new FaceMapEntry[m_iFaceCount];
m_ReverseFaceMap = new int[m_iTotalTesselatedFaceCount];
memset(m_ReverseFaceMap, 0, m_iTotalTesselatedFaceCount * sizeof(int));
for ( int i = 0; i < m_iFaceCount; i++ )
{
if (m_allQuads) {
if (pMesh) {
}
m_FaceMap[i].m_NumEdges = 4;
m_FaceMap[i].m_NumTessellatedFaces = 1;
m_FaceMap[i].m_MBFaceID = i;
m_FaceMap[i].m_PTexSubfaceID = curSubFaceID;
m_ReverseFaceMap[i] = i;
curSubFaceID += 1;
} else {
const int faceSize = aFaceSizes[i];
int subTri = 0;
m_FaceMap[i].m_NumEdges = faceSize;
m_FaceMap[i].m_MBFaceID = curTri;
m_ReverseFaceMap[curTri] = i;
if (pMesh) {
}
++curTri; ++subTri;
for (int j = 3; j < faceSize; ++j) {
m_ReverseFaceMap[curTri] = i;
if (pMesh) {
}
++curTri; ++subTri;
}
curVertex += faceSize;
m_FaceMap[i].m_NumTessellatedFaces = subTri;
m_FaceMap[i].m_PTexSubfaceID = curSubFaceID;
curSubFaceID += (faceSize == 4) ? 1 : faceSize;
}
}
m_iSubFaceCount = curSubFaceID;
Kernel()->Log(
QString(
"Ptex: Computed subface count = %1, actual in file = %2\n").
arg(m_iSubFaceCount).arg(pTexSubFaceCount));
if (pMesh) {
AddMesh( pMesh );
Material *pMat = CreateInstance<Material>();
Kernel()->Scene()->AddChild( pMat );
}
pT->release();
return pMesh;
}
void PtexImporter::BuildMapsFromBaseMesh(Mesh *pMesh)
{
if (!pMesh)
return;
if ((pMesh->Type() == Topology::typeQuadric)) {
m_allQuads = true;
m_maxFaceSize = 4;
m_minFaceSize = 4;
m_hist[4] = polyCount;
m_iFaceCount = m_iTotalTesselatedFaceCount = m_iSubFaceCount = polyCount;
m_FaceMap = new FaceMapEntry[m_iFaceCount];
m_ReverseFaceMap = new int[m_iTotalTesselatedFaceCount];
for (int i = 0; i < polyCount; ++i) {
m_FaceMap[i].m_NumEdges = 4;
m_FaceMap[i].m_MBFaceID = i;
m_FaceMap[i].m_PTexSubfaceID = i;
m_FaceMap[i].m_NumTessellatedFaces = 1;
m_ReverseFaceMap[i] = i;
}
} else {
m_allQuads = false;
m_maxFaceSize = 3;
m_minFaceSize = 3;
int poly = 0, subface = 0;
for (int i = 0; i < polyCount; ++i)
{
int edgeCount = 3;
while (pMesh->IsFakeTriangle(i+1))
{
++i; ++edgeCount;
}
++poly;
subface += (edgeCount == 4) ? 1 : edgeCount;
++m_hist[edgeCount];
if (m_minFaceSize > edgeCount) m_minFaceSize = edgeCount;
if (m_maxFaceSize < edgeCount) m_maxFaceSize = edgeCount;
}
m_iFaceCount = poly;
m_iTotalTesselatedFaceCount = polyCount;
m_iSubFaceCount = subface;
m_FaceMap = new FaceMapEntry[m_iFaceCount];
m_ReverseFaceMap = new int[m_iTotalTesselatedFaceCount];
poly = 0, subface = 0;
for (int i = 0; i < polyCount; ++i)
{
const int ff = i;
m_ReverseFaceMap[i] = poly;
int edgeCount = 3;
while (pMesh->IsFakeTriangle(i+1))
{
++i; ++edgeCount;
m_ReverseFaceMap[i] = poly;
}
m_FaceMap[poly].m_NumEdges = edgeCount;
m_FaceMap[poly].m_MBFaceID = ff;
m_FaceMap[poly].m_PTexSubfaceID = subface;
m_FaceMap[poly].m_NumTessellatedFaces = edgeCount - 2;
++poly;
subface += (edgeCount == 4) ? 1 : edgeCount;
}
}
}