Closed Nicogene closed 10 months ago
Ideally, it should be simple to get relevant data from the element tree without the Toolkit for Mechanica, see the example called OTKXCreateSweep.cxx
in C:\Program Files\PTC\Creo 9.0.4.0\Common Files\otk\otk_cpp\otk_examples\otk_examples_feat
:
wfcElemPathItems_ptr sketchItems = wfcElemPathItems::create();
wfcElemPathItem_ptr sketchItem0 = wfcElemPathItem::Create(wfcELEM_PATH_ITEM_TYPE_ID,wfcPRO_E_SWEEP_PROF_COMP);
sketchItems->append(sketchItem0);
wfcElemPathItem_ptr sketchItem1 = wfcElemPathItem::Create(wfcELEM_PATH_ITEM_TYPE_ID,wfcPRO_E_SWEEP_SECTION);
sketchItems->append(sketchItem1);
wfcElemPathItem_ptr sketchItem2 = wfcElemPathItem::Create(wfcELEM_PATH_ITEM_TYPE_ID,wfcPRO_E_SKETCHER);
sketchItems->append(sketchItem2);
wfcElementPath_ptr sketchPath = wfcElementPath::Create(sketchItems);
wfcElement_ptr element = elemTree->GetElement(sketchPath);
Playing around a little bit with the assembly I was able to get the information of joint type (pin) and limits with this code:
void getLimits(pfcFeature_ptr feat)
{
wfcWFeature_ptr wfeat = wfcWFeature::cast(feat);
wfcElementTree_ptr tree = wfeat->GetElementTree(nullptr, wfcFEAT_EXTRACT_NO_OPTS);
wfcElemPathItems_ptr elemItems = wfcElemPathItems::create();
wfcElemPathItem_ptr Item = wfcElemPathItem::Create(wfcELEM_PATH_ITEM_TYPE_ID, wfcPRO_E_COMPONENT_SETS);
elemItems->append(Item);
Item = wfcElemPathItem::Create(wfcELEM_PATH_ITEM_TYPE_ID, wfcPRO_E_COMPONENT_SET);
elemItems->append(Item);
Item = wfcElemPathItem::Create(wfcELEM_PATH_ITEM_TYPE_ID, wfcPRO_E_COMPONENT_SET_TYPE);
elemItems->append(Item);
wfcElementPath_ptr constraintPath = wfcElementPath::Create(elemItems);
wfcElement_ptr element = tree->GetElement(constraintPath);
if (element->GetValue()->GetIntValue() != PRO_ASM_SET_TYPE_PIN)
printToMessageWindow("found something that is not pin");
else
{
printToMessageWindow("found pin");
elemItems->clear();
Item = wfcElemPathItem::Create(wfcELEM_PATH_ITEM_TYPE_ID, wfcPRO_E_COMPONENT_SETS);
elemItems->append(Item);
Item = wfcElemPathItem::Create(wfcELEM_PATH_ITEM_TYPE_ID, wfcPRO_E_COMPONENT_SET);
elemItems->append(Item);
Item = wfcElemPathItem::Create(wfcELEM_PATH_ITEM_TYPE_ID, wfcPRO_E_COMPONENT_JAS_SETS);
elemItems->append(Item);
Item = wfcElemPathItem::Create(wfcELEM_PATH_ITEM_TYPE_ID, wfcPRO_E_COMPONENT_JAS_SET);
elemItems->append(Item);
Item = wfcElemPathItem::Create(wfcELEM_PATH_ITEM_TYPE_ID, wfcPRO_E_COMPONENT_JAS_MAX_LIMIT);
elemItems->append(Item);
Item = wfcElemPathItem::Create(wfcELEM_PATH_ITEM_TYPE_ID, wfcPRO_E_COMPONENT_JAS_MAX_LIMIT_VAL);
elemItems->append(Item);
wfcElementPath_ptr limitpath = wfcElementPath::Create(elemItems);
element = tree->GetElement(limitpath);
printToMessageWindow(to_string(element->GetValue()->GetDoubleValue()));
}
return;
}
Basically one needs to create a vector of element path items, which are the xml tags of the element tree:
For the joint type, for example:
<PRO_E_COMPONENT_SETS type="array">
<PRO_E_COMPONENT_SET type="compound">
...
<PRO_E_COMPONENT_SET_TYPE type="int">1</PRO_E_COMPONENT_SET_TYPE>
We could use the element tree to get the parent and child parts as suggested by @Nicogene
<PRO_E_COMPONENT_CONSTRAINTS type="array">
<PRO_E_COMPONENT_CONSTRAINT type="compound">
<PRO_E_COMPONENT_CONSTR_TYPE type="int">2</PRO_E_COMPONENT_CONSTR_TYPE>
<PRO_E_COMPONENT_COMP_CONSTR_REF type="selection">
<PRO_XML_REFERENCE type="reference">
<PRO_XML_REFERENCE_OWNER type="owner">SIM_ECUB_1-1_TORSO_1.prt</PRO_XML_REFERENCE_OWNER>
Heres is an example of an ElementTree dump: SIM_ECUB_1-1_TORSO_1.xml.txt
Latest commit retrieves also the child name inside the element tree, and adds some small robustness checks. This might be useful since it's not needed to pass around the name of the part currently examined by the main loop.
Though there is ambiguity if parents and child have the same name, maybe it's better to check the feature ID instead of the simple model name.
Today @Nicogene and I successfully used the information of parent-child links of the element tree to simplify the processing of each part of the assembly.
In the past, all the parts were iterated over to:
Now:
This new method greatly simplifies the search for useful information, by avoiding pointless loops. In fact, we do not have any more warnings regarding missing axes for fixed joints, and the code is faster:
Work done in: https://github.com/icub-tech-iit/creo2urdf/commit/819ce65b419e801034360b873b0302223788113d
In this next one https://github.com/icub-tech-iit/creo2urdf/commit/e89d3c9bcaddca2e9865fbcf56e75554bb43cbc8 we can avoid the matching altogether 🎉
Either via
ElementTree
orProMech
toolkit, we should retrieve the joints' information from creo directly (e.g. link parent and child, type of mechanism etc.)Right now we consider:
With these assumptions, we are not considering the prismatic joint case, and joints/csys w/ the same names could give problems
Related to #55
cc @pattacini @mfussi66