/*********************************************************************************************************************** * * 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 #include #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;iIdm_usUsedEntitiesFlags & kA3DTessFaceDataTriangleStripe) { iNbEntities = SIZE_TRIANGLE_ENTITY(iNumberIndex); iStartId = iNumberIndex+1; for(iId=0;iIdm_usUsedEntitiesFlags & kA3DTessFaceDataTriangleOneNormal) { iNbFacet+=SIZE_TRIANGLE_ENTITY(iNumberIndex); iNumberIndex++; } if(psTessFaceData->m_usUsedEntitiesFlags & kA3DTessFaceDataTriangleFanOneNormal) { iNbEntities = SIZE_TRIANGLE_ENTITY(iNumberIndex); iStartId = iNumberIndex+1; for(iId=0;iIdm_usUsedEntitiesFlags & kA3DTessFaceDataTriangleStripeOneNormal) { iNbEntities = SIZE_TRIANGLE_ENTITY(iNumberIndex); iStartId = iNumberIndex+1; for(iId=0;iIdm_usUsedEntitiesFlags & kA3DTessFaceDataTriangleTextured) { iNbFacet+=SIZE_TRIANGLE_ENTITY(iNumberIndex); iNumberIndex++; } if(psTessFaceData->m_usUsedEntitiesFlags & kA3DTessFaceDataTriangleFanTextured) { iNbEntities = SIZE_TRIANGLE_ENTITY(iNumberIndex); iStartId = iNumberIndex+1; for(iId=0;iIdm_usUsedEntitiesFlags & kA3DTessFaceDataTriangleStripeTextured) { iNbEntities = SIZE_TRIANGLE_ENTITY(iNumberIndex); iStartId = iNumberIndex+1; for(iId=0;iIdm_usUsedEntitiesFlags & kA3DTessFaceDataTriangleOneNormalTextured) { iNbFacet+=SIZE_TRIANGLE_ENTITY(iNumberIndex); iNumberIndex++; } if(psTessFaceData->m_usUsedEntitiesFlags & kA3DTessFaceDataTriangleFanOneNormalTextured) { iNbEntities = SIZE_TRIANGLE_ENTITY(iNumberIndex); iStartId = iNumberIndex+1; for(iId=0;iIdm_usUsedEntitiesFlags & kA3DTessFaceDataTriangleStripeOneNormalTextured) { iNbEntities = SIZE_TRIANGLE_ENTITY(iNumberIndex); iStartId = iNumberIndex+1; for(iId=0;iIdm_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 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 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;uim_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