/*********************************************************************************************************************** * * Copyright (c) 2010 - 2025 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. * ***********************************************************************************************************************/ /** \file wrapper/HXWMarkupTessellation.cpp ***********************************************************************************************************************/ #include #include "HXWMarkupTessellation.h" #include //###################################################################################################################### HXWMarkupTessellation::HXWMarkupTessellation() { A3D_INITIALIZE_DATA(A3DTessMarkupData, m_data); m_data.m_puiCodes = NULL; m_data.m_ppcTexts = NULL; m_data.m_uiCodesSize = m_uiAllocatedCodes = 0; m_data.m_uiTextsSize = m_uiAllocatedTexts = 0; } //###################################################################################################################### HXWMarkupTessellation::~HXWMarkupTessellation() { reset(); } //###################################################################################################################### A3DEntity* HXWMarkupTessellation::GetEntity() { A3DTessMarkup* pTessMarkup; GetMarkupTess(pTessMarkup); return pTessMarkup; } //###################################################################################################################### void HXWMarkupTessellation::reset() { HXWBasicTessellation::reset(); free(m_data.m_pcLabel); m_data.m_pcLabel = NULL; free(m_data.m_puiCodes); m_data.m_puiCodes = NULL; A3DUns32 i; for(i = 0; i < m_data.m_uiTextsSize; ++i) free(m_data.m_ppcTexts[i]); free(m_data.m_ppcTexts); m_data.m_ppcTexts = NULL; m_data.m_uiCodesSize = m_uiAllocatedCodes = 0; m_data.m_uiTextsSize = m_uiAllocatedTexts = 0; } //###################################################################################################################### void HXWMarkupTessellation::add_code(A3DUns32 uiCode) { if(m_uiAllocatedCodes == 0) { m_data.m_puiCodes = (A3DUns32*) malloc(ALLOCATION_STEP * sizeof(A3DUns32)); m_uiAllocatedCodes = ALLOCATION_STEP; } else if(!(m_data.m_uiCodesSize + 1 < m_uiAllocatedCodes)) { m_uiAllocatedCodes = m_data.m_uiCodesSize + ALLOCATION_STEP; A3DUns32* temp = (A3DUns32*) malloc((size_t) m_uiAllocatedCodes * sizeof(A3DUns32)); memcpy(temp, m_data.m_puiCodes, (size_t) m_data.m_uiCodesSize * sizeof(A3DUns32)); if(m_data.m_puiCodes != NULL) { free(m_data.m_puiCodes); m_data.m_puiCodes = NULL; } m_data.m_puiCodes = temp; } m_data.m_puiCodes[m_data.m_uiCodesSize++] = uiCode; } //###################################################################################################################### int HXWMarkupTessellation::set_color(A3DDouble dRed, A3DDouble dGreen, A3DDouble dBlue) { // add color in session color table A3DUns32 uiIndexColor; A3DGraphRgbColorData sData; A3D_INITIALIZE_DATA(A3DGraphRgbColorData, sData); sData.m_dRed = dRed; sData.m_dGreen = dGreen; sData.m_dBlue = dBlue; ERR_RET(A3DGlobalInsertGraphRgbColor(&sData,&uiIndexColor)); // add in tessellation return set_color(uiIndexColor); } //###################################################################################################################### int HXWMarkupTessellation::set_color(A3DUns32 uiIndexColor) { if(uiIndexColor == A3D_DEFAULT_COLOR_INDEX) return 0; // add in tessellation // 1 = number of additionnal codes, here just one for the index color add_code(A3D_ENCODE_EXTRA_DATA(kA3DMarkupColorMask, 1)); add_code(0); add_code(uiIndexColor); return A3D_SUCCESS; } //###################################################################################################################### int HXWMarkupTessellation::set_textfont(const A3DUTF8Char* pcFamilyName, A3DUns32 uiSize, A3DInt8 cAttributes, A3DECharSet eCharset) { // add font in session font tables A3DFontData sFontData; A3D_INITIALIZE_DATA(A3DFontData, sFontData); sFontData.m_cAttributes = cAttributes; // kA3DFontItalic | kA3DFontUnderlined; sFontData.m_eCharset = eCharset; unsigned int uiLength = (A3DUns32) (pcFamilyName ? strlen(pcFamilyName) : 0); if(!uiLength) return A3D_ERROR; A3DUTF8Char* newText = (A3DUTF8Char*) malloc(((size_t) (uiLength + 1)) * sizeof(A3DUTF8Char)); memcpy(newText, pcFamilyName, ((size_t) (uiLength + 1)) * sizeof(A3DUTF8Char)); sFontData.m_pcFamilyName = newText; sFontData.m_uiSize = uiSize; A3DFontKeyData sFontKeyData; A3D_INITIALIZE_DATA(A3DFontKeyData, sFontKeyData); ERR_RET(A3DGlobalFontKeyCreate(&sFontData, &sFontKeyData)); free(newText); m_sFontKeyData.m_cAttributes = sFontKeyData.m_cAttributes; m_sFontKeyData.m_iFontFamilyIndex = sFontKeyData.m_iFontFamilyIndex; m_sFontKeyData.m_iFontSizeIndex = sFontKeyData.m_iFontSizeIndex; m_sFontKeyData.m_iFontStyleIndex = sFontKeyData.m_iFontStyleIndex; m_sFontKeyData.m_usStructSize = sFontKeyData.m_usStructSize; // the font attributes are compressed A3DUns32 uiAttrib = (sFontKeyData.m_cAttributes) + (sFontKeyData.m_iFontSizeIndex << 12) + (sFontKeyData.m_iFontStyleIndex << 24); // add in tessellation add_code(A3D_ENCODE_EXTRA_DATA(kA3DMarkupFontMask, 2)); add_code(0); add_code(sFontKeyData.m_iFontFamilyIndex); add_code(uiAttrib); return A3D_SUCCESS; } //###################################################################################################################### void HXWMarkupTessellation::setlabel(A3DUTF8Char* pcLabel) { free(m_data.m_pcLabel); unsigned int uiSize = (A3DUns32) (pcLabel ? strlen(pcLabel) : 0); m_data.m_pcLabel = (A3DUTF8Char*) malloc(((size_t) (uiSize + 1)) * sizeof(A3DUTF8Char)); memcpy(m_data.m_pcLabel, pcLabel, (size_t) (uiSize + 1) * sizeof(A3DUTF8Char)); return; } //###################################################################################################################### void HXWMarkupTessellation::add_text(const A3DUTF8Char* pcText, A3DDouble dTextWidth, A3DDouble dTextHeight) { unsigned int uiSize = (A3DUns32) (pcText ? strlen(pcText) : 0); if (!uiSize) return; if (m_data.m_uiTextsSize == 0) { m_data.m_ppcTexts = (A3DUTF8Char**) malloc(ALLOCATION_STEP * sizeof(A3DUTF8Char*)); m_uiAllocatedTexts = ALLOCATION_STEP; } else if (!(m_data.m_uiTextsSize + 1 < m_uiAllocatedTexts)) { m_uiAllocatedTexts = m_data.m_uiTextsSize + ALLOCATION_STEP; m_data.m_ppcTexts = (A3DUTF8Char**) realloc(m_data.m_ppcTexts, (size_t) m_uiAllocatedTexts * sizeof(A3DUTF8Char*)); } A3DUTF8Char* newText = (A3DUTF8Char*) malloc(((size_t) (uiSize + 1)) * sizeof(A3DUTF8Char)); memcpy(newText, pcText, ((size_t) (uiSize + 1)) * sizeof(A3DUTF8Char)); m_data.m_ppcTexts[m_data.m_uiTextsSize] = newText; add_code(A3D_ENCODE_EXTRA_DATA(kA3DMarkupTextMask, 1)); add_code(2); // width of text + height of text add_code(m_data.m_uiTextsSize); //index in text array m_data.m_uiTextsSize++; double dWidth, dHeight; A3DGlobalFontTextBoxGet(&m_sFontKeyData, (char*)pcText, &dWidth, &dHeight); double dScaleWidth, dScaleHeight; // dScaleHeight = dScaleWidth = 1; dScaleWidth = dTextWidth / dWidth; dScaleHeight = dTextHeight / dHeight; m_coordsdata.m_pdCoords[m_coordsdata.m_uiCoordSize - 16] *= dScaleWidth; m_coordsdata.m_pdCoords[m_coordsdata.m_uiCoordSize - 15] *= dScaleWidth; m_coordsdata.m_pdCoords[m_coordsdata.m_uiCoordSize - 14] *= dScaleWidth; m_coordsdata.m_pdCoords[m_coordsdata.m_uiCoordSize - 12] *= dScaleHeight; m_coordsdata.m_pdCoords[m_coordsdata.m_uiCoordSize - 11] *= dScaleHeight; m_coordsdata.m_pdCoords[m_coordsdata.m_uiCoordSize - 10] *= dScaleHeight; add_coord(dWidth); add_coord(dHeight); } //###################################################################################################################### void HXWMarkupTessellation::add_text(const A3DUTF8Char* pcText) { unsigned int uiSize = (A3DUns32) (pcText ? strlen(pcText) : 0); if (!uiSize) return; if (m_data.m_uiTextsSize == 0) { m_data.m_ppcTexts = (A3DUTF8Char**) malloc(ALLOCATION_STEP * sizeof(A3DUTF8Char*)); m_uiAllocatedTexts = ALLOCATION_STEP; } else if (!(m_data.m_uiTextsSize + 1 < m_uiAllocatedTexts)) { m_uiAllocatedTexts = m_data.m_uiTextsSize + ALLOCATION_STEP; m_data.m_ppcTexts = (A3DUTF8Char**) realloc(m_data.m_ppcTexts, (size_t) m_uiAllocatedTexts * sizeof(A3DUTF8Char*)); } A3DUTF8Char* newText = (A3DUTF8Char*) malloc(((size_t) (uiSize + 1)) * sizeof(A3DUTF8Char)); memcpy(newText, pcText, ((size_t) (uiSize + 1)) * sizeof(A3DUTF8Char)); m_data.m_ppcTexts[m_data.m_uiTextsSize] = newText; add_code(A3D_ENCODE_EXTRA_DATA(kA3DMarkupTextMask, 1)); add_code(2); // width of text + height of text add_code(m_data.m_uiTextsSize); //index in text array m_data.m_uiTextsSize++; double dWidth, dHeight; A3DGlobalFontTextBoxGet(&m_sFontKeyData, (char*)pcText, &dWidth, &dHeight); add_coord(dWidth); add_coord(dHeight); } //###################################################################################################################### void HXWMarkupTessellation::free_extra_codes() { if(m_data.m_uiCodesSize == m_uiAllocatedCodes) return; A3DUns32* pnew = NULL; if(m_data.m_uiCodesSize != 0) { pnew = (A3DUns32*) malloc((size_t) m_data.m_uiCodesSize * sizeof(A3DUns32)); memcpy(pnew, m_data.m_puiCodes, (size_t) m_data.m_uiCodesSize * sizeof(A3DUns32)); } if(m_data.m_puiCodes != NULL) { free(m_data.m_puiCodes); m_data.m_puiCodes = NULL; } m_data.m_puiCodes = pnew; m_uiAllocatedCodes = m_data.m_uiCodesSize; } //###################################################################################################################### void HXWMarkupTessellation::add_polyline(A3DDouble* ppoints, A3DUns32 uPtSize) { add_code(0); // start of coords in tessellation array add_code(uPtSize*3); // number of doubles to take into account add_coords(ppoints, uPtSize*3); } //###################################################################################################################### void HXWMarkupTessellation::add_polygon(A3DDouble* ppoints, A3DUns32 uPtSize) { add_code(A3D_ENCODE_EXTRA_DATA(kA3DMarkupPolygonMask, 0)); add_code(uPtSize * 3); // number of doubles to take into account add_coords(ppoints, uPtSize * 3); } //###################################################################################################################### void HXWMarkupTessellation::add_triangle(A3DDouble* pptriangles) { add_code(A3D_ENCODE_EXTRA_DATA(kA3DMarkupTrianglesMask, 0)); add_code(9); add_coords(pptriangles, 9); } //###################################################################################################################### void HXWMarkupTessellation::add_triangles(A3DDouble* pptriangles, A3DUns32 uTriangleSize) { add_code(A3D_ENCODE_EXTRA_DATA(kA3DMarkupTrianglesMask, 0)); add_code(uTriangleSize * 9); add_coords(pptriangles, uTriangleSize * 9); } //###################################################################################################################### void HXWMarkupTessellation::add_polygons(A3DDouble* ppolygons, A3DUns32 uPolygonSize) { add_code(A3D_ENCODE_EXTRA_DATA(kA3DMarkupPolygonMask, 0)); add_code(uPolygonSize * 3); add_coords(ppolygons, uPolygonSize * 3); } //###################################################################################################################### void HXWMarkupTessellation::add_ellipse(A3DDouble dWidth, A3DDouble dHeight) { int numPoints = 150; // Background A3DDouble* pdMarkupEllipseData = (A3DDouble*) malloc(3* numPoints * sizeof(A3DDouble)); for (int p = 0; p < numPoints; ++p) { pdMarkupEllipseData[3 * p] = dWidth / 2 * std::cos(p * 2 * 3.14159265 / numPoints); pdMarkupEllipseData[3 * p + 1] = dHeight / 2 * std::sin(p * 2 * 3.14159265 / numPoints); pdMarkupEllipseData[3 * p + 2] = 0; } add_polygons(pdMarkupEllipseData, numPoints); //set_color(0, 0, 1); //dd_polyline(pdMarkupEllipseData, numPoints); free(pdMarkupEllipseData); } //###################################################################################################################### void HXWMarkupTessellation::add_ellipseFrame(A3DDouble dWidth, A3DDouble dHeight) { int numPoints = 150; // Background A3DDouble* pdMarkupEllipseData = (A3DDouble*) malloc(3 * numPoints * sizeof(A3DDouble)); for (int p = 0; p < numPoints; ++p) { pdMarkupEllipseData[3 * p] = dWidth / 2 * std::cos(p * 2 * 3.14159265 / numPoints); pdMarkupEllipseData[3 * p + 1] = dHeight / 2 * std::sin(p * 2 * 3.14159265 / numPoints); pdMarkupEllipseData[3 * p + 2] = 0; } add_polyline(pdMarkupEllipseData, numPoints); free(pdMarkupEllipseData); } //###################################################################################################################### void HXWMarkupTessellation::add_rectFrame(A3DDouble dWidth, A3DDouble dHeight) { // Frame A3DDouble* pdMarkupFrameData = (A3DDouble*) malloc(16 * sizeof(A3DDouble)); pdMarkupFrameData[0] = -dWidth / 2; // lower left corner pdMarkupFrameData[1] = -dHeight / 2; pdMarkupFrameData[2] = 0; pdMarkupFrameData[3] = pdMarkupFrameData[0] + dWidth; // lower right corner pdMarkupFrameData[4] = pdMarkupFrameData[1]; pdMarkupFrameData[5] = pdMarkupFrameData[2]; pdMarkupFrameData[6] = pdMarkupFrameData[0] + dWidth; // upper right corner pdMarkupFrameData[7] = pdMarkupFrameData[1] + dHeight; pdMarkupFrameData[8] = pdMarkupFrameData[2]; pdMarkupFrameData[9] = pdMarkupFrameData[0]; // upper left corner pdMarkupFrameData[10] = pdMarkupFrameData[1] + dHeight; pdMarkupFrameData[11] = pdMarkupFrameData[2]; pdMarkupFrameData[12] = pdMarkupFrameData[0]; // lower left corner pdMarkupFrameData[13] = pdMarkupFrameData[1]; pdMarkupFrameData[14] = pdMarkupFrameData[2]; add_polyline(pdMarkupFrameData, 5); free(pdMarkupFrameData); } //###################################################################################################################### void HXWMarkupTessellation::add_rect(A3DDouble dWidth, A3DDouble dHeight) { A3DDouble* pdMarkupBackGroundData = (A3DDouble*) malloc(12 * sizeof(A3DDouble)); pdMarkupBackGroundData[0] = -dWidth / 2; // lower left corner pdMarkupBackGroundData[1] = - dHeight / 2; pdMarkupBackGroundData[2] = 0; pdMarkupBackGroundData[3] = pdMarkupBackGroundData[0] + dWidth; // lower right corner pdMarkupBackGroundData[4] = pdMarkupBackGroundData[1]; pdMarkupBackGroundData[5] = pdMarkupBackGroundData[2]; pdMarkupBackGroundData[6] = pdMarkupBackGroundData[0] + dWidth; // upper right corner pdMarkupBackGroundData[7] = pdMarkupBackGroundData[1] + dHeight; pdMarkupBackGroundData[8] = pdMarkupBackGroundData[2]; pdMarkupBackGroundData[9] = pdMarkupBackGroundData[0]; // upper left corner pdMarkupBackGroundData[10] = pdMarkupBackGroundData[1] + dHeight; pdMarkupBackGroundData[11] = pdMarkupBackGroundData[2]; add_polygons(pdMarkupBackGroundData, 4); free(pdMarkupBackGroundData); } //###################################################################################################################### void HXWMarkupTessellation::begin_matrix(A3DDouble* matrix) { if(matrix) { add_code(kA3DMarkupIsMatrix); add_code(16); // start of coords in tessellation array add_coords(matrix, 16); } } //###################################################################################################################### void HXWMarkupTessellation::begin_matrix(const A3DVector3dData& position_3d, const A3DVector3dData& plane_normal, const A3DVector3dData& x_direction) { A3DVector3dData y_direction; y_direction.m_dX = plane_normal.m_dY * x_direction.m_dZ - plane_normal.m_dZ * x_direction.m_dY; y_direction.m_dY = -(plane_normal.m_dX * x_direction.m_dZ - plane_normal.m_dZ * x_direction.m_dX); y_direction.m_dZ = plane_normal.m_dX * x_direction.m_dY - plane_normal.m_dY * x_direction.m_dX; double dScaleX = 1; double dScaleY = 1; A3DDouble *matrix = (A3DDouble*) malloc(16 * sizeof(A3DDouble)); matrix[0] = x_direction.m_dX * dScaleX; matrix[1] = x_direction.m_dY * dScaleX; matrix[2] = x_direction.m_dZ * dScaleX; matrix[3] = 0.0; matrix[4] = y_direction.m_dX * dScaleY; matrix[5] = y_direction.m_dY * dScaleY; matrix[6] = y_direction.m_dZ * dScaleY; matrix[7] = 0.0; matrix[8] = plane_normal.m_dX * 1; matrix[9] = plane_normal.m_dY* 1; matrix[10] = plane_normal.m_dZ* 1; matrix[11] = 0.0; matrix[12] = position_3d.m_dX; matrix[13] = position_3d.m_dY; matrix[14] = position_3d.m_dZ; matrix[15] = 1.0; add_code(kA3DMarkupIsMatrix); add_code(16); //start of coords in tessellation array add_coords(matrix, 16); free(matrix); } //###################################################################################################################### void HXWMarkupTessellation::end_matrix() { /* end of matrix mode */ add_code(kA3DMarkupIsMatrix); add_code(0); } //###################################################################################################################### void HXWMarkupTessellation::GetMarkupTess(A3DTessMarkup*& pTessMarkup) { pTessMarkup = NULL; A3DTessMarkupData sTessData; A3D_INITIALIZE_DATA(A3DTessMarkupData, sTessData); free_extra_coords(); free_extra_codes(); A3DTessMarkupCreate(&m_data,&pTessMarkup); A3DTessBaseData sTessBaseData; A3D_INITIALIZE_DATA(A3DTessBaseData, sTessBaseData); SetCoords(pTessMarkup); } /* Not managed by Acrobat Reader for now - Tech Soft 3D needs to work with Adobe on this issue. //###################################################################################################################### void HXWMarkupTessellation::set_line_width(double dWidth) { add_code(A3D_ENCODE_EXTRA_DATA(kA3DMarkupLineWidthMask, 0)); add_code(1); add_coords(&dWidth, 1); } //###################################################################################################################### void HXWMarkupTessellation::end_line_width() { add_code(A3D_ENCODE_EXTRA_DATA(kA3DMarkupLineWidthMask, 0)); add_code(0); } */ //######################################################################################################################*/ void HXWMarkupTessellation::BeginFaceView(A3DDouble* pOrigin) { add_code(A3D_ENCODE_EXTRA_DATA(kA3DMarkupFaceViewMask, 0)); add_code(3); add_coords(pOrigin, 3); m_uiStartSizeWireFV = m_data.m_uiCodesSize - 2; m_uiStartCoordsFV = m_coordsdata.m_uiCoordSize - 3; } //######################################################################################################################*/ void HXWMarkupTessellation::BeginFaceViewAlwaysOnTop(A3DDouble* pOrigin) { add_code(A3D_ENCODE_EXTRA_DATA(kA3DMarkupFaceViewMask, 0)); m_data.m_cBehaviour |= kA3DMarkupIsOnTop; add_code(3); add_coords(pOrigin, 3); m_uiStartSizeWireFV = m_data.m_uiCodesSize - 2; m_uiStartCoordsFV = m_coordsdata.m_uiCoordSize - 3; } //######################################################################################################################*/ void HXWMarkupTessellation::EndFaceView() { add_code(A3D_ENCODE_EXTRA_DATA(kA3DMarkupFaceViewMask, 0)); add_code(0); // start of coords in tessellation array // definition de la taille du mode m_data.m_puiCodes[m_uiStartSizeWireFV] += m_data.m_uiCodesSize - m_uiStartSizeWireFV - 2; m_data.m_puiCodes[m_uiStartSizeWireFV+1] = m_coordsdata.m_uiCoordSize - m_uiStartCoordsFV; } //######################################################################################################################*/ void HXWMarkupTessellation::BeginFrameDraw(A3DDouble* pOrigin) { add_code(A3D_ENCODE_EXTRA_DATA(kA3DMarkupFrameDrawMask, 15)); add_code(3); add_coords(pOrigin, 3); m_uiStartSizeWireFS = m_data.m_uiCodesSize - 2; m_uiStartCoordsFS = m_coordsdata.m_uiCoordSize - 3; } //######################################################################################################################*/ void HXWMarkupTessellation::EndFrameDraw() { add_code(A3D_ENCODE_EXTRA_DATA(kA3DMarkupFrameDrawMask, 0)); add_code(0); m_data.m_puiCodes[m_uiStartSizeWireFS] += m_data.m_uiCodesSize - m_uiStartSizeWireFS - 2; m_data.m_puiCodes[m_uiStartSizeWireFS+1] = m_coordsdata.m_uiCoordSize - m_uiStartCoordsFS; }