Files
2025-12-15 22:06:49 +08:00

3820 lines
129 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 <math.h>
#include <A3DSDKIncludes.h>
#include "callback_opengl.h"
#define VIEWS
//######################################################################################################################
static bool stbUseCallbacks = true;
static A3DDrawCallbacksData stsCallbacks;
static bool stbCallbacksInitialized = false;
static A3DBoundingBoxData* stpsBoundingBox = NULL;
static bool stbDraw3D = false;
static bool stbDrawMarkups = false;
//######################################################################################################################
static void stDefaultPushMatrix() {}
static void stDefaultPopMatrix() {}
static void stDefaultMultMatrix(const A3DDouble /*adMatrix*/[16]) {}
static void stDefaultBegin(A3DEDrawBeginEndType /*eType*/, const A3DUTF8Char* /*pcName*/, A3DUns32 /*uiTrianglesCount*/) {}
static void stDefaultEnd(A3DEDrawBeginEndType /*eType*/) {}
static void stDefaultSetTessellationPoints(const A3DVector3dData* /*pasPoint*/, A3DUns32 /*uiPointsSize*/) {}
#ifdef A3D_DRAW_WITH_INDICES
static void stDefaultSetTessellationNormals(const A3DVector3dData* /*pasNormal*/, A3DUns32 /*uiPointsSize*/) {}
#endif
static void stDefaultTriangle(const A3DVector3dData* /*pasNormals*/, const A3DVector3dData* /*pasPoints*/, A3DUns32 /*uiPointsSize*/) {}
static void stDefaultTriangleFan(const A3DVector3dData* /*pasNormals*/, const A3DVector3dData* /*pasPoints*/, A3DUns32 /*uiPointsSize*/) {}
static void stDefaultTriangleStripe(const A3DVector3dData* /*pasNormals*/, const A3DVector3dData* /*pasPoints*/, A3DUns32 /*uiPointsSize*/) {}
static void stDefaultTriangleOneNormal(const A3DVector3dData* /*pasNormals*/, const A3DVector3dData* /*pasPoints*/, A3DUns32 /*uiPointsSize*/) {}
static void stDefaultTriangleFanOneNormal(const A3DVector3dData* /*psNormal*/, const A3DVector3dData* /*pasPoints*/, A3DUns32 /*uiPointsSize*/) {}
static void stDefaultTriangleStripeOneNormal(const A3DVector3dData* /*psNormal*/, const A3DVector3dData* /*pasPoints*/, A3DUns32 /*uiPointsSize*/) {}
static void stDefaultTriangleTextured(const A3DVector3dData* /*pasNormals*/, const A3DVector3dData* /*pasPoints*/, A3DUns32 /*uiPointsSize*/) {}
static void stDefaultTriangleFanTextured(const A3DVector3dData* /*pasNormals*/, const A3DVector3dData* /*pasPoints*/, A3DUns32 /*uiPointsSize*/) {}
static void stDefaultTriangleStripeTextured(const A3DVector3dData* /*pasNormals*/, const A3DVector3dData* /*pasPoints*/, A3DUns32 /*uiPointsSize*/) {}
static void stDefaultTriangleOneNormalTextured(const A3DVector3dData* /*pasNormals*/, const A3DVector3dData* /*pasPoints*/, A3DUns32 /*uiPointsSize*/) {}
static void stDefaultTriangleFanOneNormalTextured(const A3DVector3dData* /*psNormal*/, const A3DVector3dData* /*pasPoints*/, A3DUns32 /*uiPointsSize*/) {}
static void stDefaultTriangleStripeOneNormalTextured(const A3DVector3dData* /*psNormal*/, const A3DVector3dData* /*pasPoints*/, A3DUns32 /*uiPointsSize*/) {}
#ifdef A3D_DRAW_WITH_INDICES
static void stDefaultTriangleWithIndices(const A3DUns32* /*pauiNormals*/, const A3DUns32* /*pauiPoints*/, A3DUns32 /*uiPointsSize*/) {}
static void stDefaultTriangleFanWithIndices(const A3DUns32* /*pauiNormals*/, const A3DUns32* /*pauiPoints*/, A3DUns32 /*uiPointsSize*/) {}
static void stDefaultTriangleStripeWithIndices(const A3DUns32* /*pauiNormals*/, const A3DUns32* /*pauiPoints*/, A3DUns32 /*uiPointsSize*/) {}
static void stDefaultTriangleOneNormalWithIndices(const A3DUns32* /*pauiNormals*/, const A3DUns32* /*pauiPoints*/, A3DUns32 /*uiPointsSize*/) {}
static void stDefaultTriangleFanOneNormalWithIndices(A3DUns32 uiNormal, const A3DUns32* /*pauiPoints*/, A3DUns32 /*uiPointsSize*/) {}
static void stDefaultTriangleStripeOneNormalWithIndices(A3DUns32 uiNormal, const A3DUns32* /*pauiPoints*/, A3DUns32 /*uiPointsSize*/) {}
static void stDefaultTriangleTexturedWithIndices(const A3DUns32* /*pauiNormals*/, const A3DUns32* /*pauiPoints*/, A3DUns32 /*uiPointsSize*/) {}
static void stDefaultTriangleFanTexturedWithIndices(const A3DUns32* /*pauiNormals*/, const A3DUns32* /*pauiPoints*/, A3DUns32 /*uiPointsSize*/) {}
static void stDefaultTriangleStripeTexturedWithIndices(const A3DUns32* /*pauiNormals*/, const A3DUns32* /*pauiPoints*/, A3DUns32 /*uiPointsSize*/) {}
static void stDefaultTriangleOneNormalTexturedWithIndices(const A3DUns32* /*pauiNormals*/, const A3DUns32* /*pauiPoints*/, A3DUns32 /*uiPointsSize*/) {}
static void stDefaultTriangleFanOneNormalTexturedWithIndices(A3DUns32 /*uiNormal*/, const A3DUns32* /*pauiPoints*/, A3DUns32 /*uiPointsSize*/) {}
static void stDefaultTriangleStripeOneNormalTexturedWithIndices(A3DUns32 /*uiNormal*/, const A3DUns32* /*pauiPoints*/, A3DUns32 /*uiPointsSize*/) {}
#endif
static void stDefaultMaterial(A3DEDrawMaterialType /*eType*/, const A3DDouble* /*pdValues*/, A3DUns32 /*uiValuesSize*/) {}
static void stDefaultColor(const A3DDouble [3]/*adValues*/) {}
static void stDefaultGetDrawContext(A3DDouble /*adProjection*/[16], A3DDouble /*adModelView*/[16], A3DInt32 /*aiViewport*/[4]) {}
static void stDefaultMarkupTriangle(const A3DDouble* /*pdPoints*/, A3DUns32 /*uiPointSize*/) {}
static void stDefaultUnProject(const A3DVector3dData* /*psPoint*/, A3DVector3dData* /*psResult*/) {}
static void stDefaultBeginFrameDraw(const A3DVector3dData* /*psPoint3d*/, A3DBool /*bIsZoomable*/, A3DDouble /*dFixedSize*/) {}
static void stDefaultEndFrameDraw(void) {}
static void stDefaultBeginFixedSize(const A3DVector3dData* /*psPoint3d*/) {}
static void stDefaultEndFixedSize(void) {}
static void stDefaultCylinder(A3DDouble /*dBaseRadius*/, A3DDouble /*dTopRadius*/, A3DDouble /*dHeight*/) {}
static void stDefaultPolygon(const A3DDouble* /*pdPoints*/, A3DUns32 /*uiPointSize*/) {}
static void stDefaultBeginLineWidth(A3DDouble /*dWidth*/) {}
static void stDefaultEndLineWidth(void) {}
static void stDefaultPoint(const A3DDouble* /*pdPoints*/, A3DUns32 /*uiPointSize*/) {}
static void stDefaultFont(const A3DFontKeyData* /*psFontKeyData*/) {}
static void stDefaultBeginLineStipple(const A3DGraphStyleData* /*psGraphStyleData*/) {}
static void stDefaultEndLineStipple(void) {}
static void stDefaultSymbol(const A3DGraphVPicturePatternData* /*psPatternData*/, const A3DVector3dData* /*psPosition*/) {}
static void stDefaultPolyLine(const A3DDouble* /*pdPoints*/, A3DUns32 /*uiPointSize*/) {}
static void stDefaultText(const A3DUTF8Char* /*pcBuffer*/, A3DDouble /*dWidth*/, A3DDouble /*dHeight*/) {}
static void stDefaultPattern(A3DUns32 /*uiLoopsSize*/, A3DUns32 /*uiPatternId*/, A3DUns32 /*uiFilledMode*/, A3DUns32 /*uiBehavior*/, const A3DDouble* /*pdPoints*/, const A3DUns32* /*puiLoopsPointSize*/) {}
static void stDefaultPicture(const A3DGraphPictureData* /*psPictureData*/) {}
static void stDefaultBeginMaterial(void) {}
static void stDefaultEndMaterial(void) {}
//######################################################################################################################
A3DStatus DrawInitCallbacks(A3DDrawCallbacksData* psCallbacks)
{
if(!stbCallbacksInitialized)
{
#define A3D_DRAW_DEFINE_CALLBACK(name) { \
stsCallbacks.m_pfunc##name = stDefault##name; \
if(psCallbacks->m_pfunc##name != NULL) \
stsCallbacks.m_pfunc##name = psCallbacks->m_pfunc##name; \
else \
stsCallbacks.m_pfunc##name = stDefault##name; \
}
A3D_DRAW_DEFINE_CALLBACK(MultMatrix);
A3D_DRAW_DEFINE_CALLBACK(PopMatrix);
A3D_DRAW_DEFINE_CALLBACK(PushMatrix);
A3D_DRAW_DEFINE_CALLBACK(Begin);
A3D_DRAW_DEFINE_CALLBACK(End);
A3D_DRAW_DEFINE_CALLBACK(SetTessellationPoints);
#ifdef A3D_DRAW_WITH_INDICES
A3D_DRAW_DEFINE_CALLBACK(SetTessellationNormals);
#endif
A3D_DRAW_DEFINE_CALLBACK(Triangle);
A3D_DRAW_DEFINE_CALLBACK(TriangleFan);
A3D_DRAW_DEFINE_CALLBACK(TriangleStripe);
A3D_DRAW_DEFINE_CALLBACK(TriangleOneNormal);
A3D_DRAW_DEFINE_CALLBACK(TriangleFanOneNormal);
A3D_DRAW_DEFINE_CALLBACK(TriangleStripeOneNormal);
A3D_DRAW_DEFINE_CALLBACK(TriangleTextured);
A3D_DRAW_DEFINE_CALLBACK(TriangleFanTextured);
A3D_DRAW_DEFINE_CALLBACK(TriangleStripeTextured);
A3D_DRAW_DEFINE_CALLBACK(TriangleOneNormalTextured);
A3D_DRAW_DEFINE_CALLBACK(TriangleFanOneNormalTextured);
A3D_DRAW_DEFINE_CALLBACK(TriangleStripeOneNormalTextured);
#ifdef A3D_DRAW_WITH_INDICES
A3D_DRAW_DEFINE_CALLBACK(TriangleWithIndices);
A3D_DRAW_DEFINE_CALLBACK(TriangleFanWithIndices);
A3D_DRAW_DEFINE_CALLBACK(TriangleStripeWithIndices);
A3D_DRAW_DEFINE_CALLBACK(TriangleOneNormalWithIndices);
A3D_DRAW_DEFINE_CALLBACK(TriangleFanOneNormalWithIndices);
A3D_DRAW_DEFINE_CALLBACK(TriangleStripeOneNormalWithIndices);
A3D_DRAW_DEFINE_CALLBACK(TriangleTexturedWithIndices);
A3D_DRAW_DEFINE_CALLBACK(TriangleFanTexturedWithIndices);
A3D_DRAW_DEFINE_CALLBACK(TriangleStripeTexturedWithIndices);
A3D_DRAW_DEFINE_CALLBACK(TriangleOneNormalTexturedWithIndices);
A3D_DRAW_DEFINE_CALLBACK(TriangleFanOneNormalTexturedWithIndices);
A3D_DRAW_DEFINE_CALLBACK(TriangleStripeOneNormalTexturedWithIndices);
#endif
A3D_DRAW_DEFINE_CALLBACK(Material);
A3D_DRAW_DEFINE_CALLBACK(Color);
A3D_DRAW_DEFINE_CALLBACK(BeginMaterial);
A3D_DRAW_DEFINE_CALLBACK(EndMaterial);
A3D_DRAW_DEFINE_CALLBACK(GetDrawContext);
A3D_DRAW_DEFINE_CALLBACK(MarkupTriangle);
A3D_DRAW_DEFINE_CALLBACK(UnProject);
A3D_DRAW_DEFINE_CALLBACK(BeginFrameDraw);
A3D_DRAW_DEFINE_CALLBACK(EndFrameDraw);
A3D_DRAW_DEFINE_CALLBACK(BeginFixedSize);
A3D_DRAW_DEFINE_CALLBACK(EndFixedSize);
A3D_DRAW_DEFINE_CALLBACK(Cylinder);
A3D_DRAW_DEFINE_CALLBACK(Polygon);
A3D_DRAW_DEFINE_CALLBACK(BeginLineWidth);
A3D_DRAW_DEFINE_CALLBACK(EndLineWidth);
A3D_DRAW_DEFINE_CALLBACK(Point);
A3D_DRAW_DEFINE_CALLBACK(Font);
A3D_DRAW_DEFINE_CALLBACK(BeginLineStipple);
A3D_DRAW_DEFINE_CALLBACK(EndLineStipple);
A3D_DRAW_DEFINE_CALLBACK(Symbol);
A3D_DRAW_DEFINE_CALLBACK(PolyLine);
A3D_DRAW_DEFINE_CALLBACK(Text);
A3D_DRAW_DEFINE_CALLBACK(Pattern);
A3D_DRAW_DEFINE_CALLBACK(Picture);
#undef A3D_DRAW_DEFINE_CALLBACK
stbCallbacksInitialized = true;
}
return A3D_SUCCESS;
}
//######################################################################################################################
#define A3D_DRAW_CALL0(name) { if(stbUseCallbacks) stsCallbacks.m_pfunc##name(); }
#define A3D_DRAW_CALL1(name, p1) { if(stbUseCallbacks) stsCallbacks.m_pfunc##name(p1); }
#define A3D_DRAW_CALL2(name, p1, p2) { if(stbUseCallbacks) stsCallbacks.m_pfunc##name(p1, p2); }
#define A3D_DRAW_CALL3(name, p1, p2, p3) { if(stbUseCallbacks) stsCallbacks.m_pfunc##name(p1, p2, p3); }
#define A3D_DRAW_CALL6(name, p1, p2, p3, p4, p5, p6) { if(stbUseCallbacks) stsCallbacks.m_pfunc##name(p1, p2, p3, p4, p5, p6); }
//######################################################################################################################
#define CHECK_RET(func_call) { iRet = func_call; }
//######################################################################################################################
class A3DInternalMarkup
{
A3DTessMarkupData* m_psData;
A3DTessBaseData* m_psBaseData;
public:
A3DInternalMarkup();
~A3DInternalMarkup();
void SetTessMarkupData(A3DTessMarkupData* psData);
void SetTessBaseData(A3DTessBaseData* psBaseData);
A3DTessMarkupData* Data() { return m_psData; }
const A3DTessMarkupData* Data() const { return m_psData; }
A3DTessBaseData* BaseData() { return m_psBaseData; }
const A3DTessBaseData* BaseData() const { return m_psBaseData; }
};
//######################################################################################################################
A3DInternalMarkup::A3DInternalMarkup()
{
m_psData = (A3DTessMarkupData*)malloc(sizeof(A3DTessMarkupData));
A3D_INITIALIZE_DATA(A3DTessMarkupData, (*m_psData));
m_psBaseData = (A3DTessBaseData*)malloc(sizeof(A3DTessBaseData));
A3D_INITIALIZE_DATA(A3DTessBaseData, (*m_psBaseData));
}
//######################################################################################################################
A3DInternalMarkup::~A3DInternalMarkup()
{
if(m_psData != NULL)
{
A3DTessMarkupGet(NULL, m_psData);
free(m_psData);
}
if(m_psBaseData != NULL)
{
A3DTessBaseGet(NULL, m_psBaseData);
free(m_psBaseData);
}
}
//######################################################################################################################
void A3DInternalMarkup::SetTessMarkupData(A3DTessMarkupData* psData)
{
m_psData = psData;
}
//######################################################################################################################
void A3DInternalMarkup::SetTessBaseData(A3DTessBaseData* psBaseData)
{
m_psBaseData = psBaseData;
}
//######################################################################################################################
static void stAllocVector3dArray(A3DVector3dData** ppasArray, A3DUns32 uiSize)
{
A3DUns32 ui;
*ppasArray = (A3DVector3dData*)malloc(uiSize * sizeof(A3DVector3dData));
for(ui = 0; ui < uiSize; ui++)
A3D_INITIALIZE_DATA(A3DVector3dData, ((*ppasArray)[ui]));
}
//######################################################################################################################
static void stAllocNormalsAndPoints(A3DVector3dData** ppasNormals, A3DUns32 uiNormalSize, A3DVector3dData** ppasPoints,
A3DUns32 uiPointSize)
{
stAllocVector3dArray(ppasNormals, uiNormalSize);
stAllocVector3dArray(ppasPoints, uiPointSize);
}
//######################################################################################################################
static void stFreeNormalsAndPoints(A3DVector3dData** ppasNormals, A3DVector3dData** ppasPoints)
{
free(*ppasNormals);
free(*ppasPoints);
}
//######################################################################################################################
typedef struct
{
unsigned int m_uiAllocated;
unsigned int m_uiSize;
void** m_ppPointers;
} A3DPointerArray;
//######################################################################################################################
static void stPointerArrayInitialize(A3DPointerArray* psArray)
{
if(psArray == NULL)
return;
psArray->m_uiAllocated = 0;
psArray->m_uiSize = 0;
psArray->m_ppPointers = NULL;
}
//######################################################################################################################
static void stPointerArrayFree(A3DPointerArray* psArray)
{
psArray->m_uiAllocated = 0;
psArray->m_uiSize = 0;
free(psArray->m_ppPointers);
}
//######################################################################################################################
static void stPointerArrayTerminate(A3DPointerArray* psArray)
{
stPointerArrayFree(psArray);
}
//######################################################################################################################
void* MiscRealloc(void* p, A3DUns32 uiOldSize, A3DUns32 uiNewSize)
{
void* newp=malloc(uiNewSize);
memcpy(newp,p,uiOldSize);
free(p);
return newp;
}
//######################################################################################################################
static unsigned int stPointerArrayAdd(A3DPointerArray* psArray, void* pPointer)
{
if(psArray == NULL)
return 0;
if(psArray->m_uiAllocated == 0)
{
psArray->m_uiAllocated = 2;
psArray->m_ppPointers = (void**)malloc(psArray->m_uiAllocated * sizeof(void*));
}
if(psArray->m_uiSize == psArray->m_uiAllocated)
{
psArray->m_uiAllocated *= 2;
psArray->m_ppPointers = (void**)MiscRealloc(psArray->m_ppPointers, psArray->m_uiSize * sizeof(void*),
psArray->m_uiAllocated * sizeof(void*));
}
psArray->m_ppPointers[psArray->m_uiSize] = pPointer;
psArray->m_uiSize++;
return psArray->m_uiSize;
}
//######################################################################################################################
static int stPointerArrayFind(A3DPointerArray* psArray, void* pPointer)
{
for(unsigned int ui = 0; ui < psArray->m_uiSize; ui++)
{
if(psArray->m_ppPointers[ui] == pPointer)
return ui;
}
return -1;
}
//######################################################################################################################
static unsigned int stPointerArrayAddUnique(A3DPointerArray* psArray, void* pPointer)
{
if(psArray == NULL)
return 0;
if(stPointerArrayFind(psArray, pPointer) != -1)
return psArray->m_uiSize;
return stPointerArrayAdd(psArray, pPointer);
}
//######################################################################################################################
static unsigned int stPointerArrayAddArray(A3DPointerArray* psArray, void** const ppPointers, unsigned int uiSize)
{
for(unsigned int ui = 0; ui < uiSize; ui++)
stPointerArrayAdd(psArray, ppPointers[ui]);
return psArray->m_uiSize;
}
//######################################################################################################################
#define A3D_MIN(a,b) (((a)<(b)) ? (a) : (b))
#define A3D_MAX(a,b) (((a)>(b)) ? (a) : (b))
//######################################################################################################################
extern void stVectoriel(const A3DVector3dData* X, const A3DVector3dData* Y, A3DVector3dData* Z)
{
Z->m_dX=X->m_dY*Y->m_dZ - X->m_dZ*Y->m_dY;
Z->m_dY=X->m_dZ*Y->m_dX - X->m_dX*Y->m_dZ;
Z->m_dZ=X->m_dX*Y->m_dY - X->m_dY*Y->m_dX;
}
//######################################################################################################################
static void stVectorMatrixMult(A3DDouble dX, A3DDouble dY, A3DDouble dZ, double adMatrix[16],
A3DDouble* pdResX, A3DDouble* pdResY, A3DDouble* pdResZ)
{
*pdResX = adMatrix[0]*dX + adMatrix[4]*dY + adMatrix[8]*dZ + adMatrix[12];
*pdResY = adMatrix[1]*dX + adMatrix[5]*dY + adMatrix[9]*dZ + adMatrix[13];
*pdResZ = adMatrix[2]*dX + adMatrix[6]*dY + adMatrix[10]*dZ + adMatrix[14];
}
//######################################################################################################################
static double staadStack[32][16];
static unsigned int uiPos = 0;
static double stadMatrix[16];
//######################################################################################################################
extern void stMatrixMatrixMult(double m[16], const double o[16])
{
memcpy(stadMatrix, m, 16*sizeof(double));
m[0] = stadMatrix[0] * o[0] + stadMatrix[4] * o[1] + stadMatrix[8] * o[2] + stadMatrix[12] * o[3];
m[1] = stadMatrix[1] * o[0] + stadMatrix[5] * o[1] + stadMatrix[9] * o[2] + stadMatrix[13] * o[3];
m[2] = stadMatrix[2] * o[0] + stadMatrix[6] * o[1] + stadMatrix[10] * o[2] + stadMatrix[14] * o[3];
m[3] = stadMatrix[3] * o[0] + stadMatrix[7] * o[1] + stadMatrix[11] * o[2] + stadMatrix[15] * o[3];
m[4] = stadMatrix[0] * o[4] + stadMatrix[4] * o[5] + stadMatrix[8] * o[6] + stadMatrix[12] * o[7];
m[5] = stadMatrix[1] * o[4] + stadMatrix[5] * o[5] + stadMatrix[9] * o[6] + stadMatrix[13] * o[7];
m[6] = stadMatrix[2] * o[4] + stadMatrix[6] * o[5] + stadMatrix[10] * o[6] + stadMatrix[14] * o[7];
m[7] = stadMatrix[3] * o[4] + stadMatrix[7] * o[5] + stadMatrix[11] * o[6] + stadMatrix[15] * o[7];
m[8] = stadMatrix[0] * o[8] + stadMatrix[4] * o[9] + stadMatrix[8] * o[10] + stadMatrix[12] * o[11];
m[9] = stadMatrix[1] * o[8] + stadMatrix[5] * o[9] + stadMatrix[9] * o[10] + stadMatrix[13] * o[11];
m[10]= stadMatrix[2] * o[8] + stadMatrix[6] * o[9] + stadMatrix[10] * o[10] + stadMatrix[14] * o[11];
m[11]= stadMatrix[3] * o[8] + stadMatrix[7] * o[9] + stadMatrix[11] * o[10] + stadMatrix[15] * o[11];
m[12]= stadMatrix[0] * o[12] + stadMatrix[4] * o[13] + stadMatrix[8] * o[14] + stadMatrix[12] * o[15];
m[13]= stadMatrix[1] * o[12] + stadMatrix[5] * o[13] + stadMatrix[9] * o[14] + stadMatrix[13] * o[15];
m[14]= stadMatrix[2] * o[12] + stadMatrix[6] * o[13] + stadMatrix[10] * o[14] + stadMatrix[14] * o[15];
m[15]= stadMatrix[3] * o[12] + stadMatrix[7] * o[13] + stadMatrix[11] * o[14] + stadMatrix[15] * o[15];
}
//######################################################################################################################
extern void stLoadIdentity()
{
memset(staadStack[uiPos], 0, 16*sizeof(double));
staadStack[uiPos][0] = 1.0;
staadStack[uiPos][5] = 1.0;
staadStack[uiPos][10] = 1.0;
staadStack[uiPos][15] = 1.0;
}
//######################################################################################################################
extern void stMultMatrix(const double m[16])
{
stMatrixMatrixMult(staadStack[uiPos], m);
}
//######################################################################################################################
extern void stPushMatrix()
{
if(uiPos < 7)
{
uiPos++;
memcpy(staadStack[uiPos], staadStack[uiPos-1], 16*sizeof(double));
}
}
//######################################################################################################################
extern void stPopMatrix()
{
if(uiPos > 0)
{
uiPos--;
}
}
//######################################################################################################################
static void stGetMatrix(double m[16])
{
memcpy(m, staadStack[uiPos], 16*sizeof(double));
}
//######################################################################################################################
extern void stExtentInit(A3DBoundingBoxData* e)
{
e->m_sMin.m_dX = 1e10;
e->m_sMin.m_dY = 1e10;
e->m_sMin.m_dZ = 1e10;
e->m_sMax.m_dX = -1e10;
e->m_sMax.m_dY = -1e10;
e->m_sMax.m_dZ = -1e10;
}
//######################################################################################################################
extern void stBoundingBoxAddPoint(A3DBoundingBoxData* e, double x, double y, double z)
{
if (e == NULL)
return;
if(x < e->m_sMin.m_dX) e->m_sMin.m_dX = x;
if(y < e->m_sMin.m_dY) e->m_sMin.m_dY = y;
if(z < e->m_sMin.m_dZ) e->m_sMin.m_dZ = z;
if(x > e->m_sMax.m_dX) e->m_sMax.m_dX = x;
if(y > e->m_sMax.m_dY) e->m_sMax.m_dY = y;
if(z > e->m_sMax.m_dZ) e->m_sMax.m_dZ = z;
}
//######################################################################################################################
static bool stExtentIsValid(A3DBoundingBoxData* e)
{
return (e->m_sMin.m_dX <= e->m_sMax.m_dX && e->m_sMin.m_dY <= e->m_sMax.m_dY && e->m_sMin.m_dZ <= e->m_sMax.m_dZ);
}
//######################################################################################################################
static void stExtentUnion(const A3DBoundingBoxData* e1, const A3DBoundingBoxData* e2, A3DBoundingBoxData* r)
{
r->m_sMin.m_dX = A3D_MIN(e1->m_sMin.m_dX, e2->m_sMin.m_dX);
r->m_sMax.m_dX = A3D_MAX(e1->m_sMax.m_dX, e2->m_sMax.m_dX);
r->m_sMin.m_dY = A3D_MIN(e1->m_sMin.m_dY, e2->m_sMin.m_dY);
r->m_sMax.m_dY = A3D_MAX(e1->m_sMax.m_dY, e2->m_sMax.m_dY);
r->m_sMin.m_dZ = A3D_MIN(e1->m_sMin.m_dZ, e2->m_sMin.m_dZ);
r->m_sMax.m_dZ = A3D_MAX(e1->m_sMax.m_dZ, e2->m_sMax.m_dZ);
}
//######################################################################################################################
static void stUnitVector(A3DVector3dData* psVect)
{
if(psVect == NULL)
return;
double x = psVect->m_dX, y = psVect->m_dY, z = psVect->m_dZ;
double norm = sqrt(x*x+y*y+z*z);
if(norm != 0)
{
psVect->m_dX = (x/norm);
psVect->m_dY = (y/norm);
psVect->m_dZ = (z/norm);
}
}
//######################################################################################################################
static void stMatrixCalculate(const A3DVector3dData* psX, const A3DVector3dData* psY, const A3DVector3dData* psZ,
double m[16])
{
m[0] = psX->m_dX;
m[1] = psX->m_dY;
m[2] = psX->m_dZ;
m[3] = 0.0;
m[4] = psY->m_dX;
m[5] = psY->m_dY;
m[6] = psY->m_dZ;
m[7] = 0.0;
m[8] = psZ->m_dX;
m[9] = psZ->m_dY;
m[10] = psZ->m_dZ;
m[11] = 0.0;
m[12] = 0.0;
m[13] = 0.0;
m[14] = 0.0;
m[15] = 1.0;
}
//######################################################################################################################
void stGetFaceViewMatrix(const A3DVector3dData* psP0, const A3DVector3dData* psP1, const A3DVector3dData* psP2,
double m[16])
{
A3DVector3dData sVectX;
sVectX.m_dX = psP1->m_dX - psP0->m_dX;
sVectX.m_dY = psP1->m_dY - psP0->m_dY;
sVectX.m_dZ = psP1->m_dZ - psP0->m_dZ;
A3DVector3dData sVectY;
sVectY.m_dX = psP2->m_dX - psP0->m_dX;
sVectY.m_dY = psP2->m_dY - psP0->m_dY;
sVectY.m_dZ = psP2->m_dZ - psP0->m_dZ;
A3DVector3dData sNormalPlane;
sNormalPlane.m_dX = sVectX.m_dY * sVectY.m_dZ - sVectX.m_dZ * sVectY.m_dY;
sNormalPlane.m_dY = -(sVectX.m_dX * sVectY.m_dZ - sVectX.m_dZ * sVectY.m_dX);
sNormalPlane.m_dZ = sVectX.m_dX * sVectY.m_dY - sVectX.m_dY * sVectY.m_dX;
stUnitVector(&sVectX);
stUnitVector(&sVectY);
stUnitVector(&sNormalPlane);
stMatrixCalculate(&sVectX, &sVectY, &sNormalPlane, m);
}
//######################################################################################################################
static A3DStatus stCreateAndPushCascadedAttributes(const A3DRootBaseWithGraphics* pBase,
const A3DMiscCascadedAttributes* pFatherAttr,
A3DMiscCascadedAttributes** ppAttr,
A3DMiscCascadedAttributesData* psAttrData)
{
A3DStatus iRet = A3D_SUCCESS;
CHECK_RET(A3DMiscCascadedAttributesCreate(ppAttr));
CHECK_RET(A3DMiscCascadedAttributesPush(*ppAttr,pBase, pFatherAttr));
A3D_INITIALIZE_DATA(A3DMiscCascadedAttributesData, (*psAttrData));
CHECK_RET(A3DMiscCascadedAttributesGet(*ppAttr, psAttrData));
return iRet;
}
//######################################################################################################################
static A3DStatus stCreateAndPushCascadedAttributesFace(const A3DRiRepresentationItem* pRepItem,
const A3DTessBase* pTessBase,
const A3DTessFaceData* psTessFaceData,
A3DUns32 uiFaceIndex,
const A3DMiscCascadedAttributes* pFatherAttr,
A3DMiscCascadedAttributes** ppAttr,
A3DMiscCascadedAttributesData* psAttrData)
{
A3DStatus iRet = A3D_SUCCESS;
CHECK_RET(A3DMiscCascadedAttributesCreate(ppAttr));
CHECK_RET(A3DMiscCascadedAttributesPushTessFace(*ppAttr, pRepItem, pTessBase, psTessFaceData, uiFaceIndex,
pFatherAttr));
A3D_INITIALIZE_DATA(A3DMiscCascadedAttributesData, (*psAttrData));
CHECK_RET(A3DMiscCascadedAttributesGet(*ppAttr, psAttrData));
return iRet;
}
//######################################################################################################################
static A3DStatus stCreateAndPushCascadedAttributesDrwEntity(const A3DDrawingBlock* pBlock,
A3DUns32 uiEntityIndex,
const A3DMiscCascadedAttributes* pFatherAttr,
A3DMiscCascadedAttributes** ppAttr,
A3DMiscCascadedAttributesData* psAttrData)
{
A3DStatus iRet = A3D_SUCCESS;
CHECK_RET(A3DMiscCascadedAttributesCreate(ppAttr));
CHECK_RET(A3DDrawingBlockPushMiscCascadedAttributes(*ppAttr, pBlock, uiEntityIndex, pFatherAttr) );
A3D_INITIALIZE_DATA(A3DMiscCascadedAttributesData, (*psAttrData));
CHECK_RET(A3DMiscCascadedAttributesGet(*ppAttr, psAttrData));
return iRet;
}
//######################################################################################################################
static A3DStatus stDrawTransformation(const A3DMiscTransformation* pTransfo3d)
{
if(pTransfo3d == NULL)
return A3D_SUCCESS;
A3DStatus iRet = A3D_SUCCESS;
A3DEEntityType eType = kA3DTypeUnknown;
A3DEntityGetType(pTransfo3d, &eType);
switch(eType)
{
case kA3DTypeMiscCartesianTransformation :
{
A3DMiscCartesianTransformationData sData;
A3D_INITIALIZE_DATA(A3DMiscCartesianTransformationData, sData);
CHECK_RET(A3DMiscCartesianTransformationGet(pTransfo3d, &sData));
double adMatrix[16];
double dMirror=(sData.m_ucBehaviour & kA3DTransformationMirror) ? -1.: 1.;
A3DVector3dData sZVector;
memset(adMatrix,0,16*sizeof(double));
stVectoriel(&sData.m_sXVector, &sData.m_sYVector, &sZVector);
adMatrix[12]=sData.m_sOrigin.m_dX;
adMatrix[13]=sData.m_sOrigin.m_dY;
adMatrix[14]=sData.m_sOrigin.m_dZ;
adMatrix[0]=sData.m_sXVector.m_dX*sData.m_sScale.m_dX;
adMatrix[1]=sData.m_sXVector.m_dY*sData.m_sScale.m_dX;
adMatrix[2]=sData.m_sXVector.m_dZ*sData.m_sScale.m_dX;
adMatrix[4]=sData.m_sYVector.m_dX*sData.m_sScale.m_dY;
adMatrix[5]=sData.m_sYVector.m_dY*sData.m_sScale.m_dY;
adMatrix[6]=sData.m_sYVector.m_dZ*sData.m_sScale.m_dY;
adMatrix[8]=dMirror*sZVector.m_dX*sData.m_sScale.m_dZ;
adMatrix[9]=dMirror*sZVector.m_dY*sData.m_sScale.m_dZ;
adMatrix[10]=dMirror*sZVector.m_dZ*sData.m_sScale.m_dZ;
adMatrix[15]=1.;
A3D_DRAW_CALL1(MultMatrix, adMatrix);
stMultMatrix(adMatrix);
CHECK_RET(A3DMiscCartesianTransformationGet(NULL, &sData));
}
break;
case kA3DTypeMiscGeneralTransformation :
{
A3DMiscGeneralTransformationData sData;
A3D_INITIALIZE_DATA(A3DMiscGeneralTransformationData, sData);
CHECK_RET(A3DMiscGeneralTransformationGet(pTransfo3d, &sData));
A3D_DRAW_CALL1(MultMatrix, sData.m_adCoeff);
stMultMatrix(sData.m_adCoeff);
CHECK_RET(A3DMiscGeneralTransformationGet(NULL, &sData));
}
break;
default:
break;
}
return iRet;
}
//######################################################################################################################
static A3DStatus stDrawBoundingBox(const A3DBoundingBoxData* /*pData*/)
{
return A3D_SUCCESS;
}
//######################################################################################################################
static A3DUns32 stTessFaceDataGetNumberOfFacets(const A3DTessFaceData* psTessFaceData)
{
A3DUns32 iNbFacet=0;
A3DUns32 iNumberIndex=0;
A3DUns32 iNbEntities=0;
A3DUns32 iStartId;
A3DUns32 iId;
#define SIZE_TRIANGLE_ENTITY(index) ((index < psTessFaceData->m_uiSizesTriangulatedSize ? \
psTessFaceData->m_puiSizesTriangulated[index] & kA3DTessFaceDataNormalMask : 0))
if(psTessFaceData->m_usUsedEntitiesFlags & kA3DTessFaceDataTriangle)
{
iNbFacet+=SIZE_TRIANGLE_ENTITY(iNumberIndex);
iNumberIndex++;
}
if(psTessFaceData->m_usUsedEntitiesFlags & kA3DTessFaceDataTriangleFan)
{
iNbEntities = SIZE_TRIANGLE_ENTITY(iNumberIndex);
iStartId = iNumberIndex+1;
for(iId=0;iId<iNbEntities;iId++)
iNbFacet+=SIZE_TRIANGLE_ENTITY((iStartId+iId))-2;
iNumberIndex+=iNbEntities+1;
}
if(psTessFaceData->m_usUsedEntitiesFlags & kA3DTessFaceDataTriangleStripe)
{
iNbEntities = SIZE_TRIANGLE_ENTITY(iNumberIndex);
iStartId = iNumberIndex+1;
for(iId=0;iId<iNbEntities;iId++)
iNbFacet+=SIZE_TRIANGLE_ENTITY((iStartId+iId))-2;
iNumberIndex+=iNbEntities+1;
}
if(psTessFaceData->m_usUsedEntitiesFlags & kA3DTessFaceDataTriangleOneNormal)
{
iNbFacet+=SIZE_TRIANGLE_ENTITY(iNumberIndex);
iNumberIndex++;
}
if(psTessFaceData->m_usUsedEntitiesFlags & kA3DTessFaceDataTriangleFanOneNormal)
{
iNbEntities = SIZE_TRIANGLE_ENTITY(iNumberIndex);
iStartId = iNumberIndex+1;
for(iId=0;iId<iNbEntities;iId++)
iNbFacet+=SIZE_TRIANGLE_ENTITY((iStartId+iId))-2;
iNumberIndex+=iNbEntities+1;
}
if(psTessFaceData->m_usUsedEntitiesFlags & kA3DTessFaceDataTriangleStripeOneNormal)
{
iNbEntities = SIZE_TRIANGLE_ENTITY(iNumberIndex);
iStartId = iNumberIndex+1;
for(iId=0;iId<iNbEntities;iId++)
{
iNbFacet+=SIZE_TRIANGLE_ENTITY((iStartId+iId))-2;
}
}
if(psTessFaceData->m_usUsedEntitiesFlags & kA3DTessFaceDataTriangleTextured)
{
iNbFacet+=SIZE_TRIANGLE_ENTITY(iNumberIndex);
iNumberIndex++;
}
if(psTessFaceData->m_usUsedEntitiesFlags & kA3DTessFaceDataTriangleFanTextured)
{
iNbEntities = SIZE_TRIANGLE_ENTITY(iNumberIndex);
iStartId = iNumberIndex+1;
for(iId=0;iId<iNbEntities;iId++)
iNbFacet+=SIZE_TRIANGLE_ENTITY((iStartId+iId))-2;
iNumberIndex+=iNbEntities+1;
}
if(psTessFaceData->m_usUsedEntitiesFlags & kA3DTessFaceDataTriangleStripeTextured)
{
iNbEntities = SIZE_TRIANGLE_ENTITY(iNumberIndex);
iStartId = iNumberIndex+1;
for(iId=0;iId<iNbEntities;iId++)
iNbFacet+=SIZE_TRIANGLE_ENTITY((iStartId+iId))-2;
iNumberIndex+=iNbEntities+1;
}
if(psTessFaceData->m_usUsedEntitiesFlags & kA3DTessFaceDataTriangleOneNormalTextured)
{
iNbFacet+=SIZE_TRIANGLE_ENTITY(iNumberIndex);
iNumberIndex++;
}
if(psTessFaceData->m_usUsedEntitiesFlags & kA3DTessFaceDataTriangleFanOneNormalTextured)
{
iNbEntities = SIZE_TRIANGLE_ENTITY(iNumberIndex);
iStartId = iNumberIndex+1;
for(iId=0;iId<iNbEntities;iId++)
iNbFacet+=SIZE_TRIANGLE_ENTITY((iStartId+iId))-2;
iNumberIndex+=iNbEntities+1;
}
if(psTessFaceData->m_usUsedEntitiesFlags & kA3DTessFaceDataTriangleStripeOneNormalTextured)
{
iNbEntities = SIZE_TRIANGLE_ENTITY(iNumberIndex);
iStartId = iNumberIndex+1;
for(iId=0;iId<iNbEntities;iId++)
{
iNbFacet+=SIZE_TRIANGLE_ENTITY((iStartId+iId))-2;
}
}
#undef SIZE_TRIANGLE_ENTITY
return iNbFacet;
}
//######################################################################################################################
static A3DUns32 stTess3DDataGetNumberOfFacets(const A3DTess3DData* psTess3DData)
{
A3DUns32 ui;
A3DUns32 uiNbFacets = 0;
for(ui = 0; ui < psTess3DData->m_uiFaceTessSize; ui++)
{
uiNbFacets += stTessFaceDataGetNumberOfFacets(&psTess3DData->m_psFaceTessData[ui]);
}
return uiNbFacets;
}
//######################################################################################################################
static A3DStatus stIsShow(const A3DRootBaseWithGraphics* pGraphics)
{
if(pGraphics == NULL)
return A3D_ERROR;
A3DStatus iRet = A3D_SUCCESS;
A3DRootBaseWithGraphicsData sRootData;
A3D_INITIALIZE_DATA(A3DRootBaseWithGraphicsData, sRootData);
CHECK_RET(A3DRootBaseWithGraphicsGet(pGraphics, &sRootData));
A3DGraphicsData sGraphicsData;
A3D_INITIALIZE_DATA(A3DGraphicsData, sGraphicsData);
CHECK_RET(A3DGraphicsGet(sRootData.m_pGraphics, &sGraphicsData));
A3DBool bShow;
if(sRootData.m_pGraphics)
bShow = (sGraphicsData.m_usBehaviour & kA3DGraphicsShow) != 0;
else
bShow = true;
CHECK_RET(A3DGraphicsGet(NULL, &sGraphicsData));
CHECK_RET(A3DRootBaseWithGraphicsGet(NULL, &sRootData));
if(bShow)
return A3D_SUCCESS;
else
return A3D_ERROR;
}
//######################################################################################################################
static A3DStatus stDrawStyle(const A3DGraphStyleData* psStyleData, A3DInt32* piUVCoordinatesIndex,
A3DUns8* pucTextureDimension,
bool* pbPush = NULL,
bool *pbPushLineStipple = NULL,
bool *pbPushLineWidth = NULL)
{
if(psStyleData == NULL)
return A3D_ERROR;
A3DStatus iRet = A3D_SUCCESS;
if(pbPush != NULL)
{
*pbPush = false;
}
if(psStyleData->m_bMaterial)
{
A3DBool bMaterialIsTexture = false;
A3DDouble adColor[4] = { 0.0, 0.0, 0.0, 1.0 };
/* check if this material is a texture */
CHECK_RET(A3DGlobalIsMaterialTexture(psStyleData->m_uiRgbColorIndex,&bMaterialIsTexture));
if(bMaterialIsTexture)
{
A3DGraphTextureApplicationData sTextureAppplicationData;
A3D_INITIALIZE_DATA(A3DGraphTextureApplicationData, sTextureAppplicationData);
CHECK_RET(A3DGlobalGetGraphTextureApplicationData(psStyleData->m_uiRgbColorIndex,
&sTextureAppplicationData));
*piUVCoordinatesIndex = sTextureAppplicationData.m_iUVCoordinatesIndex;
A3DGraphTextureDefinitionData sTextureDefinitionData;
A3D_INITIALIZE_DATA(A3DGraphTextureDefinitionData, sTextureDefinitionData);
CHECK_RET(A3DGlobalGetGraphTextureDefinitionData(sTextureAppplicationData.m_uiTextureDefinitionIndex,
&sTextureDefinitionData));
*pucTextureDimension = sTextureDefinitionData.m_ucTextureDimension;
adColor[0] = sTextureDefinitionData.m_dRed;
adColor[1] = sTextureDefinitionData.m_dGreen;
adColor[2] = sTextureDefinitionData.m_dBlue;
adColor[3] = sTextureDefinitionData.m_dAlpha;
if(pbPush != NULL)
{
A3D_DRAW_CALL0(BeginMaterial);
*pbPush = true;
}
A3D_DRAW_CALL3(Material, kA3DDrawMaterialDiffuse, adColor, 4);
CHECK_RET(A3DGlobalGetGraphTextureDefinitionData(A3D_DEFAULT_TEXTURE_DEFINITION_INDEX,
&sTextureDefinitionData));
CHECK_RET(A3DGlobalGetGraphTextureApplicationData(A3D_DEFAULT_MATERIAL_INDEX, &sTextureAppplicationData));
}
else
{
if(pbPush != NULL)
{
A3D_DRAW_CALL0(BeginMaterial);
*pbPush = true;
}
A3DGraphMaterialData sMaterialData;
A3D_INITIALIZE_DATA(A3DGraphMaterialData, sMaterialData);
CHECK_RET(A3DGlobalGetGraphMaterialData(psStyleData->m_uiRgbColorIndex,&sMaterialData));
A3DGraphRgbColorData sRgbColorData;
A3D_INITIALIZE_DATA(A3DGraphRgbColorData, sRgbColorData);
CHECK_RET(A3DGlobalGetGraphRgbColorData(sMaterialData.m_uiDiffuse, &sRgbColorData));
adColor[0] = sRgbColorData.m_dRed;
adColor[1] = sRgbColorData.m_dGreen;
adColor[2] = sRgbColorData.m_dBlue;
adColor[3] = sMaterialData.m_dDiffuseAlpha;
A3D_DRAW_CALL3(Material, kA3DDrawMaterialDiffuse, adColor, 4);
CHECK_RET(A3DGlobalGetGraphRgbColorData(A3D_DEFAULT_COLOR_INDEX, &sRgbColorData));
CHECK_RET(A3DGlobalGetGraphRgbColorData(sMaterialData.m_uiAmbient, &sRgbColorData));
adColor[0] = sRgbColorData.m_dRed;
adColor[1] = sRgbColorData.m_dGreen;
adColor[2] = sRgbColorData.m_dBlue;
adColor[3] = sMaterialData.m_dAmbientAlpha;
A3D_DRAW_CALL3(Material, kA3DDrawMaterialAmbient, adColor, 4);
CHECK_RET(A3DGlobalGetGraphRgbColorData(A3D_DEFAULT_COLOR_INDEX, &sRgbColorData));
CHECK_RET(A3DGlobalGetGraphRgbColorData(sMaterialData.m_uiEmissive, &sRgbColorData));
adColor[0] = sRgbColorData.m_dRed;
adColor[1] = sRgbColorData.m_dGreen;
adColor[2] = sRgbColorData.m_dBlue;
adColor[3] = sMaterialData.m_dEmissiveAlpha;
A3D_DRAW_CALL3(Material, kA3DDrawMaterialEmission, adColor, 4);
CHECK_RET(A3DGlobalGetGraphRgbColorData(A3D_DEFAULT_COLOR_INDEX, &sRgbColorData));
CHECK_RET(A3DGlobalGetGraphRgbColorData(sMaterialData.m_uiSpecular, &sRgbColorData));
adColor[0] = sRgbColorData.m_dRed;
adColor[1] = sRgbColorData.m_dGreen;
adColor[2] = sRgbColorData.m_dBlue;
adColor[3] = sMaterialData.m_dSpecularAlpha;
A3D_DRAW_CALL3(Material, kA3DDrawMaterialSpecular, adColor, 4);
CHECK_RET(A3DGlobalGetGraphRgbColorData(A3D_DEFAULT_COLOR_INDEX, &sRgbColorData));
A3DDouble adShininess[1] = { sMaterialData.m_dShininess };
A3D_DRAW_CALL3(Material, kA3DDrawMaterialShininess, adShininess, 1);
CHECK_RET(A3DGlobalGetGraphMaterialData(A3D_DEFAULT_MATERIAL_INDEX, &sMaterialData));
}
}
else
{
if(psStyleData->m_uiRgbColorIndex != A3D_DEFAULT_COLOR_INDEX)
{
if(pbPush != NULL)
{
A3D_DRAW_CALL0(BeginMaterial);
*pbPush = true;
}
A3DGraphRgbColorData sRgbColorData;
A3D_INITIALIZE_DATA(A3DGraphRgbColorData, sRgbColorData);
CHECK_RET(A3DGlobalGetGraphRgbColorData(psStyleData->m_uiRgbColorIndex,&sRgbColorData));
A3DDouble adColor[3] = { sRgbColorData.m_dRed, sRgbColorData.m_dGreen, sRgbColorData.m_dBlue };
A3D_DRAW_CALL3(Material, kA3DDrawMaterialDiffuse, adColor, 3);
A3D_DRAW_CALL1(Color, adColor);
CHECK_RET(A3DGlobalGetGraphRgbColorData(A3D_DEFAULT_COLOR_INDEX, &sRgbColorData));
}
}
if (pbPushLineWidth != NULL)
{
if (psStyleData->m_dWidth!=0.)
{
*pbPushLineWidth = true;
A3D_DRAW_CALL1(BeginLineWidth, psStyleData->m_dWidth);
}
else
*pbPushLineWidth = false;
}
if (pbPushLineStipple!=NULL)
{
if (psStyleData->m_uiLinePatternIndex != A3D_DEFAULT_LINEPATTERN_INDEX)
{
*pbPushLineStipple = true;
A3D_DRAW_CALL1(BeginLineStipple, psStyleData);
}
else
*pbPushLineStipple = false;
}
return iRet;
}
//######################################################################################################################
static A3DUTF8Char* stpcRepresentationItemName = NULL;
//######################################################################################################################
static A3DStatus stDrawTess3DWire(const A3DTess3DWire* pTess3DWire, const A3DRiRepresentationItem* /*pRepItem*/,
const A3DMiscCascadedAttributes* pFatherAttr)
{
A3DStatus iRet = A3D_SUCCESS;
A3DTessBaseData sTessBaseData;
A3D_INITIALIZE_DATA(A3DTessBaseData, sTessBaseData);
CHECK_RET(A3DTessBaseGet(pTess3DWire,&sTessBaseData));
A3DMiscCascadedAttributesData sAttrData;
A3D_INITIALIZE_DATA(A3DMiscCascadedAttributesData, sAttrData);
CHECK_RET(A3DMiscCascadedAttributesGet(pFatherAttr, &sAttrData));
// computing the box if we're not using the callbacks (A3DDrawModelFileGetBoundingBox)
double adMatrix[16];
stGetMatrix(adMatrix);
A3DDouble dX, dY, dZ;
A3DDouble dAbsX, dAbsY, dAbsZ;
const A3DDouble* pdCoord = &sTessBaseData.m_pdCoords[0];
const A3DDouble* pdEnd = &sTessBaseData.m_pdCoords[sTessBaseData.m_uiCoordSize-1];
A3DInt32 iUVCoordinatesIndex = -1;
A3DUns8 ucTextureDimension = 2;
CHECK_RET(stDrawStyle(&sAttrData.m_sStyle, &iUVCoordinatesIndex, &ucTextureDimension));
A3DUns32 uiPointSize=sTessBaseData.m_uiCoordSize/3;
A3D_DRAW_CALL2(PolyLine, pdCoord, uiPointSize);
for(; pdCoord < pdEnd; pdCoord += 3)
{
dX = *pdCoord;
dY = *(pdCoord+1);
dZ = *(pdCoord+2);
stVectorMatrixMult(dX, dY, dZ, adMatrix, &dAbsX, &dAbsY, &dAbsZ);
stBoundingBoxAddPoint(stpsBoundingBox, dAbsX, dAbsY, dAbsZ);
}
CHECK_RET(A3DTessBaseGet(NULL, &sTessBaseData));
CHECK_RET(A3DMiscCascadedAttributesGet(NULL, &sAttrData));
return iRet;
}
//######################################################################################################################
static A3DStatus stDrawTess3D(const A3DTess3D* pTess3D, const A3DRiRepresentationItem* pRepItem,
const A3DMiscCascadedAttributes* pFatherAttr)
{
A3DEEntityType eType=kA3DTypeUnknown;
A3DStatus iRet = A3D_SUCCESS;
CHECK_RET(A3DEntityGetType(pRepItem, &eType));
bool bIsPlane = eType == kA3DTypeRiPlane;
A3DTess3DData sTess3DData;
A3D_INITIALIZE_DATA(A3DTess3DData, sTess3DData);
CHECK_RET(A3DTess3DGet(pTess3D, &sTess3DData));
A3DTessBaseData sTessBaseData;
A3D_INITIALIZE_DATA(A3DTessBaseData, sTessBaseData);
CHECK_RET(A3DTessBaseGet(pTess3D,&sTessBaseData));
A3DDouble adMinimumNormals[3];
if (sTess3DData.m_bMustRecalculateNormals)
{
sTess3DData.m_uiNormalSize = 3;
sTess3DData.m_pdNormals = adMinimumNormals;
sTess3DData.m_pdNormals[0] = 0;
sTess3DData.m_pdNormals[1] = 0;
sTess3DData.m_pdNormals[2] = 0;
}
A3DMiscCascadedAttributesData sAttrData;
A3D_INITIALIZE_DATA(A3DMiscCascadedAttributesData, sAttrData);
CHECK_RET(A3DMiscCascadedAttributesGet(pFatherAttr, &sAttrData));
//if(stpcRepresentationItemName != NULL)
{
A3DUns32 uiNbTriangles = stTess3DDataGetNumberOfFacets(&sTess3DData);
A3D_DRAW_CALL3(Begin, kA3DDrawBeginEndRepresentationItem, stpcRepresentationItemName, uiNbTriangles);
}
// stbUseCallbacks is set to false when we're asking for the box computing (A3DDrawModelFileGetBoundingBox).
// In the case where we're using Draw, it's set to true.
A3DVector3dData* pasPoints = NULL;
if(stbUseCallbacks)
stAllocVector3dArray(&pasPoints, sTessBaseData.m_uiCoordSize/3);
// computing the box if we're not using the callbacks (A3DDrawModelFileGetBoundingBox)
double adMatrix[16];
stGetMatrix(adMatrix);
A3DDouble dX, dY, dZ;
A3DDouble dAbsX, dAbsY, dAbsZ;
const A3DDouble* pdCoord = &sTessBaseData.m_pdCoords[0];
const A3DDouble* pdEnd = &sTessBaseData.m_pdCoords[sTessBaseData.m_uiCoordSize-1];
A3DVector3dData* psCurPoint = NULL;
if(stbUseCallbacks)
psCurPoint = &pasPoints[0];
if(pdCoord != NULL)
{
for(; pdCoord < pdEnd; pdCoord += 3)
{
dX = *pdCoord;
dY = *(pdCoord+1);
dZ = *(pdCoord+2);
if(stbUseCallbacks)
{
psCurPoint->m_dX = dX;
psCurPoint->m_dY = dY;
psCurPoint->m_dZ = dZ;
psCurPoint++;
}
else
{
if(!bIsPlane)
{
stVectorMatrixMult(dX, dY, dZ, adMatrix, &dAbsX, &dAbsY, &dAbsZ);
stBoundingBoxAddPoint(stpsBoundingBox, dAbsX, dAbsY, dAbsZ);
}
}
}
}
if(!stbUseCallbacks)
{
if (sTess3DData.m_bMustRecalculateNormals)
sTess3DData.m_pdNormals=NULL;
CHECK_RET(A3DTess3DGet(NULL, &sTess3DData));
CHECK_RET(A3DTessBaseGet(NULL, &sTessBaseData));
// it's OK because we have allocating pasPoints in the case where stbUseCallbacks == true
return iRet;
}
A3D_DRAW_CALL2(SetTessellationPoints, pasPoints, sTessBaseData.m_uiCoordSize/3);
if(stbUseCallbacks)
free(pasPoints);
#ifdef A3D_DRAW_WITH_INDICES
// getting the normals for the callbacks
if(stbUseCallbacks)
{
A3DVector3dData* pasNormals = NULL;
stAllocVector3dArray(&pasNormals, sTess3DData.m_uiNormalSize/3);
const A3DDouble* pdNormal = &sTess3DData.m_pdNormals[0];
const A3DDouble* pdEnd = &sTess3DData.m_pdNormals[sTess3DData.m_uiNormalSize-1];
A3DVector3dData* psCurNormal = &pasNormals[0];
for(; pdNormal < pdEnd; pdNormal += 3)
{
psCurNormal->m_dX = *pdNormal;
psCurNormal->m_dY = *(pdNormal+1);
psCurNormal->m_dZ = *(pdNormal+2);
psCurNormal++;
}
A3D_DRAW_CALL2(SetTessellationNormals, pasNormals, sTess3DData.m_uiNormalSize/3);
A3DMiscFree(pasNormals);
}
#endif
A3DUns32 uiNumberOfFaces = sTess3DData.m_uiFaceTessSize;
A3DUns32 ui;
for(ui = 0; ui < uiNumberOfFaces; ui++)
{
A3DTessFaceData& sTessFaceData = sTess3DData.m_psFaceTessData[ui];
A3DMiscCascadedAttributes* pAttr;
A3D_INITIALIZE_DATA(A3DMiscCascadedAttributesData, sAttrData);
CHECK_RET(stCreateAndPushCascadedAttributesFace(pRepItem, pTess3D, &sTessFaceData, ui, pFatherAttr, &pAttr,
&sAttrData));
/* is there only one color/material for the face or for each triangle? */
/* is there a texture ? */
//A3DBool bOneColorForFace = sTessFaceData.m_uiStyleIndexesSize == 1;
A3DInt32 iUVCoordinatesIndex = -1;
A3DUns8 ucTextureDimension = 2;
CHECK_RET(stDrawStyle(&sAttrData.m_sStyle, &iUVCoordinatesIndex, &ucTextureDimension));
//if(bOneColorForFace)
//{
//A3DGraphStyleData sLineStyleData;
//A3D_INITIALIZE_DATA(sLineStyleData);
//CHECK_RET(A3DGlobalLineStyleGet(sTessFaceData.m_puiStyleIndexes[0],&sLineStyleData))
//CHECK_RET(stDrawStyle(&sLineStyleData, &iUVCoordinatesIndex, &ucTextureDimension));
//CHECK_RET(A3DGlobalLineStyleGet(NULL, &sLineStyleData));
//A3DGlobalLineStyleGet(A3D_DEFAULT_LINESTYLE_INDEX,&sLineStyleData);
//}
if(sTessFaceData.m_uiSizesTriangulatedSize)
{
A3DUns32 uiCurrentSize = 0;
A3DUns32* puiTriangulatedIndexes = sTess3DData.m_puiTriangulatedIndexes +
sTessFaceData.m_uiStartTriangulated;
if(sTessFaceData.m_usUsedEntitiesFlags & kA3DTessFaceDataTriangle)
{
/* number of triangles for this face */
A3DUns32 uiNbTriangles = sTessFaceData.m_puiSizesTriangulated[uiCurrentSize++];
A3DUns32 uiTri, uiId;
//uiTotalTriangles += uiNbTriangles;
A3DVector3dData* pasGNormals;
A3DVector3dData* pasGPoints;
stAllocNormalsAndPoints(&pasGNormals, uiNbTriangles*3, &pasGPoints, uiNbTriangles*3);
#ifdef A3D_DRAW_WITH_INDICES
A3DUns32* pauiNormals = (A3DUns32*)A3DMiscAlloc(uiNbTriangles*3 * sizeof(A3DUns32));
A3DUns32* pauiPoints = (A3DUns32*)A3DMiscAlloc(uiNbTriangles*3 * sizeof(A3DUns32));
#endif
for(uiTri = 0; uiTri < uiNbTriangles; uiTri++)
{
/* Point and normal #1 */
uiId = *puiTriangulatedIndexes++; /* normal index */
if (!sTess3DData.m_bMustRecalculateNormals)
{
pasGNormals[uiTri*3].m_dX = sTess3DData.m_pdNormals[uiId]; /* x */
pasGNormals[uiTri*3].m_dY = sTess3DData.m_pdNormals[uiId+1]; /* y */
pasGNormals[uiTri*3].m_dZ = sTess3DData.m_pdNormals[uiId+2]; /* z */
}
#ifdef A3D_DRAW_WITH_INDICES
pauiNormals[uiTri*3] = uiId/3;
#endif
uiId = *puiTriangulatedIndexes++; /* point index */
pasGPoints[uiTri*3].m_dX = sTessBaseData.m_pdCoords[uiId]; /* x */
pasGPoints[uiTri*3].m_dY = sTessBaseData.m_pdCoords[uiId+1]; /* y */
pasGPoints[uiTri*3].m_dZ = sTessBaseData.m_pdCoords[uiId+2]; /* z */
#ifdef A3D_DRAW_WITH_INDICES
pauiPoints[uiTri*3] = uiId/3;
#endif
/* Point and normal #2 */
uiId = *puiTriangulatedIndexes++; /* normal index */
if (!sTess3DData.m_bMustRecalculateNormals)
{
pasGNormals[uiTri*3+1].m_dX = sTess3DData.m_pdNormals[uiId]; /* x */
pasGNormals[uiTri*3+1].m_dY = sTess3DData.m_pdNormals[uiId+1]; /* y */
pasGNormals[uiTri*3+1].m_dZ = sTess3DData.m_pdNormals[uiId+2]; /* z */
}
#ifdef A3D_DRAW_WITH_INDICES
pauiNormals[uiTri*3+1] = uiId/3;
#endif
uiId = *puiTriangulatedIndexes++; /* point index */
pasGPoints[uiTri*3+1].m_dX = sTessBaseData.m_pdCoords[uiId]; /* x */
pasGPoints[uiTri*3+1].m_dY = sTessBaseData.m_pdCoords[uiId+1]; /* y */
pasGPoints[uiTri*3+1].m_dZ = sTessBaseData.m_pdCoords[uiId+2]; /* z */
#ifdef A3D_DRAW_WITH_INDICES
pauiPoints[uiTri*3+1] = uiId/3;
#endif
/* Point and normal #3 */
uiId = *puiTriangulatedIndexes++; /* normal index */
if (!sTess3DData.m_bMustRecalculateNormals)
{
pasGNormals[uiTri*3+2].m_dX = sTess3DData.m_pdNormals[uiId]; /* x */
pasGNormals[uiTri*3+2].m_dY = sTess3DData.m_pdNormals[uiId+1]; /* y */
pasGNormals[uiTri*3+2].m_dZ = sTess3DData.m_pdNormals[uiId+2]; /* z */
}
#ifdef A3D_DRAW_WITH_INDICES
pauiNormals[uiTri*3+2] = uiId/3;
#endif
uiId = *puiTriangulatedIndexes++; /* point index */
pasGPoints[uiTri*3+2].m_dX = sTessBaseData.m_pdCoords[uiId]; /* x */
pasGPoints[uiTri*3+2].m_dY = sTessBaseData.m_pdCoords[uiId+1]; /* y */
pasGPoints[uiTri*3+2].m_dZ = sTessBaseData.m_pdCoords[uiId+2]; /* z */
#ifdef A3D_DRAW_WITH_INDICES
pauiPoints[uiTri*3+2] = uiId/3;
#endif
}
A3D_DRAW_CALL3(Triangle, pasGNormals, pasGPoints, uiNbTriangles*3);
stFreeNormalsAndPoints(&pasGNormals, &pasGPoints);
#ifdef A3D_DRAW_WITH_INDICES
A3D_DRAW_CALL3(TriangleWithIndices, pauiNormals, pauiPoints, uiNbTriangles*3);
A3DMiscFree(pauiNormals);
A3DMiscFree(pauiPoints);
#endif
}
if(sTessFaceData.m_usUsedEntitiesFlags & kA3DTessFaceDataTriangleFan)
{
A3DUns32 uiNbFan = sTessFaceData.m_puiSizesTriangulated[uiCurrentSize++];
A3DUns32 uiFan, uiPoint;
for(uiFan = 0; uiFan < uiNbFan; uiFan++)
{
A3DUns32 uiNumberOfPointsForThisFan = sTessFaceData.m_puiSizesTriangulated[uiCurrentSize++];
//if(uiNumberOfPointsForThisFan > 2)
// uiTotalTriangles += (uiNumberOfPointsForThisFan - 2);
A3DVector3dData* pasGNormals;
A3DVector3dData* pasGPoints;
stAllocNormalsAndPoints(&pasGNormals, uiNumberOfPointsForThisFan, &pasGPoints,
uiNumberOfPointsForThisFan);
#ifdef A3D_DRAW_WITH_INDICES
A3DUns32* pauiNormals = (A3DUns32*)A3DMiscAlloc(uiNumberOfPointsForThisFan * sizeof(A3DUns32));
A3DUns32* pauiPoints = (A3DUns32*)A3DMiscAlloc(uiNumberOfPointsForThisFan * sizeof(A3DUns32));
#endif
A3DDouble* pdNormal = NULL;
A3DDouble* pdPoint = NULL;
for(uiPoint = 0; uiPoint < uiNumberOfPointsForThisFan; uiPoint++)
{
#ifdef A3D_DRAW_WITH_INDICES
pauiNormals[uiPoint] = (*puiTriangulatedIndexes)/3;
#endif
pdNormal = &sTess3DData.m_pdNormals[*puiTriangulatedIndexes++];
if (!sTess3DData.m_bMustRecalculateNormals)
{
pasGNormals[uiPoint].m_dX = pdNormal[0];
pasGNormals[uiPoint].m_dY = pdNormal[1];
pasGNormals[uiPoint].m_dZ = pdNormal[2];
}
#ifdef A3D_DRAW_WITH_INDICES
pauiPoints[uiPoint] = (*puiTriangulatedIndexes)/3;
#endif
pdPoint = &sTessBaseData.m_pdCoords[*puiTriangulatedIndexes++];
pasGPoints[uiPoint].m_dX = pdPoint[0];
pasGPoints[uiPoint].m_dY = pdPoint[1];
pasGPoints[uiPoint].m_dZ = pdPoint[2];
}
A3D_DRAW_CALL3(TriangleFan, pasGNormals, pasGPoints, uiNumberOfPointsForThisFan);
stFreeNormalsAndPoints(&pasGNormals, &pasGPoints);
#ifdef A3D_DRAW_WITH_INDICES
A3D_DRAW_CALL3(TriangleFanWithIndices, pauiNormals, pauiPoints, uiNumberOfPointsForThisFan);
A3DMiscFree(pauiNormals);
A3DMiscFree(pauiPoints);
#endif
}
}
if(sTessFaceData.m_usUsedEntitiesFlags & kA3DTessFaceDataTriangleStripe)
{
A3DUns32 uiNbStripe = sTessFaceData.m_puiSizesTriangulated[uiCurrentSize++];
A3DUns32 uiStripe, uiPoint;
for(uiStripe = 0; uiStripe < uiNbStripe; uiStripe++)
{
A3DUns32 uiNumberOfPointsForThisStripe = sTessFaceData.m_puiSizesTriangulated[uiCurrentSize++];
//if(uiNumberOfPointsForThisStripe > 2)
// uiTotalTriangles += (uiNumberOfPointsForThisStripe - 2);
A3DVector3dData* pasGNormals;
A3DVector3dData* pasGPoints;
stAllocNormalsAndPoints(&pasGNormals, uiNumberOfPointsForThisStripe, &pasGPoints,
uiNumberOfPointsForThisStripe);
#ifdef A3D_DRAW_WITH_INDICES
A3DUns32* pauiNormals = (A3DUns32*)A3DMiscAlloc(uiNumberOfPointsForThisStripe * sizeof(A3DUns32));
A3DUns32* pauiPoints = (A3DUns32*)A3DMiscAlloc(uiNumberOfPointsForThisStripe * sizeof(A3DUns32));
#endif
A3DDouble* pdNormal = NULL;
A3DDouble* pdPoint = NULL;
for(uiPoint = 0; uiPoint < uiNumberOfPointsForThisStripe; uiPoint++)
{
#ifdef A3D_DRAW_WITH_INDICES
pauiNormals[uiPoint] = (*puiTriangulatedIndexes)/3;
#endif
pdNormal = &sTess3DData.m_pdNormals[*puiTriangulatedIndexes++];
if (!sTess3DData.m_bMustRecalculateNormals)
{
pasGNormals[uiPoint].m_dX = pdNormal[0];
pasGNormals[uiPoint].m_dY = pdNormal[1];
pasGNormals[uiPoint].m_dZ = pdNormal[2];
}
#ifdef A3D_DRAW_WITH_INDICES
pauiPoints[uiPoint] = (*puiTriangulatedIndexes)/3;
#endif
pdPoint = &sTessBaseData.m_pdCoords[*puiTriangulatedIndexes++];
pasGPoints[uiPoint].m_dX = pdPoint[0];
pasGPoints[uiPoint].m_dY = pdPoint[1];
pasGPoints[uiPoint].m_dZ = pdPoint[2];
}
A3D_DRAW_CALL3(TriangleStripe, pasGNormals, pasGPoints, uiNumberOfPointsForThisStripe);
stFreeNormalsAndPoints(&pasGNormals, &pasGPoints);
#ifdef A3D_DRAW_WITH_INDICES
A3D_DRAW_CALL3(TriangleStripeWithIndices, pauiNormals, pauiPoints, uiNumberOfPointsForThisStripe);
A3DMiscFree(pauiNormals);
A3DMiscFree(pauiPoints);
#endif
}
}
if(sTessFaceData.m_usUsedEntitiesFlags & kA3DTessFaceDataTriangleOneNormal)
{
A3DUns32 uiTri, uiNbTriangles = sTessFaceData.m_puiSizesTriangulated[uiCurrentSize++];
//uiTotalTriangles += uiNbTriangles;
A3DVector3dData* pasGNormals;
A3DVector3dData* pasGPoints;
stAllocNormalsAndPoints(&pasGNormals, uiNbTriangles, &pasGPoints, uiNbTriangles*3);
#ifdef A3D_DRAW_WITH_INDICES
A3DUns32* pauiNormals = (A3DUns32*)A3DMiscAlloc(uiNbTriangles * sizeof(A3DUns32));
A3DUns32* pauiPoints = (A3DUns32*)A3DMiscAlloc(uiNbTriangles*3 * sizeof(A3DUns32));
#endif
A3DDouble* pdNormal = NULL;
A3DDouble* pdPoint = NULL;
for(uiTri = 0; uiTri < uiNbTriangles; uiTri++)
{
#ifdef A3D_DRAW_WITH_INDICES
pauiNormals[uiTri] = (*puiTriangulatedIndexes)/3;
#endif
pdNormal = &sTess3DData.m_pdNormals[*puiTriangulatedIndexes++];
if (!sTess3DData.m_bMustRecalculateNormals)
{
pasGNormals[uiTri].m_dX = pdNormal[0];
pasGNormals[uiTri].m_dY = pdNormal[1];
pasGNormals[uiTri].m_dZ = pdNormal[2];
}
#ifdef A3D_DRAW_WITH_INDICES
pauiPoints[uiTri*3] = (*puiTriangulatedIndexes)/3;
#endif
pdPoint = &sTessBaseData.m_pdCoords[*puiTriangulatedIndexes++];
pasGPoints[uiTri*3].m_dX = pdPoint[0];
pasGPoints[uiTri*3].m_dY = pdPoint[1];
pasGPoints[uiTri*3].m_dZ = pdPoint[2];
#ifdef A3D_DRAW_WITH_INDICES
pauiPoints[uiTri*3+1] = (*puiTriangulatedIndexes)/3;
#endif
pdPoint = &sTessBaseData.m_pdCoords[*puiTriangulatedIndexes++];
pasGPoints[uiTri*3+1].m_dX = pdPoint[0];
pasGPoints[uiTri*3+1].m_dY = pdPoint[1];
pasGPoints[uiTri*3+1].m_dZ = pdPoint[2];
#ifdef A3D_DRAW_WITH_INDICES
pauiPoints[uiTri*3+2] = (*puiTriangulatedIndexes)/3;
#endif
pdPoint = &sTessBaseData.m_pdCoords[*puiTriangulatedIndexes++];
pasGPoints[uiTri*3+2].m_dX = pdPoint[0];
pasGPoints[uiTri*3+2].m_dY = pdPoint[1];
pasGPoints[uiTri*3+2].m_dZ = pdPoint[2];
}
A3D_DRAW_CALL3(TriangleOneNormal, pasGNormals, pasGPoints, uiNbTriangles*3);
stFreeNormalsAndPoints(&pasGNormals, &pasGPoints);
#ifdef A3D_DRAW_WITH_INDICES
A3D_DRAW_CALL3(TriangleOneNormalWithIndices, pauiNormals, pauiPoints, uiNbTriangles*3);
A3DMiscFree(pauiNormals);
A3DMiscFree(pauiPoints);
#endif
}
if(sTessFaceData.m_usUsedEntitiesFlags & kA3DTessFaceDataTriangleFanOneNormal)
{
A3DUns32 uiNbFan = sTessFaceData.m_puiSizesTriangulated[uiCurrentSize++];
A3DUns32 uiFan, uiSize, uiPoint;
for(uiFan = 0; uiFan < uiNbFan; uiFan++)
{
uiSize = sTessFaceData.m_puiSizesTriangulated[uiCurrentSize++];
A3DUns32 uiNumberOfPointsForThisFan = (uiSize & kA3DTessFaceDataNormalMask);
//if(uiNumberOfPointsForThisFan > 2)
// uiTotalTriangles += (uiNumberOfPointsForThisFan - 2);
if(uiSize & kA3DTessFaceDataNormalSingle) /* only one normal for the entire fan */
{
A3DVector3dData* pasGNormals;
A3DVector3dData* pasGPoints;
stAllocNormalsAndPoints(&pasGNormals, 1, &pasGPoints, uiNumberOfPointsForThisFan);
#ifdef A3D_DRAW_WITH_INDICES
A3DUns32* pauiPoints = (A3DUns32*)A3DMiscAlloc(uiNumberOfPointsForThisFan * sizeof(A3DUns32));
A3DUns32 uiNormal = (*puiTriangulatedIndexes)/3;
#endif
A3DDouble* pdNormal = NULL;
A3DDouble* pdPoint = NULL;
pdNormal = &sTess3DData.m_pdNormals[*puiTriangulatedIndexes++];
if (!sTess3DData.m_bMustRecalculateNormals)
{
pasGNormals[0].m_dX = pdNormal[0];
pasGNormals[0].m_dY = pdNormal[1];
pasGNormals[0].m_dZ = pdNormal[2];
}
for(uiPoint = 0; uiPoint < uiNumberOfPointsForThisFan; uiPoint++)
{
#ifdef A3D_DRAW_WITH_INDICES
pauiPoints[uiPoint] = (*puiTriangulatedIndexes)/3;
#endif
pdPoint = &sTessBaseData.m_pdCoords[*puiTriangulatedIndexes++];
pasGPoints[uiPoint].m_dX = pdPoint[0];
pasGPoints[uiPoint].m_dY = pdPoint[1];
pasGPoints[uiPoint].m_dZ = pdPoint[2];
}
A3D_DRAW_CALL3(TriangleFanOneNormal, &pasGNormals[0], pasGPoints, uiNumberOfPointsForThisFan);
stFreeNormalsAndPoints(&pasGNormals, &pasGPoints);
#ifdef A3D_DRAW_WITH_INDICES
A3D_DRAW_CALL3(TriangleFanOneNormalWithIndices, uiNormal, pauiPoints,
uiNumberOfPointsForThisFan);
A3DMiscFree(pauiPoints);
#endif
}
else
{
A3DVector3dData* pasGNormals;
A3DVector3dData* pasGPoints;
stAllocNormalsAndPoints(&pasGNormals, uiNumberOfPointsForThisFan, &pasGPoints,
uiNumberOfPointsForThisFan);
#ifdef A3D_DRAW_WITH_INDICES
A3DUns32* pauiNormals = (A3DUns32*)A3DMiscAlloc(uiNumberOfPointsForThisFan * sizeof(A3DUns32));
A3DUns32* pauiPoints = (A3DUns32*)A3DMiscAlloc(uiNumberOfPointsForThisFan * sizeof(A3DUns32));
#endif
A3DDouble* pdNormal = NULL;
A3DDouble* pdPoint = NULL;
for(uiPoint = 0; uiPoint < uiNumberOfPointsForThisFan; uiPoint++)
{
#ifdef A3D_DRAW_WITH_INDICES
pauiNormals[uiPoint] = (*puiTriangulatedIndexes)/3;
#endif
pdNormal = &sTess3DData.m_pdNormals[*puiTriangulatedIndexes++];
if (!sTess3DData.m_bMustRecalculateNormals)
{
pasGNormals[uiPoint].m_dX = pdNormal[0];
pasGNormals[uiPoint].m_dY = pdNormal[1];
pasGNormals[uiPoint].m_dZ = pdNormal[2];
}
#ifdef A3D_DRAW_WITH_INDICES
pauiPoints[uiPoint] = (*puiTriangulatedIndexes)/3;
#endif
pdPoint = &sTessBaseData.m_pdCoords[*puiTriangulatedIndexes++];
pasGPoints[uiPoint].m_dX = pdPoint[0];
pasGPoints[uiPoint].m_dY = pdPoint[1];
pasGPoints[uiPoint].m_dZ = pdPoint[2];
}
A3D_DRAW_CALL3(TriangleFan, pasGNormals, pasGPoints, uiNumberOfPointsForThisFan);
stFreeNormalsAndPoints(&pasGNormals, &pasGPoints);
#ifdef A3D_DRAW_WITH_INDICES
A3D_DRAW_CALL3(TriangleFanWithIndices, pauiNormals, pauiPoints, uiNumberOfPointsForThisFan);
A3DMiscFree(pauiNormals);
A3DMiscFree(pauiPoints);
#endif
}
}
}
if(sTessFaceData.m_usUsedEntitiesFlags & kA3DTessFaceDataTriangleStripeOneNormal)
{
A3DUns32 uiNbStripe = sTessFaceData.m_puiSizesTriangulated[uiCurrentSize++];
A3DUns32 uiStripe, uiPoint;
for(uiStripe = 0; uiStripe < uiNbStripe; uiStripe++)
{
A3DUns32 uiSize = sTessFaceData.m_puiSizesTriangulated[uiCurrentSize++];
A3DUns32 uiNumberOfPointsForThisStripe = (uiSize & kA3DTessFaceDataNormalMask);
//if(uiNumberOfPointsForThisStripe > 2)
// uiTotalTriangles += (uiNumberOfPointsForThisStripe - 2);
if(uiSize & kA3DTessFaceDataNormalSingle) /* only one normal for the entire stripe */
{
A3DVector3dData* pasGNormals;
A3DVector3dData* pasGPoints;
stAllocNormalsAndPoints(&pasGNormals, 1, &pasGPoints, uiNumberOfPointsForThisStripe);
#ifdef A3D_DRAW_WITH_INDICES
A3DUns32* pauiPoints = (A3DUns32*)A3DMiscAlloc(uiNumberOfPointsForThisStripe *
sizeof(A3DUns32));
A3DUns32 uiNormal = (*puiTriangulatedIndexes)/3;
#endif
A3DDouble* pdNormal = NULL;
A3DDouble* pdPoint = NULL;
pdNormal = &sTess3DData.m_pdNormals[*puiTriangulatedIndexes++];
if (!sTess3DData.m_bMustRecalculateNormals)
{
pasGNormals[0].m_dX = pdNormal[0];
pasGNormals[0].m_dY = pdNormal[1];
pasGNormals[0].m_dZ = pdNormal[2];
}
for(uiPoint = 0; uiPoint < uiNumberOfPointsForThisStripe; uiPoint++)
{
#ifdef A3D_DRAW_WITH_INDICES
pauiPoints[uiPoint] = (*puiTriangulatedIndexes)/3;
#endif
pdPoint = &sTessBaseData.m_pdCoords[*puiTriangulatedIndexes++];
pasGPoints[uiPoint].m_dX = pdPoint[0];
pasGPoints[uiPoint].m_dY = pdPoint[1];
pasGPoints[uiPoint].m_dZ = pdPoint[2];
}
A3D_DRAW_CALL3(TriangleStripeOneNormal, &pasGNormals[0], pasGPoints,
uiNumberOfPointsForThisStripe);
stFreeNormalsAndPoints(&pasGNormals, &pasGPoints);
#ifdef A3D_DRAW_WITH_INDICES
A3D_DRAW_CALL3(TriangleStripeOneNormalWithIndices, uiNormal, pauiPoints,
uiNumberOfPointsForThisStripe);
A3DMiscFree(pauiPoints);
#endif
}
else
{
A3DVector3dData* pasGNormals;
A3DVector3dData* pasGPoints;
stAllocNormalsAndPoints(&pasGNormals, uiNumberOfPointsForThisStripe, &pasGPoints,
uiNumberOfPointsForThisStripe);
#ifdef A3D_DRAW_WITH_INDICES
A3DUns32* pauiNormals = (A3DUns32*)A3DMiscAlloc(uiNumberOfPointsForThisStripe *
sizeof(A3DUns32));
A3DUns32* pauiPoints = (A3DUns32*)A3DMiscAlloc(uiNumberOfPointsForThisStripe *
sizeof(A3DUns32));
#endif
A3DDouble* pdNormal = NULL;
A3DDouble* pdPoint = NULL;
for(uiPoint = 0; uiPoint < uiNumberOfPointsForThisStripe; uiPoint++)
{
#ifdef A3D_DRAW_WITH_INDICES
pauiNormals[uiPoint] = (*puiTriangulatedIndexes)/3;
#endif
pdNormal = &sTess3DData.m_pdNormals[*puiTriangulatedIndexes++];
if (!sTess3DData.m_bMustRecalculateNormals)
{
pasGNormals[uiPoint].m_dX = pdNormal[0];
pasGNormals[uiPoint].m_dY = pdNormal[1];
pasGNormals[uiPoint].m_dZ = pdNormal[2];
}
#ifdef A3D_DRAW_WITH_INDICES
pauiPoints[uiPoint] = (*puiTriangulatedIndexes)/3;
#endif
pdPoint = &sTessBaseData.m_pdCoords[*puiTriangulatedIndexes++];
pasGPoints[uiPoint].m_dX = pdPoint[0];
pasGPoints[uiPoint].m_dY = pdPoint[1];
pasGPoints[uiPoint].m_dZ = pdPoint[2];
}
A3D_DRAW_CALL3(TriangleStripe, pasGNormals, pasGPoints, uiNumberOfPointsForThisStripe);
stFreeNormalsAndPoints(&pasGNormals, &pasGPoints);
#ifdef A3D_DRAW_WITH_INDICES
A3D_DRAW_CALL3(TriangleStripeWithIndices, pauiNormals, pauiPoints,
uiNumberOfPointsForThisStripe);
A3DMiscFree(pauiNormals);
A3DMiscFree(pauiPoints);
#endif
}
}
}
if(sTessFaceData.m_usUsedEntitiesFlags & kA3DTessFaceDataTriangleTextured)
{
// number of triangles for this face
A3DUns32 uiNbTriangles = sTessFaceData.m_puiSizesTriangulated[uiCurrentSize++];
A3DUns32 uiTri, uiId;
// read the 3 points, and the 3 normals of each triangle and read the texture uv coordinates
// For each point of the face we can have several uv coordinates indexes.
// This number of uv coordinates indexes is given by the parameter
// sTessFaceData.m_uiTextureCoordIndexesSize. To know which is the index to use read
// the parameter m_iUVCoordinatesIndex of the A3DTextureDefinition linked to this face -- see above.
A3DDouble sUV1[2],sUV2[2],sUV3[2];
A3DVector3dData* pasGNormals;
A3DVector3dData* pasGPoints;
stAllocNormalsAndPoints(&pasGNormals, uiNbTriangles*3, &pasGPoints, uiNbTriangles*3);
#ifdef A3D_DRAW_WITH_INDICES
A3DUns32* pauiNormals = (A3DUns32*)A3DMiscAlloc(uiNbTriangles*3 * sizeof(A3DUns32));
A3DUns32* pauiPoints = (A3DUns32*)A3DMiscAlloc(uiNbTriangles*3 * sizeof(A3DUns32));
#endif
for(uiTri = 0; uiTri < uiNbTriangles; uiTri++)
{
/* Point uv and normal #1 */
uiId = *puiTriangulatedIndexes++; /* normal index */
if (!sTess3DData.m_bMustRecalculateNormals)
{
pasGNormals[uiTri*3].m_dX = sTess3DData.m_pdNormals[uiId]; /* x */
pasGNormals[uiTri*3].m_dY = sTess3DData.m_pdNormals[uiId+1]; /* y */
pasGNormals[uiTri*3].m_dZ = sTess3DData.m_pdNormals[uiId+2]; /* z */
}
#ifdef A3D_DRAW_WITH_INDICES
pauiNormals[uiTri*3] = uiId/3;
#endif
if(iUVCoordinatesIndex!=-1 && ucTextureDimension == 2 )
{
uiId = *(puiTriangulatedIndexes+iUVCoordinatesIndex); /* UV index */
sUV1[0] = sTess3DData.m_pdTextureCoords[uiId]; /* U */
sUV1[1] = sTess3DData.m_pdTextureCoords[uiId+1]; /* V */
}
puiTriangulatedIndexes+=sTessFaceData.m_uiTextureCoordIndexesSize;
uiId = *puiTriangulatedIndexes++; /* point index */
pasGPoints[uiTri*3].m_dX = sTessBaseData.m_pdCoords[uiId]; /* x */
pasGPoints[uiTri*3].m_dY = sTessBaseData.m_pdCoords[uiId+1]; /* y */
pasGPoints[uiTri*3].m_dZ = sTessBaseData.m_pdCoords[uiId+2]; /* z */
#ifdef A3D_DRAW_WITH_INDICES
pauiPoints[uiTri*3] = uiId/3;
#endif
/* Point uv and normal #2 */
uiId = *puiTriangulatedIndexes++; /* normal index */
if (!sTess3DData.m_bMustRecalculateNormals)
{
pasGNormals[uiTri*3+1].m_dX = sTess3DData.m_pdNormals[uiId]; /* x */
pasGNormals[uiTri*3+1].m_dY = sTess3DData.m_pdNormals[uiId+1]; /* y */
pasGNormals[uiTri*3+1].m_dZ = sTess3DData.m_pdNormals[uiId+2]; /* z */
}
#ifdef A3D_DRAW_WITH_INDICES
pauiNormals[uiTri*3+1] = uiId/3;
#endif
if(iUVCoordinatesIndex!=-1 && ucTextureDimension == 2 )
{
uiId = *(puiTriangulatedIndexes+iUVCoordinatesIndex); /* UV index */
sUV2[0] = sTess3DData.m_pdTextureCoords[uiId]; /* U */
sUV2[1] = sTess3DData.m_pdTextureCoords[uiId+1]; /* V */
}
puiTriangulatedIndexes+=sTessFaceData.m_uiTextureCoordIndexesSize;
uiId = *puiTriangulatedIndexes++; /* point index */
pasGPoints[uiTri*3+1].m_dX = sTessBaseData.m_pdCoords[uiId]; /* x */
pasGPoints[uiTri*3+1].m_dY = sTessBaseData.m_pdCoords[uiId+1]; /* y */
pasGPoints[uiTri*3+1].m_dZ = sTessBaseData.m_pdCoords[uiId+2]; /* z */
#ifdef A3D_DRAW_WITH_INDICES
pauiPoints[uiTri*3+1] = uiId/3;
#endif
/* Point uv and normal #3 */
uiId = *puiTriangulatedIndexes++; /* normal index */
if (!sTess3DData.m_bMustRecalculateNormals)
{
pasGNormals[uiTri*3+2].m_dX = sTess3DData.m_pdNormals[uiId]; /* x */
pasGNormals[uiTri*3+2].m_dY = sTess3DData.m_pdNormals[uiId+1]; /* y */
pasGNormals[uiTri*3+2].m_dZ = sTess3DData.m_pdNormals[uiId+2]; /* z */
}
#ifdef A3D_DRAW_WITH_INDICES
pauiNormals[uiTri*3+2] = uiId/3;
#endif
if(iUVCoordinatesIndex!=-1 && ucTextureDimension == 2 )
{
uiId = *(puiTriangulatedIndexes+iUVCoordinatesIndex); /* UV index */
sUV3[0] = sTess3DData.m_pdTextureCoords[uiId]; /* U */
sUV3[1] = sTess3DData.m_pdTextureCoords[uiId+1]; /* V */
}
puiTriangulatedIndexes+=sTessFaceData.m_uiTextureCoordIndexesSize;
uiId = *puiTriangulatedIndexes++; /* point index */
pasGPoints[uiTri*3+2].m_dX = sTessBaseData.m_pdCoords[uiId]; /* x */
pasGPoints[uiTri*3+2].m_dY = sTessBaseData.m_pdCoords[uiId+1]; /* y */
pasGPoints[uiTri*3+2].m_dZ = sTessBaseData.m_pdCoords[uiId+2]; /* z */
#ifdef A3D_DRAW_WITH_INDICES
pauiPoints[uiTri*3+2] = uiId/3;
#endif
}
A3D_DRAW_CALL3(Triangle, pasGNormals, pasGPoints, uiNbTriangles*3);
stFreeNormalsAndPoints(&pasGNormals, &pasGPoints);
#ifdef A3D_DRAW_WITH_INDICES
A3D_DRAW_CALL3(TriangleWithIndices, pauiNormals, pauiPoints, uiNbTriangles*3);
A3DMiscFree(pauiNormals);
A3DMiscFree(pauiPoints);
#endif
}
if(sTessFaceData.m_usUsedEntitiesFlags & kA3DTessFaceDataTriangleFanTextured)
{
A3DUns32 uiNbFan = sTessFaceData.m_puiSizesTriangulated[uiCurrentSize++];
A3DUns32 uiFan, uiPoint;
for(uiFan = 0; uiFan < uiNbFan; uiFan++)
{
A3DUns32 uiNumberOfPointsForThisFan = sTessFaceData.m_puiSizesTriangulated[uiCurrentSize++];
//if(uiNumberOfPointsForThisFan > 2)
// uiTotalTriangles += (uiNumberOfPointsForThisFan - 2);
A3DVector3dData* pasGNormals;
A3DVector3dData* pasGPoints;
stAllocNormalsAndPoints(&pasGNormals, uiNumberOfPointsForThisFan, &pasGPoints,
uiNumberOfPointsForThisFan);
#ifdef A3D_DRAW_WITH_INDICES
A3DUns32* pauiNormals = (A3DUns32*)A3DMiscAlloc(uiNumberOfPointsForThisFan *
sizeof(A3DUns32));
A3DUns32* pauiPoints = (A3DUns32*)A3DMiscAlloc(uiNumberOfPointsForThisFan *
sizeof(A3DUns32));
#endif
A3DDouble* pdNormal = NULL;
A3DDouble* pdPoint = NULL;
for(uiPoint = 0; uiPoint < uiNumberOfPointsForThisFan; uiPoint++)
{
#ifdef A3D_DRAW_WITH_INDICES
pauiNormals[uiPoint] = (*puiTriangulatedIndexes)/3;
#endif
pdNormal = &sTess3DData.m_pdNormals[*puiTriangulatedIndexes++];
if (!sTess3DData.m_bMustRecalculateNormals)
{
pasGNormals[uiPoint].m_dX = pdNormal[0];
pasGNormals[uiPoint].m_dY = pdNormal[1];
pasGNormals[uiPoint].m_dZ = pdNormal[2];
}
// we're not reading the UV for now
puiTriangulatedIndexes += sTessFaceData.m_uiTextureCoordIndexesSize;
#ifdef A3D_DRAW_WITH_INDICES
pauiPoints[uiPoint] = (*puiTriangulatedIndexes)/3;
#endif
pdPoint = &sTessBaseData.m_pdCoords[*puiTriangulatedIndexes++];
pasGPoints[uiPoint].m_dX = pdPoint[0];
pasGPoints[uiPoint].m_dY = pdPoint[1];
pasGPoints[uiPoint].m_dZ = pdPoint[2];
}
A3D_DRAW_CALL3(TriangleFan, pasGNormals, pasGPoints, uiNumberOfPointsForThisFan);
stFreeNormalsAndPoints(&pasGNormals, &pasGPoints);
#ifdef A3D_DRAW_WITH_INDICES
A3D_DRAW_CALL3(TriangleFanWithIndices, pauiNormals, pauiPoints,
uiNumberOfPointsForThisFan);
A3DMiscFree(pauiNormals);
A3DMiscFree(pauiPoints);
#endif
}
}
else if(sTessFaceData.m_usUsedEntitiesFlags & kA3DTessFaceDataTriangleStripeTextured)
{
A3DUns32 uiNbStripe = sTessFaceData.m_puiSizesTriangulated[uiCurrentSize++];
A3DUns32 uiStripe, uiPoint;
for(uiStripe = 0; uiStripe < uiNbStripe; uiStripe++)
{
A3DUns32 uiNumberOfPointsForThisStripe = sTessFaceData.m_puiSizesTriangulated[uiCurrentSize++];
//if(uiNumberOfPointsForThisStripe > 2)
// uiTotalTriangles += (uiNumberOfPointsForThisStripe - 2);
A3DVector3dData* pasGNormals;
A3DVector3dData* pasGPoints;
stAllocNormalsAndPoints(&pasGNormals, uiNumberOfPointsForThisStripe, &pasGPoints,
uiNumberOfPointsForThisStripe);
#ifdef A3D_DRAW_WITH_INDICES
A3DUns32* pauiNormals = (A3DUns32*)A3DMiscAlloc(uiNumberOfPointsForThisStripe * sizeof(A3DUns32));
A3DUns32* pauiPoints = (A3DUns32*)A3DMiscAlloc(uiNumberOfPointsForThisStripe * sizeof(A3DUns32));
#endif
A3DDouble* pdNormal = NULL;
A3DDouble* pdPoint = NULL;
for(uiPoint = 0; uiPoint < uiNumberOfPointsForThisStripe; uiPoint++)
{
#ifdef A3D_DRAW_WITH_INDICES
pauiNormals[uiPoint] = (*puiTriangulatedIndexes)/3;
#endif
pdNormal = &sTess3DData.m_pdNormals[*puiTriangulatedIndexes++];
if (!sTess3DData.m_bMustRecalculateNormals)
{
pasGNormals[uiPoint].m_dX = pdNormal[0];
pasGNormals[uiPoint].m_dY = pdNormal[1];
pasGNormals[uiPoint].m_dZ = pdNormal[2];
}
// we're not reading the UV for now
puiTriangulatedIndexes += sTessFaceData.m_uiTextureCoordIndexesSize;
#ifdef A3D_DRAW_WITH_INDICES
pauiPoints[uiPoint] = (*puiTriangulatedIndexes)/3;
#endif
pdPoint = &sTessBaseData.m_pdCoords[*puiTriangulatedIndexes++];
pasGPoints[uiPoint].m_dX = pdPoint[0];
pasGPoints[uiPoint].m_dY = pdPoint[1];
pasGPoints[uiPoint].m_dZ = pdPoint[2];
}
A3D_DRAW_CALL3(TriangleStripe, pasGNormals, pasGPoints, uiNumberOfPointsForThisStripe);
stFreeNormalsAndPoints(&pasGNormals, &pasGPoints);
#ifdef A3D_DRAW_WITH_INDICES
A3D_DRAW_CALL3(TriangleStripeWithIndices, pauiNormals, pauiPoints, uiNumberOfPointsForThisStripe);
A3DMiscFree(pauiNormals);
A3DMiscFree(pauiPoints);
#endif
}
}
else if(sTessFaceData.m_usUsedEntitiesFlags & kA3DTessFaceDataTriangleOneNormalTextured)
{
A3DUns32 uiTri, uiNbTriangles = sTessFaceData.m_puiSizesTriangulated[uiCurrentSize++];
// uiTotalTriangles += uiNbTriangles;
A3DVector3dData* pasGNormals;
A3DVector3dData* pasGPoints;
stAllocNormalsAndPoints(&pasGNormals, uiNbTriangles, &pasGPoints, uiNbTriangles*3);
#ifdef A3D_DRAW_WITH_INDICES
A3DUns32* pauiNormals = (A3DUns32*)A3DMiscAlloc(uiNbTriangles * sizeof(A3DUns32));
A3DUns32* pauiPoints = (A3DUns32*)A3DMiscAlloc(uiNbTriangles*3 * sizeof(A3DUns32));
#endif
A3DDouble* pdNormal = NULL;
A3DDouble* pdPoint = NULL;
for(uiTri = 0; uiTri < uiNbTriangles; uiTri++)
{
#ifdef A3D_DRAW_WITH_INDICES
pauiNormals[uiTri] = (*puiTriangulatedIndexes)/3;
#endif
pdNormal = &sTess3DData.m_pdNormals[*puiTriangulatedIndexes++];
if (!sTess3DData.m_bMustRecalculateNormals)
{
pasGNormals[uiTri].m_dX = pdNormal[0];
pasGNormals[uiTri].m_dY = pdNormal[1];
pasGNormals[uiTri].m_dZ = pdNormal[2];
}
// we're not reading the UV for now
puiTriangulatedIndexes += sTessFaceData.m_uiTextureCoordIndexesSize;
#ifdef A3D_DRAW_WITH_INDICES
pauiPoints[uiTri*3] = (*puiTriangulatedIndexes)/3;
#endif
pdPoint = &sTessBaseData.m_pdCoords[*puiTriangulatedIndexes++];
pasGPoints[uiTri*3].m_dX = pdPoint[0];
pasGPoints[uiTri*3].m_dY = pdPoint[1];
pasGPoints[uiTri*3].m_dZ = pdPoint[2];
// we're not reading the UV for now
puiTriangulatedIndexes += sTessFaceData.m_uiTextureCoordIndexesSize;
#ifdef A3D_DRAW_WITH_INDICES
pauiPoints[uiTri*3+1] = (*puiTriangulatedIndexes)/3;
#endif
pdPoint = &sTessBaseData.m_pdCoords[*puiTriangulatedIndexes++];
pasGPoints[uiTri*3+1].m_dX = pdPoint[0];
pasGPoints[uiTri*3+1].m_dY = pdPoint[1];
pasGPoints[uiTri*3+1].m_dZ = pdPoint[2];
// we're not reading the UV for now
puiTriangulatedIndexes += sTessFaceData.m_uiTextureCoordIndexesSize;
#ifdef A3D_DRAW_WITH_INDICES
pauiPoints[uiTri*3+2] = (*puiTriangulatedIndexes)/3;
#endif
pdPoint = &sTessBaseData.m_pdCoords[*puiTriangulatedIndexes++];
pasGPoints[uiTri*3+2].m_dX = pdPoint[0];
pasGPoints[uiTri*3+2].m_dY = pdPoint[1];
pasGPoints[uiTri*3+2].m_dZ = pdPoint[2];
}
A3D_DRAW_CALL3(TriangleOneNormal, pasGNormals, pasGPoints, uiNbTriangles*3);
stFreeNormalsAndPoints(&pasGNormals, &pasGPoints);
#ifdef A3D_DRAW_WITH_INDICES
A3D_DRAW_CALL3(TriangleOneNormalWithIndices, pauiNormals, pauiPoints, uiNbTriangles*3);
A3DMiscFree(pauiNormals);
A3DMiscFree(pauiPoints);
#endif
}
else if(sTessFaceData.m_usUsedEntitiesFlags & kA3DTessFaceDataTriangleFanOneNormalTextured)
{
A3DUns32 uiNbFan = sTessFaceData.m_puiSizesTriangulated[uiCurrentSize++];
A3DUns32 uiFan,uiSize, uiPoint;
for(uiFan=0;uiFan<uiNbFan;uiFan++)
{
uiSize = sTessFaceData.m_puiSizesTriangulated[uiCurrentSize++];
A3DUns32 uiNumberOfPointsForThisFan = (uiSize & kA3DTessFaceDataNormalMask);
//if(uiNumberOfPointsForThisFan > 2)
// uiTotalTriangles += (uiNumberOfPointsForThisFan - 2);
if(uiSize & kA3DTessFaceDataNormalSingle) /* only one normal for the entire fan */
{
A3DVector3dData* pasGNormals;
A3DVector3dData* pasGPoints;
stAllocNormalsAndPoints(&pasGNormals, 1, &pasGPoints, uiNumberOfPointsForThisFan);
#ifdef A3D_DRAW_WITH_INDICES
A3DUns32* pauiPoints = (A3DUns32*)A3DMiscAlloc(uiNumberOfPointsForThisFan * sizeof(A3DUns32));
A3DUns32 uiNormal = (*puiTriangulatedIndexes)/3;
#endif
A3DDouble* pdNormal = NULL;
A3DDouble* pdPoint = NULL;
pdNormal = &sTess3DData.m_pdNormals[*puiTriangulatedIndexes++];
if (!sTess3DData.m_bMustRecalculateNormals)
{
pasGNormals[0].m_dX = pdNormal[0];
pasGNormals[0].m_dY = pdNormal[1];
pasGNormals[0].m_dZ = pdNormal[2];
}
for(uiPoint = 0; uiPoint < uiNumberOfPointsForThisFan; uiPoint++)
{
// we're not reading the UV for now
puiTriangulatedIndexes += sTessFaceData.m_uiTextureCoordIndexesSize;
#ifdef A3D_DRAW_WITH_INDICES
pauiPoints[uiPoint] = (*puiTriangulatedIndexes)/3;
#endif
pdPoint = &sTessBaseData.m_pdCoords[*puiTriangulatedIndexes++];
pasGPoints[uiPoint].m_dX = pdPoint[0];
pasGPoints[uiPoint].m_dY = pdPoint[1];
pasGPoints[uiPoint].m_dZ = pdPoint[2];
}
A3D_DRAW_CALL3(TriangleFanOneNormal, &pasGNormals[0], pasGPoints, uiNumberOfPointsForThisFan);
stFreeNormalsAndPoints(&pasGNormals, &pasGPoints);
#ifdef A3D_DRAW_WITH_INDICES
A3D_DRAW_CALL3(TriangleFanOneNormalWithIndices, uiNormal, pauiPoints,
uiNumberOfPointsForThisFan);
A3DMiscFree(pauiPoints);
#endif
}
else
{
A3DVector3dData* pasGNormals;
A3DVector3dData* pasGPoints;
stAllocNormalsAndPoints(&pasGNormals, uiNumberOfPointsForThisFan, &pasGPoints,
uiNumberOfPointsForThisFan);
#ifdef A3D_DRAW_WITH_INDICES
A3DUns32* pauiNormals = (A3DUns32*)A3DMiscAlloc(uiNumberOfPointsForThisFan * sizeof(A3DUns32));
A3DUns32* pauiPoints = (A3DUns32*)A3DMiscAlloc(uiNumberOfPointsForThisFan * sizeof(A3DUns32));
#endif
A3DDouble* pdNormal = NULL;
A3DDouble* pdPoint = NULL;
for(uiPoint = 0; uiPoint < uiNumberOfPointsForThisFan; uiPoint++)
{
#ifdef A3D_DRAW_WITH_INDICES
pauiNormals[uiPoint] = (*puiTriangulatedIndexes)/3;
#endif
pdNormal = &sTess3DData.m_pdNormals[*puiTriangulatedIndexes++];
if (!sTess3DData.m_bMustRecalculateNormals)
{
pasGNormals[uiPoint].m_dX = pdNormal[0];
pasGNormals[uiPoint].m_dY = pdNormal[1];
pasGNormals[uiPoint].m_dZ = pdNormal[2];
}
// we're not reading the UV for now
puiTriangulatedIndexes += sTessFaceData.m_uiTextureCoordIndexesSize;
#ifdef A3D_DRAW_WITH_INDICES
pauiPoints[uiPoint] = (*puiTriangulatedIndexes)/3;
#endif
pdPoint = &sTessBaseData.m_pdCoords[*puiTriangulatedIndexes++];
pasGPoints[uiPoint].m_dX = pdPoint[0];
pasGPoints[uiPoint].m_dY = pdPoint[1];
pasGPoints[uiPoint].m_dZ = pdPoint[2];
}
A3D_DRAW_CALL3(TriangleFan, pasGNormals, pasGPoints, uiNumberOfPointsForThisFan);
stFreeNormalsAndPoints(&pasGNormals, &pasGPoints);
#ifdef A3D_DRAW_WITH_INDICES
A3D_DRAW_CALL3(TriangleFanWithIndices, pauiNormals, pauiPoints, uiNumberOfPointsForThisFan);
A3DMiscFree(pauiNormals);
A3DMiscFree(pauiPoints);
#endif
}
}
}
else if(sTessFaceData.m_usUsedEntitiesFlags & kA3DTessFaceDataTriangleStripeOneNormalTextured)
{
A3DUns32 uiNbStripe = sTessFaceData.m_puiSizesTriangulated[uiCurrentSize++];
A3DUns32 uiStripe, uiPoint;
for(uiStripe=0;uiStripe<uiNbStripe;uiStripe++)
{
A3DUns32 uiSize = sTessFaceData.m_puiSizesTriangulated[uiCurrentSize++];
A3DUns32 uiNumberOfPointsForThisStripe = (uiSize & kA3DTessFaceDataNormalMask);
//if(uiNumberOfPointsForThisStripe > 2)
// uiTotalTriangless += (uiNumberOfPointsForThisStripe - 2);
if(uiSize & kA3DTessFaceDataNormalSingle) /* only one normal for the entire stripe */
{
A3DVector3dData* pasGNormals;
A3DVector3dData* pasGPoints;
stAllocNormalsAndPoints(&pasGNormals, 1, &pasGPoints, uiNumberOfPointsForThisStripe);
#ifdef A3D_DRAW_WITH_INDICES
A3DUns32* pauiPoints = (A3DUns32*)A3DMiscAlloc(uiNumberOfPointsForThisStripe *
sizeof(A3DUns32));
A3DUns32 uiNormal = (*puiTriangulatedIndexes)/3;
#endif
A3DDouble* pdNormal = NULL;
A3DDouble* pdPoint = NULL;
pdNormal = &sTess3DData.m_pdNormals[*puiTriangulatedIndexes++];
if (!sTess3DData.m_bMustRecalculateNormals)
{
pasGNormals[0].m_dX = pdNormal[0];
pasGNormals[0].m_dY = pdNormal[1];
pasGNormals[0].m_dZ = pdNormal[2];
}
for(uiPoint = 0; uiPoint < uiNumberOfPointsForThisStripe; uiPoint++)
{
// we're not reading the UV for now
puiTriangulatedIndexes += sTessFaceData.m_uiTextureCoordIndexesSize;
#ifdef A3D_DRAW_WITH_INDICES
pauiPoints[uiPoint] = (*puiTriangulatedIndexes)/3;
#endif
pdPoint = &sTessBaseData.m_pdCoords[*puiTriangulatedIndexes++];
pasGPoints[uiPoint].m_dX = pdPoint[0];
pasGPoints[uiPoint].m_dY = pdPoint[1];
pasGPoints[uiPoint].m_dZ = pdPoint[2];
}
A3D_DRAW_CALL3(TriangleStripeOneNormal, &pasGNormals[0], pasGPoints,
uiNumberOfPointsForThisStripe);
stFreeNormalsAndPoints(&pasGNormals, &pasGPoints);
#ifdef A3D_DRAW_WITH_INDICES
A3D_DRAW_CALL3(TriangleStripeOneNormalWithIndices, uiNormal, pauiPoints,
uiNumberOfPointsForThisStripe);
A3DMiscFree(pauiPoints);
#endif
}
else
{
A3DVector3dData* pasGNormals;
A3DVector3dData* pasGPoints;
stAllocNormalsAndPoints(&pasGNormals, uiNumberOfPointsForThisStripe, &pasGPoints,
uiNumberOfPointsForThisStripe);
#ifdef A3D_DRAW_WITH_INDICES
A3DUns32* pauiNormals = (A3DUns32*)A3DMiscAlloc(uiNumberOfPointsForThisStripe *
sizeof(A3DUns32));
A3DUns32* pauiPoints = (A3DUns32*)A3DMiscAlloc(uiNumberOfPointsForThisStripe *
sizeof(A3DUns32));
#endif
A3DDouble* pdNormal = NULL;
A3DDouble* pdPoint = NULL;
for(uiPoint = 0; uiPoint < uiNumberOfPointsForThisStripe; uiPoint++)
{
#ifdef A3D_DRAW_WITH_INDICES
pauiNormals[uiPoint] = (*puiTriangulatedIndexes)/3;
#endif
pdNormal = &sTess3DData.m_pdNormals[*puiTriangulatedIndexes++];
if (!sTess3DData.m_bMustRecalculateNormals)
{
pasGNormals[uiPoint].m_dX = pdNormal[0];
pasGNormals[uiPoint].m_dY = pdNormal[1];
pasGNormals[uiPoint].m_dZ = pdNormal[2];
}
// we're not reading the UV for now
puiTriangulatedIndexes += sTessFaceData.m_uiTextureCoordIndexesSize;
#ifdef A3D_DRAW_WITH_INDICES
pauiPoints[uiPoint] = (*puiTriangulatedIndexes)/3;
#endif
pdPoint = &sTessBaseData.m_pdCoords[*puiTriangulatedIndexes++];
pasGPoints[uiPoint].m_dX = pdPoint[0];
pasGPoints[uiPoint].m_dY = pdPoint[1];
pasGPoints[uiPoint].m_dZ = pdPoint[2];
}
A3D_DRAW_CALL3(TriangleStripe, pasGNormals, pasGPoints, uiNumberOfPointsForThisStripe);
stFreeNormalsAndPoints(&pasGNormals, &pasGPoints);
#ifdef A3D_DRAW_WITH_INDICES
A3D_DRAW_CALL3(TriangleStripeWithIndices, pauiNormals, pauiPoints,
uiNumberOfPointsForThisStripe);
A3DMiscFree(pauiNormals);
A3DMiscFree(pauiPoints);
#endif
}
}
}
}
CHECK_RET(A3DMiscCascadedAttributesDelete(pAttr));
}
//if(stpcRepresentationItemName != NULL)
A3D_DRAW_CALL1(End, kA3DDrawBeginEndRepresentationItem);
if (sTess3DData.m_bMustRecalculateNormals)
sTess3DData.m_pdNormals=NULL;
CHECK_RET(A3DTessBaseGet(NULL, &sTessBaseData));
CHECK_RET(A3DTess3DGet(NULL, &sTess3DData));
return iRet;
}
//######################################################################################################################
static bool stCheckExtent(const A3DBoundingBoxData* psExtent)
{
if(psExtent->m_sMin.m_dX == -1.0e+020 || psExtent->m_sMin.m_dY == -1.0e+020 || psExtent->m_sMin.m_dZ == -1.0e+020)
return false;
if(psExtent->m_sMax.m_dX == -1.0e+020 || psExtent->m_sMax.m_dY == -1.0e+020 || psExtent->m_sMax.m_dZ == -1.0e+020)
return false;
return true;
}
//######################################################################################################################
static A3DStatus stEvaluateMarkupTessellationBox(const A3DTessBaseData* psTessBaseData,
const A3DTessMarkupData* psTessMarkupData, A3DBoundingBoxData* psBox)
{
A3DStatus iRet = A3D_SUCCESS;
if(psTessBaseData == NULL || psTessMarkupData == NULL)
return A3D_ERROR;
if(psTessMarkupData->m_uiCodesSize == 0)
return A3D_ERROR;
stExtentInit(psBox);
const A3DDouble* pData = psTessBaseData->m_pdCoords;
unsigned int k, kSize;
//TfFontKey sFontKey;
A3DBoundingBoxData sTextBox;
// to know if in "matrix" mode we've had some text
// and if we have to transform the text box with the current matrix
bool bGotText = false;
double adMatrix[16];
stExtentInit(&sTextBox);
const A3DDouble* pTD = pData;
unsigned int uiCount;
const A3DUns32* puiStart = &psTessMarkupData->m_puiCodes[0];
const A3DUns32* puiEnd = &psTessMarkupData->m_puiCodes[psTessMarkupData->m_uiCodesSize-1];
float fWidthMetrics, fHeightMetrics;
#define DEFAULT_OFFSET \
pData += *(puiStart+1); \
puiStart += (uiCount + 1); // knowing we're gonna do puiStart++ right afterwards
#define MAKE_OFFSET(CountInt, CountFloats) \
pData += CountFloats; \
puiStart += (CountInt + 1);
for(; puiStart < puiEnd; puiStart++)
{
uiCount = *puiStart & kA3DMarkupIntegerMask;
if(*puiStart & kA3DMarkupIsExtraData)
{
switch(A3D_DECODE_EXTRA_DATA(*puiStart))
{
case 6 :
case 7 :
case 8 :
MAKE_OFFSET(0, (*(puiStart+1) > 0) ? 3 : 0)
break;
case 2 :
kSize = *(puiStart+1) / 9; // triangle number
pTD = pData;
for(k = 0; k < kSize; k++)
{
stBoundingBoxAddPoint(psBox, *pTD, *(pTD+1), *(pTD+2));
pTD += 3;
stBoundingBoxAddPoint(psBox, *pTD, *(pTD+1), *(pTD+2));
pTD += 3;
stBoundingBoxAddPoint(psBox, *pTD, *(pTD+1), *(pTD+2));
pTD += 3;
}
DEFAULT_OFFSET
break;
case 16 :
kSize = *(puiStart+1) / 3; // vertex number
pTD = pData;
for(k = 0; k < kSize; k++)
{
stBoundingBoxAddPoint(psBox, *pTD, *(pTD+1), *(pTD+2));
pTD += 3;
}
DEFAULT_OFFSET
break;
case 15 :
kSize = *(puiStart+1) / 3; // vertex number
pTD = pData;
for(k = 0; k < kSize; k++)
{
stBoundingBoxAddPoint(psBox, *pTD, *(pTD+1), *(pTD+2));
pTD += 3;
}
DEFAULT_OFFSET
break;
case 13 :
{
DEFAULT_OFFSET
}
break;
case 14 :
{
fWidthMetrics = (float)*pData;
fHeightMetrics = (float)*(pData+1);
bGotText = true;
stBoundingBoxAddPoint(&sTextBox, 0.0, 0.0, 0.0);
stBoundingBoxAddPoint(&sTextBox, fWidthMetrics, fHeightMetrics, 0.0);
DEFAULT_OFFSET
}
break;
default :
DEFAULT_OFFSET
}
}
else if(*puiStart & kA3DMarkupIsMatrix)
{
if(*(puiStart+1) > 0) // if there are floats, beginning the "matrix" mode
{
// getting the matrix stored in sMatrix
for(k = 0; k < 16; k++)
adMatrix[k] = (double)(*(pData + k));
MAKE_OFFSET(0, 16)
}
else // if there aren't any floats, ending the "matrix" mode
{
if(bGotText) // if we've had some text in this "matrix" mode
{
// transforming the text box with the current matrix
A3DVector3dData& sMin = sTextBox.m_sMin;
A3DVector3dData& sMax = sTextBox.m_sMax;
stVectorMatrixMult(sMin.m_dX, sMin.m_dY, sMin.m_dZ, adMatrix, &sMin.m_dX, &sMin.m_dY, &sMin.m_dZ);
stVectorMatrixMult(sMax.m_dX, sMax.m_dY, sMax.m_dZ, adMatrix, &sMax.m_dX, &sMax.m_dY, &sMax.m_dZ);
stBoundingBoxAddPoint(psBox, sMin.m_dX, sMin.m_dY, sMin.m_dZ);
stBoundingBoxAddPoint(psBox, sMax.m_dX, sMax.m_dY, sMax.m_dZ);
stExtentInit(&sTextBox);
bGotText = false;
}
MAKE_OFFSET(0, 0)
}
}
else
{
kSize = *(puiStart+1) / 3; // vertex number
pTD = pData;
for(k = 0; k < kSize; k++)
{
stBoundingBoxAddPoint(psBox, *pTD, *(pTD+1), *(pTD+2));
pTD += 3;
}
DEFAULT_OFFSET
}
}
#undef DEFAULT_OFFSET
#undef MAKE_OFFSET
if(stExtentIsValid(psBox))
{
// we can have a box with NAN and infinite values
if(!stCheckExtent(psBox))
iRet = A3D_ERROR;
}
return iRet;
}
//######################################################################################################################
#define START_TREAT_DRWENTITY_ATTRIBUT \
if(bUseAttribut) \
{ \
stCreateAndPushCascadedAttributesDrwEntity((A3DDrawingBlock*)pRepItem, uiDrwEntityCount, pFatherAttr, &pAttr, &sAttrData); \
CHECK_RET(stDrawStyle(&sAttrData.m_sStyle, NULL, NULL, &bPushMaterial, &bPushLineStipple, &bPushLineWidth)); \
bShow = (sAttrData.m_bShow==TRUE); \
}
//######################################################################################################################
#define END_TREAT_DRWENTITY_ATTRIBUT \
if(bUseAttribut) \
{ \
CHECK_RET(A3DMiscCascadedAttributesDelete(pAttr)); \
if (bPushLineStipple) \
{ \
A3D_DRAW_CALL0(EndLineStipple); \
bPushLineStipple = false; \
} \
if (bPushLineWidth) \
{ \
A3D_DRAW_CALL0(EndLineWidth); \
bPushLineWidth = false; \
} \
if (bPushMaterial) \
{ \
A3D_DRAW_CALL0(EndMaterial); \
} \
uiDrwEntityCount++; \
}
//######################################################################################################################
//static A3DStatus stTreatDrawingEntityAttribute(A3DRiRepresentationItem const * pRepItem,
// A3DMiscCascadedAttributes const * pFatherAttr,
// A3DUns32 uiDrwEntityCount)
//{
// A3DMiscCascadedAttributes *pAttr;
// A3DMiscCascadedAttributesData sAttrData;
// stCreateAndPushCascadedAttributesDrwEntity((A3DDrawingBlock*)pRepItem, uiDrwEntityCount, pFatherAttr, pAttr,
// &sAttrData);
//
// return A3D_SUCCESS;
//}
static A3DStatus stDrawSet(const A3DRiSet* pSet, const A3DMiscCascadedAttributes* pFatherAttr);
//######################################################################################################################
static A3DStatus stDrawMarkupTessellation(const A3DTessBaseData* psTessBaseData,
const A3DTessMarkupData* psTessMarkupData,
const A3DRiRepresentationItem* pRepItem,
const A3DMiscCascadedAttributes* pFatherAttr)
{
A3DStatus iRet = A3D_SUCCESS;
if(psTessBaseData == NULL || psTessMarkupData == NULL)
return A3D_ERROR;
#define DEFAULT_OFFSET {\
pData += *(puiStart+1); \
puiStart += (uiCount + 1); /* knowing we'll increment puiStart right afterwards */ \
}
#define MAKE_OFFSET(CountInt, CountFloats) {\
pData += CountFloats; \
puiStart += (CountInt + 1); \
}
double dFixedSize = 1.0;//_GetFixedSize();
//double dFixedSizeArrow = dFixedSize * SIZE_ARROW;
//double dScaleText=1.0;
//float fFontScale;
//A3DVector3dData sPntFrame;
//TfwOldMatrix sMatGroup;
bool bIsScreenMarkupZoomable = true;
unsigned int kSize;
unsigned int uiCount = 0;
A3DDouble adMatrix[16];
A3DDouble adMv[16], adPr[16];
A3DInt32 aiVp[4];
A3D_DRAW_CALL3(GetDrawContext, adPr, adMv, aiVp);
bool bUseAttribut = false;
if(pRepItem != NULL)
{
A3DEEntityType eType=kA3DTypeUnknown;
CHECK_RET(A3DEntityGetType(pRepItem, &eType));
if(eType==kA3DTypeDrawingBlockBasic || eType==kA3DTypeDrawingBlockOperator)
bUseAttribut = true;
}
A3DMiscCascadedAttributesData sAttrData;
A3DMiscCascadedAttributes* pAttr = NULL;
A3DGraphRgbColorData sRgbColorData;
A3D_INITIALIZE_DATA(A3DGraphRgbColorData, sRgbColorData);
A3DGraphStyleData sGraphStyleData;
A3D_INITIALIZE_DATA(A3DGraphStyleData, sGraphStyleData);
A3DFontKeyData sFontKeyData;
A3D_INITIALIZE_DATA(A3DFontKeyData, sFontKeyData);
A3DGraphPictureData sPictureData;
A3D_INITIALIZE_DATA(A3DGraphPictureData, sPictureData);
bIsScreenMarkupZoomable = (psTessMarkupData->m_cBehaviour & kA3DMarkupIsZoomable) != 0;
const A3DDouble* pData = psTessBaseData->m_pdCoords;
const A3DUns32* puiStart = &psTessMarkupData->m_puiCodes[0];
const A3DUns32* puiEnd = &psTessMarkupData->m_puiCodes[psTessMarkupData->m_uiCodesSize-1];
A3DUns32 uiDrwEntityCount = 0;
bool bShow, bPushMaterial = false;
bool bPushLineStipple = false;
bool bPushLineWidth = false;
for(; puiStart < puiEnd; puiStart++)
{
uiCount = *puiStart & kA3DMarkupIntegerMask;
bShow = true;
if(*puiStart & kA3DMarkupIsExtraData)
{
A3DUns32 uiExtraDataValue = A3D_DECODE_EXTRA_DATA(*puiStart);
switch(uiExtraDataValue)
{
case 2 : // triangles
{
kSize = *(puiStart+1) / 9; // triangle number
A3D_DRAW_CALL2(MarkupTriangle, pData, kSize*3);
DEFAULT_OFFSET;
}
break;
case 6 : // faceview
{
if(*(puiStart+1) > 0)
{
A3DVector3dData sP1, sP2, sP3, sP1Proj, sP2Proj, sP3Proj;
A3D_INITIALIZE_DATA(A3DVector3dData, sP1);
A3D_INITIALIZE_DATA(A3DVector3dData, sP2);
A3D_INITIALIZE_DATA(A3DVector3dData, sP3);
A3D_INITIALIZE_DATA(A3DVector3dData, sP1Proj);
A3D_INITIALIZE_DATA(A3DVector3dData, sP2Proj);
A3D_INITIALIZE_DATA(A3DVector3dData, sP3Proj);
sP1.m_dX = 0.0; sP1.m_dY = 0.0; sP1.m_dZ = 0.0;
sP2.m_dX = 1.0; sP2.m_dY = 0.0; sP2.m_dZ = 0.0;
sP3.m_dX = 0.0; sP3.m_dY = 1.0; sP3.m_dZ = 0.0;
A3D_DRAW_CALL2(UnProject, &sP1, &sP1Proj);
A3D_DRAW_CALL2(UnProject, &sP2, &sP2Proj);
A3D_DRAW_CALL2(UnProject, &sP3, &sP3Proj);
stGetFaceViewMatrix(&sP1Proj, &sP2Proj, &sP3Proj, adMatrix);
adMatrix[12] = *pData;
adMatrix[13] = *(pData+1);
adMatrix[14] = *(pData+2);
A3D_DRAW_CALL0(PushMatrix);
A3D_DRAW_CALL1(MultMatrix, adMatrix);
MAKE_OFFSET(0, 3);
}
else
{
A3D_DRAW_CALL0(PopMatrix);
MAKE_OFFSET(0, 0);
}
}
break;
case 7 : // framedraw
{
if(*(puiStart+1) > 0)
{
A3DVector3dData sP;
A3D_INITIALIZE_DATA(A3DVector3dData, sP);
sP.m_dX = *pData;
sP.m_dY = *(pData+1);
sP.m_dZ = *(pData+2);
A3D_DRAW_CALL3(BeginFrameDraw, &sP, bIsScreenMarkupZoomable, dFixedSize);
MAKE_OFFSET(0, 3);
}
else
{
A3D_DRAW_CALL0(EndFrameDraw);
MAKE_OFFSET(0, 0);
}
}
break;
case 8 : // fixedsize
{
if(*(puiStart+1) > 0)
{
A3DVector3dData sP;
A3D_INITIALIZE_DATA(A3DVector3dData, sP);
sP.m_dX = *pData;
sP.m_dY = *(pData+1);
sP.m_dZ = *(pData+2);
A3D_DRAW_CALL1(BeginFixedSize, &sP);
MAKE_OFFSET(0, 3);
}
else
{
A3D_DRAW_CALL0(EndFixedSize);
MAKE_OFFSET(0, 0);
}
}
break;
case 10 : // cylinder
{
A3D_DRAW_CALL3(Cylinder, *pData, *(pData+1), *(pData+2));
DEFAULT_OFFSET;
}
break;
case 9 : // symbol
{
A3DVector3dData sPosition;
A3D_INITIALIZE_DATA(A3DVector3dData, sPosition);
sPosition.m_dX = *pData;
sPosition.m_dY = *(pData+1);
sPosition.m_dZ = *(pData+2);
A3DGraphVPicturePatternData sPatternData;
A3D_INITIALIZE_DATA(A3DGraphVPicturePatternData, sPatternData);
CHECK_RET(A3DGlobalGetGraphVPicturePatternData(*(puiStart+2), &sPatternData));
A3D_DRAW_CALL2(Symbol, &sPatternData, &sPosition);
DEFAULT_OFFSET;
}
break;
case 16 : // polygon
{
kSize = *(puiStart+1) / 3; // vertex number
A3D_DRAW_CALL2(Polygon, pData, kSize);
DEFAULT_OFFSET;
}
break;
case 11 : // color
{
CHECK_RET(A3DGlobalGetGraphRgbColorData(*(puiStart+2), &sRgbColorData));
A3DDouble adColor[3] = { sRgbColorData.m_dRed, sRgbColorData.m_dGreen, sRgbColorData.m_dBlue };
A3D_DRAW_CALL1(Color,adColor);
CHECK_RET(A3DGlobalGetGraphRgbColorData(A3D_DEFAULT_COLOR_INDEX, &sRgbColorData));
DEFAULT_OFFSET;
}
break;
case 12 : // line stipple
{
if(uiCount > 0)
{
CHECK_RET(A3DGlobalGetGraphStyleData(*(puiStart+2), &sGraphStyleData));
A3D_DRAW_CALL1(BeginLineStipple, &sGraphStyleData);
CHECK_RET(A3DGlobalGetGraphStyleData(A3D_DEFAULT_STYLE_INDEX, &sGraphStyleData));
}
else
A3D_DRAW_CALL0(EndLineStipple);
DEFAULT_OFFSET;
}
break;
case 17 : // line width
{
if(*(puiStart+1) > 0)
{
A3D_DRAW_CALL1(BeginLineWidth, *pData);
}
else
A3D_DRAW_CALL0(EndLineWidth);
DEFAULT_OFFSET;
}
break;
case 15 : // points
{
START_TREAT_DRWENTITY_ATTRIBUT;
kSize = *(puiStart+1) / 3; // vertex number
if(bShow)
A3D_DRAW_CALL2(Point, pData, kSize);
DEFAULT_OFFSET;
END_TREAT_DRWENTITY_ATTRIBUT;
}
break;
case 13 : // font
{
sFontKeyData.m_iFontFamilyIndex = *(puiStart+2);
sFontKeyData.m_iFontStyleIndex = (*(puiStart+3) & kA3DFontKeyStyle) >> 24;
sFontKeyData.m_iFontSizeIndex = (*(puiStart+3) & kA3DFontKeySize) >> 12;
sFontKeyData.m_cAttributes = (A3DInt8)(*(puiStart+3) & kA3DFontKeyAttrib);
A3D_DRAW_CALL1(Font, &sFontKeyData);
DEFAULT_OFFSET;
}
break;
case 14 : // text
{
A3DUns32 uiTextIndex = *(puiStart+2);
A3DUTF8Char* pcBuffer = NULL;
if(uiTextIndex < psTessMarkupData->m_uiTextsSize)
pcBuffer = psTessMarkupData->m_ppcTexts[uiTextIndex];
//A3D_DRAW_CALL3(Text, pcBuffer, *pData, *(pData+1));
// Draw Text
A3DRiSet *pSet = NULL;
A3DDouble dLength = 0.;
if(A3DGlobalFontTextTessellationGet(&sFontKeyData, pcBuffer, &pSet, &dLength) == A3D_SUCCESS)
{
A3DRiSetData sDataSet;
A3D_INITIALIZE_DATA(A3DRiSetData, sDataSet);
if(A3DRiSetGet(pSet, &sDataSet) == A3D_SUCCESS)
{
A3DMiscCascadedAttributes* psCascadeAttribute;
A3DMiscCascadedAttributesCreate(&psCascadeAttribute);
stDrawSet(pSet, psCascadeAttribute);
A3DMiscCascadedAttributesDelete(psCascadeAttribute);
A3DRiSetGet(nullptr, &sDataSet);
}
}
A3DGlobalFontTextTessellationGet(NULL, pcBuffer, &pSet, &dLength);
DEFAULT_OFFSET;
}
break;
case 0 : // pattern
{
START_TREAT_DRWENTITY_ATTRIBUT;
if(bShow)
{
A3DUns32 uiLoopCount = uiCount-3;
A3DUns32* puiLoopsPointSize = (A3DUns32*)malloc(uiLoopCount * sizeof(A3DUns32));
for(A3DUns32 ui = 0; ui < uiLoopCount; ui++)
puiLoopsPointSize[ui] = *(puiStart+5+ui);
A3D_DRAW_CALL6(Pattern, uiLoopCount, *(puiStart+2), *(puiStart+3), *(puiStart+4), pData,
puiLoopsPointSize);
free(puiLoopsPointSize);
}
DEFAULT_OFFSET;
END_TREAT_DRWENTITY_ATTRIBUT;
}
break;
case 1 : // picture
{
START_TREAT_DRWENTITY_ATTRIBUT;
if(bShow)
{
CHECK_RET(A3DGlobalGetGraphPictureData(*(puiStart+2), &sPictureData));
A3D_DRAW_CALL1(Picture, &sPictureData);
}
DEFAULT_OFFSET;
END_TREAT_DRWENTITY_ATTRIBUT;
}
break;
default :
DEFAULT_OFFSET;
}
}
else if(*puiStart & kA3DMarkupIsMatrix)
{
if(*(puiStart+1) > 0) // if there are floats, beginning the "matrix" mode
{
A3D_DRAW_CALL0(PushMatrix);
A3D_DRAW_CALL1(MultMatrix, pData);
//dScaleText=stGetScaleText(pData);
MAKE_OFFSET(0, 16);
}
else // if there aren't any floats, ending the "matrix" mode
{
A3D_DRAW_CALL0(PopMatrix);
MAKE_OFFSET(0, 0);
}
}
else
{
START_TREAT_DRWENTITY_ATTRIBUT;
if(bShow)
{
kSize = *(puiStart+1) / 3; // vertex number
A3D_DRAW_CALL2(PolyLine, pData, kSize);
}
DEFAULT_OFFSET;
END_TREAT_DRWENTITY_ATTRIBUT;
}
}
#undef DEFAULT_OFFSET
#undef MAKE_OFFSET
#undef SIZE_ARROW
return iRet;
}
//######################################################################################################################
static A3DStatus stDrawTessMarkup(const A3DTessMarkup* pTessMarkup, const A3DRiRepresentationItem* pRepItem,
const A3DMiscCascadedAttributes* pFatherAttr)
{
A3DStatus iRet = A3D_SUCCESS;
//A3DInternalMarkup* psTessMarkup = TFG_BASE_NEW A3DInternalMarkup();
A3DTessMarkupData sMarkupData;
A3D_INITIALIZE_DATA(A3DTessMarkupData, sMarkupData);
CHECK_RET(A3DTessMarkupGet(pTessMarkup, &sMarkupData));
if((sMarkupData.m_cBehaviour & kA3DMarkupIsHidden) || sMarkupData.m_uiCodesSize == 0)
{
CHECK_RET(A3DTessMarkupGet(NULL, &sMarkupData));
return iRet;
}
A3DTessBaseData sBaseData;
A3D_INITIALIZE_DATA(A3DTessBaseData, sBaseData);
CHECK_RET(A3DTessBaseGet(pTessMarkup, &sBaseData));
if(stbUseCallbacks)
stDrawMarkupTessellation(&sBaseData, &sMarkupData, pRepItem, pFatherAttr);
else
{
A3DBoundingBoxData sMarkupBox;
stEvaluateMarkupTessellationBox(&sBaseData, &sMarkupData, &sMarkupBox);
stExtentUnion(&sMarkupBox, stpsBoundingBox, stpsBoundingBox);
}
CHECK_RET(A3DTessBaseGet(NULL, &sBaseData));
CHECK_RET(A3DTessMarkupGet(NULL, &sMarkupData));
return iRet;
}
//######################################################################################################################
static A3DStatus stDrawTessBase(A3DTessBase* pTessBase, const A3DRiRepresentationItem* pRepItem,
const A3DMiscCascadedAttributes* pFatherAttr)
{
if(pTessBase == NULL)
return A3D_ERROR;
A3DStatus iRet = A3D_SUCCESS;
A3DEEntityType eEntityType;
CHECK_RET(A3DEntityGetType(pTessBase, &eEntityType));
switch(eEntityType)
{
case kA3DTypeTess3D :
{
CHECK_RET(stDrawTess3D((A3DTess3D*)pTessBase, pRepItem, pFatherAttr));
break;
}
case kA3DTypeTess3DWire :
{
CHECK_RET(stDrawTess3DWire((A3DTess3DWire*)pTessBase, pRepItem, pFatherAttr));
break;
}
case kA3DTypeTessMarkup :
{
CHECK_RET(stDrawTessMarkup((A3DTessMarkup*)pTessBase, pRepItem, pFatherAttr));
break;
}
default:
break;
}
return iRet;
}
//######################################################################################################################
static A3DStatus stDrawRepresentationItem(const A3DRiRepresentationItem* pRepItem,
const A3DMiscCascadedAttributes* pFatherAttr);
//######################################################################################################################
static A3DStatus stDrawSet(const A3DRiSet* pSet, const A3DMiscCascadedAttributes* pFatherAttr)
{
A3DStatus iRet = A3D_SUCCESS;
A3DMiscCascadedAttributes* pAttr;
A3DMiscCascadedAttributesData sAttrData;
CHECK_RET(stCreateAndPushCascadedAttributes(pSet, pFatherAttr, &pAttr, &sAttrData));
if(sAttrData.m_bShow && !sAttrData.m_bRemoved && stIsShow(pSet) == A3D_SUCCESS)
{
A3DRiSetData sData;
A3D_INITIALIZE_DATA(A3DRiSetData, sData);
CHECK_RET(A3DRiSetGet(pSet, &sData));
A3DUns32 ui;
for(ui = 0; ui < sData.m_uiRepItemsSize; ui++)
{
CHECK_RET(stDrawRepresentationItem(sData.m_ppRepItems[ui], pAttr));
}
CHECK_RET(A3DRiSetGet(NULL, &sData));
}
CHECK_RET(A3DMiscCascadedAttributesDelete(pAttr));
return iRet;
}
//######################################################################################################################
static A3DStatus stDrawRepresentationItem(const A3DRiRepresentationItem* pRepItem,
const A3DMiscCascadedAttributes* pFatherAttr)
{
A3DStatus iRet = A3D_SUCCESS;
A3DMiscCascadedAttributes* pAttr;
A3DMiscCascadedAttributesData sAttrData;
CHECK_RET(stCreateAndPushCascadedAttributes(pRepItem, pFatherAttr, &pAttr, &sAttrData));
if(sAttrData.m_bShow && !sAttrData.m_bRemoved && stIsShow(pRepItem) == A3D_SUCCESS)
{
A3DEEntityType eType=kA3DTypeUnknown;
CHECK_RET(A3DEntityGetType(pRepItem, &eType));
if(eType == kA3DTypeRiSet)
{
CHECK_RET(stDrawSet((A3DRiSet*)pRepItem, pAttr));
}
else
{
//uiTotalRepItems++;
A3DRootBaseData sRootBaseData;
A3D_INITIALIZE_DATA(A3DRootBaseData, sRootBaseData);
CHECK_RET(A3DRootBaseGet(pRepItem, &sRootBaseData));
stpcRepresentationItemName = sRootBaseData.m_pcName;
if(sRootBaseData.m_uiSize>0)
{
for(A3DUns32 ui=0;ui<sRootBaseData.m_uiSize;ui++)
{
A3DMiscAttributeData sMiscAttrData;
A3D_INITIALIZE_DATA(A3DMiscAttributeData, sMiscAttrData);
CHECK_RET(A3DMiscAttributeGet(sRootBaseData.m_ppAttributes[ui], &sMiscAttrData));
CHECK_RET(A3DMiscAttributeGet(NULL, &sMiscAttrData));
}
}
A3DRiRepresentationItemData sData;
A3D_INITIALIZE_DATA(A3DRiRepresentationItemData, sData);
CHECK_RET(A3DRiRepresentationItemGet(pRepItem, &sData));
const A3DRiCoordinateSystem* pCoordSys = NULL;
if(sAttrData.m_pCoordinateSystem !=
NULL)
pCoordSys = sAttrData.m_pCoordinateSystem;
else if(sData.m_pCoordinateSystem != NULL)
pCoordSys = sData.m_pCoordinateSystem;
if(pCoordSys != NULL)
{
A3D_DRAW_CALL0(PushMatrix);
stPushMatrix();
A3DRiCoordinateSystemData sCSysData;
A3D_INITIALIZE_DATA(A3DRiCoordinateSystemData, sCSysData);
CHECK_RET(A3DRiCoordinateSystemGet(sData.m_pCoordinateSystem, &sCSysData));
CHECK_RET(stDrawTransformation(sCSysData.m_pTransformation));
CHECK_RET(A3DRiCoordinateSystemGet(NULL, &sCSysData));
}
if(sData.m_pTessBase != NULL)
{
CHECK_RET(stDrawTessBase(sData.m_pTessBase, pRepItem, pAttr));
}
else
{
A3DRWParamsTessellationData sTesselationData;
A3D_INITIALIZE_DATA(A3DRWParamsTessellationData, sTesselationData);
sTesselationData.m_eTessellationLevelOfDetail=kA3DTessLODExtraLow;
CHECK_RET(A3DRiRepresentationItemComputeTessellation((A3DRiRepresentationItem *) pRepItem,
&sTesselationData));
A3D_INITIALIZE_DATA(A3DRiRepresentationItemData, sData);
CHECK_RET(A3DRiRepresentationItemGet(pRepItem, &sData));
if(sData.m_pTessBase != NULL)
{
CHECK_RET(stDrawTessBase(sData.m_pTessBase, pRepItem, pAttr));
}
}
if(pCoordSys != NULL)
{
A3D_DRAW_CALL0(PopMatrix);
stPopMatrix();
}
CHECK_RET(A3DRiRepresentationItemGet(NULL, &sData));
stpcRepresentationItemName = NULL;
CHECK_RET(A3DRootBaseGet(NULL, &sRootBaseData));
}
}
CHECK_RET(A3DMiscCascadedAttributesDelete(pAttr));
return iRet;
}
//######################################################################################################################
static A3DStatus stDrawLeader(const A3DMkpLeader* pMkpLeader, const A3DMiscCascadedAttributes* pFatherAttr)
{
A3DStatus iRet = A3D_SUCCESS;
A3DMkpLeaderData sMkpLeaderData;
A3D_INITIALIZE_DATA(A3DMkpLeaderData, sMkpLeaderData);
CHECK_RET(A3DMkpLeaderGet(pMkpLeader,&sMkpLeaderData));
if(sMkpLeaderData.m_pTessellation != NULL)
{
CHECK_RET(stDrawTessBase((A3DTessBase*)sMkpLeaderData.m_pTessellation, NULL, pFatherAttr));
}
CHECK_RET(A3DMkpLeaderGet(NULL, &sMkpLeaderData));
return iRet;
}
//######################################################################################################################
A3DStatus DrawMarkup(const A3DMkpMarkup* pMarkup, const A3DMiscCascadedAttributes* pFatherAttr)
{
A3DStatus iRet = A3D_SUCCESS;
A3DMiscCascadedAttributes* pAttr;
A3DMiscCascadedAttributesData sAttrData;
CHECK_RET(stCreateAndPushCascadedAttributes(pMarkup, pFatherAttr, &pAttr, &sAttrData));
if(sAttrData.m_bShow && !sAttrData.m_bRemoved)
{
A3DRootBaseData sRootBaseData;
A3D_INITIALIZE_DATA(A3DRootBaseData, sRootBaseData);
CHECK_RET(A3DRootBaseGet(pMarkup, &sRootBaseData));
A3D_DRAW_CALL3(Begin, kA3DDrawBeginEndMarkup, sRootBaseData.m_pcName, 0);
A3DMkpMarkupData sMarkupData;
A3D_INITIALIZE_DATA(A3DMkpMarkupData, sMarkupData);
CHECK_RET(A3DMkpMarkupGet(pMarkup,&sMarkupData));
A3DEMarkupType eType;
A3DEMarkupSubType eSubType;
eType = sMarkupData.m_eType;
eSubType = sMarkupData.m_eSubType;
if(sMarkupData.m_pTessellation != NULL)
{
CHECK_RET(stDrawTessBase((A3DTessBase*)sMarkupData.m_pTessellation, NULL, pAttr));
}
A3DUns32 ui;
for(ui=0;ui<sMarkupData.m_uiLeadersSize;ui++)
{
CHECK_RET(stDrawLeader(sMarkupData.m_ppLeaders[ui], pAttr));
}
CHECK_RET(A3DMkpMarkupGet(NULL, &sMarkupData));
A3D_DRAW_CALL1(End, kA3DDrawBeginEndMarkup);
CHECK_RET(A3DRootBaseGet(NULL, &sRootBaseData));
//uiTotalMarkups++;
}
CHECK_RET(A3DMiscCascadedAttributesDelete(pAttr));
return iRet;
}
//######################################################################################################################
static A3DStatus stDrawAnnotation(const A3DMkpAnnotationEntity* pAnnotation,
const A3DMiscCascadedAttributes* pFatherAttr);
//######################################################################################################################
static A3DStatus stDrawAnnotationSet(const A3DMkpAnnotationSet* pAnnotationSet,
const A3DMiscCascadedAttributes* pFatherAttr)
{
A3DStatus iRet = A3D_SUCCESS;
A3DMiscCascadedAttributes* pAttr;
A3DMiscCascadedAttributesData sAttrData;
CHECK_RET(stCreateAndPushCascadedAttributes(pAnnotationSet, pFatherAttr, &pAttr, &sAttrData));
if(sAttrData.m_bShow && !sAttrData.m_bRemoved)
{
A3DMkpAnnotationSetData sAnnotationSetData;
A3D_INITIALIZE_DATA(A3DMkpAnnotationSetData, sAnnotationSetData);
CHECK_RET(A3DMkpAnnotationSetGet(pAnnotationSet,&sAnnotationSetData));
A3DUns32 ui;
for(ui = 0; ui < sAnnotationSetData.m_uiAnnotationsSize; ui++)
{
CHECK_RET(stDrawAnnotation(sAnnotationSetData.m_ppAnnotations[ui], pAttr));
}
CHECK_RET(A3DMkpAnnotationSetGet(NULL, &sAnnotationSetData));
}
CHECK_RET(A3DMiscCascadedAttributesDelete(pAttr));
return iRet;
}
//######################################################################################################################
static A3DStatus stDrawAnnotationReference(const A3DMkpAnnotationItem* /*pAnnotationItem*/,
const A3DMiscCascadedAttributes* /*pFatherAttr*/)
{
A3DStatus iRet = A3D_SUCCESS;
return iRet;
}
//######################################################################################################################
static A3DStatus stDrawAnnotationItem(const A3DMkpAnnotationItem* pAnnotationItem,
const A3DMiscCascadedAttributes* pFatherAttr)
{
A3DStatus iRet = A3D_SUCCESS;
A3DMiscCascadedAttributes* pAttr;
A3DMiscCascadedAttributesData sAttrData;
CHECK_RET(stCreateAndPushCascadedAttributes(pAnnotationItem, pFatherAttr, &pAttr, &sAttrData));
if(sAttrData.m_bShow && !sAttrData.m_bRemoved)
{
A3DMkpAnnotationItemData sAnnotationItemData;
A3D_INITIALIZE_DATA(A3DMkpAnnotationItemData, sAnnotationItemData);
CHECK_RET(A3DMkpAnnotationItemGet(pAnnotationItem,&sAnnotationItemData));
CHECK_RET(DrawMarkup(sAnnotationItemData.m_pMarkup, pAttr));
CHECK_RET(A3DMkpAnnotationItemGet(NULL, &sAnnotationItemData));
}
CHECK_RET(A3DMiscCascadedAttributesDelete(pAttr));
return iRet;
}
//######################################################################################################################
static A3DStatus stDrawAnnotation(const A3DMkpAnnotationEntity* pAnnotation,
const A3DMiscCascadedAttributes* pFatherAttr)
{
A3DStatus iRet = A3D_SUCCESS;
A3DEEntityType eType=kA3DTypeUnknown;
CHECK_RET(A3DEntityGetType(pAnnotation,&eType));
switch(eType)
{
case kA3DTypeMkpAnnotationSet:
CHECK_RET(stDrawAnnotationSet(pAnnotation, pFatherAttr));
break;
case kA3DTypeMkpAnnotationReference:
CHECK_RET(stDrawAnnotationReference(pAnnotation, pFatherAttr));
break;
case kA3DTypeMkpAnnotationItem:
CHECK_RET(stDrawAnnotationItem(pAnnotation, pFatherAttr));
break;
default:
break;
}
return iRet;
}
//######################################################################################################################
#ifdef VIEWS
static A3DStatus stDrawView(const A3DMkpView* pView, const A3DMiscCascadedAttributes* pFatherAttr)
{
A3DStatus iRet = A3D_SUCCESS;
A3DMiscCascadedAttributes* pAttr;
A3DMiscCascadedAttributesData sAttrData;
CHECK_RET(stCreateAndPushCascadedAttributes(pView, pFatherAttr, &pAttr, &sAttrData));
if(/*sAttrData.m_bShow && */!sAttrData.m_bRemoved) // TODO m_bShow
{
A3DMkpViewData sViewData;
A3D_INITIALIZE_DATA(A3DMkpViewData, sViewData);
CHECK_RET(A3DMkpViewGet(pView, &sViewData));
for(A3DUns32 ui = 0; ui < sViewData.m_uiAnnotationsSize; ui++)
{
CHECK_RET(stDrawAnnotation(sViewData.m_ppAnnotations[ui], pAttr));
}
CHECK_RET(A3DMkpViewGet(NULL, &sViewData));
}
CHECK_RET(A3DMiscCascadedAttributesDelete(pAttr));
return iRet;
}
#endif
//######################################################################################################################
static A3DStatus stAnnotationGetMarkups(const A3DMkpAnnotationEntity* pAnnotation, A3DPointerArray* psArray);
//######################################################################################################################
static A3DStatus stPartDefinitionGetMarkups(const A3DAsmPartDefinitionData* psPartData, A3DPointerArray* psArray)
{
if(psPartData == NULL || psArray == NULL)
return A3D_ERROR;
A3DStatus iRet = A3D_SUCCESS;
A3DUns32 ui, uiSize = psPartData->m_uiAnnotationsSize;
for(ui = 0; ui < uiSize; ui++)
{
CHECK_RET(stAnnotationGetMarkups(psPartData->m_ppAnnotations[ui], psArray));
}
return iRet;
}
//######################################################################################################################
static A3DStatus stDrawPartDefinition(const A3DAsmPartDefinition* pPart, const A3DMiscCascadedAttributes* pFatherAttr)
{
A3DStatus iRet = A3D_SUCCESS;
A3DMiscCascadedAttributes* pAttr;
A3DMiscCascadedAttributesData sAttrData;
CHECK_RET(stCreateAndPushCascadedAttributes(pPart, pFatherAttr, &pAttr, &sAttrData));
if(sAttrData.m_bShow && !sAttrData.m_bRemoved && stIsShow(pPart) == A3D_SUCCESS)
{
A3DAsmPartDefinitionData sData;
A3D_INITIALIZE_DATA(A3DAsmPartDefinitionData, sData);
CHECK_RET(A3DAsmPartDefinitionGet(pPart, &sData));
CHECK_RET(stDrawBoundingBox(&sData.m_sBoundingBox));
if(stbDraw3D)
{
A3DUns32 ui;
for(ui = 0; ui < sData.m_uiRepItemsSize; ui++)
{
CHECK_RET(stDrawRepresentationItem(sData.m_ppRepItems[ui], pAttr));
}
}
if(stbDrawMarkups)
{
A3DPointerArray sMarkups;
stPointerArrayInitialize(&sMarkups);
stPartDefinitionGetMarkups(&sData, &sMarkups);
A3DUns32 ui;
#ifdef VIEWS
for(ui = 0; ui < sData.m_uiViewsSize; ui++)
CHECK_RET(stDrawView(sData.m_ppViews[ui], pAttr));
#endif
A3DUns32 uiSize = sMarkups.m_uiSize;
for(ui = 0; ui < uiSize; ui++)
CHECK_RET(DrawMarkup(sMarkups.m_ppPointers[ui], pAttr));
stPointerArrayTerminate(&sMarkups);
}
CHECK_RET(A3DAsmPartDefinitionGet(NULL, &sData));
}
CHECK_RET(A3DMiscCascadedAttributesDelete(pAttr));
return iRet;
}
//######################################################################################################################
static A3DStatus stProductOccurrenceGetExternalData(const A3DAsmProductOccurrenceData* psPOccData,
A3DAsmProductOccurrence** ppExternalData)
{
if(psPOccData == NULL)
return A3D_ERROR;
A3DStatus iRet = A3D_SUCCESS;
if(psPOccData->m_pExternalData == NULL && psPOccData->m_pPrototype != NULL)
{
A3DAsmProductOccurrenceData sProductPrototypeData;
A3D_INITIALIZE_DATA(A3DAsmProductOccurrenceData, sProductPrototypeData);
CHECK_RET(A3DAsmProductOccurrenceGet(psPOccData->m_pPrototype, &sProductPrototypeData));
CHECK_RET(stProductOccurrenceGetExternalData(&sProductPrototypeData, ppExternalData));
CHECK_RET(A3DAsmProductOccurrenceGet(NULL, &sProductPrototypeData));
}
else
*ppExternalData = psPOccData->m_pExternalData;
return iRet;
}
//######################################################################################################################
static A3DStatus stProductOccurrenceGetPart(const A3DAsmProductOccurrenceData* psPOccData,
A3DAsmPartDefinition** ppPart)
{
if(psPOccData == NULL)
return A3D_ERROR;
A3DStatus iRet = A3D_SUCCESS;
*ppPart = NULL;
if(psPOccData->m_pPart != NULL)
{
*ppPart = psPOccData->m_pPart;
return iRet;
}
A3DAsmProductOccurrence* pProductPrototype = psPOccData->m_pPrototype;
while(pProductPrototype != NULL)
{
A3DAsmProductOccurrenceData sProductPrototypeData;
A3D_INITIALIZE_DATA(A3DAsmProductOccurrenceData, sProductPrototypeData);
CHECK_RET(A3DAsmProductOccurrenceGet(pProductPrototype, &sProductPrototypeData));
if(sProductPrototypeData.m_pPart != NULL)
{
CHECK_RET(A3DAsmProductOccurrenceGet(NULL, &sProductPrototypeData));
*ppPart = sProductPrototypeData.m_pPart;
return iRet;
}
else
pProductPrototype = sProductPrototypeData.m_pPrototype;
CHECK_RET(A3DAsmProductOccurrenceGet(NULL, &sProductPrototypeData));
}
if(psPOccData->m_uiPOccurrencesSize == 0)
{
A3DAsmProductOccurrence* pExternal = NULL;
CHECK_RET(stProductOccurrenceGetExternalData(psPOccData, &pExternal));
if(pExternal != NULL)
{
A3DAsmProductOccurrenceData sExternalDataData;
A3D_INITIALIZE_DATA(A3DAsmProductOccurrenceData, sExternalDataData);
CHECK_RET(A3DAsmProductOccurrenceGet(pExternal, &sExternalDataData));
A3DAsmPartDefinition* pPartDefinition;
CHECK_RET(stProductOccurrenceGetPart(&sExternalDataData, &pPartDefinition));
*ppPart = pPartDefinition;
CHECK_RET(A3DAsmProductOccurrenceGet(NULL, &sExternalDataData));
return iRet;
}
}
return iRet;
}
//######################################################################################################################
static A3DStatus stProductOccurrenceGetLocation(const A3DAsmProductOccurrenceData* psPOccData,
A3DMiscCartesianTransformation** ppLocation)
{
if(psPOccData == NULL)
return A3D_ERROR;
A3DStatus iRet = A3D_SUCCESS;
*ppLocation = NULL;
if(psPOccData->m_pLocation != NULL)
{
*ppLocation = psPOccData->m_pLocation;
return iRet;
}
A3DAsmProductOccurrence* pProductPrototype = psPOccData->m_pPrototype;
while(pProductPrototype != NULL)
{
A3DAsmProductOccurrenceData sProductPrototypeData;
A3D_INITIALIZE_DATA(A3DAsmProductOccurrenceData, sProductPrototypeData);
CHECK_RET(A3DAsmProductOccurrenceGet(pProductPrototype, &sProductPrototypeData));
if(sProductPrototypeData.m_pLocation != NULL)
{
CHECK_RET(A3DAsmProductOccurrenceGet(NULL, &sProductPrototypeData));
*ppLocation = sProductPrototypeData.m_pLocation;
return iRet;
}
else
pProductPrototype = sProductPrototypeData.m_pPrototype;
CHECK_RET(A3DAsmProductOccurrenceGet(NULL, &sProductPrototypeData));
}
if(psPOccData->m_uiPOccurrencesSize == 0)
{
A3DAsmProductOccurrence* pExternal = NULL;
CHECK_RET(stProductOccurrenceGetExternalData(psPOccData, &pExternal));
if(pExternal != NULL)
{
A3DAsmProductOccurrenceData sExternalDataData;
A3D_INITIALIZE_DATA(A3DAsmProductOccurrenceData, sExternalDataData);
CHECK_RET(A3DAsmProductOccurrenceGet(pExternal, &sExternalDataData));
A3DAsmPartDefinition* pLoc;
CHECK_RET(stProductOccurrenceGetLocation(&sExternalDataData, &pLoc));
*ppLocation = pLoc;
CHECK_RET(A3DAsmProductOccurrenceGet(NULL, &sExternalDataData));
return iRet;
}
}
return iRet;
}
//######################################################################################################################
static A3DStatus stProductOccurrenceGetOccurrences(const A3DAsmProductOccurrenceData* psPOccData,
A3DPointerArray* psArray)
{
if(psPOccData == NULL || psArray == NULL)
return A3D_ERROR;
A3DStatus iRet = A3D_SUCCESS;
if(psPOccData->m_uiPOccurrencesSize == 0 && psPOccData->m_pPrototype != NULL)
{
A3DAsmProductOccurrenceData sPrototypeData;
A3D_INITIALIZE_DATA(A3DAsmProductOccurrenceData, sPrototypeData);
CHECK_RET(A3DAsmProductOccurrenceGet(psPOccData->m_pPrototype, &sPrototypeData));
CHECK_RET(stProductOccurrenceGetOccurrences(&sPrototypeData, psArray));
CHECK_RET(A3DAsmProductOccurrenceGet(NULL, &sPrototypeData));
}
else
{
stPointerArrayAddArray(psArray, psPOccData->m_ppPOccurrences, psPOccData->m_uiPOccurrencesSize);
}
return iRet;
}
//######################################################################################################################
static A3DStatus stProductOccurrenceGetSons(const A3DAsmProductOccurrenceData* psPOccData, A3DPointerArray* psArray)
{
if(psPOccData == NULL || psArray == NULL)
return A3D_ERROR;
A3DStatus iRet = A3D_SUCCESS;
CHECK_RET(stProductOccurrenceGetOccurrences(psPOccData, psArray));
A3DAsmProductOccurrence* pExternal = NULL;
CHECK_RET(stProductOccurrenceGetExternalData(psPOccData, &pExternal));
if(pExternal != NULL)
{
A3DAsmProductOccurrenceData sExternalDataData;
A3D_INITIALIZE_DATA(A3DAsmProductOccurrenceData, sExternalDataData);
CHECK_RET(A3DAsmProductOccurrenceGet(pExternal, &sExternalDataData));
if(psArray->m_uiSize == 0)
{
CHECK_RET(stProductOccurrenceGetSons(&sExternalDataData, psArray));
}
else
stPointerArrayAdd(psArray, pExternal);
CHECK_RET(A3DAsmProductOccurrenceGet(NULL, &sExternalDataData));
}
return iRet;
}
//######################################################################################################################
static A3DStatus stProductOccurrenceGetViews(const A3DAsmProductOccurrenceData* psPOccData, A3DPointerArray* psArray)
{
if(psPOccData == NULL || psArray == NULL)
return A3D_ERROR;
A3DStatus iRet = A3D_SUCCESS;
if(psPOccData->m_uiViewsSize == 0 && psPOccData->m_pPrototype != NULL)
{
A3DAsmProductOccurrenceData sPrototypeData;
A3D_INITIALIZE_DATA(A3DAsmProductOccurrenceData, sPrototypeData);
CHECK_RET(A3DAsmProductOccurrenceGet(psPOccData->m_pPrototype, &sPrototypeData));
CHECK_RET(stProductOccurrenceGetViews(&sPrototypeData, psArray));
CHECK_RET(A3DAsmProductOccurrenceGet(NULL, &sPrototypeData));
}
else
stPointerArrayAddArray(psArray, psPOccData->m_ppViews, psPOccData->m_uiViewsSize);
return iRet;
}
//######################################################################################################################
static A3DStatus stAnnotationSetGetMarkups(const A3DMkpAnnotationSet* pAnnotationSet, A3DPointerArray* psArray)
{
A3DStatus iRet = A3D_SUCCESS;
A3DMkpAnnotationSetData sAnnotationSetData;
A3D_INITIALIZE_DATA(A3DMkpAnnotationSetData, sAnnotationSetData);
CHECK_RET(A3DMkpAnnotationSetGet(pAnnotationSet,&sAnnotationSetData));
for(A3DUns32 ui = 0; ui < sAnnotationSetData.m_uiAnnotationsSize; ui++)
{
CHECK_RET(stAnnotationGetMarkups(sAnnotationSetData.m_ppAnnotations[ui], psArray));
}
CHECK_RET(A3DMkpAnnotationSetGet(NULL, &sAnnotationSetData));
return iRet;
}
//######################################################################################################################
static A3DStatus stAnnotationReferenceGetMarkups(const A3DMkpAnnotationItem* /*pAnnotationItem*/, A3DPointerArray* /*psArray*/)
{
A3DStatus iRet = A3D_SUCCESS;
return iRet;
}
//######################################################################################################################
static A3DStatus stAnnotationItemGetMarkups(const A3DMkpAnnotationItem* pAnnotationItem, A3DPointerArray* psArray)
{
if(pAnnotationItem == NULL || psArray == NULL)
return A3D_ERROR;
A3DStatus iRet = A3D_SUCCESS;
A3DMkpAnnotationItemData sAnnotationItemData;
A3D_INITIALIZE_DATA(A3DMkpAnnotationItemData, sAnnotationItemData);
CHECK_RET(A3DMkpAnnotationItemGet(pAnnotationItem,&sAnnotationItemData));
stPointerArrayAddUnique(psArray, sAnnotationItemData.m_pMarkup);
CHECK_RET(A3DMkpAnnotationItemGet(NULL, &sAnnotationItemData));
return iRet;
}
//######################################################################################################################
static A3DStatus stAnnotationGetMarkups(const A3DMkpAnnotationEntity* pAnnotation, A3DPointerArray* psArray)
{
A3DStatus iRet = A3D_SUCCESS;
A3DEEntityType eType=kA3DTypeUnknown;
CHECK_RET(A3DEntityGetType(pAnnotation,&eType));
switch(eType)
{
case kA3DTypeMkpAnnotationSet:
CHECK_RET(stAnnotationSetGetMarkups(pAnnotation, psArray));
break;
case kA3DTypeMkpAnnotationReference:
CHECK_RET(stAnnotationReferenceGetMarkups(pAnnotation, psArray));
break;
case kA3DTypeMkpAnnotationItem:
CHECK_RET(stAnnotationItemGetMarkups(pAnnotation, psArray));
break;
default:
break;
}
return iRet;
}
//######################################################################################################################
static A3DStatus stProductOccurrenceGetMarkups(const A3DAsmProductOccurrenceData* psPOccData, A3DPointerArray* psArray)
{
if(psPOccData == NULL || psArray == NULL)
return A3D_ERROR;
A3DStatus iRet = A3D_SUCCESS;
if(psPOccData->m_uiAnnotationsSize == 0 && psPOccData->m_pPrototype != NULL)
{
A3DAsmProductOccurrenceData sPrototypeData;
A3D_INITIALIZE_DATA(A3DAsmProductOccurrenceData, sPrototypeData);
CHECK_RET(A3DAsmProductOccurrenceGet(psPOccData->m_pPrototype, &sPrototypeData));
CHECK_RET(stProductOccurrenceGetMarkups(&sPrototypeData, psArray));
CHECK_RET(A3DAsmProductOccurrenceGet(NULL, &sPrototypeData));
}
else
{
unsigned int ui, uiSize = psPOccData->m_uiAnnotationsSize;
for(ui = 0; ui < uiSize; ui++)
{
CHECK_RET(stAnnotationGetMarkups(psPOccData->m_ppAnnotations[ui], psArray));
}
}
return iRet;
}
//######################################################################################################################
static A3DStatus stDrawProductOccurrence(const A3DAsmProductOccurrence* pOccurrence,
const A3DMiscCascadedAttributes* pFatherAttr)
{
A3DStatus iRet = A3D_SUCCESS;
A3DMiscCascadedAttributes* pAttr;
A3DMiscCascadedAttributesData sAttrData;
CHECK_RET(stCreateAndPushCascadedAttributes(pOccurrence, pFatherAttr, &pAttr, &sAttrData));
if(sAttrData.m_bShow && !sAttrData.m_bRemoved && stIsShow(pOccurrence) == A3D_SUCCESS)
{
A3DAsmProductOccurrenceData sData;
A3D_INITIALIZE_DATA(A3DAsmProductOccurrenceData, sData);
CHECK_RET(A3DAsmProductOccurrenceGet(pOccurrence, &sData));
if(sData.m_ucBehaviour != 1)
{
A3DRootBaseData sRootBaseData;
A3D_INITIALIZE_DATA(A3DRootBaseData, sRootBaseData);
CHECK_RET(A3DRootBaseGet(pOccurrence, &sRootBaseData));
if(sRootBaseData.m_uiSize>0)
{
for(A3DUns32 ui=0;ui<sRootBaseData.m_uiSize;ui++)
{
A3DMiscAttributeData sMiscAttrData;
A3D_INITIALIZE_DATA(A3DMiscAttributeData, sMiscAttrData);
CHECK_RET(A3DMiscAttributeGet(sRootBaseData.m_ppAttributes[ui], &sMiscAttrData));
CHECK_RET(A3DMiscAttributeGet(NULL, &sMiscAttrData));
}
}
A3D_DRAW_CALL3(Begin, kA3DDrawBeginEndProductOccurrence, sRootBaseData.m_pcName, 0);
A3DMiscTransformation* pLocation = NULL;
CHECK_RET(stProductOccurrenceGetLocation(&sData, &pLocation));
if(pLocation != NULL)
{
A3D_DRAW_CALL0(PushMatrix);
stPushMatrix();
CHECK_RET(stDrawTransformation(pLocation));
}
A3DAsmPartDefinition* pPart = NULL;
CHECK_RET(stProductOccurrenceGetPart(&sData, &pPart));
if(pPart != NULL)
{
CHECK_RET(stDrawPartDefinition(pPart, pAttr));
}
A3DPointerArray sSons;
stPointerArrayInitialize(&sSons);
CHECK_RET(stProductOccurrenceGetSons(&sData, &sSons));
A3DUns32 ui, uiSize = sSons.m_uiSize;
for(ui = 0; ui < uiSize; ui++)
CHECK_RET(stDrawProductOccurrence(sSons.m_ppPointers[ui], pAttr));
stPointerArrayTerminate(&sSons);
if(stbDrawMarkups)
{
A3DPointerArray sMarkups, sViews;
stPointerArrayInitialize(&sMarkups);
stPointerArrayInitialize(&sViews);
stProductOccurrenceGetMarkups(&sData, &sMarkups);
stProductOccurrenceGetViews(&sData, &sViews);
#ifdef VIEWS
uiSize = sViews.m_uiSize;
for(ui = 0; ui < uiSize; ui++)
CHECK_RET(stDrawView(sViews.m_ppPointers[ui], pAttr));
#endif
uiSize = sMarkups.m_uiSize;
for(ui = 0; ui < uiSize; ui++)
CHECK_RET(DrawMarkup(sMarkups.m_ppPointers[ui], pAttr));
stPointerArrayTerminate(&sMarkups);
stPointerArrayTerminate(&sViews);
}
if(pLocation != NULL)
{
A3D_DRAW_CALL0(PopMatrix);
stPopMatrix();
}
A3D_DRAW_CALL1(End, kA3DDrawBeginEndProductOccurrence);
CHECK_RET(A3DRootBaseGet(NULL, &sRootBaseData));
}
CHECK_RET(A3DAsmProductOccurrenceGet(NULL, &sData));
}
CHECK_RET(A3DMiscCascadedAttributesDelete(pAttr));
return iRet;
}
//######################################################################################################################
static A3DStatus stDrawModel(const A3DAsmModelFile* pModelFile)
{
A3DAsmModelFileData sData;
A3D_INITIALIZE_DATA(A3DAsmModelFileData, sData);
A3DStatus iRet = A3D_SUCCESS;
CHECK_RET(A3DAsmModelFileGet(pModelFile, &sData));
A3DMiscCascadedAttributes* pAttr;
CHECK_RET(A3DMiscCascadedAttributesCreate(&pAttr));
for(A3DUns32 ui = 0; ui < sData.m_uiPOccurrencesSize; ui++)
CHECK_RET(stDrawProductOccurrence(sData.m_ppPOccurrences[ui], pAttr));
CHECK_RET(A3DAsmModelFileGet(NULL, &sData));
CHECK_RET(A3DMiscCascadedAttributesDelete(pAttr));
return iRet;
}
//######################################################################################################################
A3DStatus DrawRepresentationItem(const A3DRiRepresentationItem* pRepItem, const A3DMiscCascadedAttributes* pFatherAttr)
{
A3DStatus iRet = A3D_SUCCESS;
if(pRepItem == NULL)
return A3D_SUCCESS;
A3DRiRepresentationItemData sData;
A3D_INITIALIZE_DATA(A3DRiRepresentationItemData, sData);
CHECK_RET(A3DRiRepresentationItemGet(pRepItem, &sData));
if(sData.m_pTessBase != NULL)
{
CHECK_RET(stDrawTessBase(sData.m_pTessBase, pRepItem, pFatherAttr));
}
else
{
A3DRWParamsTessellationData sTesselationData;
A3D_INITIALIZE_DATA(A3DRWParamsTessellationData, sTesselationData);
sTesselationData.m_eTessellationLevelOfDetail=kA3DTessLODExtraLow;
CHECK_RET(A3DRiRepresentationItemComputeTessellation((A3DRiRepresentationItem *) pRepItem,&sTesselationData));
A3D_INITIALIZE_DATA(A3DRiRepresentationItemData, sData);
CHECK_RET(A3DRiRepresentationItemGet(pRepItem, &sData));
if(sData.m_pTessBase != NULL)
{
CHECK_RET(stDrawTessBase(sData.m_pTessBase, pRepItem, pFatherAttr));
}
}
CHECK_RET(A3DRiRepresentationItemGet(NULL, &sData));
return iRet;
}
//######################################################################################################################
A3DStatus Draw(const A3DAsmModelFile* pModelFile, A3DUns32 uiDrawFlags)
{
A3DStatus iRet = A3D_SUCCESS;
if(pModelFile == NULL)
return A3D_INVALID_ENTITY_NULL;
if(!stbCallbacksInitialized)
return A3D_ERROR;
stLoadIdentity();
stbDraw3D = (uiDrawFlags & kA3DDraw3D) != 0;
stbDrawMarkups = (uiDrawFlags & kA3DDrawMarkups) != 0;
stbUseCallbacks = true;
CHECK_RET(stDrawModel(pModelFile));
return iRet;
}
//######################################################################################################################
A3DStatus DrawGetBoundingBox(const A3DAsmModelFile* pModelFile, A3DBoundingBoxData* psBoundingBox, A3DUns32 uiDrawFlags)
{
//A3DCHECKINIT("A3DDrawGetBoundingBox");
//A3D_CHECKFILLED_POINTERDATA(A3DBoundingBoxData, psBoundingBox);
A3DStatus iRet = A3D_SUCCESS;
if(pModelFile == NULL)
return A3D_INVALID_ENTITY_NULL;
if(psBoundingBox == NULL)
return A3D_INVALID_DATA_STRUCT_NULL;
stLoadIdentity();
stExtentInit(psBoundingBox);
stbDraw3D = (uiDrawFlags & kA3DDraw3D) != 0;
stbDrawMarkups = (uiDrawFlags & kA3DDrawMarkups) != 0;
stpsBoundingBox = psBoundingBox;
stbUseCallbacks = false;
CHECK_RET(stDrawModel(pModelFile));
return iRet;
}