Continue to Site

Eng-Tips is the largest engineering community on the Internet

Intelligent Work Forums for Engineering Professionals

  • Congratulations IDS on being selected by the Eng-Tips community for having the most helpful posts in the forums last week. Way to Go!

Extracting Assembly Feature Data Through API

Status
Not open for further replies.

moleary

Computer
Mar 23, 2005
38
Does anyone know how to extract assembly feature data? For example, say I have a part that is just a cylinder. I then add this part to an assembly. In the assembly, I then put a hole through the cylinder. When I attempt to extract the geometry, I do not get that there is a hole there, but if the hole were placed in the part, I would get it. Does anyone know why this is and what can be done about it?

Thanks for any help you can give!
 
Replies continue below

Recommended for you

Cuts created in assembly level, act like real cuts. If you make a hole in an assembled part, the individual parts dont have that hole when they come from the supplier.

To pass that hole down to the part, select to MAKE NEW NAMES in the assmebly feature dialoge box.

You will now have a generic and instance of the part with and without the cut feature.

There are other ways to do want you need.

Steve

 
Do you mean that ProSolidFeatureVisit function does not recognize the assembly cut as a feature?

-Hora
 
Moleary,

I made your exercice as you: an assembly with 3 planes and a coordinate system, then I added a cube and I made an assembly cut.

There are 6 features in total, including the cube (ProToolkit counts the component as a feature)

I started my program to read all the features in the current assembly and I got the following answer:

Processing feature 1 of 5, with ID 1, type: 923
Processing feature 2 of 5, with ID 3, type: 923
Processing feature 3 of 5, with ID 5, type: 923
Processing feature 4 of 5, with ID 7, type: 979
Processing feature 5 of 5, with ID 54, type: 916

The solid is ignored by a filter function. Indeed my assembly cut is counted, feature 5, ID=54, feature type = 916

the 923 type means datum plane and the 979 means coordinate system. Then 916 must be the cut.

Then, the program will scan all components of the assemby and I recieved the following info:

Processing feature 1 of 6, with ID 1, type: 923
Processing feature 2 of 6, with ID 3, type: 923
Processing feature 3 of 6, with ID 5, type: 923
Processing feature 4 of 6, with ID 7, type: 979
Processing feature 5 of 6, with ID 55, type: 917
Processing feature 6 of 6, with ID 1107296256, type: 947

Indded, my part has 3 datum planes (923), a coordinate system (979) and a protusion (917).

As you can see, the assemby cut (last feature) is counted here too, but has a type = 947. I did't put a filter here to skip the innactive features or assembly cuts.


The 917 type means PRO_FEAT_PROTUSION

Now if you look in the profeattype.h, you'll find the following info:

#define PRO_FEAT_CUT 916

and

#define PRO_FEAT_ASSEM_CUT 947



To obtain these numbers I used the function:

ProFeatureTypeGet(&feature, &featureType);



Probably you have an error in your code. Check it again.

Good luck,
-Hora

 
Hora,

Could I see what you did to find out where I'm going wrong? You can just post the relevant stuff. I don't need a whole program. I've been unable to find what I'm doing wrong.

Thanks for the help!
 
I don't know if I can help you, I had only the dll file here. I wrote this program last year and I do not remember all details.

Basicaly, you must call a routine to collect all features from the model (assy or part). Something like this:

MyFeaturesCollect(model, &feature)

In this routine you must call the API function to
visit the model features (ProSolidFeatVisit).
Attention if you have an assembly. You must call it
for a recursive checking.

Then you must get the number of features found:

ProArraySizeGet(feature, &totalFeatures);

And then you can check the tpe of each feature:

for (i=0; i<totalFeatures; i++)
{
ProFeatureTypeGet(&feature, &featureType);

Of course, you can do it in the same time as you collect the features. Is up to you.

Good luck.
-Hora
 
Basically, my problem right now is that the prodb_surface_tessellation function call is crashing. I know this is quite a bit of code, but if anyone could point out what is going wrong, it would be greatly appreciated. I do get the assembly features but am ignoring them here. I know I'm not checking return error codes from most of these functions, but I've stepped through the code line-by-line and examined what is returned. So that isn't a problem.

void MainFunction()
{
// Show message
ProError error;
error = ProMessageDisplay(UserMsg, "USER %0s", "User click 2");
ProMessageClear();

// Get the current mode
ProMode mode;
error = ProModeCurrentGet(&mode);
if(mode != PRO_MODE_ASSEMBLY)
{
//Write a message using a "Popup dialog"
ProUIMessageButton *buttons;
ProUIMessageButton user_choice;
ProArrayAlloc(1, sizeof (ProUIMessageButton), 1, (ProArray*)&buttons);
buttons [0] = PRO_UI_MESSAGE_OK;
ProUIMessageDialogDisplay( PROUIMESSAGE_INFO, L"Solid",
L"There is no assembly here!",
buttons, PRO_UI_MESSAGE_OK, &user_choice);
ProArrayFree((ProArray*)&buttons);
return;
}

// Get the current assembly
ProMdl asmm;
ProMdlCurrentGet(&asmm);

// Get data of the current assembly and print them
char assemblyname[PRO_NAME_SIZE];
char type[PRO_TYPE_SIZE];
ProMdldata mdldata;
ProMdlDataGet(asmm, &mdldata);
ProWstringToString(assemblyname, mdldata.name);
ProWstringToString(type, mdldata.type);

// Open the file
char filename[PRO_NAME_SIZE];
FILE *fp;
strcpy(filename, FILENAMEASSMBLY);
fp = fopen(filename, "w");

// Print name and type of the assembly
fprintf(fp, "The name of the assembly is: %s(%s)\n\n", assemblyname, type);

// Initialise global user-defined data
UserGitemdata appdata;
appdata.fp = fp;
appdata.mdlcount = 0;
appdata.p_compmdls = NULL;
appdata.srfcount = 0;
appdata.p_surfaces = NULL;
appdata.level = 0;
//
ProGeomitem *psrf;
error = ProArrayAlloc(0, sizeof(ProGeomitem), 1, (ProArray*)&psrf);
appdata.p_surfaces = psrf;
//
ProMdl *pcompmdl;
error = ProArrayAlloc(0, sizeof(ProMdl), 1, (ProArray*)&pcompmdl);
appdata.p_compmdls = pcompmdl;

// List the assembly members
error = ProSolidFeatVisit((ProSolid)asmm, VisitAsmCompAction,
FilterAsmCompAction, &appdata);
}

/*===========================================================================*\
FUNCTION: FilterAsmCompAction()
PURPOSE: A filter used by ProSolidFeatVisit() of func2() to visit features
that are assembly components
\*===========================================================================*/
ProError FilterAsmCompAction(ProFeature *feature, ProAppData app_data)
{
// Get type of the feature(only select assembly component)
ProError status;
ProFeattype ftype;
status = ProFeatureTypeGet(feature, &ftype);
if (ftype != PRO_FEAT_COMPONENT)
return(PRO_TK_CONTINUE);

// Get visibility of the feature
ProBoolean visible;
status = ProFeatureVisibilityGet(feature, &visible);
if(status == PRO_TK_NO_ERROR)
if(visible == PRO_B_FALSE)
return(PRO_TK_CONTINUE);

// If the feature is not active, skip it
ProFeatStatus fstatus;
status = ProFeatureStatusGet(feature, &fstatus);
if(fstatus != PRO_FEAT_ACTIVE)
return(PRO_TK_CONTINUE);

return(PRO_TK_NO_ERROR);
}

/*================================================================*\
FUNCTION: VisitAsmCompAction()
PURPOSE: Write the information to the file.
\*================================================================*/
ProError VisitAsmCompAction(ProFeature *feature, ProError status,
ProAppData appdata)
{
// Initialise use-defined data
ProError error;
FILE *fp;
ProMdl **mdlarrary;
UserGitemdata *appd;
appd = (UserGitemdata *)appdata;
fp = appd->fp;
mdlarrary = &(appd->p_compmdls);

// Get the model and solid of the assembly component
error = ProAsmcompMdlGet(feature, &(appd->mdl));
//
ProMdl mdl;
error = ProAsmcompMdlGet(feature, &mdl);
ProMdlType type;
ProName name;
ProSolid solid;
error = ProMdlTypeGet((ProMdl)mdl, &type);
error = ProMdlNameGet((ProMdl)mdl, name);
error = ProSolidInit(name, (ProType)type, &solid);

// Get names and typies of the assembly component
ProMdldata mdldata;
char mname[PRO_NAME_SIZE];
char mtype[PRO_TYPE_SIZE];
error = ProMdlDataGet(mdl, &mdldata);
ProWstringToString(mname, mdldata.name);
ProWstringToString(mtype, mdldata.type);
//
if(strncmp(mtype, "ASM", 3) == 0)
{
//ProSolidFeatVisit((ProSolid)mdl, user_action, UserAsmCompFilter, &subappd);
}
else if(strncmp(mtype, "PRT", 3) == 0)
{
// Add part component to arrary
fprintf(fp, "This is a part component here!\n");
error = ProArrayObjectAdd((ProArray*)mdlarrary, -1, 1, &mdl);
(appd->mdlcount)++;

// Visit all the surfaces of the model
fprintf(fp, "This is a component of assembly!\n");
error = ProSolidSurfaceVisit((ProSolid)mdl,
(ProSurfaceVisitAction)SrfVisitAction,
(ProSurfaceFilterAction)SrfFilterAction,
appdata);
fprintf(fp, "\n\n");
}

// Return error
if (feature != NULL)
return(PRO_TK_NO_ERROR);

// Return correctly
return(PRO_TK_CONTINUE);
}

/*===========================================================================*\
FUNCTION:
PURPOSE:
\*===========================================================================*/
ProError SrfFilterAction(ProSurface p_surface, ProAppData app_data)
{
return(PRO_TK_NO_ERROR);
}


/*===========================================================================*\
FUNCTION:
PURPOSE:
\*===========================================================================*/
ProError SrfVisitAction(ProSurface p_surface, ProError status,
ProAppData app_data)
{
// Initialise use-defined data
ProError error;
UserGitemdata *appd;
appd = (UserGitemdata*)app_data;
//
FILE *fp;
fp = appd->fp;
//
ProGeomitem **srfarray;
srfarray = &(appd->p_surfaces);

// Convert the surface to geometry
ProGeomitem geomitem;
error = ProSurfaceToGeomitem((ProSolid)(appd->mdl), p_surface, &geomitem);
ProFeature feature;
error = ProGeomitemFeatureGet(&geomitem, &feature);
ProSolid owner;
error = ProFeatureSolidGet(&feature, &owner);

// Add surface to array
fprintf(fp, "This is a surface here!\n");
error = ProArrayObjectAdd((ProArray*)srfarray, -1, 1, &geomitem);
(appd->srfcount)++;

// Get the tessellation of the surface
int n_verts, n_facets, (*findices)[3];
double (*fverts)[3], (*fnorms)[3];

int srf_id = 0;
error = ProSurfaceIdGet(p_surface, &srf_id);
ProName mdlName;
ProMdlNameGet(owner,mdlName);
int rev = prodb_surface_tessellation((Prohandle)(owner), srf_id, 0.5, 0.5,
NULL, &n_verts, &fverts, &fnorms, NULL,
&n_facets, &findices);

// Return correctly
fprintf(fp, "\n\n");
return(PRO_TK_NO_ERROR);
}
 
Are you sure that your prodb_surface_tesselation declarationis correct?

int rev = prodb_surface_tessellation((Prohandle)(owner), srf_id, 0.5, 0.5,
NULL, &n_verts, &fverts, &fnorms, NULL,
&n_facets, &findices);

Try to use NULL for the first parameter.

-Hora.
 
Using NULL would mean that I was talking about a surface of the current model, but that is the assembly. So that wouldn't work. I tried it for the hell of it, but it crashed anyway.
 
The surfaces are part of the components and not to the assembly! Even in ProE if you create an assembly cut and you want to select the assembly surfaces created by this cut and to change their color, you cannot pick them.

Try to apply the same function to each component rather to your assembly. I think this is why your routine crash.

Good luck.
-Hora
 
The problem turned out to be the second NULL in the call to prodb_surface_tessellation. API should have checked for that, first of all. Secondly, given the other parameters passed, it should have had no need to access it. I pulled my hair out for quite some time on this one.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor