Skip to main content
9-Granite
November 3, 2023
Solved

How to hide and unhide with toolkit, check out my code!

  • November 3, 2023
  • 2 replies
  • 5260 views

 Can anyone please check out my code here, trying to hide selected components with proselectbuffer here, it worked just before it crushed, can anyone help me out, thanks.

ProError ShowMessageText(ProModelitem *modelitem)
{
/*********************************************************/
AFX_MANAGE_STATE(AfxGetStaticModuleState());
ProError status,err1,err2,err3;
ProSelection *sels;
ProAsmcomppath comppath;
ProMdl mdl;
status = ProSelbufferSelectionsGet(&sels);

// status = ProSelectionModelitemGet(sels[0],modelitem);
status = ProSelectionAsmcomppathGet(sels[0], &comppath);


status= ProAsmcomppathMdlGet(&comppath,&mdl);

if(status == PRO_TK_NO_ERROR)
{
AfxMessageBox(_T("get mdl"));

status=ProMdlToModelitem(mdl,modelitem);
if(status == PRO_TK_NO_ERROR)
{ AfxMessageBox(_T("pass")); }
modelitem->type = PRO_FEATURE;
modelitem->owner = comppath.owner;
modelitem->id = comppath.comp_id_table[0];
err2 = ProModelitemHide(modelitem);
if(err2 == PRO_TK_NO_ERROR)
{ AfxMessageBox(_T("done")); }
ProSelectionarrayFree(sels);
}
return PRO_TK_NO_ERROR;
}

Best answer by FabianWolf

Hello JC,

 

by providing the tiny code snippet my goal was just to illustrate the role of different contents in the selection buffer. It was not intended to be a real world code ready to go live, of course 🙂

 

Here I provide a function that should suit your requirement to hide parts or subassemblies that are in active selection buffer:

 

auto HideSelectedPartsAndSubAssemblies() -> void
{
 ProSelection *selbufferSelections = nullptr;
 if (ProSelbufferSelectionsGet(&selbufferSelections) != PRO_TK_NO_ERROR)
 return;

 int nSels;
 CHECKVOID(ProArraySizeGet(selbufferSelections, &nSels));

 for (int i = 0; i < nSels; ++i)
 {
 ProModelitem modelItem;
 CHECKVOID(ProSelectionModelitemGet(selbufferSelections[i], &modelItem));

 if (modelItem.type != PRO_PART && modelItem.type != PRO_ASSEMBLY)
 continue;

 ProAsmcomppath acp;
 CHECKVOID(ProSelectionAsmcomppathGet(selbufferSelections[i], &acp));

 if (acp.table_num < 1)
 continue;

 const auto componentFeatureId = acp.comp_id_table[acp.table_num - 1];

 acp.comp_id_table[acp.table_num - 1] = PRO_VALUE_UNUSED;
 --acp.table_num;

 ProMdl acpModelOwner;
 CHECKVOID(ProAsmcomppathMdlGet(&acp, &acpModelOwner));

 ProModelitem modelitemToHide = { PRO_FEATURE,
 componentFeatureId,
 acpModelOwner };

 CHECKVOID(ProModelitemHide(&modelitemToHide));
 }

 ProSelectionarrayFree(selbufferSelections);

 ProMdl curModel;
 CHECKVOID(ProMdlCurrentGet(&curModel));
 ProTreetoolRefresh(curModel);
 
 ProSelbufferClear();
}

 

2 replies

18-Opal
November 3, 2023

You have to validate and to deal with the path.

 

For example, if your path is 85 77 45 (size 3, these are feature IDs!) then you have selected the model 45 'index 2' in the sub assembly 77 (size-1, index 1) and your model item owner must be the handle to that assembly 77 and NOT the comp path owner , because this is the top level assembly you have just open.

 

To Hide 45

the model item should look like:

 

type is PRO_FEATURE

id is 45

owner is the model handle of 77 (with ProMdlToModelitem(memb_id_tab, size-1,&model))

 

You hide a feature in one assembly, so you hide it in every occurrence where this the assembly is used!

The owner is always the parent assembly of the selected model.

 

ProMdlToModelitem is useless because you need to deal with feature IDs and NOT with Model IDs. And 'modelitem' is not declared in your code snippet.

 

ProAsmcomppathMdlGet will return the model the Model based on the given path AND table_size, and you can modify the table_size before you call, this would not change  ProIdTable memb_id_tab,

 

Only if the size is 1 you have selected something in the root assembly, than your code should work as far I can see this.

 

In that case:

 

type is PRO_FEATURE

id is 85 (for my example this must be an assembly)

owner is comppath.owner (the root assy)

 

Maybe this helps.

 

14-Alexandrite
November 3, 2023

Try this:

 

ProAsmcomppath acp;
CHECKERROR(ProSelectionAsmcomppathGet(selection, &acp));

ProModelitem modelItem;
CHECKERROR(ProSelectionModelitemGet(selection, &modelItem));

const auto componentFeatureId =
acp.table_num > 0 ? acp.comp_id_table[acp.table_num - 1]
: modelItem.id;

ProModelitem modelitemToHide = { PRO_FEATURE, componentFeatureId, acp.owner };

CHECKERROR(ProModelitemHide(&modelitemToHide));

 

The point here why it worked before and no more after the "crush" might be that you had different selections in selbuffer. On the one hand, if you select the component itself, the  AsmComppath has a table_num of zero and this won't lead to the correct component feature id for your modelitem to hide. On the other hand, if you select anything inside the component feature, a revolve for instance, then the component feature id will be contained in the com_id_table and the table_num won't be zero.

18-Opal
November 3, 2023

Hello Fabian, if a feature (a revolve) was selected, the model item will contain this feature ID, and NOT the path, the path is not impacted, it tells you only the path to the model. You should check the selected model item type and than decide if you want to hide the component where a revolve was selected.

 

It's a component path, not the path to a selected feature.

 

But maybe I'm wrong, hopefully not 🙂

14-Alexandrite
November 3, 2023

@RPN  schrieb:

... if a feature (a revolve) was selected, the model item will contain this feature ID, and NOT the path, the path is not impacted, it tells you only the path to the model. ...

Exactly, and that's what we want. The revolve id is not of interest. We want the component feature id of the component, that owns the revolve. And this id is contained in the asmcomppath.