/*********************************************************************************************************************** * * 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. * ***********************************************************************************************************************/ /** * Sample CreatePRCCubes * file CreateMartkups.cpp * This file is containing the function allowing to create markups. * * Markups creation exemple * Create tessellated markups with linked items. * Different style of markups can be created (normal or face to screen). * Different links to the PRC entities can be created as well. * * These exemples are using the tessellation wrapper: HXWMarkupTessellation.cpp * * ***********************************************************************************************************************/ #include "CreateMarkups.h" #include "../tessellation_wrapper/HXWMarkupTessellation.h" #include //###################################################################################################################### // // Tessellation Helper // //###################################################################################################################### // Create a leader and an arrow static void stCreateLeaderTess(HXWMarkupTessellation* sMarkupLeaderTessellation, A3DVector3dData* pLeaderBegin, A3DVector3dData* pLeaderEnd) { // Leader A3DDouble* pdLeaderPolylineData = (A3DDouble*) malloc(9 * sizeof(A3DDouble)); pdLeaderPolylineData[0] = pLeaderBegin->m_dX; pdLeaderPolylineData[1] = pLeaderBegin->m_dY; pdLeaderPolylineData[2] = pLeaderBegin->m_dZ; pdLeaderPolylineData[3] = pdLeaderPolylineData[0]; pdLeaderPolylineData[4] = pdLeaderPolylineData[1]; pdLeaderPolylineData[5] = pLeaderEnd->m_dZ; pdLeaderPolylineData[6] = pLeaderEnd->m_dX; pdLeaderPolylineData[7] = pLeaderEnd->m_dY; pdLeaderPolylineData[8] = pLeaderEnd->m_dZ; sMarkupLeaderTessellation->set_color(YELLOW); sMarkupLeaderTessellation->add_polyline(pdLeaderPolylineData, 3); free(pdLeaderPolylineData); // Arrow A3DDouble* pdTriangle = (A3DDouble*) malloc(9 * sizeof(A3DDouble)); pdTriangle[0] = pLeaderBegin->m_dX; pdTriangle[1] = pLeaderBegin->m_dY; pdTriangle[2] = pLeaderBegin->m_dZ; pdTriangle[3] = pdTriangle[0]; pdTriangle[4] = pdTriangle[1] - 3; pdTriangle[5] = pdTriangle[2] + 6; pdTriangle[6] = pdTriangle[0]; pdTriangle[7] = pdTriangle[1] + 3; pdTriangle[8] = pdTriangle[2] + 6; sMarkupLeaderTessellation->set_color(YELLOW); sMarkupLeaderTessellation->add_triangle(pdTriangle); free(pdTriangle); } //###################################################################################################################### // Create a Frame and Background static void stCreateFrameTess(HXWMarkupTessellation* pMarkupTessellation, A3DVector3dData* pBottomLeft, // this feel the most natural as text will begin from that point A3DDouble width, A3DDouble height) { // Frame A3DDouble* pdMarkupFrameData = (A3DDouble*) malloc(16 * sizeof(A3DDouble)); pdMarkupFrameData[0] = pBottomLeft->m_dX; // lower left corner pdMarkupFrameData[1] = pBottomLeft->m_dY; pdMarkupFrameData[2] = pBottomLeft->m_dZ; pdMarkupFrameData[3] = pdMarkupFrameData[0] + width; // lower right corner pdMarkupFrameData[4] = pdMarkupFrameData[1]; pdMarkupFrameData[5] = pdMarkupFrameData[2]; pdMarkupFrameData[6] = pdMarkupFrameData[0] + width; // upper right corner pdMarkupFrameData[7] = pdMarkupFrameData[1] + height; pdMarkupFrameData[8] = pdMarkupFrameData[2]; pdMarkupFrameData[9] = pdMarkupFrameData[0]; // upper left corner pdMarkupFrameData[10] = pdMarkupFrameData[1] + height; pdMarkupFrameData[11] = pdMarkupFrameData[2]; pdMarkupFrameData[12] = pdMarkupFrameData[0]; // lower left corner pdMarkupFrameData[13] = pdMarkupFrameData[1]; pdMarkupFrameData[14] = pdMarkupFrameData[2]; pMarkupTessellation->set_color(RED); pMarkupTessellation->add_polyline(pdMarkupFrameData, 5); free(pdMarkupFrameData); // Background A3DDouble* pdMarkupBackGroundData = (A3DDouble*) malloc(12 * sizeof(A3DDouble)); pdMarkupBackGroundData[0] = pBottomLeft->m_dX; // lower left corner pdMarkupBackGroundData[1] = pBottomLeft->m_dY; pdMarkupBackGroundData[2] = pBottomLeft->m_dZ - 0.01; pdMarkupBackGroundData[3] = pdMarkupBackGroundData[0] + width; // lower right corner pdMarkupBackGroundData[4] = pdMarkupBackGroundData[1]; pdMarkupBackGroundData[5] = pdMarkupBackGroundData[2] - 0.01;; pdMarkupBackGroundData[6] = pdMarkupBackGroundData[0] + width; // upper right corner pdMarkupBackGroundData[7] = pdMarkupBackGroundData[1] + height; pdMarkupBackGroundData[8] = pdMarkupBackGroundData[2] - 0.01;; pdMarkupBackGroundData[9] = pdMarkupBackGroundData[0]; // upper left corner pdMarkupBackGroundData[10] = pdMarkupBackGroundData[1] + height; pdMarkupBackGroundData[11] = pdMarkupBackGroundData[2] - 0.01;; pMarkupTessellation->set_color(WHITE); pMarkupTessellation->add_polygons(pdMarkupBackGroundData, 4); free(pdMarkupBackGroundData); } //###################################################################################################################### // Create a Text static void stCreateText(HXWMarkupTessellation* pMarkupTessellation, const A3DUTF8Char* pcText, A3DVector3dData* pBottomLeft, A3DDouble width, A3DDouble height) { // Text HXWVector3d position(pBottomLeft->m_dX + 5, pBottomLeft->m_dY + 5, pBottomLeft->m_dZ); HXWVector3d normal(0., 0., 1.); HXWVector3d x_direction(1., 0., 0.); pMarkupTessellation->begin_matrix(position.m_data, normal.m_data, x_direction.m_data); pMarkupTessellation->set_textfont("Courier New", 10, kA3DFontBold); pMarkupTessellation->set_color(BLUE); pMarkupTessellation->add_text(pcText, width, height); pMarkupTessellation->end_matrix(); /* to test a second text position.m_data.m_dX += width + 5; pMarkupTessellation->begin_matrix(position.m_data, normal.m_data, x_direction.m_data); pMarkupTessellation->set_textfont("Myriad CAD", 10, kA3DFontBold); pMarkupTessellation->set_color(BLUE); pMarkupTessellation->add_text("Publish"); pMarkupTessellation->end_matrix(); */ } //###################################################################################################################### // // Leader, frame and text // //###################################################################################################################### static const double sdFrameWidth = 110; static const double sdFrameHeight = 25; static const double sdTextWidth = 100; static const double sdTextHeight = 10; // Create a Tessellation static A3DStatus stCreateFrameAndText(A3DTessMarkup** ppTessMarkup, const A3DUTF8Char* pcText, A3DVector3dData* pFramePos) { A3DStatus iRet = A3D_SUCCESS; // label HXWMarkupTessellation sMarkupTessellation; stCreateFrameTess(&sMarkupTessellation, pFramePos, sdFrameWidth, sdFrameHeight); stCreateText(&sMarkupTessellation, pcText, pFramePos, sdTextWidth, sdTextHeight); *ppTessMarkup = sMarkupTessellation.GetEntity(); return iRet; } // Create a Face to screen Tessellation static A3DStatus stCreateFrameAndTextFaceToScreen(A3DTessMarkup** ppTessMarkup, const A3DUTF8Char* pcText, A3DVector3dData* pFrame3DPos, FlatToScreenMode inFlatToScreenMode) { A3DStatus iRet = A3D_SUCCESS; HXWMarkupTessellation sMarkupTessellation; // FaceMode A3DDouble pFaceModeOrigin[3]; pFaceModeOrigin[0] = pFrame3DPos->m_dX; pFaceModeOrigin[1] = pFrame3DPos->m_dY; pFaceModeOrigin[2] = pFrame3DPos->m_dZ; A3DVector3dData sOrigin; A3D_INITIALIZE_DATA(A3DVector3dData, sOrigin); sOrigin.m_dX = 0; sOrigin.m_dY = 0; sOrigin.m_dZ = 0; switch (inFlatToScreenMode) { case FlatToScreen: sMarkupTessellation.BeginFaceView(pFaceModeOrigin); break; case FlatToScreenAlwaysOnTop: sMarkupTessellation.BeginFaceViewAlwaysOnTop(pFaceModeOrigin); break; case FlatToScreenNonZoomable: sMarkupTessellation.BeginFrameDraw(pFaceModeOrigin); break; } stCreateFrameTess(&sMarkupTessellation, &sOrigin, sdFrameWidth, sdFrameHeight); stCreateText(&sMarkupTessellation, pcText, &sOrigin, sdTextWidth, sdTextHeight); switch (inFlatToScreenMode) { case FlatToScreen: case FlatToScreenAlwaysOnTop: sMarkupTessellation.EndFaceView(); break; case FlatToScreenNonZoomable: sMarkupTessellation.EndFrameDraw(); break; } *ppTessMarkup = sMarkupTessellation.GetEntity(); return iRet; } //###################################################################################################################### // Create a Leader Tessellation static A3DStatus stCreateLeader(A3DMkpLeader** ppMkpLeader, A3DVector3dData* pBeginLeaderPos, A3DVector3dData* pEndLeaderPos) { A3DStatus iRet = A3D_SUCCESS; // leader HXWMarkupTessellation sMarkupLeaderTessellation; stCreateLeaderTess(&sMarkupLeaderTessellation, pBeginLeaderPos, pEndLeaderPos); A3DMkpLeaderData sMkpLeaderData; A3D_INITIALIZE_DATA(A3DMkpLeaderData, sMkpLeaderData); A3DTessMarkup* pLeaderTessMarkup = sMarkupLeaderTessellation.GetEntity(); sMkpLeaderData.m_pTessellation = pLeaderTessMarkup; CHECK_RET(A3DMkpLeaderCreate(&sMkpLeaderData, ppMkpLeader)); return iRet; } //###################################################################################################################### static A3DStatus stCreateMkpMarkup(A3DMkpMarkup** ppMarkup, A3DTessMarkup* pTessMarkup, A3DUns32 uiMkpLeaderSize, A3DMkpLeader** ppMkpLeader, A3DUns32 uiMarkupLinkedItemSize, A3DMiscMarkupLinkedItem** ppMarkupLinkedItem) { A3DStatus iRet = A3D_SUCCESS; A3DMkpMarkupData sMarkupData; A3D_INITIALIZE_DATA(A3DMkpMarkupData, sMarkupData); sMarkupData.m_eType = kA3DMarkupTypeText; sMarkupData.m_eSubType = kA3DMarkupSubTypeUnknown; sMarkupData.m_uiLeadersSize = uiMkpLeaderSize; sMarkupData.m_ppLeaders = ppMkpLeader; sMarkupData.m_uiLinkedItemsSize = uiMarkupLinkedItemSize; sMarkupData.m_ppLinkedItems = ppMarkupLinkedItem; sMarkupData.m_pTessellation = pTessMarkup; CHECK_RET(A3DMkpMarkupCreate(&sMarkupData, ppMarkup)); return iRet; } //###################################################################################################################### // // Markups creation // //###################################################################################################################### // Tesselated Markup creation //###################################################################################################################### // Tesselated Markup creation A3DStatus createMarkup(A3DMkpAnnotationItem** ppOutAnnotItem, const A3DUTF8Char* pcText, A3DUns32 uiLinkedEntitySize, A3DEntity** ppLinkedEntity, A3DAsmProductOccurrence** ppPOTarget, A3DVector3dData* pFramePos, A3DVector3dData* pLeaderPos) { A3DStatus iRet = A3D_SUCCESS; A3DMkpLeader* pMkpLeader = 0; A3DUns32 uiMkpLeaderSize = 0; if (pLeaderPos) { CHECK_RET(stCreateLeader(&pMkpLeader, pLeaderPos, pFramePos)); uiMkpLeaderSize = 1; } A3DTessMarkup* pTessMarkup = 0; CHECK_RET(stCreateFrameAndText(&pTessMarkup, pcText, pFramePos)); // ----------------------------------------------------------- // creation of linked item std::vector vLinkedItems; for (A3DUns32 i = 0; i < uiLinkedEntitySize; ++i) { A3DMiscMarkupLinkedItem* pMarkupLinkedItem = 0; CHECK_RET(createMarkupLinkedItemOnEntity(ppLinkedEntity[i], ppPOTarget[i], &pMarkupLinkedItem)); vLinkedItems.push_back(pMarkupLinkedItem); } // ----------------------------------------------------------- // create a Markup from the MarkupTessData A3DMkpMarkup* pMarkup = 0; CHECK_RET(stCreateMkpMarkup(&pMarkup, pTessMarkup, uiMkpLeaderSize, &pMkpLeader, (A3DUns32)vLinkedItems.size(), &(vLinkedItems[0]))); vLinkedItems.clear(); // ----------------------------------------------------------- // Annotation item creation A3DMkpAnnotationItemData sAnnotItemData; A3D_INITIALIZE_DATA(A3DMkpAnnotationItemData, sAnnotItemData); sAnnotItemData.m_pMarkup = pMarkup; CHECK_RET(A3DMkpAnnotationItemCreate(&sAnnotItemData, ppOutAnnotItem)); return iRet; } //###################################################################################################################### // Tesselated Markup creation // Only the linked item creation process will change from the normal sample markup. A3DStatus createMarkupOnFace(A3DMkpAnnotationItem** ppOutAnnotItem, const A3DUTF8Char* pcText, A3DUns32 uiLinkedEntitySize, A3DEntity** ppLinkedEntity, A3DAsmProductOccurrence** ppPOTarget, A3DUns32* puiFaceIndexes, A3DVector3dData* pFramePos, A3DVector3dData* pLeaderPos) { A3DStatus iRet = A3D_SUCCESS; A3DMkpLeader* pMkpLeader = 0; A3DUns32 uiMkpLeaderSize = 0; if (pLeaderPos) { CHECK_RET(stCreateLeader(&pMkpLeader, pLeaderPos, pFramePos)); uiMkpLeaderSize = 1; } A3DTessMarkup* pTessMarkup = 0; CHECK_RET(stCreateFrameAndText(&pTessMarkup, pcText, pFramePos)); // ----------------------------------------------------------- // creation of linked item on a face std::vector vLinkedItems; for (A3DUns32 i = 0; i < uiLinkedEntitySize; ++i) { A3DMiscMarkupLinkedItem* pMarkupLinkedItem = 0; CHECK_RET(createMarkupLinkedItemOnTess(ppLinkedEntity[i], kA3DTypeTessFace, 1, &puiFaceIndexes[i], ppPOTarget[i], &pMarkupLinkedItem)); vLinkedItems.push_back(pMarkupLinkedItem); } // ----------------------------------------------------------- // create a Markup from the MarkupTessData A3DMkpMarkup* pMarkup = 0; CHECK_RET(stCreateMkpMarkup(&pMarkup, pTessMarkup, uiMkpLeaderSize, &pMkpLeader, (A3DUns32)vLinkedItems.size(), &(vLinkedItems[0]))); vLinkedItems.clear(); // ----------------------------------------------------------- // Annotation item creation A3DMkpAnnotationItemData sAnnotItemData; A3D_INITIALIZE_DATA(A3DMkpAnnotationItemData, sAnnotItemData); sAnnotItemData.m_pMarkup = pMarkup; CHECK_RET(A3DMkpAnnotationItemCreate(&sAnnotItemData, ppOutAnnotItem)); return iRet; } //###################################################################################################################### // FaceMode Markup creation A3DStatus createMarkupFaceToScreen(A3DMkpAnnotationItem** ppOutAnnotItem, const A3DUTF8Char* pcText, A3DUns32 uiLinkedEntitySize, A3DEntity** ppLinkedEntity, A3DAsmProductOccurrence** ppPOTarget, A3DVector3dData* pFramePos, FlatToScreenMode inFlatToScreenMode) { A3DStatus iRet = A3D_SUCCESS; A3DTessMarkup* pTessMarkup = 0; CHECK_RET(stCreateFrameAndTextFaceToScreen(&pTessMarkup, pcText, pFramePos, inFlatToScreenMode)); // ----------------------------------------------------------- // creation of linked item // creation of linked item std::vector vLinkedItems; for (A3DUns32 i = 0; i < uiLinkedEntitySize; ++i) { A3DMiscMarkupLinkedItem* pMarkupLinkedItem = 0; CHECK_RET(createMarkupLinkedItemOnEntity(ppLinkedEntity[i], ppPOTarget[i], &pMarkupLinkedItem)); vLinkedItems.push_back(pMarkupLinkedItem); } // ----------------------------------------------------------- // create a Markup from the MarkupTessData A3DMkpMarkup* pMarkup = 0; CHECK_RET(stCreateMkpMarkup(&pMarkup, pTessMarkup, 0, 0, (A3DUns32)vLinkedItems.size(), &(vLinkedItems[0]))); vLinkedItems.clear(); // ----------------------------------------------------------- // Annotation item creation A3DMkpAnnotationItemData sAnnotItemData; A3D_INITIALIZE_DATA(A3DMkpAnnotationItemData, sAnnotItemData); sAnnotItemData.m_pMarkup = pMarkup; CHECK_RET(A3DMkpAnnotationItemCreate(&sAnnotItemData, ppOutAnnotItem)); return iRet; }