/*====================================================================*\ FILE : UtilGeom. PURPOSE : Pro/TOOLKIT Utilities for geometry HISTORY.. DATE BUILD AUTHOR MODIFICATIONS 14 Feb 96 G-03-02 Alistair $$1 Created 15 Apr 96 G-03-10 Alistair $$2 Add new functions 01 May 96 G-03-12 Alistair $$3 Bug fix 20 May 96 G-03-13 Alistair $$4 Use scientific notation for mesh dump Add complete assembly travsersal 22 May 96 G-03-15 Amin $$5 renamed ProGeomitemSelect --> ProModelitemSelect 04 Jun 96 G-03-16 Amin $$6 renamed ProCurveLengthGet --> ProCurveLengthEval 26-Aug-96 H-01-05 Xuekai $$7 Modify due to change to ProMdl 12-Sep-96 H-01-09 Xuekai $$8 Modify due to Pro[Point,Axis] => Opaque 24-Sep-96 H-01-10 Xuekai $$9 Pro[Surface, Curve]=>Opaque 01-Oct-96 H-01-11 Xuekai $$10 ProSelection=>Opaque 04-Oct-96 H-01-11+ Xuekai $$11 Further ProSelect changes 26-Oct-96 H-01-15 amin $$12 ProCompPath -> ProAsmcomppath 26-Nov-96 H-01-18 amin $$13 ProType -> ProMdlType 09-Dec-96 H-01-20 amin $$14 renamed dataGet -> dataGet 12-Dec-96 H-01-21 mgs $$15 Split out some asm visit functions 20-Jan-97 H-01-21 Pavel $$22 Added calls some function 20-Feb-97 H-03-02 amin $$23 Removed ifdefs 28-Mar-97 H-01-30 Pavel $$24 Added support for PT/Products Toolkit Used UtilCollect.h 25-Jun-97 H-03-15 Pavel $$25 Changed func ProTestGeometryAtPoint 15-Sep-97 H-03-22 Pavel $$26 Replace Pro/D on Pro/T 06-Oct-97 H-03-25 Pavel $$27 Type cast 18-Nov-97 H-03-35 Akula $$28 Fixed bug in ProUtilPointMindist() 26-Nov-98 I-01-27 Pavel $$29 Fixed TEST_CALL_REPORT 10-Dec-98 I-01-28 agsh $$30 Fixed calls ProSelectionHighlight() 03-Jun-99 I-03-11 mka $$31 Delete unused variable \*====================================================================*/ /*--------------------------------------------------------------------*\ Pro/TOOLKIT includes \*--------------------------------------------------------------------*/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include /*--------------------------------------------------------------------*\ Application includes \*--------------------------------------------------------------------*/ #include "TestGeom.h" #include "UtilColor.h" #include "UtilGeom.h" #include "UtilIntfData.h" #include "UtilMath.h" #include "UtilMatrix.h" #include "UtilNames.h" #include "UtilString.h" #include "UtilVisit.h" #include "UtilCollect.h" /*====================================================================*\ FUNCTION : ProUtilSurfaceMesh() PURPOSE : Make a UV mesh over a specified surface \*====================================================================*/ int ProUtilSurfaceMesh( ProSurface *surface, double resolution, /* The step size in model unit */ int nlines[2], /* No of U and V lines */ ProUtilMeshAct action, /* Function to call at each mesh point */ ProAppData tmp_app_data) /* General data */ { ProError status; ProGeomitemdata *sdata; double u_min, v_min, u_max, v_max, u_step, v_step, u_res, v_res, uv[2], last_uv[2], der1[2][3]; ProTestGeomData *app_data = (ProTestGeomData *) tmp_app_data; ProUvStatus uvstatus; int start, error; ProSolid solid; solid = *(app_data->model); /*--------------------------------------------------------------------*\ Get the maxmum and minium U and V for the surface \*--------------------------------------------------------------------*/ status = ProSurfaceDataGet(*surface, &sdata); TEST_CALL_REPORT("ProSurfaceDataGet()","ProUtilSurfaceMesh()", status, status != PRO_TK_NO_ERROR); /*--------------------------------------------------------------------*\ Calculate the U and V parameters \*--------------------------------------------------------------------*/ u_min = sdata->data.p_surface_data->uv_min[0]; v_min = sdata->data.p_surface_data->uv_min[1]; u_max = sdata->data.p_surface_data->uv_max[0]; v_max = sdata->data.p_surface_data->uv_max[1]; u_step = (u_max - u_min) / (nlines[0] + 1); v_step = (v_max - v_min) / (nlines[1] + 1); /*--------------------------------------------------------------------*\ Calculate the U and V resolution to give the correct resolution in model units. \*--------------------------------------------------------------------*/ uv[0] = (u_max + u_min) / 2.0; uv[1] = (v_max + v_min) / 2.0; status = ProSurfaceXyzdataEval(*surface, uv, NULL, der1, NULL, NULL); TEST_CALL_REPORT("ProSurfaceXyzdataEval()","ProUtilSurfaceMesh()", status, status != PRO_TK_NO_ERROR); u_res = resolution / ProUtilVectorLength(der1[0]); v_res = resolution / ProUtilVectorLength(der1[1]); /*--------------------------------------------------------------------*\ Adjust the upper limits to ensure that we get a mesh line at the max \*--------------------------------------------------------------------*/ u_max += u_res/ 2.0; v_max += v_res/ 2.0; /*--------------------------------------------------------------------*\ Do lines of constant U \*--------------------------------------------------------------------*/ for(uv[0] = u_min; uv[0] <= u_max; uv[0] += u_step) { last_uv[1] = -1000000.0; for(uv[1] = v_min; uv[1] <= v_max; uv[1] += v_res) { /*--------------------------------------------------------------------*\ If this point is outside the domain, skip it \*--------------------------------------------------------------------*/ status = ProSurfaceUvpntVerify(solid, *surface, uv, &uvstatus); TEST_CALL_REPORT("ProSurfaceUvpntVerify()", "ProUtilSurfaceMesh()", status, status != PRO_TK_NO_ERROR); if(uvstatus == PRO_UV_OUTSIDE) continue; start = (uv[1] - last_uv[1]) > (u_res + EPSM6); error = (*action)(surface, uv, start, app_data); if(error != 0) return(error); last_uv[1] = uv[1]; } } /*--------------------------------------------------------------------*\ Do lines of constant V \*--------------------------------------------------------------------*/ for(uv[1] = v_min; uv[1] <= v_max; uv[1] += v_step) { last_uv[0] = -1000000.0; for(uv[0] = u_min; uv[0] <= u_max; uv[0] += u_res) { /*--------------------------------------------------------------------*\ If this point is outside the domain, skip it \*--------------------------------------------------------------------*/ status = ProSurfaceUvpntVerify(solid, *surface, uv, &uvstatus); TEST_CALL_REPORT("ProSurfaceUvpntVerify()", "ProUtilSurfaceMesh()", status, status != PRO_TK_NO_ERROR); if(uvstatus == PRO_UV_OUTSIDE) continue; start = (uv[0] - last_uv[0]) > (v_res + EPSM6); error = (*action)(surface, uv, start, tmp_app_data); if(error != 0) return(error); last_uv[0] = uv[0]; } } return(0); } /*====================================================================*\ FUNCTION : ProUtilGeomitemshapeDump() PURPOSE : Dump the geometry of a geometry item \*====================================================================*/ int ProUtilGeomitemshapeDump( FILE *fp, ProGeomitemdata *geom) { ProUtilCname type_str; switch(geom->obj_type) { case PRO_AXIS : case PRO_EDGE : case PRO_CURVE : case PRO_POINT : /*--------------------------------------------------------------------*\ Get and dump geometry of the curve for the axis, edge, or curve \*--------------------------------------------------------------------*/ ProUtilObjtypeStr(geom->obj_type, type_str); fprintf(fp,"CURVE geometry for %s\n", type_str); ProUtilCurvedataPrint(fp, "\0", geom->data.p_curve_data); break; case PRO_CSYS : /*--------------------------------------------------------------------*\ Dump directly the CSYS geometry \*--------------------------------------------------------------------*/ fprintf(fp,"CSYS geometry\n"); fprintf(fp,"X vector = %.5f, %.5f, %.5f\n", geom->data.p_csys_data->x_vector[0], geom->data.p_csys_data->x_vector[1], geom->data.p_csys_data->x_vector[2]); fprintf(fp,"Y vector = %.5f, %.5f, %.5f\n", geom->data.p_csys_data->y_vector[0], geom->data.p_csys_data->y_vector[1], geom->data.p_csys_data->y_vector[2]); fprintf(fp,"Z vector = %.5f, %.5f, %.5f\n", geom->data.p_csys_data->z_vector[0], geom->data.p_csys_data->z_vector[1], geom->data.p_csys_data->z_vector[2]); fprintf(fp,"Shift vec= %.5f, %.5f, %.5f\n", geom->data.p_csys_data->origin[0], geom->data.p_csys_data->origin[1], geom->data.p_csys_data->origin[2]); break; case PRO_SURFACE : /*--------------------------------------------------------------------*\ Get and dump the surface geometry \*--------------------------------------------------------------------*/ ProUtilObjtypeStr(geom->obj_type, type_str); fprintf(fp,"SURFACE geometry for %s\n", type_str); ProUtilSurfacedataPrint(fp, "\0", geom->data.p_surface_data); default :; } return(0); } /*====================================================================*\ FUNCTION : ProUtilGeomitemDump() PURPOSE : Dump the geometry of a selected geometry item EDGE, AXIS, CSYS, CURVE, POINT, QUILT, SURFACE \*====================================================================*/ int ProUtilGeomitemDump( FILE *fp, ProSelection *item) { ProError status; ProVector xyz_point, xyz_min, xyz_max, dir; double area, length; int m, i, n, curve_id, comp_crv_id; ProMdl comp; ProAsmcomppath temp_comp_path; ProCharName name, type; ProGeomitemdata *gitem_data = NULL; ProAxis axis; ProPoint point, point2; ProCsys p_csys; ProCurve p_curve ; ProEdge p_edge; ProQuilt p_quilt; ProSurface p_surface; ProAsmcomppath comp_path; ProModelitem model_item; ProGeomitem geomitem; ProCurvedata *p_curve_data; ProSurfacedata *p_surf_data; ProMdlType mdltype; CurveComponent *curvecomps; ProEnttype curve_type; ProVectorlist vect_list; int num, id; double t; ProUvParam uv[2], uvd1[2], uvd2[2]; ProCharName type_str; ProContour *p_contours; status = ProSelectionAsmcomppathGet(*item, &comp_path); TEST_CALL_REPORT("ProSelectionAsmcomppathGet()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); /*--------------------------------------------------------------------*\ Dump the component id table (the path through the assembly) \*--------------------------------------------------------------------*/ fprintf(fp,"Component table ..\n"); memcpy(&temp_comp_path, &comp_path, sizeof(ProAsmcomppath)); for(m=0; m < comp_path.table_num; m++) { temp_comp_path.table_num = m+1; status = ProAsmcomppathMdlGet(&temp_comp_path, &comp); TEST_CALL_REPORT("ProAsmcomppathMdlGet()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); ProUtilModelnameGet(&comp, name, type); fprintf(fp, " comp_id_table[%2d] = %2d, model = %s.%s\n", m, comp_path.comp_id_table[m], name, type); } fprintf(fp,"\n"); /*--------------------------------------------------------------------*\ Depending upon the object type, get its geometry \*--------------------------------------------------------------------*/ status = ProSelectionModelitemGet(*item, &model_item); TEST_CALL_REPORT("ProSelectionModelitemGet()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); /*--------------------------------------------------------------------*\ Dump the geomitem type and id \*--------------------------------------------------------------------*/ ProUtilObjtypeStr(model_item.type, type_str); fprintf(fp, "Geometry item %s id %d.\n", type_str, model_item.id); switch(model_item.type) { case PRO_EDGE : /*--------------------------------------------------------------------*\ Get the length of the edge \*--------------------------------------------------------------------*/ status = ProEdgeInit(model_item.owner, model_item.id, &p_edge); TEST_CALL_REPORT("ProEdgeInit()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); status = ProEdgeToGeomitem(model_item.owner, p_edge, &geomitem); TEST_CALL_REPORT("ProEdgeToGeomitem()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); status = ProGeomitemToEdge(&geomitem, &p_edge); TEST_CALL_REPORT("ProGeomitemToEdge()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); status = ProEdgeLengthEval(p_edge, &length); TEST_CALL_REPORT("ProEdgeLengthEval()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); fprintf(fp,"Edge length = %6.2f\n\n", length); /*--------------------------------------------------------------------*\ Get the geometrical equations for the edge \*--------------------------------------------------------------------*/ status = ProEdgeDataGet(p_edge, &gitem_data); TEST_CALL_REPORT("ProEdgeDataGet()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); if(status == PRO_TK_NO_ERROR) { /*--------------------------------------------------------------------*\ Dump the edge geometry \*--------------------------------------------------------------------*/ ProUtilGeomitemshapeDump(fp, gitem_data); } /*--------------------------------------------------------------------*\ Edge to NURBS \*--------------------------------------------------------------------*/ status = ProEdgeToNURBS(p_edge, &p_curve_data); TEST_CALL_REPORT("ProEdgeToNURBS()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); if(status == PRO_TK_NO_ERROR) { fprintf(fp, "Edge, translated to NURBS\n"); ProUtilCurvedataPrint(fp, " ", p_curve_data); status = ProCurveDataFree(&p_curve_data); TEST_CALL_REPORT("ProCurveDataFree()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); } status = ProEdgeTessellationGet(p_edge, &vect_list, NULL, NULL, NULL, &num); TEST_CALL_REPORT("ProEdgeTessellationGet()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); fprintf(fp,"Edge, tesselated with %d points\n", num); for (i = 0; i < num ; i++) { fprintf(fp,"\tvector[%d] = %6.2f, %6.2f, %6.2f\n", i, vect_list[i][0], vect_list[i][1], vect_list[i][2]); } ProArrayFree((ProArray*)&vect_list); fprintf(fp,"Edge, UV data\n"); fprintf(fp,"\t t uv[0] uv[1] uvd1[0] uvd1[1]" " uvd2[0] uvd2[1]\n"); for (i=0; i<=4; i++) { t=i*0.25; status = ProEdgeUvdataEval(p_edge, t, uv, uvd1, uvd2); TEST_CALL_REPORT("ProEdgeUvdataEval()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); fprintf(fp,"\t %4.2f %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f\n", t, uv[0][0], uv[0][1], uvd1[0][0], uvd1[0][1], uvd2[0][0], uvd2[0][1]); fprintf(fp,"\t %4.2f %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f\n", t, uv[1][0], uv[1][1], uvd1[1][0], uvd1[1][1], uvd2[1][0], uvd2[1][1]); } break; case PRO_AXIS : /*--------------------------------------------------------------------*\ Get the geometrical equations for the axis (a line) \*--------------------------------------------------------------------*/ status = ProAxisInit(model_item.owner, model_item.id, &axis); TEST_CALL_REPORT("ProAxisInit()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); status = ProAxisToGeomitem(model_item.owner, axis, &geomitem); TEST_CALL_REPORT("ProAxisToGeomitem()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); status = ProGeomitemToAxis(&geomitem, &axis); TEST_CALL_REPORT("ProGeomitemToAxis()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); status = ProAxisDataGet(axis, &gitem_data); TEST_CALL_REPORT("ProAxisDataGet()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); if(status == PRO_TK_NO_ERROR) { /*--------------------------------------------------------------------*\ Dump the axis geometry \*--------------------------------------------------------------------*/ ProUtilGeomitemshapeDump(fp, gitem_data); } /*--------------------------------------------------------------------*\ Check the parent surface \*--------------------------------------------------------------------*/ status = ProAxisSurfaceGet(model_item.owner, axis, &p_surface); TEST_CALL_REPORT("ProAxisSurfaceGet()", "ProTestGeomitemVisAct()", status, status!=PRO_TK_NO_ERROR && status != PRO_TK_E_NOT_FOUND); if (status == PRO_TK_NO_ERROR) { status = ProSurfaceIdGet(p_surface, &id); TEST_CALL_REPORT("ProAxisSurfaceGet()", "ProTestGeomitemVisAct()", status, status!=PRO_TK_NO_ERROR); fprintf(fp,"\tAxis was created by surface %d\n", id); } break; case PRO_CSYS : /*--------------------------------------------------------------------*\ Get the geometry of the CSYS \*--------------------------------------------------------------------*/ status = ProCsysInit(model_item.owner,model_item.id,&p_csys); TEST_CALL_REPORT("ProCsysInit()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); status = ProCsysToGeomitem(model_item.owner, p_csys, &geomitem); TEST_CALL_REPORT("ProCsysToGeomitem()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); status = ProGeomitemToCsys(&geomitem, &p_csys); TEST_CALL_REPORT("ProGeomitemToCsys()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); status = ProCsysDataGet(p_csys, &gitem_data); TEST_CALL_REPORT("ProCsysDataGet()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); if(status == PRO_TK_NO_ERROR) { /*--------------------------------------------------------------------*\ Dump the geometry of the csys \*--------------------------------------------------------------------*/ ProUtilGeomitemshapeDump(fp, gitem_data); } break; case PRO_CURVE : /*--------------------------------------------------------------------*\ Get the geometrical equations for the CURVE \*--------------------------------------------------------------------*/ status = ProCurveInit(model_item.owner,model_item.id,&p_curve); TEST_CALL_REPORT("ProCurveInit()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); status = ProCurveToGeomitem(model_item.owner, p_curve, &geomitem); TEST_CALL_REPORT("ProCurveToGeomitem()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); status = ProGeomitemToCurve(&geomitem, &p_curve); TEST_CALL_REPORT("ProGeomitemToCurve()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); status = ProCurveLengthEval(p_curve, &length); TEST_CALL_REPORT("ProCurveLengthEval()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); fprintf(fp,"Curve length = %6.2f\n\n", length); /*--------------------------------------------------------------------*\ Maybe it's an ordinary datum curve \*--------------------------------------------------------------------*/ status = ProCurveDataGet(p_curve, &gitem_data); TEST_CALL_REPORT("ProCurveDataGet()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); if(status == PRO_TK_NO_ERROR) { /*--------------------------------------------------------------------*\ Dump the geometry of the curve \*--------------------------------------------------------------------*/ ProUtilGeomitemshapeDump(fp, gitem_data); } /*--------------------------------------------------------------------*\ Curve to NURBS \*--------------------------------------------------------------------*/ status = ProCurveToNURBS(p_curve, &p_curve_data); TEST_CALL_REPORT("ProCurveToNURBS()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); if(status == PRO_TK_NO_ERROR) { fprintf(fp, "Curve, translated to NURBS\n"); ProUtilCurvedataPrint(fp, " ", p_curve_data); status = ProCurveDataFree(&p_curve_data); TEST_CALL_REPORT("ProCurveDataFree()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); } /*--------------------------------------------------------------------*\ Maybe it's a composite curve. \*--------------------------------------------------------------------*/ #ifndef PT_PRODUCTS_BUILD status = ProCurveTypeGet(p_curve, &curve_type); TEST_CALL_REPORT("ProCurveTypeGet()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); if (curve_type == PRO_ENT_CMP_CRV ) { status = ProUtilCollectCurveComponents(p_curve, &curvecomps); if (status!=PRO_TK_NO_ERROR) break; status = ProArraySizeGet((ProArray)curvecomps, &n); TEST_CALL_REPORT("ProArraySizeGet()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); for (i=0; i