Files
Hoops_Exchange/exchange/exchangesource/Viewer/traverse/VisitorTessellation.cpp
2025-12-15 22:06:49 +08:00

322 lines
11 KiB
C++

/***********************************************************************************************************************
*
* Copyright (c) 2010 - 2022 by Tech Soft 3D, Inc.
* The information contained herein is confidential and proprietary to Tech Soft 3D, Inc., and considered a trade secret
* as defined under civil and criminal statutes. Tech Soft 3D shall pursue its civil and criminal remedies in the event
* of unauthorized use or misappropriation of its trade secrets. Use of this information by anyone other than authorized
* employees of Tech Soft 3D, Inc. is granted only under a written non-disclosure agreement, expressly prescribing the
* scope and manner of such use.
*
***********************************************************************************************************************/
#include "../VisitorTessellation.h"
#include "../TessConnector.h"
#include "../VisitorCascadedAttribute.h"
#include "../VisitorTransfo.h"
#include "../VisitorContainer.h"
#include "../TransfoConnector.h"
#include "../CascadedAttributeConnector.h"
#include "../MarkupTessConnector.h"
#include "../callback_opengl.h"
A3DStatus A3DVisitorTessellation::visitEnter(const A3DFaceTessDataConnector& sFaceTessConnector)
{
const A3DTessDataConnector * psTessDataConnector = sFaceTessConnector.GetTessDataConnector();
A3DStatus iRet = A3D_SUCCESS;
unsigned int uPointSize, uNormalSize, uUVSize;
double* pdPoint, *pdNormal, *pdUV;
CHECK_RET(psTessDataConnector->Points(pdPoint, uPointSize));
CHECK_RET(psTessDataConnector->Normals(pdNormal, uNormalSize));
CHECK_RET(psTessDataConnector->UV(pdUV, uUVSize));
std::vector<unsigned> auTriangleWithPointNormalindices;
std::vector<unsigned> auTriangleWithPointNormalUVindices;
unsigned uTextureCount = 0;
CHECK_RET(psTessDataConnector->GetTextureCount(sFaceTessConnector.GetFaceIndex(), uTextureCount));
CHECK_RET(psTessDataConnector->IndicesPerFaceAsTriangle(sFaceTessConnector.GetFaceIndex(),
auTriangleWithPointNormalindices,
auTriangleWithPointNormalUVindices));
///////////////////////////////////////////////////////////////
// Draw the tessellation - PLEASE, ADD your sources HERE
///////////////////////////////////////////////////////////////
//manage the visibility of the items
if (m_bShow)
{
// Draw all the triangles of the model (we're not reading the UV for now)
if (auTriangleWithPointNormalindices.size() != 0)
OpenGL_Triangle(pdNormal, uNormalSize, pdPoint, uPointSize, auTriangleWithPointNormalindices, uTextureCount);
if (auTriangleWithPointNormalUVindices.size() != 0)
OpenGL_Triangle(pdNormal, uNormalSize, pdPoint, uPointSize, auTriangleWithPointNormalUVindices, uTextureCount);
}
///////////////////////////////////////////////////////////////
return A3D_SUCCESS;
}
A3DStatus A3DVisitorTessellation::visitLeave(const A3DFaceTessDataConnector& /*sTessConnector*/)
{
return A3D_SUCCESS;
}
A3DStatus A3DVisitorTessellation::visitEnter(const A3DTessDataConnector& sTessConnector)
{
///////////////////////////////////////////////////////////////
// Get the bounding box - PLEASE, ADD your sources HERE
///////////////////////////////////////////////////////////////
A3DStatus iRet = A3D_SUCCESS;
unsigned int uPointSize, uNormalSize, uUVSize, uFaceSize;
double* pdPoint, *pdNormal, *pdUV;
CHECK_RET(sTessConnector.Points(pdPoint, uPointSize));
CHECK_RET(sTessConnector.Normals(pdNormal, uNormalSize));
CHECK_RET(sTessConnector.UV(pdUV, uUVSize));
uFaceSize = sTessConnector.FacesSize();
///////////////////////////////////////////////////////////////
// Get the Bounding Box - PLEASE, ADD your sources HERE
///////////////////////////////////////////////////////////////
if(!GetstbUseCallbacks())
{
if (m_bShow)
{
A3DVisitorTransfo* psVisitorTransfo = (A3DVisitorTransfo*) m_psContainer->GetVisitor()[0];
A3DTransfoConnector* pConnector = psVisitorTransfo->GetTransfoConnector();
A3DMatrix4x4 sGlobalTransfo;
A3DMatrix4x4 sLocalTransfo;
pConnector->GetGlobalTransfo(sGlobalTransfo);
//pConnector->GetLocalMatrix(sLocalTransfo);
delete pConnector;
A3DVector3d sCurrentPt;
for(unsigned int uI = 0; uI < uPointSize/3; uI++)
{
sCurrentPt.set(pdPoint[uI*3], pdPoint[uI*3 + 1], pdPoint[uI*3+2]);
sCurrentPt = sGlobalTransfo * sCurrentPt;
stBoundingBoxAddPoint(GetstpsBoundingBox(), sCurrentPt.x, sCurrentPt.y, sCurrentPt.z);
}
}
}
else
{
A3DVisitorTransfo* psVisitorTransfo = (A3DVisitorTransfo*) m_psContainer->GetVisitor()[0];
A3DTransfoConnector* pConnector = psVisitorTransfo->GetTransfoConnector();
A3DMatrix4x4 sGlobalTransfo;
pConnector->GetGlobalTransfo(sGlobalTransfo);
delete pConnector;
OpenGL_PushMatrix();
OpenGL_MultMatrix(sGlobalTransfo.m_adM);
}
return A3D_SUCCESS;
}
A3DStatus A3DVisitorTessellation::visitLeave(const A3DTessDataConnector& /*sTessConnector*/)
{
if(GetstbUseCallbacks())
OpenGL_PopMatrix();
return A3D_SUCCESS;
}
A3DStatus A3DVisitorTessellation::visitEnter(const A3DRiConnector& /*sTessConnector*/)
{
A3DVisitorColorMaterials* pVisitorColorAndMaterials = (A3DVisitorColorMaterials *)m_psContainer->GetVisitor()[1];
ColorMaterialsConnector sColorMaterialConnec(pVisitorColorAndMaterials->GetLastCascadedAttributes());
if (sColorMaterialConnec.IsShow() && !sColorMaterialConnec.IsRemoved())
m_bShow = true;
else
m_bShow = false;
return A3D_SUCCESS;
}
A3DStatus A3DVisitorTessellation::visitLeave(const A3DRiConnector& /*sTessConnector*/)
{
return A3D_SUCCESS;
}
A3DStatus A3DVisitorTessellation::visitEnter(const A3DMarkupTessConnector& sMarkupTessConnector)
{
A3DVisitorColorMaterials* pVisitorColorAndMaterials = (A3DVisitorColorMaterials *)m_psContainer->GetVisitor()[1];
ColorMaterialsConnector sColorMaterialConnec(pVisitorColorAndMaterials->GetLastCascadedAttributes());
if (sColorMaterialConnec.IsShow() && !sColorMaterialConnec.IsRemoved())
m_bShow = true;
else
m_bShow = false;
if (GetstbDrawMarkups())
{
// Get the bounding box
if(!GetstbUseCallbacks())
{
A3DVisitorTransfo* psVisitorTransfo = (A3DVisitorTransfo*) m_psContainer->GetVisitor()[0];
A3DTransfoConnector* pConnector = psVisitorTransfo->GetTransfoConnector();
A3DMatrix4x4 sGlobalTransfo;
A3DMatrix4x4 sLocalTransfo;
pConnector->GetGlobalTransfo(sGlobalTransfo);
delete pConnector;
std::vector<double> adPolyline = sMarkupTessConnector.GetPolyLineCoords(); // Copy
A3DVector3d sCurrentPt;
size_t uI, uPolylineSize = adPolyline.size();
for(uI = 0; uI < uPolylineSize/3; uI++)
{
sCurrentPt.set(adPolyline[uI*3], adPolyline[uI*3 + 1], adPolyline[uI*3+2]);
sCurrentPt = sGlobalTransfo * sCurrentPt;
stBoundingBoxAddPoint(GetstpsBoundingBox(), sCurrentPt.x, sCurrentPt.y, sCurrentPt.z);
}
}
// Draw the markups
else
{
OpenGL_Begin(kA3DDrawBeginEndMarkup, NULL, 0);
if (m_bShow)
{
// Draw the global matrix
OpenGL_PushMatrix();
OpenGL_MultMatrix(sMarkupTessConnector.GetWorldMatrix());
// *** Draw the colors
double a_adRGB[3] = {0, 0, 0};
sMarkupTessConnector.GetColor(a_adRGB);
OpenGL_Color(a_adRGB);
// *** Draw the triangles
std::vector<double> triangles = sMarkupTessConnector.GetTriangles();
size_t uTrianglesSize = triangles.size();
double* adTriangle = new double[uTrianglesSize];
for (size_t ui=0; ui<uTrianglesSize; ++ui)
adTriangle[ui] = triangles[ui];
if (uTrianglesSize != 0)
{
OpenGL_MarkupTriangle(adTriangle, A3DUns32(uTrianglesSize)/3);
}
delete[] adTriangle;
// *** Draw text
std::vector<A3DPMITextEntry*> const& textEntries = sMarkupTessConnector.GetTextEntries();
for (size_t ui = 0; ui < textEntries.size(); ++ui)
{
A3DPMITextEntry mTextEntries = *textEntries[ui];
A3DFontKeyData sFontKeyData = mTextEntries.GetFontKeyData();
OpenGL_Font(&sFontKeyData);
A3DUTF8Char * m_ppcTexts = mTextEntries.GetText();
// Draw Text
A3DRiSet *pSet = NULL;
A3DDouble dLength = 0.;
if(A3DGlobalFontTextTessellationGet(&sFontKeyData, m_ppcTexts, &pSet, &dLength) == A3D_SUCCESS)
{
A3DRiConnector sRiSet(pSet);
sRiSet.TraverseRi(this->m_psContainer);
}
}
// *** Draw the polylines
std::vector<int> polylineindex = sMarkupTessConnector.GetPolyLineIndices();
std::vector<double> polylines = sMarkupTessConnector.GetPolyLineCoords();
double* adPolyline = new double[polylines.size()];
for (size_t ui=0; ui<polylines.size(); ++ui)
adPolyline[ui] = polylines[ui];
if (polylineindex.size() != 0)
{
size_t uPolylineIndicesSize = polylineindex.size();
for (size_t uI=0; uI < uPolylineIndicesSize-1; ++uI)
{
OpenGL_PolyLine(&adPolyline[polylineindex[uI]*3], polylineindex[uI+1] - polylineindex[uI]);
}
}
delete[] adPolyline;
OpenGL_PopMatrix();
stPopMatrix();
}
OpenGL_End(kA3DDrawBeginEndMarkup);
}
}
return A3D_SUCCESS;
}
A3DStatus A3DVisitorTessellation::visitEnter(const A3DWireTessDataConnector& sWireTessConnector)
{
A3DStatus iRet = A3D_SUCCESS;
double* pPoint;
unsigned int uSize;
std::vector<int> auPolylineIndices;
// manage the visibility of the items
A3DVisitorColorMaterials* pVisitorColorAndMaterials = (A3DVisitorColorMaterials *)m_psContainer->GetVisitor()[1];
ColorMaterialsConnector sColorMaterialConnec(pVisitorColorAndMaterials->GetLastCascadedAttributes());
pVisitorColorAndMaterials->GetColorMaterialConnector(sColorMaterialConnec, false);
A3DVisitorTransfo* psVisitorTransfo = (A3DVisitorTransfo*)m_psContainer->GetVisitor()[0];
A3DTransfoConnector* pConnector = psVisitorTransfo->GetTransfoConnector();
A3DMatrix4x4 sGlobalTransfo;
pConnector->GetGlobalTransfo(sGlobalTransfo);
delete pConnector;
OpenGL_PushMatrix();
OpenGL_MultMatrix(sGlobalTransfo.m_adM);
if (sColorMaterialConnec.IsShow() && !sColorMaterialConnec.IsRemoved())
{
CHECK_RET(sWireTessConnector.Points(pPoint, uSize));
CHECK_RET(sWireTessConnector.Indices(auPolylineIndices));
size_t uI, uPolylineIndicesSize = auPolylineIndices.size();
// section case:
if (auPolylineIndices[0] > 0)
{
for (uI = 0; uI < uPolylineIndicesSize; uI++)
{
std::vector<A3DDouble> aPoints;
// kA3DTess3DWireDataIsContinuous && kA3DTess3DWireDataIsClosing to be treated
unsigned int uPolyLineSize = auPolylineIndices[uI] & ~(kA3DTess3DWireDataIsContinuous | kA3DTess3DWireDataIsClosing);
for (size_t uJ = uI + 1; uJ < uI + uPolyLineSize + 1; uJ++)
{
aPoints.push_back(pPoint[auPolylineIndices[uJ]]);
aPoints.push_back(pPoint[auPolylineIndices[uJ] + 1]);
aPoints.push_back(pPoint[auPolylineIndices[uJ] + 2]);
}
OpenGL_PolyLine(aPoints.data(), uPolyLineSize);
uI += uPolyLineSize;
}
}
else
{
for (uI = 0; uI + 1 < uPolylineIndicesSize; ++uI)
{
// manage the case of polywire
int test = auPolylineIndices[uI + 1] - auPolylineIndices[uI];
if (test > 0)
OpenGL_PolyLine(&pPoint[auPolylineIndices[uI] * 3], auPolylineIndices[uI + 1] - auPolylineIndices[uI]);
}
}
}
return A3D_SUCCESS;
}
A3DStatus A3DVisitorTessellation::visitLeave(const A3DWireTessDataConnector& /*sWireTessConnector*/)
{
OpenGL_PopMatrix();
return A3D_SUCCESS;
}