/* Copyright (c) 2024 PTC Inc. and/or Its Subsidiary Companies. All Rights Reserved. */ /*--------------------------------------------------------------------*\ Pro/TOOLKIT includes \*--------------------------------------------------------------------*/ #include "ProToolkit.h" #include "ProObjects.h" #include "ProAxis.h" #include "ProCsys.h" #include "ProGraphic.h" #include "ProDisplist.h" #include "ProGeomitem.h" #include "ProMenu.h" #include "ProMessage.h" #include "ProPoint.h" #include "ProSelection.h" #include "ProSolid.h" #include "ProUtil.h" #include "ProWindows.h" #include "ProEdge.h" /*--------------------------------------------------------------------*\ System includes \*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*\ Application includes \*--------------------------------------------------------------------*/ #include "TestError.h" /*--------------------------------------------------------------------*\ Application macros \*--------------------------------------------------------------------*/ #define DSPL1_ID 115 #define DSPL2_ID (DSPL1_ID+1) #ifdef MSGFIL #undef MSGFIL #endif #define MSGFIL msgfil #define COPY3D(a, b) memcpy(a, b, 3*sizeof(double)) /*--------------------------------------------------------------------*\ Application data types \*--------------------------------------------------------------------*/ typedef struct tag_hit_list { Pro3dPnt origin; int n_hits; Pro3dPnt *p_pnt; ProBoolean *to_front; } Hit_list; /*--------------------------------------------------------------------*\ Application global/external data \*--------------------------------------------------------------------*/ static ProFileName msgfil; /*--------------------------------------------------------------------*\ Function prototypes \*--------------------------------------------------------------------*/ int ProTestSolidRay(ProAppData data, int value); int ProUtilDeleteRay(ProAppData data, int value); static int CreateRays(ProModelitem *, ProRay *); static int CreateRaysFromPoint(ProModelitem *, ProRay *); static int CreateRaysFromEdgeEnd(ProModelitem *, ProRay *); static int CreateRaysFromCsys(ProModelitem *, ProRay *); static int CreateRaysFromAxis(ProModelitem *, ProRay *); static int TransfRays(ProSelection, ProRay *, int); static int CreateHitList(ProSolid, ProRay*, Hit_list *); static int CreateDispList(Hit_list *, int *, int *); /*=============================================================*\ Function: ProTestRay Purpose: To initiate the user's options \*=============================================================*/ int ProTestRay (void *data, int dummy) { /* Declare external functions */ int m_id, action; ProError status; ProStringToWstring (msgfil,(char*) "gen_msg.txt"); status = ProMenuFileRegister((char*)"TkRay",(char*) "tkray.mnu", &m_id); TEST_CALL_REPORT("ProMenuFileRegister()", "ProTestRay()", status, status !=PRO_TK_NO_ERROR); if (status != PRO_TK_NO_ERROR) return (-1); status = ProMenubuttonActionSet((char*)"TkRay",(char*) "-Ray Inter Demo", (ProMenubuttonAction)ProTestSolidRay, NULL, 0); TEST_CALL_REPORT("ProMenubuttonActionSet()", "ProTestRay()", status, status !=PRO_TK_NO_ERROR); if (status != PRO_TK_NO_ERROR) return (-1); status = ProMenubuttonActionSet((char*)"TkRay",(char*) "-Ray Del", (ProMenubuttonAction)ProUtilDeleteRay, NULL, 0); TEST_CALL_REPORT("ProMenubuttonActionSet()", "ProTestRay()", status, status !=PRO_TK_NO_ERROR); if (status != PRO_TK_NO_ERROR) return (-1); status = ProMenubuttonActionSet((char*)"TkRay",(char*) "-Done", (ProMenubuttonAction)ProMenuDelete, NULL, 0); TEST_CALL_REPORT("ProMenubuttonActionSet()", "ProTestRay()", status, status !=PRO_TK_NO_ERROR); if (status != PRO_TK_NO_ERROR) return (-1); status = ProMenubuttonActionSet((char*)"TkRay",(char*) "TkRay", (ProMenubuttonAction)ProMenuDelete, NULL, 0); TEST_CALL_REPORT("ProMenubuttonActionSet()", "ProTestRay()", status, status !=PRO_TK_NO_ERROR); if (status != PRO_TK_NO_ERROR) return (-1); status = ProMenuCreate(PROMENUTYPE_MAIN,(char*) "TkRay", NULL); status = ProMenuProcess((char*)"TkRay", &action); return(0); } /*=============================================================*\ Function: ProTestSolidRay Purpose: main test ProSolidRayIntersectionCompute() function \*=============================================================*/ int ProTestSolidRay(ProAppData data, int value) { ProSelection *p_sel; ProModelitem modelitem; ProRay rays[3]; ProSolid model; int n_ray, n_sel, i, mode; ProError status; Hit_list h_list[3]; ProAsmcomppath comp_path; ProMessageDisplay(MSGFIL, (char*)"TEST %0s", "Select Csys, Axis or Datum Point"); status = ProSelect((char*)"point,axis,csys,edge_end", 1, NULL, NULL, NULL, NULL, &p_sel, &n_sel); if (status != PRO_TK_NO_ERROR) return (0); status = ProSelectionModelitemGet(p_sel[0], &modelitem); TEST_CALL_REPORT("ProSelectionModelitemGet()", "ProTestSolidRay()", status, status != PRO_TK_NO_ERROR); status = ProSelectionModelitemGet(p_sel[0], &modelitem); TEST_CALL_REPORT("ProSelectionModelitemGet()", "ProTestSolidRay()", status, status != PRO_TK_NO_ERROR); status = ProSelectionAsmcomppathGet(p_sel[0], &comp_path); TEST_CALL_REPORT("ProSelectionAsmcomppathGet()", "ProTestSolidRay()", status, status != PRO_TK_NO_ERROR); model=(comp_path.owner)!=NULL?comp_path.owner:(ProSolid)modelitem.owner; n_ray = CreateRays(&modelitem, rays); if (n_ray == -1) return (-1); TransfRays(p_sel[0], rays, n_ray); for (i=0; i<n_ray; i++) { CreateHitList(model, rays+i, h_list+i); } ProUtilDeleteRay(NULL, 0); mode=0; status = ProDisplist3dCreate( DSPL1_ID, (ProDisplistCallback)CreateDispList, (void *)h_list, (void *)&n_ray, (void *)&mode, NULL, NULL, NULL ); TEST_CALL_REPORT("ProDisplist3dCreate()", "ProTestSolidRay()", status, status != PRO_TK_NO_ERROR); mode=1; status = ProDisplist3dCreate( DSPL2_ID, (ProDisplistCallback)CreateDispList, (void *)h_list, (void *)&n_ray, (void *)&mode, NULL, NULL, NULL); TEST_CALL_REPORT("ProDisplist3dCreate()", "ProTestSolidRay()", status, status != PRO_TK_NO_ERROR); for (i=0; i<n_ray; i++) { free(h_list[i].p_pnt); free(h_list[i].to_front); } status = ProWindowRepaint(PRO_VALUE_UNUSED); TEST_CALL_REPORT("ProWindowRepaint()", "ProTestSolidRay()", status, status != PRO_TK_NO_ERROR); return (0); } /*=============================================================*\ Function: ProUtilDeleteRay Purpose: to delete application's display list \*=============================================================*/ int ProUtilDeleteRay(ProAppData data, int value) { ProError status; status = ProDisplist3dDelete( DSPL1_ID ); TEST_CALL_REPORT("ProDisplist3dDelete()", "ProUtilDeleteRay()", status, status != PRO_TK_NO_ERROR && status != PRO_TK_E_NOT_FOUND); status = ProDisplist3dDelete( DSPL2_ID ); TEST_CALL_REPORT("ProDisplist3dDelete()", "ProUtilDeleteRay()", status, status != PRO_TK_NO_ERROR && status != PRO_TK_E_NOT_FOUND); status = ProWindowRepaint(PRO_VALUE_UNUSED); TEST_CALL_REPORT("ProWindowRepaint()", "ProUtilDeleteRay()", status, status != PRO_TK_NO_ERROR && status != PRO_TK_E_NOT_FOUND); return (0); } /*=============================================================*\ Function: CreateRays Purpose: to fill ProRays structure Return : # of rays, -1 if unsuccessfull \*=============================================================*/ static int CreateRays( ProModelitem *mod_item, /* In : user's selection */ ProRay *rays) /* Out: the filled ray structure */ { int ret; switch (mod_item->type) { case PRO_EDGE_END: case PRO_EDGE_START: ret = CreateRaysFromEdgeEnd (mod_item, rays) == 0 ? 3 : -1; break; case PRO_POINT: ret = CreateRaysFromPoint(mod_item, rays) == 0 ? 3 : -1; break; case PRO_CSYS: ret = CreateRaysFromCsys(mod_item, rays) == 0 ? 3 : -1; break; case PRO_AXIS: ret = CreateRaysFromAxis(mod_item, rays) == 0 ? 1 : -1; break; default : ret =-1; } return (ret); } /*=============================================================*\ Function: CreateRaysFromEdgeEnd Purpose: to fill ProRays structure Return : 0 if successfull, -1 if unsuccessfull \*=============================================================*/ static int CreateRaysFromEdgeEnd( ProModelitem *mod_item, /* In : user's selection */ ProRay *rays) /* Out: the filled ray structure */ { ProEdge edge; ProError status; double edge_param; ProVector xyz, der1, der2, dir; rays[0].dir_vector[0] = rays[1].dir_vector[1] = 1.0; rays[2].dir_vector[2] = 1.0; rays[0].dir_vector[1] = rays[0].dir_vector[2] = 0.0; rays[1].dir_vector[0] = rays[1].dir_vector[2] = 0.0; rays[2].dir_vector[0] = rays[2].dir_vector[1] = 0.0; status = ProEdgeInit((ProSolid)mod_item->owner, mod_item->id, &edge); TEST_CALL_REPORT("ProEdgeInit()", "CreateRaysFromEdgeEnd()", status, status != PRO_TK_NO_ERROR); if (status!=PRO_TK_NO_ERROR) return (-1); edge_param = 1.0 * (mod_item->type == PRO_EDGE_END); ProEdgeXyzdataEval (edge, edge_param, xyz, der1, der2, dir); COPY3D (rays[0].start_point, xyz); COPY3D(rays[1].start_point, rays[0].start_point); COPY3D(rays[2].start_point, rays[0].start_point); return (0); } /*=============================================================*\ Function: CreateRaysFromPoint Purpose: to fill ProRays structure Return : 0 if successfull, -1 if unsuccessfull \*=============================================================*/ static int CreateRaysFromPoint( ProModelitem *mod_item, /* In : user's selection */ ProRay *rays) /* Out: the filled ray structure */ { ProPoint pnt; ProError status; rays[0].dir_vector[0] = rays[1].dir_vector[1] = 1.0; rays[2].dir_vector[2] = 1.0; rays[0].dir_vector[1] = rays[0].dir_vector[2] = 0.0; rays[1].dir_vector[0] = rays[1].dir_vector[2] = 0.0; rays[2].dir_vector[0] = rays[2].dir_vector[1] = 0.0; status = ProPointInit((ProSolid)mod_item->owner, mod_item->id, &pnt); TEST_CALL_REPORT("ProPointInit()", "CreateRaysFromPoint()", status, status != PRO_TK_NO_ERROR); if (status!=PRO_TK_NO_ERROR) return (-1); status = ProPointCoordGet(pnt, rays[0].start_point); TEST_CALL_REPORT("ProPointCoordGet()", "CreateRaysFromPoint()", status, status != PRO_TK_NO_ERROR); if (status!=PRO_TK_NO_ERROR) return (-1); COPY3D(rays[1].start_point, rays[0].start_point); COPY3D(rays[2].start_point, rays[0].start_point); return (0); } /*=============================================================*\ Function: CreateRaysFromCsys Purpose: to fill ProRays structure Return : 0 if successfull, -1 if unsuccessfull \*=============================================================*/ static int CreateRaysFromCsys( ProModelitem *mod_item, /* In : user's selection */ ProRay *rays) /* Out: the filled ray structure */ { ProError status; ProCsys csys; ProGeomitemdata *geomdata; status = ProCsysInit((ProSolid)mod_item->owner, mod_item->id, &csys); TEST_CALL_REPORT("ProCsysInit()", "CreateRaysFromCsys()", status, status != PRO_TK_NO_ERROR); if (status!=PRO_TK_NO_ERROR) return (-1); status = ProCsysDataGet(csys, &geomdata); TEST_CALL_REPORT("ProCsysDataGet()", "CreateRaysFromCsys()", status, status != PRO_TK_NO_ERROR); if (status!=PRO_TK_NO_ERROR) return (-1); COPY3D(rays[0].start_point, geomdata->data.p_csys_data->origin); COPY3D(rays[1].start_point, rays[0].start_point); COPY3D(rays[2].start_point, rays[0].start_point); COPY3D(rays[0].dir_vector, geomdata->data.p_csys_data->x_vector); COPY3D(rays[1].dir_vector, geomdata->data.p_csys_data->y_vector); COPY3D(rays[2].dir_vector, geomdata->data.p_csys_data->z_vector); status = ProGeomitemdataFree(&geomdata); TEST_CALL_REPORT("ProGeomitemdataFree()", "CreateRaysFromCsys()", status, status != PRO_TK_NO_ERROR); return (0); } /*=============================================================*\ Function: CreateRaysFromAsys Purpose: to fill ProRays structure Return : 0 if successfull, -1 if unsuccessfull \*=============================================================*/ static int CreateRaysFromAxis( ProModelitem *mod_item, /* In : user's selection */ ProRay *rays) /* Out: the filled ray structure */ { ProError status; ProAxis axis; ProGeomitemdata *geomdata; status = ProAxisInit((ProSolid)mod_item->owner, mod_item->id, &axis); TEST_CALL_REPORT("ProAxisInit()", "CreateRaysFromAxis()", status, status != PRO_TK_NO_ERROR); if (status!=PRO_TK_NO_ERROR) return (-1); status = ProAxisDataGet(axis, &geomdata); TEST_CALL_REPORT("ProAxisDataGet()", "CreateRaysFromAxis()", status, status != PRO_TK_NO_ERROR); if (status!=PRO_TK_NO_ERROR) return (-1); COPY3D(rays[0].start_point, geomdata->data.p_curve_data->line.end1); COPY3D(rays[0].dir_vector, geomdata->data.p_curve_data->line.end2); rays[0].dir_vector[0] -= rays[0].start_point[0]; rays[0].dir_vector[1] -= rays[0].start_point[1]; rays[0].dir_vector[2] -= rays[0].start_point[2]; return (0); } /*=============================================================*\ Function: TransfRays Purpose: to transform ray's origin and direction to top level assembly csys \*=============================================================*/ static int TransfRays( ProSelection sel, /* In : the user's selection structure */ ProRay *rays, /* In, Out : the array of ProRay structures */ int n_ray) /* In : # of rays*/ { ProMatrix trf; ProError status; ProAsmcomppath comp_path; ProVector pnt; int i; status = ProSelectionAsmcomppathGet(sel, &comp_path); TEST_CALL_REPORT("ProSelectionAsmcomppathGet()", "TransfRays()", status, status != PRO_TK_NO_ERROR); if (comp_path.owner==NULL) return (0); status = ProAsmcomppathTrfGet(&comp_path, PRO_B_TRUE, trf); TEST_CALL_REPORT("ProAsmcomppathTrfGet()", "TransfRays()", status, status != PRO_TK_NO_ERROR); for (i=0; i<n_ray; i++) { status = ProPntTrfEval(rays[i].start_point, trf, pnt); TEST_CALL_REPORT("ProPntTrfEval()", "TransfRays()", status, status != PRO_TK_NO_ERROR); COPY3D(rays[i].start_point, pnt); status = ProVectorTrfEval(rays[i].dir_vector, trf, rays[i].dir_vector); TEST_CALL_REPORT("ProVectorTrfEval()", "TransfRays()", status, status != PRO_TK_NO_ERROR); } return (0); } /*=============================================================*\ Function: CreateHitList Purpose: generate hit list for one ray \*=============================================================*/ static int CreateHitList( ProSolid model, /* In : The model */ ProRay* ray, /* In : ray */ Hit_list *h_list) /* In : The hit list, user's memory */ { ProError status; int n_hits, i; ProSelection *p_sel; ProAsmcomppath comp_path; double depth; ProPoint3d pnt; ProMode mode; ProMatrix trf = { {1.0, 0.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, 0.0, 1.0} }; h_list->p_pnt = NULL; h_list->to_front = NULL; h_list->n_hits =0; status = ProSolidRayIntersectionCompute(model, -1, ray, &p_sel, &n_hits); TEST_CALL_REPORT("ProSolidRayIntersectionCompute()", "CreateHitList()", status, status != PRO_TK_NO_ERROR && status != PRO_TK_E_NOT_FOUND); if (status != PRO_TK_NO_ERROR) return (-1); COPY3D(h_list->origin, ray->start_point); h_list->n_hits = n_hits; h_list->p_pnt = (Pro3dPnt *)calloc(n_hits, sizeof(Pro3dPnt)); h_list->to_front = (ProBoolean *)calloc(n_hits, sizeof(ProBoolean)); for (i=0; i<n_hits; i++) { status = ProSelectionDepthGet(p_sel[i], &depth); TEST_CALL_REPORT("ProSelectionDepthGet()", "CreateHitList()", status, status != PRO_TK_NO_ERROR); h_list->to_front[i] = (ProBoolean)(depth>=0); status = ProSelectionAsmcomppathGet(p_sel[i], &comp_path); TEST_CALL_REPORT("ProSelectionAsmcomppathGet()", "CreateHitList()", status, status != PRO_TK_NO_ERROR); status = ProModeCurrentGet(&mode); TEST_CALL_REPORT("ProModeCurrentGet()", "CreateHitList()", status, status != PRO_TK_NO_ERROR); if(mode == PRO_MODE_ASSEMBLY) { status = ProAsmcomppathTrfGet(&comp_path, PRO_B_TRUE, trf); TEST_CALL_REPORT("ProAsmcomppathTrfGet()", "CreateHitList()", status, status != PRO_TK_NO_ERROR); } status = ProSelectionPoint3dGet(p_sel[i], pnt); TEST_CALL_REPORT("ProSelectionPoint3dGet()", "CreateHitList()", status, status != PRO_TK_NO_ERROR); status = ProPntTrfEval(pnt, trf, h_list->p_pnt[i]); TEST_CALL_REPORT("ProPntTrfEval()", "CreateHitList()", status, status != PRO_TK_NO_ERROR); } return (0); } /*=============================================================*\ Function: CreateDispList Purpose: generate display list \*=============================================================*/ static int CreateDispList( Hit_list *p_list, /*In : the hit list array */ int *n_list, /*In : n_list[0] contains number of lists in p_list */ int *mode) /*In : mode[0]==0 behind origin mode[0]==1 front origin */ { int i, l; ProError status; ProColor keep_color, letter_color, highlite_color; double radius; ProMdl model; Pro3dPnt points[2]; TEST_CALL_REPORT("ProDisplistCallback()", "CreateDispList()", (ProError)0, 0); status = ProMdlCurrentGet (&model); TEST_CALL_REPORT("ProMdlCurrentGet()", "CreateDispList()", status, status != PRO_TK_NO_ERROR); status = ProSolidOutlineGet ((ProSolid)model, points); TEST_CALL_REPORT("ProSolidOutlineGet()", "CreateDispList()", status, status != PRO_TK_NO_ERROR); radius = 0.3*(points[1][0] - points[0][0])/100.0; highlite_color.method = PRO_COLOR_METHOD_TYPE; highlite_color.value.type = PRO_COLOR_HIGHLITE; letter_color.method = PRO_COLOR_METHOD_TYPE; letter_color.value.type = PRO_COLOR_LETTER; status = ProGraphicsColorModify(mode[0] ? &letter_color : &highlite_color, &keep_color); TEST_CALL_REPORT("ProGraphicsColorModify()", "CreateDispList()", status, status != PRO_TK_NO_ERROR); for (l=0; l<n_list[0]; l++) { for (i=0; i<p_list[l].n_hits; i++) { if (mode[0] ^ (p_list[l].to_front[i]==PRO_B_TRUE)) continue; ProGraphicsPenPosition(p_list[l].origin); ProGraphicsLineDraw(p_list[l].p_pnt[i]); ProGraphicsCircleDraw(p_list[l].p_pnt[i], radius); } } status = ProGraphicsColorModify(&keep_color, NULL); TEST_CALL_REPORT("ProGraphicsColorModify()", "CreateDispList()", status, status != PRO_TK_NO_ERROR); return (0); }