cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

Community Tip - Learn all about PTC Community Badges. Engage with PTC and see how many you can earn! X

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

JonC_16
7-Bedrock

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

 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;
}

1 ACCEPTED SOLUTION

Accepted Solutions
FabianWolf
12-Amethyst
(To:JonC_16)

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();
}

 

View solution in original post

15 REPLIES 15
RPN
17-Peridot
17-Peridot
(To:JonC_16)

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.

 

FabianWolf
12-Amethyst
(To:JonC_16)

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.

RPN
17-Peridot
17-Peridot
(To:FabianWolf)

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 🙂

FabianWolf
12-Amethyst
(To:RPN)


@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.

RPN
17-Peridot
17-Peridot
(To:FabianWolf)

For me it’s easy to misunderstand 

 

„ … then the component feature id will be contained in the com_id_table …“

 

because the revolve is a feature ID of the component. . 

But we are on the same page, and I wasn’t wrong. 

God bless 😜

FabianWolf
12-Amethyst
(To:RPN)

Yes, the feature id is not the same as the id of the component owning the feature. They both have their own lifes and dreams and ids 😄

 

Have a nice day!

RPN
17-Peridot
17-Peridot
(To:FabianWolf)

Hello Fabian

 

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

 

Hmm, acp.owner are you sure about, I think this will not work if you path size is greater then one.

 

I thought again about this riddle,.

If you have a selection buffer, the model item is PRO_PART or PRO_ASSEMBLY regardless of the selection filter, if a Part or an Assembly was picked. If this is the case you need to configure the model item to hide, by the last path id, and you need to get the parent of the id, this is for sure an assembly, The parent may the active assembly as well (size 0).

 

Here a working Tcl code, just use the same logic in your C code:

 

 

proc HideSelBuffer {} {
	# prepare the sel object commands 
	# and link to an model item and comp path object
	ps_sel selObj -modelitem miObj -comppath cpObj

	# how big is the buffer
	set size [selObj buffsize]

	# if nothing selected do nothing
	if {$size < 1} {
		Debug "Buffer is empty or not available"
		return
	}
	# now loop through
	for {set idx 0 } {$idx < $size} {incr idx} {
		# get the selection idx
		selObj buffget $idx

		# Check model item type
		# only for PART or ASSEMBLY check for hide
		if { [miObj cget -type] eq "PART" || [miObj cget -type] eq "ASSEMBLY"} {
			# get the path
			set path [cpObj cget -path]

			# for '47 98 44' the level is three
			# level 0 is comp path owner
			set level [llength $path ]

			# only if a path found
			if {$level > 0} {

				# get the selected component id
				# from '47 98 44' it would be 44
				set selcomp [lindex $path end]

				# get the parent
				# for '47 98 44' the parent is at '47 98'
				# should be an assembly
				set assy [cpObj model [incr level -1] ]

				# prepare to hide
				miObj config -model $assy -type Feature -id $selcomp

				# hide only if not already hidden
				if {[miObj ishidden] == 0 } {
					# hide it
					miObj hide
				}
			}
		}
	}
}

 

 

 

 

JonC_16
7-Bedrock
(To:RPN)

Dear RPN,

yes, you are right, i tried, and the code from Fabian only works for part in active assembly.

i try to interpret your codes into toolkit, but don't have a clue how to find the parent assembly, can you help me out?which function should i use?

thanks.

Jon

RPN
17-Peridot
17-Peridot
(To:JonC_16)

extern ProError ProAsmcomppathMdlGet (ProAsmcomppath *p_path,
ProMdl *p_model);
/*
Purpose: Retrieves the model specified by the component path.

Input Arguments:
p_path - The component path

Output Arguments:
p_model - The model found at the end of the component path

Return Values:
PRO_TK_NO_ERROR - The function successfully retrieved the model.
PRO_TK_BAD_INPUTS - The input argument is invalid.
PRO_TK_GENERAL_ERROR - The specified component path was wrong, or
contained missing members.
*/

 

 

typedef struct pro_comp_path
{
ProSolid owner;
ProIdTable comp_id_table;
int table_num;
} ProAsmcomppath;

 

Tcl level = Tk table_num

FabianWolf
12-Amethyst
(To:JonC_16)

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();
}

 

HI Fabian, thanks for your help, the code works perfectly. 

FabianWolf
12-Amethyst
(To:RPN)

From what I can see, RPN provided a great solution on this topic for tcl users 👍

RPN
17-Peridot
17-Peridot
(To:FabianWolf)

Hello Fabian, thank you for the 🥀🥀.

 

Some Notes:

 

 

if (acp.table_num < 1)
            continue;

 

 

May not needed if PRO_PART or PRO_ASSEMBLY is checked.

In Creo 10 the tree selection will return the model item based on the filter as I see.

 

Here the more Tcl enhanced version (regarding access to comp ID and parent model), without notes:

 
proc HideSelBuffer {} {
  ps_sel selObj -modelitem miObj -comppath cpObj

  for {set idx 0 } {$idx <   [selObj buffsize] } {incr idx} {
  selObj buffget $idx

  set type [miObj cget -type]

  if { $type ne "PART" || $type ne "ASSEMBLY"} continue 

  set compID [cpObj compid end]

  set ParentAsm [cpObj model_in_level end-1]

  miObj config -model $ParentAsm -type Feature -id $compID

  miObj hide
}

selObj buffclear
ps_model tree_update -model [ps_model cur]
ps_wind rep
}

 

And a Proof 🙂

 

Cheers !!!

 

 

FabianWolf
12-Amethyst
(To:RPN)

if (acp.table_num < 1)
    continue;

is needed as the root assembly might be selected, which is also a PRO_ASSEMBLY 🙂

 

Great video!

RPN
17-Peridot
17-Peridot
(To:FabianWolf)

 

Hide root!  I get not an error if I try that 🙂

And the video lags a bit of Quality.

Anyhow stop thinking about that Buffer Stuff 🙂

 

Top Tags