/* Copyright (c) 2024 PTC Inc. and/or Its Subsidiary Companies. All Rights Reserved. */ /*---------------------- Pro/Toolkit Includes ------------------------*/ #include <ProToolkit.h> #include <ProMdl.h> #include <ProUtil.h> #include <ProFit.h> #include "PTApplsUnicodeUtils.h" /*---------------------- Function Prototypes -------------------------*/ ProError user_surf_clear (); ProError user_dist_manifolds (); ProError user_part_interference (); ProError user_global_interference (); int user_dump_interferences (); int user_dump_mdl(); /*------------------------- External Data ----------------------------*/ extern char *UserUtilGenFilename(ProMdl p_obj, char *filext, char *filename); /*================================================================*\ FUNCTION : user_surf_clear PURPOSE : Computes the clearance between two surfaces. \*================================================================*/ ProError user_surf_clear () { ProError status; ProBoolean interf; double distance; Pro3dPnt coord[2]; ProSelection *sel; int n_sel; ProFileName msg_fil; ProStringToWstring( msg_fil, "msg_uggeom.txt" ); while (1) { status = ProMessageDisplay (msg_fil, "USER Select a face"); ERROR_CHECK("user_surf_clear","ProMessageDisplay",status); status = ProSelect("face", 2, NULL, NULL, NULL, NULL, &sel, &n_sel); if (n_sel <= 1) return (PRO_TK_GENERAL_ERROR); /*----------------------------------------------------------------*\ Computes the clearance between the two selected surfaces. \*----------------------------------------------------------------*/ status = ProFitClearanceCompute(sel[0], PRO_FIT_INCLUDE_NONE, sel[1], PRO_FIT_INCLUDE_NONE, PRO_FIT_WHOLE_SURFACE, NULL, PRO_B_FALSE, &distance, NULL, &interf, coord); ERROR_CHECK("user_surf_clear","ProFitClearanceCompute", status); status = ProMessageDisplay (msg_fil, "USER Distance is %0(5.3)f", &distance); ERROR_CHECK("user_surf_clear","ProMessageDisplay",status); if (interf) { status = ProMessageDisplay (msg_fil, "USER Interference exists"); ERROR_CHECK("user_surf_clear","ProMessageDisplay",status); } } return (PRO_TK_NO_ERROR); } /*================================================================*\ FUNCTION : user_dist_manifolds PURPOSE : Computes the critical distance between two objects. \*================================================================*/ ProError user_dist_manifolds () { ProError status; ProSelection *sel; int n_sel; double distance; Pro2dPnt uv1, uv2; Pro3dPnt xyz1, xyz2; ProFileName msg_fil; ProStringToWstring( msg_fil, "msg_uggeom.txt" ); status = ProMessageDisplay (msg_fil, "USER %0s", "Select two entities"); ERROR_CHECK("user_dist_manifolds","ProMessageDisplay",status); status = ProSelect("point,edge,curve,surface", 2, NULL, NULL, NULL, NULL, &sel, &n_sel); if (n_sel < 2) return (PRO_TK_GENERAL_ERROR); /*----------------------------------------------------------------*\ Compute the distance between the two manifolds. \*----------------------------------------------------------------*/ status = ProSelectionWithOptionsDistanceEval(sel[0], PRO_B_TRUE, sel[1], PRO_B_TRUE, uv1, uv2, xyz1, xyz2, &distance); ERROR_CHECK("user_dist_manifolds","ProSelectionWithOptionsDistanceEval",status); if (status) { status = ProMessageDisplay (msg_fil, "USER Distance is %0(5.3)f", &distance); ERROR_CHECK("user_dist_manifolds","ProMessageDisplay",status); } else { status = ProMessageDisplay (msg_fil, "USER %0s", "No min/max distances found"); ERROR_CHECK("user_dist_manifolds","ProMessageDisplay",status); } return (PRO_TK_NO_ERROR); } /*================================================================*\ FUNCTION : user_part_interference PURPOSE : Computes the interference between two parts. \*================================================================*/ ProError user_part_interference () { ProError status; ProSelection *sel; int n_sel; wchar_t w_str[5]; char str[100], a_str[5]; double volume; FILE *fp; char fname[PRO_NAME_SIZE+4]; wchar_t w_fname[PRO_NAME_SIZE+4]; ProMdl p_model; ProFileName msg_fil; ProInterferenceData interf_data; status = ProMdlCurrentGet(&p_model); ERROR_CHECK("user_part_interference","pro_get_current_object", (p_model == NULL)); if (p_model == NULL) return (PRO_TK_E_NOT_FOUND); ProStringToWstring( msg_fil, "msg_uggeom.txt" ); status = ProMessageDisplay (msg_fil, "USER %0s", "Select two parts"); ERROR_CHECK("user_part_interference","ProMessageDisplay",status); status = ProSelect("part", 2, NULL, NULL, NULL, NULL, &sel, &n_sel); /*----------------------------------------------------------------*\ Compute the interference between the two parts. \*----------------------------------------------------------------*/ status = ProFitInterferenceCompute(sel[0], sel[1], PRO_B_FALSE, PRO_B_FALSE, &interf_data); ERROR_CHECK("user_part_interference","ProFitInterferenceCompute",status); if (status != PRO_TK_NO_ERROR) return (PRO_TK_GENERAL_ERROR); if (NULL == interf_data) { status = ProMessageDisplay (msg_fil, "USER %0s", "No interference was detected."); ERROR_CHECK("user_part_interference","ProMessageDisplay",status); return (PRO_TK_NO_ERROR); } ProTKSprintf (str, "Interference found. Display? [Y]:"); status = ProMessageDisplay (msg_fil,"USER %0s", str); ERROR_CHECK("user_part_interference","ProMessageDisplay",status); if (!ProMessageStringRead (4, w_str)) { ProWstringToString (a_str, w_str); if (a_str[0] != 'y' || a_str[0] != 'Y') return (PRO_TK_NO_ERROR); } UserUtilGenFilename (p_model, ".intf", fname); if ((fp = PTApplsUnicodeFopen (fname, "w")) == NULL) return (PRO_TK_GENERAL_ERROR); ProTKFprintf (fp, "Interference in "); user_dump_mdl (fp, p_model); ProTKFprintf (fp, "\n\n"); /*----------------------------------------------------------------*\ Compute the interference volume. \*----------------------------------------------------------------*/ status = ProFitInterferencevolumeCompute(interf_data, &volume); ERROR_CHECK("user_part_interference","pro_compute_volume",status); user_dump_interferences (fp, sel, volume); /*----------------------------------------------------------------*\ Highlight the interference regions. \*----------------------------------------------------------------*/ status = ProFitInterferencevolumeDisplay(interf_data, PRO_COLOR_EDGE_HIGHLIGHT); ERROR_CHECK("user_part_interference","pro_display_interf_volume",status); ProTKSprintf (str, "Total Interference Volume = %lf", volume); status = ProMessageDisplay (msg_fil, "USER %0s", str); ERROR_CHECK("user_part_interference","ProMessageDisplay",status); /*----------------------------------------------------------------*\ Release the memory for the interference volume. \*----------------------------------------------------------------*/ fclose (fp); ProStringToWstring (w_fname, fname); status = ProInfoWindowDisplay (w_fname, NULL, NULL); ERROR_CHECK("user_part_interference","ProInfoWindowDisplay",status); status = ProInterferenceDataFree(interf_data); ERROR_CHECK("user_part_interference","ProInterferenceDataFree",status); return (PRO_TK_NO_ERROR); } /*================================================================*\ FUNCTION : user_global_interference PURPOSE : Computes the global interference within an assembly. \*================================================================*/ ProError user_global_interference () { ProError status; ProSelection *sel; int n_intf_parts, *n_part_surfs, i; wchar_t w_str[5]; char str[100], a_str[5]; double volume; FILE *fp; char fname[PRO_NAME_SIZE+4]; wchar_t w_fname[PRO_NAME_SIZE+4]; ProFileName msg_fil; ProMdl p_model; ProInterferenceInfo *interf_info_arr; ProStringToWstring( msg_fil, "msg_uggeom.txt" ); status = ProMdlCurrentGet(&p_model); ERROR_CHECK("user_global_interference","pro_get_current_object", (p_model == NULL)); if (p_model == NULL) return (PRO_TK_E_NOT_FOUND); /*----------------------------------------------------------------*\ Compute the interference within the assembly. \*----------------------------------------------------------------*/ status = ProFitGlobalinterferenceCompute((ProAssembly)p_model, PRO_FIT_SUB_ASSEMBLY, PRO_B_FALSE, PRO_B_FALSE, PRO_B_FALSE, &interf_info_arr); ERROR_CHECK("user_global_interference","ProFitGlobalinterferenceCompute",status); if (status != PRO_TK_NO_ERROR) return (PRO_TK_GENERAL_ERROR); status = ProArraySizeGet(interf_info_arr, &n_intf_parts); if (n_intf_parts == 0) { status = ProMessageDisplay (msg_fil, "USER %0s", "No interference was detected."); ERROR_CHECK("user_global_interference","ProMessageDisplay",status); } ProTKSprintf (str, "%d interfering part pairs found. Display interference pair volumes? [Y]:", n_intf_parts); ProMessageDisplay (msg_fil, "USER %0s", str); if (!ProMessageStringRead (4, w_str)) { ProWstringToString (a_str, w_str); if (a_str[0] != 'y' || a_str[0] != 'Y') return (PRO_TK_NO_ERROR); } UserUtilGenFilename (p_model, ".intf", fname); if ((fp = PTApplsUnicodeFopen (fname, "w")) == NULL) return (PRO_TK_GENERAL_ERROR); ProTKFprintf (fp, "Interference in "); user_dump_mdl (fp, p_model); ProTKFprintf (fp, "\n\n"); for (i = 0; i < n_intf_parts; i++) { /*----------------------------------------------------------------*\ Compute the interference volumes. \*----------------------------------------------------------------*/ status = ProFitInterferencevolumeCompute(interf_info_arr[i].interf_data, &volume); ERROR_CHECK("user_global_interference","ProFitInterferencevolumeCompute",status); user_dump_interferences (fp, interf_info_arr[i].part_1, interf_info_arr[i].part_2, volume); /*----------------------------------------------------------------*\ Highlight the interference regions. \*----------------------------------------------------------------*/ status = ProFitInterferencevolumeDisplay(interf_info_arr[i].interf_data, PRO_COLOR_EDGE_HIGHLIGHT); ERROR_CHECK("user_global_interference","ProFitInterferencevolumeDisplay",status); ProTKSprintf (str, "Interference pair %d of %d: Volume = %0.2lf: Continue? [y]:", i+1, n_intf_parts, volume); status = ProMessageDisplay (msg_fil, "USER %0s", str); ERROR_CHECK("user_global_interference","ProMessageDisplay",status); if (!ProMessageStringRead (4, w_str)) { ProWstringToString (a_str, w_str); if (a_str[0] != 'y' || a_str[0] != 'Y') { fclose (fp); return (PRO_TK_NO_ERROR); } } /*----------------------------------------------------------------*\ Release the memory for the interference volume. \*----------------------------------------------------------------*/ } fclose (fp); ProStringToWstring (w_fname, fname); status = ProInfoWindowDisplay (w_fname, NULL, NULL); ERROR_CHECK("user_global_interference","ProInfoWindowDisplay",status); status = ProInterferenceInfoProarrayFree(interf_info_arr); return (PRO_TK_NO_ERROR); } /*================================================================*\ FUNCTION : user_dump_interferences PURPOSE : Writes the interference information into a file. \*================================================================*/ int user_dump_interferences (fp, part_1, part_2, volume) FILE *fp; ProSelection part_1, part_2; double volume; { int m; ProMdl mdl; ProModelitem modelitem; ProAsmcomppath cmp_path; ProError status; ProTKFprintf (fp, "Interfering Parts:\n"); ProTKFprintf (fp, "\t "); status = ProSelectionModelitemGet(part_1, &modelitem); user_dump_mdl (fp, modelitem.owner); status = ProSelectionAsmcomppathGet(part_1, &cmp_path); ProTKFprintf (fp, "\tmemb_id_tab["); for (m = 0; m < cmp_path.table_num; m++) { ProTKFprintf (fp, "%d", cmp_path.comp_id_table[m]); if (m < cmp_path.table_num-1) ProTKFprintf (fp, ","); } ProTKFprintf (fp, "]\n"); ProTKFprintf (fp, "\t "); status = ProSelectionModelitemGet(part_2, &modelitem); user_dump_mdl (fp, modelitem.owner); status = ProSelectionAsmcomppathGet(part_2, &cmp_path); ProTKFprintf (fp, "\tmemb_id_tab["); for (m = 0; m < cmp_path.table_num; m++) { ProTKFprintf (fp, "%d", cmp_path.comp_id_table[m]); if (m < cmp_path.table_num-1) ProTKFprintf (fp, ","); } ProTKFprintf (fp, "]\n"); ProTKFprintf (fp, "\tInterfering Volume: %0.2lf\n\n", volume); return(0); } int user_dump_mdl (fp, p_model) FILE *fp; ProMdl p_model; { char name[PRO_MDLNAME_SIZE], type[PRO_MDLEXTENSION_SIZE]; ProMdlName modelName; ProMdlExtension modelExtension; if (p_model == NULL) return (0); ProMdlMdlnameGet(p_model, modelName); ProMdlExtensionGet(p_model, modelExtension); ProTKFprintf (fp, "%s.%s:", ProWstringToString (name, modelName), ProWstringToString (type, modelExtension)); return (0); }