Files
Hoops_Exchange/exchange/exchangesource/CreatePRCCubes/tessellation_wrapper/HXWMarkupTessellation.cpp
2025-12-15 23:22:33 +08:00

557 lines
21 KiB
C++

/***********************************************************************************************************************
*
* 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 <A3DSDKIncludes.h>
#include "HXWMarkupTessellation.h"
#include <cmath>
//######################################################################################################################
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;
}