1341 lines
46 KiB
C++
1341 lines
46 KiB
C++
/***********************************************************************************************************************
|
||
*
|
||
* Copyright (c) 2010 - 2022 by Tech Soft 3D, Inc.
|
||
* The information contained herein is confidential and proprietary to Tech Soft 3D, Inc., and considered a trade secret
|
||
* as defined under civil and criminal statutes. Tech Soft 3D shall pursue its civil and criminal remedies in the event
|
||
* of unauthorized use or misappropriation of its trade secrets. Use of this information by anyone other than authorized
|
||
* employees of Tech Soft 3D, Inc. is granted only under a written non-disclosure agreement, expressly prescribing the
|
||
* scope and manner of such use.
|
||
*
|
||
***********************************************************************************************************************/
|
||
/**
|
||
\file DemoDataModelData.cpp
|
||
|
||
Demonstrates how to create a table in which the table data is linked to the model data.
|
||
|
||
***********************************************************************************************************************/
|
||
|
||
// Do not define INITIALIZE_A3D_API here. It should be only included once in a project.
|
||
#define HOOPS_PRODUCT_PUBLISH_ADVANCED
|
||
#include <A3DSDKIncludes.h>
|
||
#include "../common.hpp"
|
||
|
||
#include <cstdlib>
|
||
#include <sstream>
|
||
#include <ostream>
|
||
#include <iostream>
|
||
#include <vector>
|
||
#include <map>
|
||
|
||
|
||
|
||
|
||
std::string intToString(int i)
|
||
{
|
||
std::ostringstream oss;
|
||
oss << i;
|
||
return oss.str();
|
||
}
|
||
|
||
|
||
//######################################################################################################################
|
||
|
||
|
||
//######################################################################################################################
|
||
|
||
A3DVoid mallocAndSetString(const A3DUTF8Char* srcString, A3DUTF8Char*& destString)
|
||
{
|
||
// we return empty strings rather than NULL because some strings usages crash with NULL values
|
||
// (for example std::string xx = NULL crashes !)
|
||
unsigned int uiSize = (unsigned int)(srcString ? strlen(srcString) : 0);
|
||
destString = (A3DUTF8Char*)malloc((uiSize + 1) * sizeof(A3DUTF8Char));
|
||
if (uiSize > 0)
|
||
{
|
||
strcpy(destString, srcString);
|
||
}
|
||
destString[uiSize] = 0;
|
||
}
|
||
|
||
//######################################################################################################################
|
||
// cleaning functions
|
||
|
||
void stFreeTable(A3DPDFDataTableData &sTableData)
|
||
{
|
||
for (A3DUns32 ir = 0; ir < sTableData.m_iNbRows ; ir++)
|
||
{
|
||
for(A3DUns32 ic = 0; ic < sTableData.m_iNbCols ; ic++)
|
||
free(sTableData.m_ppcTexts[ir*sTableData.m_iNbCols+ic]);
|
||
}
|
||
free(sTableData.m_ppcTexts);
|
||
}
|
||
|
||
|
||
void stFreeTable3DViews(A3DPDFTable3DViewsData &sTable3DViewsData)
|
||
{
|
||
if (sTable3DViewsData.m_piViewIndexes)
|
||
free(sTable3DViewsData.m_piViewIndexes);
|
||
if (sTable3DViewsData.m_ppcViewLabels)
|
||
{
|
||
for(A3DUns32 ic = 0; ic < sTable3DViewsData.m_iNbViews ; ic++)
|
||
if (sTable3DViewsData.m_ppcViewLabels[ic])
|
||
free(sTable3DViewsData.m_ppcViewLabels[ic]);
|
||
free(sTable3DViewsData.m_ppcViewLabels);
|
||
}
|
||
if (sTable3DViewsData.m_ppImages)
|
||
free(sTable3DViewsData.m_ppImages);
|
||
|
||
if (sTable3DViewsData.m_pDataTableData)
|
||
{
|
||
for (A3DUns32 ir = 0; ir < sTable3DViewsData.m_pDataTableData->m_iNbRows ; ir++)
|
||
{
|
||
for(A3DUns32 ic = 0; ic < sTable3DViewsData.m_pDataTableData->m_iNbCols ; ic++)
|
||
free(sTable3DViewsData.m_pDataTableData->m_ppcTexts[ir*sTable3DViewsData.m_pDataTableData->m_iNbCols+ic]);
|
||
}
|
||
free(sTable3DViewsData.m_pDataTableData->m_ppcTexts);
|
||
}
|
||
|
||
}
|
||
|
||
void stFreeRelationship(A3DPDFDataRelationshipData &sRelationshipData)
|
||
{
|
||
free(sRelationshipData.m_pMapIndexes);
|
||
}
|
||
|
||
|
||
//######################################################################################################################
|
||
|
||
|
||
A3DStatus stCreateTable(A3DPDFDocument* pDoc, const std::vector<std::vector<std::string> > &aRows, A3DPDFDataTable*& pDataTable)
|
||
{
|
||
A3DStatus iRet = A3D_SUCCESS;
|
||
A3DUns32 iNbRows = (A3DUns32)aRows.size();
|
||
A3DUns32 iNbCols = (A3DUns32)aRows[0].size();
|
||
A3DPDFDataTableData sTableData;
|
||
A3D_INITIALIZE_DATA(A3DPDFDataTableData, sTableData);
|
||
sTableData.m_iNbRows = iNbRows;
|
||
sTableData.m_iNbCols = iNbCols;
|
||
sTableData.m_ppcTexts = (A3DUTF8Char**)malloc(iNbRows * iNbCols * A3DUns32(sizeof(A3DUTF8Char*)));
|
||
for (A3DUns32 ir = 0; ir < iNbRows; ir++)
|
||
{
|
||
for (A3DUns32 ic = 0; ic < iNbCols; ic++)
|
||
mallocAndSetString(
|
||
aRows[ir][ic].c_str(), // src
|
||
sTableData.m_ppcTexts[ir*iNbCols + ic]); // dest
|
||
}
|
||
|
||
CHECK_RET(A3DPDFDataTableCreate(pDoc, &sTableData, &pDataTable));
|
||
|
||
stFreeTable(sTableData);
|
||
|
||
return iRet;
|
||
}
|
||
|
||
|
||
A3DStatus stCreateRelationship(A3DPDFDocument* pDoc, std::vector< std::pair <size_t, size_t> > &aMapIndexes,
|
||
A3DPDFDataTable* pDataTableSource, A3DPDFDataTable* pDataTableTarget)
|
||
{
|
||
A3DStatus iRet = A3D_SUCCESS;
|
||
A3DUns32 iNbRows = (A3DUns32)aMapIndexes.size();
|
||
|
||
A3DPDFDataRelationshipData sRelationshipData;
|
||
A3D_INITIALIZE_DATA(A3DPDFDataRelationshipData, sRelationshipData);
|
||
sRelationshipData.m_iSizeMap = iNbRows;
|
||
sRelationshipData.m_pDataTableSource = pDataTableSource;
|
||
sRelationshipData.m_pDataTableTarget = pDataTableTarget;
|
||
sRelationshipData.m_pMapIndexes = (A3DPDFMapIndexData *)malloc(iNbRows * sizeof(A3DPDFMapIndexData));
|
||
memset(sRelationshipData.m_pMapIndexes, 0, iNbRows * sizeof(A3DPDFMapIndexData));
|
||
for (A3DUns32 ir = 0; ir < iNbRows; ir++)
|
||
{
|
||
sRelationshipData.m_pMapIndexes[ir].m_aiIndexes[0] = (A3DInt32)(aMapIndexes[ir].first);
|
||
sRelationshipData.m_pMapIndexes[ir].m_aiIndexes[1] = (A3DInt32)(aMapIndexes[ir].second);
|
||
}
|
||
|
||
CHECK_RET(A3DPDFDataRelationshipCreate(pDoc, &sRelationshipData));
|
||
|
||
stFreeRelationship(sRelationshipData);
|
||
|
||
return iRet;
|
||
}
|
||
|
||
std::string stStoreIcon(A3DPDFDocument* pDoc, std::string sFileName)
|
||
{
|
||
A3DStatus iRet = A3D_SUCCESS;
|
||
std::string sIconId;
|
||
|
||
// icons must primarily be stored into the document
|
||
A3DPDFImage* pImage = nullptr;
|
||
|
||
iRet = A3DPDFImageCreateFromFile(pDoc,
|
||
sFileName.c_str(),
|
||
kA3DPDFImageFormatUnknown, // not defined -> format is deducted from file extension
|
||
&pImage);
|
||
|
||
if (iRet == A3D_SUCCESS)
|
||
{
|
||
A3DUTF8Char* pcIconId = NULL;
|
||
iRet = A3DPDFDocumentAddImageAsIcon2(pDoc, pImage,
|
||
nullptr, // pcIconId : not defined -> a unique id is automatically generated; see last argument for retrieving.
|
||
&pcIconId);
|
||
if (pcIconId)
|
||
{
|
||
sIconId = pcIconId;
|
||
A3DPDFDocumentAddImageAsIcon2(nullptr, nullptr, nullptr,&pcIconId);
|
||
}
|
||
}
|
||
else
|
||
std::cout << "Can't create image from file " << sFileName << ". Error number=" << iRet << std::endl;
|
||
|
||
return sIconId;
|
||
}
|
||
|
||
//######################################################################################################################
|
||
|
||
A3DStatus PageGetTextField( A3DPDFPage* pPage,
|
||
const std::string& sFieldId,
|
||
A3DPDFTextField** ppField)
|
||
{
|
||
A3DStatus iRet = A3D_SUCCESS;
|
||
|
||
*ppField = NULL;
|
||
|
||
A3DPDFField* pField = NULL;
|
||
CHECK_RET(A3DPDFPageGetField(pPage, sFieldId.c_str(), &pField));
|
||
|
||
A3DPDFEWidgetType eWidgetType;
|
||
CHECK_RET(A3DPDFWidgetGetType((A3DPDFWidget*)pField, &eWidgetType));
|
||
if (eWidgetType!=kA3DTypeFieldText)
|
||
iRet = A3D_INVALID_ENTITY_TYPE;
|
||
else
|
||
*ppField = (A3DPDFTextField*)pField;
|
||
|
||
return iRet;
|
||
}
|
||
|
||
A3DStatus PageGetButtonField(A3DPDFPage* pPage,
|
||
const std::string& sFieldId,
|
||
A3DPDFButton** ppField)
|
||
{
|
||
A3DStatus iRet = A3D_SUCCESS;
|
||
|
||
*ppField = NULL;
|
||
|
||
A3DPDFField* pField = NULL;
|
||
CHECK_RET(A3DPDFPageGetField(pPage, sFieldId.c_str(), &pField));
|
||
|
||
A3DPDFEWidgetType eWidgetType;
|
||
CHECK_RET(A3DPDFWidgetGetType((A3DPDFWidget*)pField, &eWidgetType));
|
||
if (eWidgetType != kA3DTypeFieldButton)
|
||
iRet = A3D_INVALID_ENTITY_TYPE;
|
||
else
|
||
*ppField = (A3DPDFButton*)pField;
|
||
|
||
return iRet;
|
||
}
|
||
|
||
A3DStatus PageGetListBoxField(A3DPDFPage* pPage,
|
||
const std::string& sFieldId,
|
||
A3DPDFListBox** ppField)
|
||
{
|
||
A3DStatus iRet = A3D_SUCCESS;
|
||
|
||
*ppField = NULL;
|
||
|
||
A3DPDFField* pField = NULL;
|
||
CHECK_RET(A3DPDFPageGetField(pPage, sFieldId.c_str(), &pField));
|
||
|
||
A3DPDFEWidgetType eWidgetType;
|
||
CHECK_RET(A3DPDFWidgetGetType((A3DPDFWidget*)pField, &eWidgetType));
|
||
if (eWidgetType!=kA3DTypeFieldListBox)
|
||
iRet = A3D_INVALID_ENTITY_TYPE;
|
||
else
|
||
*ppField = (A3DPDFListBox*)pField;
|
||
|
||
return iRet;
|
||
}
|
||
|
||
A3DStatus PageGetDropDownListField(A3DPDFPage* pPage,
|
||
const std::string& sFieldId,
|
||
A3DPDFDropDownList** ppField)
|
||
{
|
||
A3DStatus iRet = A3D_SUCCESS;
|
||
|
||
*ppField = NULL;
|
||
|
||
A3DPDFField* pField = NULL;
|
||
CHECK_RET(A3DPDFPageGetField(pPage, sFieldId.c_str(), &pField));
|
||
|
||
A3DPDFEWidgetType eWidgetType;
|
||
CHECK_RET(A3DPDFWidgetGetType((A3DPDFWidget*)pField, &eWidgetType));
|
||
if (eWidgetType!=kA3DTypeFieldDropDownList)
|
||
iRet = A3D_INVALID_ENTITY_TYPE;
|
||
else
|
||
*ppField = (A3DPDFDropDownList*)pField;
|
||
|
||
return iRet;
|
||
}
|
||
|
||
|
||
//######################################################################################################################
|
||
|
||
|
||
class BomElement
|
||
{
|
||
public:
|
||
BomElement() : m_iQty(0), m_PtrPRCEntity(NULL) {}
|
||
|
||
BomElement(const BomElement& other) : m_attrib(other.m_attrib), m_name(other.m_name),
|
||
m_bIsRepresentationItem(other.m_bIsRepresentationItem), m_PtrPRCEntity(other.m_PtrPRCEntity),
|
||
m_iQty(other.m_iQty), m_keyAttribValue(other.m_keyAttribValue){};
|
||
|
||
static bool isInMapByKeyAttrib(const std::vector<BomElement> mapBomElements, const std::string& sKeyAttrib, size_t& idxinbommap);
|
||
static bool isInMapByName(const std::vector<BomElement> mapBomElements, const std::string& sName, size_t& idxinbommap);
|
||
|
||
std::string m_attrib;
|
||
std::string m_name;
|
||
bool m_bIsRepresentationItem;
|
||
void* m_PtrPRCEntity;
|
||
int m_iQty;
|
||
std::string m_keyAttribValue;
|
||
std::vector<size_t> m_NodeIndexes;
|
||
};
|
||
|
||
bool BomElement::isInMapByKeyAttrib(
|
||
const std::vector<BomElement> mapBomElements, const std::string& sKeyAttribValue,
|
||
size_t& idxinbommap)
|
||
{
|
||
// find in map
|
||
size_t imap;
|
||
bool bFoundIdxinbommap = false;
|
||
for (imap = 0; !bFoundIdxinbommap && imap < mapBomElements.size(); imap++)
|
||
{
|
||
if (mapBomElements[imap].m_keyAttribValue == sKeyAttribValue)
|
||
{
|
||
idxinbommap = imap;
|
||
bFoundIdxinbommap = true;
|
||
}
|
||
}
|
||
|
||
return bFoundIdxinbommap;
|
||
}
|
||
|
||
bool BomElement::isInMapByName(
|
||
const std::vector<BomElement> mapBomElements, const std::string& sName,
|
||
size_t& idxinbommap)
|
||
{
|
||
// find in map
|
||
size_t imap;
|
||
bool bFoundIdxinbommap = false;
|
||
for (imap = 0; !bFoundIdxinbommap && imap < mapBomElements.size(); imap++)
|
||
{
|
||
if (mapBomElements[imap].m_name == sName)
|
||
{
|
||
idxinbommap = imap;
|
||
bFoundIdxinbommap = true;
|
||
}
|
||
}
|
||
|
||
return bFoundIdxinbommap;
|
||
}
|
||
|
||
|
||
|
||
//######################################################################################################################
|
||
|
||
|
||
A3DStatus CreateTable_Sple1_Statics(A3DPDFDocument* pDoc, A3DPDFDataTable*& pDataTable_Statics)
|
||
{
|
||
// structure for Tables definitions
|
||
std::vector<std::vector<std::string> > aRows;
|
||
std::vector<std::string> aOneRow;
|
||
|
||
// TABLE Statics
|
||
aRows.clear();
|
||
aOneRow.clear();
|
||
aOneRow.push_back("CRANK");
|
||
aOneRow.push_back("23/07/2017");
|
||
aOneRow.push_back("Joe");
|
||
aRows.push_back(aOneRow);
|
||
|
||
return stCreateTable(pDoc, aRows, pDataTable_Statics);
|
||
}
|
||
|
||
A3DStatus CreateTable_Sple1_Manufacturers(A3DPDFDocument* pDoc, A3DPDFDataTable*& pDataTable)
|
||
{
|
||
// structure for Tables definitions
|
||
std::vector<std::vector<std::string> > aRows;
|
||
std::vector<std::string> aOneRow;
|
||
aRows.clear();
|
||
aOneRow.clear();
|
||
aOneRow.push_back("Tech Soft 3D");
|
||
aOneRow.push_back("US");
|
||
aOneRow.push_back("Joe Bill");
|
||
aOneRow.push_back("931 Ashby Ave.\nBerkeley\nCA 94710-2805\nUSA");
|
||
aRows.push_back(aOneRow);
|
||
aOneRow.clear();
|
||
aOneRow.push_back("Tetra4D");
|
||
aOneRow.push_back("US");
|
||
aOneRow.push_back("James Orning");
|
||
aOneRow.push_back("1567 SW Chandler Ave,\nSuite 100, Bend, OR 97702\nUSA");
|
||
aRows.push_back(aOneRow);
|
||
aOneRow.clear();
|
||
aOneRow.push_back("Adden");
|
||
aOneRow.push_back("UK");
|
||
aOneRow.push_back("David Grival");
|
||
aOneRow.push_back("River Mill, Staveley Mill Yard,\nStaveley Cumbria LA8 9LR\nUK");
|
||
aRows.push_back(aOneRow);
|
||
aOneRow.clear();
|
||
aOneRow.push_back("Hart");
|
||
aOneRow.push_back("Germany");
|
||
aOneRow.push_back("Martin Zucher");
|
||
aOneRow.push_back("Schonwalder Allee 30\nEckernforde\nSchleswig-Holstein\n24334");
|
||
aRows.push_back(aOneRow);
|
||
aOneRow.clear();
|
||
aOneRow.push_back("Dynamics");
|
||
aOneRow.push_back("Japan");
|
||
aOneRow.push_back("Tetsuo Taniguchi");
|
||
aOneRow.push_back("Yokohama ST Bldg. 7F 1-11-15\nKitasaiwai, Nishi-ku, Yokohama, Kanagawa\n220-0004 Japan");
|
||
aRows.push_back(aOneRow);
|
||
aOneRow.clear();
|
||
aOneRow.push_back("Prendergast");
|
||
aOneRow.push_back("US");
|
||
aOneRow.push_back("Alexandru Pintilie");
|
||
aOneRow.push_back("4010 Executive Park Dr, Suite 250\nCincinnati, OH 45241\nUSA");
|
||
aRows.push_back(aOneRow);
|
||
aOneRow.clear();
|
||
aOneRow.push_back("Vector Solutions");
|
||
aOneRow.push_back("France");
|
||
aOneRow.push_back("Jean Fran<61>ois Marchand");
|
||
aOneRow.push_back("200 ave Jean Jaures\n69007 Lyon\nFrance");
|
||
aRows.push_back(aOneRow);
|
||
aOneRow.clear();
|
||
aOneRow.push_back("Rimmer");
|
||
aOneRow.push_back("Belgium");
|
||
aOneRow.push_back("Johan Groeningen");
|
||
aOneRow.push_back("Rue des Honnelles 495\nZeebrugge\nWest Flanders\n8380");
|
||
aRows.push_back(aOneRow);
|
||
|
||
return stCreateTable(pDoc, aRows, pDataTable);
|
||
}
|
||
|
||
|
||
A3DStatus CreateTable_Sple1_3DModel_Bom(A3DPDFDocument* pDoc, A3DAsmModelFile* pModelFile, A3DRWParamsPrcWriteHelper* pPRCWriteHelper,
|
||
const std::string& sPathIcons,
|
||
int& iKeyNode3dUID, int& iKeyNode3dName, int& iKeyNode3dInstance,
|
||
int& iKeyBomNumArt, int& iKeyBomNamePart, int& iKeyBomQty, int& iKeyBomMaterial, int& iKeyBomIcon,
|
||
A3DPDFDataTable*& pDataTable3D, A3DPDFDataTable*& pDataTableBom,
|
||
A3DPDFDataTable* pDataTableManufacturers)
|
||
{
|
||
A3DStatus iRet = A3D_SUCCESS;
|
||
pDataTable3D = NULL;
|
||
pDataTableBom = NULL;
|
||
|
||
// structure for Tables definitions
|
||
std::vector<std::vector<std::string> > aTable3DRows;
|
||
std::vector<std::vector<std::string> > aTableBomRows;
|
||
// structure for Relationships definitions
|
||
std::vector< std::pair <size_t, size_t> > aMapIndexes_3dToBom;
|
||
std::vector< std::pair <size_t, size_t> > aMapIndexes_BomTo3D;
|
||
std::vector< std::pair <size_t, size_t> > aMapIndexes_BomToManufacturers;
|
||
std::vector<BomElement> mapBomElements;
|
||
|
||
// parse the 3D PDF nodes
|
||
A3DPDFModelFileNodesData* pModelFileNodesInfo = NULL;
|
||
CHECK_RET(A3DPDFGetModelFileNodes(pModelFile, pPRCWriteHelper, &pModelFileNodesInfo));
|
||
|
||
std::map<std::string, int> mapOfNames;
|
||
|
||
int iFirstNode = 2; // for this sample, we don't take the 2 first nodes (node 0 is for the root, and node 1 doesn't exist)
|
||
for (size_t inodein3d = iFirstNode; inodein3d < (size_t)pModelFileNodesInfo->m_iNbNodes; inodein3d++)
|
||
{
|
||
A3DPDFNodeData* nodeInfos = pModelFileNodesInfo->m_ppNodes[inodein3d];
|
||
|
||
// in this sample, the 3D nodes involved in datamodel are the Product Occurences
|
||
// the product name is the key to bom entry
|
||
|
||
if (nodeInfos->m_eNodeType == kA3DPDFNodeProductOccurrence)
|
||
{
|
||
std::string sNodeName = nodeInfos->m_pcName;
|
||
|
||
// instance number
|
||
std::map<std::string, int>::iterator it = mapOfNames.find(sNodeName);
|
||
int iIbnstanceNb = 0;
|
||
if (it != mapOfNames.end()) // found : increment second
|
||
{
|
||
it->second++;
|
||
iIbnstanceNb = it->second;
|
||
}
|
||
else // not found : create entry
|
||
{
|
||
mapOfNames.insert(std::make_pair(sNodeName, 1));
|
||
iIbnstanceNb = 1;
|
||
}
|
||
|
||
std::vector<std::string> aOneRow;
|
||
aOneRow.push_back(nodeInfos->m_pcNodeUid); iKeyNode3dUID = (int)aOneRow.size() - 1;
|
||
aOneRow.push_back(sNodeName); iKeyNode3dName = (int)aOneRow.size() - 1;
|
||
aOneRow.push_back(intToString(iIbnstanceNb)); iKeyNode3dInstance = (int)aOneRow.size() - 1;
|
||
aTable3DRows.push_back(aOneRow);
|
||
|
||
|
||
// Build Bom map entry
|
||
|
||
size_t idxinbommap = 0;
|
||
bool bFoundIdxinbommap = BomElement::isInMapByName(mapBomElements, sNodeName, idxinbommap);
|
||
if (!bFoundIdxinbommap)
|
||
{
|
||
// node not found in map, put it
|
||
BomElement bomElement;
|
||
bomElement.m_iQty = 1;
|
||
bomElement.m_name = nodeInfos->m_pcName;
|
||
mapBomElements.push_back(bomElement);
|
||
idxinbommap = (int)mapBomElements.size() - 1;
|
||
}
|
||
else
|
||
{
|
||
// node is already in map
|
||
|
||
// only count mesh nodes ? not needed in this sample as we go here only for productoccurence
|
||
// if (nodeInfos->m_bIsRepresentationItem)
|
||
mapBomElements[idxinbommap].m_iQty++;
|
||
mapBomElements[idxinbommap].m_NodeIndexes.push_back(inodein3d);
|
||
}
|
||
|
||
// create relationship between 3d node and bom entry
|
||
size_t iThisNodein3d = aTable3DRows.size()-1;
|
||
aMapIndexes_3dToBom.push_back(std::make_pair(iThisNodein3d, idxinbommap));
|
||
aMapIndexes_BomTo3D.push_back(std::make_pair(idxinbommap, iThisNodein3d));
|
||
}
|
||
}
|
||
CHECK_RET(A3DPDFGetModelFileNodes(nullptr, nullptr, &pModelFileNodesInfo));
|
||
|
||
// Build BOM table
|
||
for (size_t imap = 0; imap < mapBomElements.size(); imap++)
|
||
{
|
||
// hard coded section for adding corresponding icons and materials
|
||
// typically, these information would be stored as attribute, or extracted from a PLM
|
||
std::string sMaterial;
|
||
std::string sIconId;
|
||
if (mapBomElements[imap].m_name == "01-2_CRANKSHAFT")
|
||
{
|
||
sMaterial = "Steel";
|
||
sIconId = stStoreIcon(pDoc, sPathIcons + "crank_crankshaft.jpg");
|
||
aMapIndexes_BomToManufacturers.push_back(std::make_pair(imap, 0));
|
||
aMapIndexes_BomToManufacturers.push_back(std::make_pair(imap, 2));
|
||
aMapIndexes_BomToManufacturers.push_back(std::make_pair(imap, 4));
|
||
}
|
||
else if (mapBomElements[imap].m_name == "CONNECTING_ROD")
|
||
{
|
||
sMaterial = "Copper";
|
||
sIconId = stStoreIcon(pDoc, sPathIcons + "crank_connectingrod.jpg");
|
||
aMapIndexes_BomToManufacturers.push_back(std::make_pair(imap, 1));
|
||
aMapIndexes_BomToManufacturers.push_back(std::make_pair(imap, 3));
|
||
}
|
||
else if (mapBomElements[imap].m_name == "CONNECTING_ROD_CAP")
|
||
{
|
||
sMaterial = "Chrome";
|
||
sIconId = stStoreIcon(pDoc, sPathIcons + "crank_connectingrod_cap.jpg");
|
||
aMapIndexes_BomToManufacturers.push_back(std::make_pair(imap, 0));
|
||
aMapIndexes_BomToManufacturers.push_back(std::make_pair(imap, 1));
|
||
}
|
||
else if (mapBomElements[imap].m_name == "CONNECTING_ROD_BUSHING")
|
||
{
|
||
sMaterial = "Nickel";
|
||
sIconId = stStoreIcon(pDoc, sPathIcons + "crank_connectingrod_bushing.jpg");
|
||
aMapIndexes_BomToManufacturers.push_back(std::make_pair(imap, 3));
|
||
}
|
||
else if (mapBomElements[imap].m_name == "CONNECTING_ROD_BOLT")
|
||
{
|
||
sMaterial = "Aluminium";
|
||
sIconId = stStoreIcon(pDoc, sPathIcons + "crank_connectingrod_bolt.jpg");
|
||
aMapIndexes_BomToManufacturers.push_back(std::make_pair(imap, 0));
|
||
aMapIndexes_BomToManufacturers.push_back(std::make_pair(imap, 1));
|
||
aMapIndexes_BomToManufacturers.push_back(std::make_pair(imap, 2));
|
||
}
|
||
else if (mapBomElements[imap].m_name == "CONNECTING_ROD_BOLT_NUT")
|
||
{
|
||
sMaterial = "Copper";
|
||
sIconId = stStoreIcon(pDoc, sPathIcons + "crank_connectingrod_boltnut.jpg");
|
||
aMapIndexes_BomToManufacturers.push_back(std::make_pair(imap, 1));
|
||
aMapIndexes_BomToManufacturers.push_back(std::make_pair(imap, 3));
|
||
}
|
||
else if (mapBomElements[imap].m_name == "01-2_PISTON")
|
||
{
|
||
sMaterial = "Chrome";
|
||
sIconId = stStoreIcon(pDoc, sPathIcons + "crank_piston.jpg");
|
||
aMapIndexes_BomToManufacturers.push_back(std::make_pair(imap, 2));
|
||
aMapIndexes_BomToManufacturers.push_back(std::make_pair(imap, 4));
|
||
}
|
||
else if (mapBomElements[imap].m_name == "01-2_PISTON_PIN")
|
||
{
|
||
sMaterial = "Nickel";
|
||
sIconId = stStoreIcon(pDoc, sPathIcons + "crank_pistonpin.jpg");
|
||
aMapIndexes_BomToManufacturers.push_back(std::make_pair(imap, 0));
|
||
aMapIndexes_BomToManufacturers.push_back(std::make_pair(imap, 4));
|
||
}
|
||
else if (mapBomElements[imap].m_name == "01-2_PISTON_RETAINER")
|
||
{
|
||
sMaterial = "Aluminium";
|
||
sIconId = stStoreIcon(pDoc, sPathIcons + "crank_pistonretainer.jpg");
|
||
aMapIndexes_BomToManufacturers.push_back(std::make_pair(imap, 4));
|
||
}
|
||
else if (mapBomElements[imap].m_name == "01-2_PISTON_TOP_COMP<01-2_PISTON_RING>")
|
||
{
|
||
sMaterial = "Aluminium";
|
||
sIconId = stStoreIcon(pDoc, sPathIcons + "crank_pistonring.jpg");
|
||
aMapIndexes_BomToManufacturers.push_back(std::make_pair(imap, 2));
|
||
}
|
||
else if (mapBomElements[imap].m_name == "PISTON_BOT_COMP<01-2_PISTON_RING>")
|
||
{
|
||
sMaterial = "Aluminium";
|
||
sIconId = stStoreIcon(pDoc, sPathIcons + "crank_pistonring.jpg");
|
||
aMapIndexes_BomToManufacturers.push_back(std::make_pair(imap, 2));
|
||
}
|
||
else if (mapBomElements[imap].m_name == "PISTON_OIL_COMP<01-2_PISTON_RING>")
|
||
{
|
||
sMaterial = "Aluminium";
|
||
sIconId = stStoreIcon(pDoc, sPathIcons + "crank_pistonring.jpg");
|
||
aMapIndexes_BomToManufacturers.push_back(std::make_pair(imap, 2));
|
||
}
|
||
else if (mapBomElements[imap].m_name == "01-2_VALVE_TIMING_SPROCKET")
|
||
{
|
||
sMaterial = "Iron";
|
||
sIconId = stStoreIcon(pDoc, sPathIcons + "crank_valve.jpg");
|
||
aMapIndexes_BomToManufacturers.push_back(std::make_pair(imap, 1));
|
||
aMapIndexes_BomToManufacturers.push_back(std::make_pair(imap, 3));
|
||
}
|
||
else if (mapBomElements[imap].m_name == "01-2_DAMPER_PULLEY")
|
||
{
|
||
sMaterial = "Iron";
|
||
sIconId = stStoreIcon(pDoc, sPathIcons + "crank_damper.jpg");
|
||
aMapIndexes_BomToManufacturers.push_back(std::make_pair(imap, 1));
|
||
aMapIndexes_BomToManufacturers.push_back(std::make_pair(imap, 3));
|
||
}
|
||
else
|
||
{
|
||
sMaterial = "";
|
||
sIconId = "";
|
||
}
|
||
|
||
std::vector<std::string> aOneRow;
|
||
aOneRow.push_back(intToString((int)imap)); iKeyBomNumArt = (int)aOneRow.size() - 1;
|
||
aOneRow.push_back(mapBomElements[imap].m_name); iKeyBomNamePart = (int)aOneRow.size() - 1;
|
||
aOneRow.push_back(sMaterial); iKeyBomMaterial = (int)aOneRow.size() - 1;
|
||
aOneRow.push_back(sIconId); iKeyBomIcon = (int)aOneRow.size() - 1;
|
||
aOneRow.push_back(intToString(mapBomElements[imap].m_iQty)); iKeyBomQty = (int)aOneRow.size() - 1;
|
||
aTableBomRows.push_back(aOneRow);
|
||
}
|
||
|
||
iRet = stCreateTable(pDoc, aTable3DRows, pDataTable3D);
|
||
iRet = stCreateTable(pDoc, aTableBomRows, pDataTableBom);
|
||
iRet = stCreateRelationship(pDoc, aMapIndexes_3dToBom, pDataTable3D, pDataTableBom);
|
||
iRet = stCreateRelationship(pDoc, aMapIndexes_BomTo3D, pDataTableBom, pDataTable3D);
|
||
iRet = stCreateRelationship(pDoc, aMapIndexes_BomToManufacturers, pDataTableBom, pDataTableManufacturers);
|
||
|
||
return iRet;
|
||
}
|
||
|
||
|
||
A3DStatus CreateTable_Sple1_CBFILTER(A3DPDFDocument* pDoc, A3DPDFDataTable*& pDataTable)
|
||
{
|
||
// structure for Tables definitions
|
||
std::vector<std::vector<std::string> > aRows;
|
||
std::vector<std::string> aOneRow;
|
||
|
||
aRows.clear();
|
||
aOneRow.clear();
|
||
aOneRow.push_back("Central parts");
|
||
aRows.push_back(aOneRow);
|
||
aOneRow.clear();
|
||
aOneRow.push_back("Connectors");
|
||
aRows.push_back(aOneRow);
|
||
aOneRow.clear();
|
||
aOneRow.push_back("Pistons");
|
||
aRows.push_back(aOneRow);
|
||
|
||
return stCreateTable(pDoc, aRows, pDataTable);
|
||
}
|
||
|
||
A3DStatus CreateRelationship_Sple1_CBFILTER_To_Bom(A3DPDFDocument* pDoc,
|
||
A3DPDFDataTable* pDataTable_Source, A3DPDFDataTable* pDataTable_Target)
|
||
{
|
||
// structure for Relationships definitions
|
||
std::vector< std::pair <size_t, size_t> > aMapIndexes;
|
||
|
||
// This is a hard-coded section working only for the 3D part provided with this sample
|
||
|
||
// filter 1 isolates a subset of parts ; here we want the central parts
|
||
aMapIndexes.push_back(std::make_pair (0, 1));
|
||
aMapIndexes.push_back(std::make_pair (0, 12));
|
||
aMapIndexes.push_back(std::make_pair (0, 13));
|
||
// filter 2 isolates a second subset of parts ; here we want the parts referring to connectors
|
||
aMapIndexes.push_back(std::make_pair(1, 1));
|
||
aMapIndexes.push_back(std::make_pair(1, 2));
|
||
aMapIndexes.push_back(std::make_pair(1, 3));
|
||
aMapIndexes.push_back(std::make_pair(1, 4));
|
||
aMapIndexes.push_back(std::make_pair (1, 5));
|
||
// filter 3 isolates a second subset of parts ; here we want the parts referring to pistons
|
||
aMapIndexes.push_back(std::make_pair(2, 6));
|
||
aMapIndexes.push_back(std::make_pair(2, 7));
|
||
aMapIndexes.push_back(std::make_pair(2, 8));
|
||
aMapIndexes.push_back(std::make_pair(2, 9));
|
||
aMapIndexes.push_back(std::make_pair(2, 10));
|
||
aMapIndexes.push_back(std::make_pair(2, 11));
|
||
|
||
return stCreateRelationship(pDoc, aMapIndexes, pDataTable_Source, pDataTable_Target);
|
||
}
|
||
|
||
|
||
|
||
//######################################################################################################################
|
||
|
||
|
||
A3DStatus CreateTable_Sple2_Statics(A3DPDFDocument* pDoc, A3DPDFDataTable*& pDataTable_Statics)
|
||
{
|
||
// structure for Tables definitions
|
||
std::vector<std::vector<std::string> > aRows;
|
||
std::vector<std::string> aOneRow;
|
||
|
||
// TABLE Statics
|
||
aRows.clear();
|
||
aOneRow.clear();
|
||
aOneRow.push_back("INSPECTION REPORT");
|
||
aOneRow.push_back("23/07/2017");
|
||
aOneRow.push_back("Bill");
|
||
aRows.push_back(aOneRow);
|
||
|
||
return stCreateTable(pDoc, aRows, pDataTable_Statics);
|
||
}
|
||
|
||
A3DStatus CreateTable_Sple2_ViewNames(A3DPDFDocument* pDoc, A3DPDFDataTable*& pDataTable)
|
||
{
|
||
// structure for Tables definitions
|
||
std::vector<std::vector<std::string> > aRows;
|
||
std::vector<std::string> aOneRow;
|
||
aRows.clear();
|
||
aOneRow.clear();
|
||
aOneRow.push_back("View 1");
|
||
aRows.push_back(aOneRow);
|
||
aOneRow.clear();
|
||
aOneRow.push_back("View 2");
|
||
aRows.push_back(aOneRow);
|
||
return stCreateTable(pDoc, aRows, pDataTable);
|
||
}
|
||
|
||
|
||
A3DStatus CreateTable_Sple2_3DModel(A3DPDFDocument* pDoc, A3DAsmModelFile* pModelFile, A3DRWParamsPrcWriteHelper* pPRCWriteHelper,
|
||
int& iKeyNode3dUID, int& iKeyPmiName, int& iKeyPmiType, int& iKeyPmiValue, int& iKeyPmiTol,
|
||
A3DPDFDataTable*& pDataTable3D, A3DPDFDataTable*& pDataTablePmis)
|
||
{
|
||
A3DStatus iRet = A3D_SUCCESS;
|
||
pDataTable3D = NULL;
|
||
|
||
// structure for Tables definitions
|
||
std::vector<std::vector<std::string> > aTable3DRows;
|
||
std::vector<std::vector<std::string> > aTablePmis;
|
||
// structure for Relationships definitions
|
||
std::vector< std::pair <size_t, size_t> > aMapIndexes_3dToPmis;
|
||
std::vector< std::pair <size_t, size_t> > aMapIndexes_PmisTo3d;
|
||
|
||
// parse the 3D PDF nodes
|
||
A3DPDFModelFileNodesData* pModelFileNodesInfo = NULL;
|
||
CHECK_RET(A3DPDFGetModelFileNodes(pModelFile, pPRCWriteHelper, &pModelFileNodesInfo));
|
||
|
||
std::map<std::string, int> mapOfNames;
|
||
|
||
for (size_t inodein3d = 0; inodein3d < (size_t)pModelFileNodesInfo->m_iNbNodes; inodein3d++)
|
||
{
|
||
A3DPDFNodeData* nodeInfos = pModelFileNodesInfo->m_ppNodes[inodein3d];
|
||
|
||
// in this sample, the 3D nodes involved in datamodel are the Pmis
|
||
// the pmi name is the key to bom entry
|
||
|
||
if (nodeInfos->m_eNodeType == kA3DPDFNodePMI)
|
||
{
|
||
std::string sNodeName = nodeInfos->m_pcName;
|
||
|
||
// hard coded section for adding corresponding icons and materials
|
||
// typically, these information would be stored as attribute, or extracted from a PLM
|
||
std::string sType;
|
||
std::string sValue;
|
||
std::string sTol;
|
||
if (sNodeName == "Chamfer 1")
|
||
{
|
||
sType = "Chamfer";
|
||
sValue = "Not specified";
|
||
sTol = "Not specified";
|
||
}
|
||
else if (sNodeName == "Chamfer 2")
|
||
{
|
||
sType = "Chamfer";
|
||
sValue = "Not specified";
|
||
sTol = "Not specified";
|
||
}
|
||
else if (sNodeName == "Roughness")
|
||
{
|
||
sType = "Roughness";
|
||
sValue = "Not specified";
|
||
sTol = "Not specified";
|
||
}
|
||
else if (sNodeName == "Datum A")
|
||
{
|
||
sType = "Datum";
|
||
sValue = "A";
|
||
sTol = "Not specified";
|
||
}
|
||
else if (sNodeName == "Datum B")
|
||
{
|
||
sType = "Datum";
|
||
sValue = "B";
|
||
sTol = "Not specified";
|
||
}
|
||
else if (sNodeName == "Perpendicularity 1")
|
||
{
|
||
sType = "Perpendicularity";
|
||
sValue = "Not specified";
|
||
sTol = "0.01";
|
||
}
|
||
else if (sNodeName == "Concentricity")
|
||
{
|
||
sType = "Concentricity";
|
||
sValue = "Not specified";
|
||
sTol = "0.01";
|
||
}
|
||
else if (sNodeName == "Linear Size.1")
|
||
{
|
||
sType = "Diameter Cylinder";
|
||
sValue = "50";
|
||
sTol = "-0.1 / 0.1";
|
||
}
|
||
else if (sNodeName == "Dimension.5")
|
||
{
|
||
sType = "Length";
|
||
sValue = "50";
|
||
sTol = "H6/f7";
|
||
}
|
||
else if (sNodeName == "Dimension.6")
|
||
{
|
||
sType = "Length";
|
||
sValue = "35";
|
||
sTol = "-0.1 / 0.1";
|
||
}
|
||
else if (sNodeName == "Linear Size.2")
|
||
{
|
||
sType = "Diameter Cylinder";
|
||
sValue = "35";
|
||
sTol = "-0.1 / 0.1";
|
||
}
|
||
else if (sNodeName == "Linear Size.3")
|
||
{
|
||
sType = "Diameter Cylinder";
|
||
sValue = "35";
|
||
sTol = "-0.1 / 0.1";
|
||
}
|
||
else if (sNodeName == "Dimension.4")
|
||
{
|
||
sType = "Distance";
|
||
sValue = "5";
|
||
sTol = "-0.1 / 0.1";
|
||
}
|
||
else if (sNodeName == "Dimension.2")
|
||
{
|
||
sType = "Distance";
|
||
sValue = "40";
|
||
sTol = "-0.1 / 0.1";
|
||
}
|
||
else if (sNodeName == "Dimension.1")
|
||
{
|
||
sType = "Distance";
|
||
sValue = "15";
|
||
sTol = "-0.1 / 0.1";
|
||
}
|
||
else if (sNodeName == "Dimension.3")
|
||
{
|
||
sType = "Distance";
|
||
sValue = "5";
|
||
sTol = "-0.1 / 0.1";
|
||
}
|
||
else if (sNodeName == "Datum C")
|
||
{
|
||
sType = "Datum";
|
||
sValue = "C";
|
||
sTol = "Not specified";
|
||
}
|
||
else if (sNodeName == "Parallelism")
|
||
{
|
||
sType = "Parallelism";
|
||
sValue = "Not specified";
|
||
sTol = "0.01";
|
||
}
|
||
else if (sNodeName == "Perpendicularity 2")
|
||
{
|
||
sType = "Perpendicularity";
|
||
sValue = "Not specified";
|
||
sTol = "0.01";
|
||
}
|
||
else if (sNodeName == "Linear Size.4")
|
||
{
|
||
sType = "Diameter Cylinder";
|
||
sValue = "10";
|
||
sTol = "-0.1 / 0.1";
|
||
}
|
||
|
||
std::vector<std::string> aOneRow3d;
|
||
aOneRow3d.push_back(nodeInfos->m_pcNodeUid); iKeyNode3dUID = (int)aOneRow3d.size() - 1;
|
||
aTable3DRows.push_back(aOneRow3d);
|
||
|
||
std::vector<std::string> aOneRowPmi;
|
||
aOneRowPmi.push_back(sNodeName); iKeyPmiName = (int)aOneRowPmi.size() - 1;
|
||
aOneRowPmi.push_back(sType); iKeyPmiType = (int)aOneRowPmi.size() - 1;
|
||
aOneRowPmi.push_back(sValue); iKeyPmiValue = (int)aOneRowPmi.size() - 1;
|
||
aOneRowPmi.push_back(sTol); iKeyPmiTol = (int)aOneRowPmi.size() - 1;
|
||
aTablePmis.push_back(aOneRowPmi);
|
||
|
||
// create relationship between 3d node and pmi entry
|
||
size_t iThisIndex = aTable3DRows.size() - 1;
|
||
aMapIndexes_3dToPmis.push_back(std::make_pair(iThisIndex, iThisIndex));
|
||
aMapIndexes_PmisTo3d.push_back(std::make_pair(iThisIndex, iThisIndex));
|
||
}
|
||
}
|
||
|
||
iRet = stCreateTable(pDoc, aTable3DRows, pDataTable3D);
|
||
iRet = stCreateTable(pDoc, aTablePmis, pDataTablePmis);
|
||
iRet = stCreateRelationship(pDoc, aMapIndexes_3dToPmis, pDataTable3D, pDataTablePmis);
|
||
iRet = stCreateRelationship(pDoc, aMapIndexes_PmisTo3d, pDataTablePmis, pDataTable3D);
|
||
|
||
CHECK_RET(A3DPDFGetModelFileNodes(nullptr, nullptr, &pModelFileNodesInfo));
|
||
|
||
return iRet;
|
||
}
|
||
|
||
|
||
|
||
|
||
/* hard coded version
|
||
|
||
A3DStatus CreateTable_Sple2_3DViews(A3DPDFDocument* pDoc, A3DPDFDataTable*& pDataTable)
|
||
{
|
||
// structure for Tables definitions
|
||
std::vector<std::vector<std::string> > aRows;
|
||
std::vector<std::string> aOneRow;
|
||
|
||
aRows.clear();
|
||
aOneRow.clear();
|
||
aOneRow.push_back("0");
|
||
aOneRow.push_back("Front View.1");
|
||
aOneRow.push_back("This is first view");
|
||
aRows.push_back(aOneRow);
|
||
aOneRow.clear();
|
||
aOneRow.push_back("1");
|
||
aOneRow.push_back("Front View.2");
|
||
aOneRow.push_back("This is second view");
|
||
aRows.push_back(aOneRow);
|
||
|
||
return stCreateTable(pDoc, aRows, pDataTable);
|
||
}
|
||
*/
|
||
|
||
A3DStatus CreateTable_Sple2_3DViews_WithCarousel(A3DPDFDocument* pDoc, A3DPDF3DArtwork* p3DArtwork, A3DAsmModelFile* pModelFile,
|
||
A3DPDFDataTable3DViews*& pDataTable)
|
||
{
|
||
A3DStatus iRet = A3D_SUCCESS;
|
||
A3DUns32 uiNbViews = 0;
|
||
A3DPDFView** ppViews = NULL;
|
||
pDataTable = NULL;
|
||
|
||
// first get views from the 3D model: do we really need a carousel
|
||
|
||
iRet = A3DPDF3DArtworkGetViews(p3DArtwork, &uiNbViews, &ppViews);
|
||
// the last view is the automatic view, automatically created by HOOPS Publish to be the default view.
|
||
// we consider in this sample that this view is not in the CAD tool, so we don't want it in the carousel
|
||
if(uiNbViews > 0)
|
||
uiNbViews--;
|
||
|
||
// if no views after that, no use to write a carousel !
|
||
if (uiNbViews == 0)
|
||
return A3D_SUCCESS;
|
||
|
||
// columns to add to the table for views
|
||
int iNbAddedCols = 2;
|
||
std::vector<std::vector<std::string> > aAddedAttribs;
|
||
std::vector<std::string> aOneRow;
|
||
aAddedAttribs.clear();
|
||
for (unsigned int ir = 0; ir < uiNbViews; ir++)
|
||
{
|
||
aOneRow.clear();
|
||
aOneRow.push_back("v" + intToString((int)ir) + " - info A");
|
||
aOneRow.push_back("v" + intToString((int)ir) + " - info B");
|
||
aAddedAttribs.push_back(aOneRow);
|
||
}
|
||
|
||
A3DInt32 *piViewIndexes = (A3DInt32 *)malloc(uiNbViews*sizeof(A3DInt32));
|
||
A3DUTF8Char* *ppcViewLabels = (A3DUTF8Char* *)malloc(uiNbViews*sizeof(A3DUTF8Char*));
|
||
A3DPDFImage* *ppImages = (A3DPDFImage* *)malloc(uiNbViews*sizeof(A3DPDFImage*));
|
||
|
||
A3DPDFDataTableData sTableAddedData;
|
||
A3D_INITIALIZE_DATA(A3DPDFDataTableData, sTableAddedData);
|
||
sTableAddedData.m_iNbRows = uiNbViews;
|
||
sTableAddedData.m_iNbCols = iNbAddedCols;
|
||
sTableAddedData.m_ppcTexts = (A3DUTF8Char**) malloc(uiNbViews * iNbAddedCols * A3DUns32(sizeof(A3DUTF8Char*)));
|
||
for (unsigned int ir = 0; ir < uiNbViews; ir++)
|
||
{
|
||
// get the view name. might be useful if there's a need to filter values depending on view name
|
||
A3DUTF8Char* pcViewId = NULL;
|
||
A3DPDFViewGetExternalName(ppViews[ir], &pcViewId);
|
||
std::string sViewId = pcViewId;
|
||
A3DPDFViewGetExternalName(nullptr, &pcViewId);
|
||
|
||
piViewIndexes[ir] = ir;// index in list view, ordered as in A3DPDF3DArtworkGetViews
|
||
|
||
//optional code: labels for carousel buttons. if null, view name are used.
|
||
if (sViewId == "Front View.1")
|
||
mallocAndSetString("VIEW 1", ppcViewLabels[ir]);
|
||
else if (sViewId == "Front View.2")
|
||
mallocAndSetString("VIEW 2", ppcViewLabels[ir]);
|
||
else
|
||
mallocAndSetString("VIEW UNKNOWN", ppcViewLabels[ir]);
|
||
|
||
// icon for view. if kA3DPDFTableFor3DViewsComputePosters, the image is automatically generated if needed for carousel.
|
||
ppImages[ir] = NULL;
|
||
|
||
// additional table columns: will be stored in the table starting from column position [2]
|
||
for(int ic = 0; ic < iNbAddedCols ; ic++)
|
||
mallocAndSetString(
|
||
aAddedAttribs[ir][ic].c_str(), // src
|
||
sTableAddedData.m_ppcTexts[ir*iNbAddedCols+ic]); // dest
|
||
}
|
||
|
||
|
||
A3DPDFTable3DViewsData sTable3DViewsData;
|
||
A3D_INITIALIZE_DATA(A3DPDFTable3DViewsData, sTable3DViewsData);
|
||
sTable3DViewsData.m_iNbViews = uiNbViews;
|
||
sTable3DViewsData.m_piViewIndexes = piViewIndexes;
|
||
sTable3DViewsData.m_ppcViewLabels = ppcViewLabels;
|
||
sTable3DViewsData.m_ppImages = ppImages; // not useful if kA3DPDFTableFor3DViewsComputePosters is specified
|
||
sTable3DViewsData.m_pDataTableData = &sTableAddedData;
|
||
|
||
CHECK_RET(A3DPDFDataTable3DViewsCreate(pDoc, p3DArtwork,pModelFile,
|
||
kA3DPDFTableFor3DViewsCustom | kA3DPDFTableFor3DViewsComputePosters, // kA3DPDFTableFor3DViewsComputePosters to automatically compute posters for all views specified
|
||
&sTable3DViewsData,
|
||
&pDataTable));
|
||
|
||
// clean
|
||
stFreeTable3DViews(sTable3DViewsData);
|
||
iRet = A3DPDF3DArtworkGetViews(NULL, NULL, &ppViews);
|
||
|
||
return iRet;
|
||
}
|
||
|
||
A3DStatus CreateTable_Sple2_3DViews_WithCarousel_Simple(A3DPDFDocument* pDoc, A3DPDF3DArtwork* p3DArtwork, A3DAsmModelFile* pModelFile,
|
||
A3DPDFDataTable3DViews*& pDataTable)
|
||
{
|
||
A3DStatus iRet = A3D_SUCCESS;
|
||
A3DUns32 uiNbViews = 0;
|
||
A3DPDFView** ppViews = NULL;
|
||
pDataTable = NULL;
|
||
|
||
// first get views from the 3D model: do we really need a carousel
|
||
iRet = A3DPDF3DArtworkGetViews(p3DArtwork, &uiNbViews, &ppViews);
|
||
// the last view is the automatic view, automatically created by HOOPS Publish to be the default view.
|
||
// we consider in this sample that this view is not in the CAD tool, so we don't want it in the carousel
|
||
if(uiNbViews > 0)
|
||
uiNbViews--;
|
||
|
||
// if no views after that, no use to write a carousel !
|
||
if (uiNbViews == 0)
|
||
return A3D_SUCCESS;
|
||
|
||
A3DInt32 *piViewIndexes = (A3DInt32 *)malloc(uiNbViews*sizeof(A3DInt32));
|
||
A3DUTF8Char* *ppcViewLabels = (A3DUTF8Char* *)malloc(uiNbViews*sizeof(A3DUTF8Char*));
|
||
A3DPDFImage* *ppImages = (A3DPDFImage* *)malloc(uiNbViews*sizeof(A3DPDFImage*));
|
||
for (unsigned int ir = 0; ir < uiNbViews; ir++)
|
||
{
|
||
piViewIndexes[ir] = ir;// index in list view, ordered as in A3DPDF3DArtworkGetViews
|
||
//optional: labels for carousel buttons. if null, view name are used.
|
||
ppcViewLabels[ir] = NULL;
|
||
ppImages[ir] = NULL; // icon for view. if kA3DPDFTableFor3DViewsComputePosters, the image is automatically generated if needed for carousel.
|
||
}
|
||
|
||
CHECK_RET(A3DPDFDataTable3DViewsCreate(pDoc, p3DArtwork,pModelFile,
|
||
kA3DPDFTableFor3DViewsCustom | kA3DPDFTableFor3DViewsComputePosters, // kA3DPDFTableFor3DViewsComputePosters to automatically compute posters for all views specified
|
||
NULL,
|
||
&pDataTable));
|
||
|
||
// clean
|
||
free(piViewIndexes);
|
||
free(ppcViewLabels);
|
||
free(ppImages);
|
||
iRet = A3DPDF3DArtworkGetViews(NULL, NULL, &ppViews);
|
||
|
||
return iRet;
|
||
}
|
||
|
||
A3DStatus CreateTable_Sple2_3DViews(A3DPDFDocument* pDoc, A3DPDF3DArtwork* p3DArtwork,
|
||
A3DPDFDataTable3DViews*& pDataTable)
|
||
{
|
||
A3DStatus iRet = A3D_SUCCESS;
|
||
pDataTable = NULL;
|
||
|
||
CHECK_RET(A3DPDFDataTable3DViewsCreate(pDoc, p3DArtwork,NULL,
|
||
kA3DPDFTableFor3DViewsAll,
|
||
NULL, // views specification unused as we want all views and no predefined posters
|
||
&pDataTable));
|
||
|
||
return iRet;
|
||
}
|
||
|
||
|
||
|
||
|
||
A3DStatus CreateRelationship_Sple2_ViewNames_To_Views(A3DPDFDocument* pDoc,
|
||
A3DPDFDataTable* pDataTable_ViewNames, A3DPDFDataTable* pDataTable_Views)
|
||
{
|
||
// structure for Relationships definitions
|
||
std::vector< std::pair <size_t, size_t> > aMapIndexes;
|
||
aMapIndexes.push_back( std::make_pair (0, 0) );
|
||
aMapIndexes.push_back( std::make_pair (1, 1) );
|
||
stCreateRelationship(pDoc, aMapIndexes, pDataTable_ViewNames, pDataTable_Views);
|
||
stCreateRelationship(pDoc, aMapIndexes, pDataTable_Views, pDataTable_ViewNames);
|
||
|
||
return A3D_SUCCESS;
|
||
}
|
||
|
||
A3DStatus CreateRelationship_Sple2_View_To_Pmis(A3DPDFDocument* pDoc,
|
||
A3DPDFDataTable* pDataTable_Source, A3DPDFDataTable* pDataTable_Target)
|
||
{
|
||
// structure for Relationships definitions
|
||
std::vector< std::pair <size_t, size_t> > aMapIndexes;
|
||
|
||
// This is a hard-coded section working only for the 3D part provided with this sample
|
||
|
||
// view 1
|
||
aMapIndexes.push_back( std::make_pair (0, 0) );
|
||
aMapIndexes.push_back( std::make_pair (0, 1) );
|
||
aMapIndexes.push_back( std::make_pair (0, 2) );
|
||
aMapIndexes.push_back( std::make_pair (0, 3) );
|
||
aMapIndexes.push_back( std::make_pair (0, 4) );
|
||
aMapIndexes.push_back( std::make_pair (0, 5) );
|
||
aMapIndexes.push_back( std::make_pair (0, 6) );
|
||
aMapIndexes.push_back( std::make_pair (0, 7) );
|
||
aMapIndexes.push_back( std::make_pair (0, 8) );
|
||
aMapIndexes.push_back( std::make_pair (0, 9) );
|
||
aMapIndexes.push_back( std::make_pair (0, 10) );
|
||
aMapIndexes.push_back( std::make_pair (0, 11) );
|
||
aMapIndexes.push_back( std::make_pair (0, 12) );
|
||
aMapIndexes.push_back( std::make_pair (0, 13) );
|
||
aMapIndexes.push_back( std::make_pair (0, 14) );
|
||
aMapIndexes.push_back( std::make_pair (0, 15) );
|
||
// view 2
|
||
aMapIndexes.push_back( std::make_pair (1, 16) );
|
||
aMapIndexes.push_back( std::make_pair (1, 17) );
|
||
aMapIndexes.push_back( std::make_pair (1, 18) );
|
||
aMapIndexes.push_back( std::make_pair (1, 19) );
|
||
|
||
return stCreateRelationship(pDoc, aMapIndexes, pDataTable_Source, pDataTable_Target);
|
||
}
|
||
|
||
|
||
|
||
//######################################################################################################################
|
||
|
||
|
||
A3DStatus CreateTable_Sple3_Statics(A3DPDFDocument* pDoc, A3DPDFDataTable*& pDataTable_Statics)
|
||
{
|
||
// structure for Tables definitions
|
||
std::vector<std::vector<std::string> > aRows;
|
||
std::vector<std::string> aOneRow;
|
||
|
||
// TABLE Statics
|
||
aRows.clear();
|
||
aOneRow.clear();
|
||
aOneRow.push_back("CRANK FOR BOM");
|
||
aOneRow.push_back("12/09/2014");
|
||
aOneRow.push_back("James");
|
||
aRows.push_back(aOneRow);
|
||
|
||
return stCreateTable(pDoc, aRows, pDataTable_Statics);
|
||
}
|
||
|
||
|
||
|
||
A3DStatus CreateTable_Sple3_3DModel_Bom(A3DPDFDocument* pDoc,
|
||
A3DAsmModelFile* pModelFile,
|
||
A3DRWParamsPrcWriteHelper* pHelper,
|
||
const std::string& sPathIcons,
|
||
int& iKeyNode3dUID, int& iKeyNode3dInstanceName, int& iKeyBomNumArt, int& iKeyBomNamePart, int& iKeyBomQty, int& iKeyBomIcon,
|
||
A3DPDFDataTable*& pDataTable3D, A3DPDFDataTable*& pDataTableBom)
|
||
{
|
||
A3DStatus iRet = A3D_SUCCESS;
|
||
pDataTable3D = NULL;
|
||
pDataTableBom = NULL;
|
||
|
||
// structure for Tables definitions
|
||
std::vector<std::vector<std::string> > aTable3DRows;
|
||
std::vector<std::vector<std::string> > aTableBomRows;
|
||
// structure for Relationships definitions
|
||
std::vector< std::pair <size_t, size_t> > aMapIndexes_3dToBom;
|
||
std::vector< std::pair <size_t, size_t> > aMapIndexes_BomTo3D;
|
||
std::vector<BomElement> mapBomElements;
|
||
|
||
// use API to parse the 3D PDF nodes
|
||
A3DPDFModelFileNodesData* pModelFileNodesInfo = NULL;
|
||
CHECK_RET(A3DPDFGetModelFileNodes(pModelFile, pHelper, &pModelFileNodesInfo));
|
||
|
||
for (size_t inodein3d = 0; inodein3d < (size_t)pModelFileNodesInfo->m_iNbNodes; inodein3d++)
|
||
{
|
||
std::vector<std::string> aOneRow;
|
||
A3DPDFNodeData* nodeInfos = pModelFileNodesInfo->m_ppNodes[inodein3d];
|
||
|
||
// in this sample, the 3D nodes involved in datamodel are all the ndoes
|
||
// the attribute 'PartNumber' is the key to bom entry
|
||
|
||
aOneRow.push_back(nodeInfos->m_pcNodeUid); iKeyNode3dUID = (int)aOneRow.size()-1;
|
||
//char acPtrPRCEntity[1024]; sprintf(acPtrPRCEntity, "%p", nodeInfos->m_pEntity);
|
||
//aOneRow.push_back(acPtrPRCEntity);
|
||
aOneRow.push_back(nodeInfos->m_pcName);
|
||
if (nodeInfos->m_eNodeType==kA3DPDFNodeProductOccurrence)
|
||
aOneRow.push_back("PO");
|
||
else if (nodeInfos->m_eNodeType==kA3DPDFNodeRepresentationItem)
|
||
aOneRow.push_back("RI");
|
||
else if (nodeInfos->m_eNodeType==kA3DPDFNodePMI)
|
||
aOneRow.push_back("PMI");
|
||
//aOneRow.push_back(nodeInfos->m_pcFilePath);
|
||
//aOneRow.push_back(nodeInfos->m_pcOriginalFilePath);
|
||
|
||
// looking for a key attribute that defines the attribute which identifies a bom entry
|
||
// in this sample, this is the attribute 'PartNumber'
|
||
char pcAttribKeyForMap[] = "PartNumber" ;
|
||
char pcAttribKeyForNode3dInstance[] = "InstanceName" ;
|
||
A3DPDFNodeAttributeData* attribKey = NULL;
|
||
A3DPDFNodeAttributeData* attribKeyForNode3dInstance = NULL;
|
||
for (int j = 0; j < nodeInfos->m_iNbAttributes; j++)
|
||
{
|
||
A3DPDFNodeAttributeData* attrib = nodeInfos->m_ppAttributes[j];
|
||
if (strcmp (attrib->m_pcType, pcAttribKeyForMap)==0)
|
||
attribKey = attrib;
|
||
if (strcmp (attrib->m_pcType, pcAttribKeyForNode3dInstance)==0)
|
||
attribKeyForNode3dInstance = attrib;
|
||
}
|
||
aOneRow.push_back(attribKey ? attribKey->m_pcValue : "");
|
||
aOneRow.push_back(attribKeyForNode3dInstance ? attribKeyForNode3dInstance->m_pcValue : "");iKeyNode3dInstanceName = (int)aOneRow.size()-1;
|
||
aTable3DRows.push_back(aOneRow);
|
||
|
||
if (attribKey)
|
||
{
|
||
// the node has the key attribute, put it into Bom map
|
||
|
||
// find in map
|
||
size_t imap = 0;
|
||
size_t idxinbommap = 0;
|
||
bool bFoundIdxinbommap = false;
|
||
for (imap = 0; !bFoundIdxinbommap && imap < mapBomElements.size(); imap++)
|
||
{
|
||
if (mapBomElements[imap].m_keyAttribValue == std::string(attribKey->m_pcValue))
|
||
{
|
||
idxinbommap = imap;
|
||
bFoundIdxinbommap = true;
|
||
}
|
||
}
|
||
|
||
if (!bFoundIdxinbommap)
|
||
{
|
||
// node not found in map, put it
|
||
BomElement bomElement;
|
||
bomElement.m_keyAttribValue = (attribKey ? attribKey->m_pcValue : "");
|
||
bomElement.m_iQty = 1;
|
||
bomElement.m_name = nodeInfos->m_pcName;
|
||
bomElement.m_attrib = (attribKey ? attribKey->m_pcValue : "");
|
||
mapBomElements.push_back(bomElement);
|
||
idxinbommap = (int)mapBomElements.size()-1;
|
||
}
|
||
else
|
||
{
|
||
// node is already in map
|
||
|
||
// only count mesh nodes ? not needed in this sample as we go here only for productoccurence
|
||
// if (nodeInfos->m_bIsRepresentationItem)
|
||
mapBomElements[idxinbommap].m_iQty++;
|
||
mapBomElements[idxinbommap].m_NodeIndexes.push_back(inodein3d);
|
||
}
|
||
|
||
// create relationship between 3d node and bom entry
|
||
aMapIndexes_3dToBom.push_back( std::make_pair (inodein3d, idxinbommap) );
|
||
aMapIndexes_BomTo3D.push_back( std::make_pair (idxinbommap, inodein3d) );
|
||
}
|
||
else
|
||
{
|
||
// the key attribute was not found on the node
|
||
|
||
// note: with this sample prc, the attrib key is not found on repitems ; the attrib is only stored onto the prodocc father
|
||
// in case where the attribute is not found on repitems, we consider that the prodoccurence father was found,
|
||
// and we connect this father node to the bom entry
|
||
if (nodeInfos->m_iPocFatherIndex != -1 && nodeInfos->m_iPocFatherIndex<(A3DInt32)aMapIndexes_3dToBom.size())
|
||
{
|
||
// get bom map entry related to m_iPocFatherIndex
|
||
size_t idxinbommap = aMapIndexes_3dToBom[nodeInfos->m_iPocFatherIndex].second;
|
||
|
||
// create relationship between 3d node and bom entry
|
||
aMapIndexes_3dToBom.push_back(std::make_pair(inodein3d, idxinbommap));
|
||
}
|
||
}
|
||
}
|
||
|
||
// Build BOM table
|
||
for (size_t imap = 0; imap < mapBomElements.size(); imap++)
|
||
{
|
||
// hard coded section for adding corresponding icons
|
||
// typically, these information would be stored as attribute, or extracted from a PLM
|
||
std::string sIconId;
|
||
if (mapBomElements[imap].m_attrib == "HOUSING")
|
||
sIconId = stStoreIcon(pDoc, sPathIcons + "microengine_housing.jpg");
|
||
else if (mapBomElements[imap].m_attrib == "CYLINDER LINER")
|
||
sIconId = stStoreIcon(pDoc, sPathIcons + "microengine_cylinderliner.jpg");
|
||
else if (mapBomElements[imap].m_attrib == "HOUSING TOP")
|
||
sIconId = stStoreIcon(pDoc, sPathIcons + "microengine_housingtop.jpg");
|
||
else if (mapBomElements[imap].m_attrib == "MOBILE PART")
|
||
sIconId = stStoreIcon(pDoc, sPathIcons + "microengine_mobilepart.jpg");
|
||
else if (mapBomElements[imap].m_attrib == "PUSH ROD")
|
||
sIconId = stStoreIcon(pDoc, sPathIcons + "microengine_pushrod.jpg");
|
||
else if (mapBomElements[imap].m_attrib == "BEARING PR DW")
|
||
sIconId = stStoreIcon(pDoc, sPathIcons + "microengine_bearing_prdw.jpg");
|
||
else if (mapBomElements[imap].m_attrib == "BEARING PR UP")
|
||
sIconId = stStoreIcon(pDoc, sPathIcons + "microengine_bearing_prup.jpg");
|
||
else if (mapBomElements[imap].m_attrib == "AXE")
|
||
sIconId = stStoreIcon(pDoc, sPathIcons + "microengine_axe.jpg");
|
||
else if (mapBomElements[imap].m_attrib == "PISTON")
|
||
sIconId = stStoreIcon(pDoc, sPathIcons + "microengine_piston.jpg");
|
||
else if (mapBomElements[imap].m_attrib == "CRANKSHAFT")
|
||
sIconId = stStoreIcon(pDoc, sPathIcons + "microengine_crankshaft.jpg");
|
||
else if (mapBomElements[imap].m_attrib == "BEARING CS")
|
||
sIconId = stStoreIcon(pDoc, sPathIcons + "microengine_bearingcs.jpg");
|
||
else if (mapBomElements[imap].m_attrib == "HOUSING BACK")
|
||
sIconId = stStoreIcon(pDoc, sPathIcons + "microengine_housingback.jpg");
|
||
else if (mapBomElements[imap].m_attrib == "HOUSING FRONT")
|
||
sIconId = stStoreIcon(pDoc, sPathIcons + "microengine_housingfront.jpg");
|
||
else if (mapBomElements[imap].m_attrib == "SCREW BACK")
|
||
sIconId = stStoreIcon(pDoc, sPathIcons + "microengine_screwback.jpg");
|
||
else if (mapBomElements[imap].m_attrib == "SCREW TOP")
|
||
sIconId = stStoreIcon(pDoc, sPathIcons + "microengine_screwtop.jpg");
|
||
else if (mapBomElements[imap].m_attrib == "CARBURETOR")
|
||
sIconId = stStoreIcon(pDoc, sPathIcons + "microengine_carburetor.jpg");
|
||
else
|
||
sIconId = "";
|
||
|
||
std::vector<std::string> aOneRow;
|
||
aOneRow.push_back(intToString((int)imap)); iKeyBomNumArt = (int)aOneRow.size() - 1;
|
||
aOneRow.push_back(mapBomElements[imap].m_name);
|
||
aOneRow.push_back(mapBomElements[imap].m_attrib); iKeyBomNamePart = (int)aOneRow.size() - 1;
|
||
aOneRow.push_back(sIconId); iKeyBomIcon = (int)aOneRow.size() - 1;
|
||
aOneRow.push_back(intToString(mapBomElements[imap].m_iQty)); iKeyBomQty = (int)aOneRow.size() - 1;
|
||
aTableBomRows.push_back(aOneRow);
|
||
}
|
||
|
||
iRet = stCreateTable(pDoc, aTable3DRows, pDataTable3D);
|
||
iRet = stCreateTable(pDoc, aTableBomRows, pDataTableBom);
|
||
iRet = stCreateRelationship(pDoc, aMapIndexes_3dToBom, pDataTable3D, pDataTableBom);
|
||
iRet = stCreateRelationship(pDoc, aMapIndexes_BomTo3D, pDataTableBom, pDataTable3D);
|
||
|
||
CHECK_RET(A3DPDFGetModelFileNodes(nullptr, nullptr, &pModelFileNodesInfo));
|
||
|
||
return iRet;
|
||
}
|