/* Copyright (c) 2024 PTC Inc. and/or Its Subsidiary Companies. All Rights Reserved. */ /*--------------------------------------------------------------------*\ Pro/TOOLKIT includes \*--------------------------------------------------------------------*/ #include <ProToolkit.h> #include <ProObjects.h> #include <ProSurface.h> #include <ProFeature.h> #include <ProFeatType.h> #include <ProSelection.h> #include <ProSolid.h> #include <ProAsmcomp.h> #include <ProEdge.h> #include <ProAxis.h> #include <ProCsys.h> #include <ProCurve.h> #include <ProPoint.h> #include <ProGeomitem.h> /*--------------------------------------------------------------------*\ 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" #include <UtilTypes.h> #include <UtilMessage.h> #include <UtilFiles.h> #include <PTApplsUnicodeUtils.h> #include <ProTKRunTime.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 = (ProSolid)*(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) { status = ProGeomitemdataFree(&sdata); TEST_CALL_REPORT("ProGeomitemdataFree()","ProUtilSurfaceMesh()" ,status, status != PRO_TK_NO_ERROR); 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) { status = ProGeomitemdataFree(&sdata); TEST_CALL_REPORT("ProGeomitemdataFree()","ProUtilSurfaceMesh()", status, status != PRO_TK_NO_ERROR); return(error); } last_uv[0] = uv[0]; } } status = ProGeomitemdataFree(&sdata); TEST_CALL_REPORT("ProGeomitemdataFree()","ProUtilSurfaceMesh()", status, status != PRO_TK_NO_ERROR); 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); ProTKFprintf(fp,"CURVE geometry for %s\n", type_str); ProUtilCurvedataPrint(fp, (char*)"\0", geom->data.p_curve_data); break; case PRO_CSYS : /*--------------------------------------------------------------------*\ Dump directly the CSYS geometry \*--------------------------------------------------------------------*/ ProTKFprintf(fp,"CSYS geometry\n"); ProTKFprintf(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]); ProTKFprintf(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]); ProTKFprintf(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]); ProTKFprintf(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); ProTKFprintf(fp,"SURFACE geometry for %s\n", type_str); ProUtilSurfacedataPrint(fp, (char*)"\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) \*--------------------------------------------------------------------*/ ProTKFprintf(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); ProTKFprintf(fp, " comp_id_table[%2d] = %2d, model = %s.%s\n", m, comp_path.comp_id_table[m], name, type); } ProTKFprintf(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); ProTKFprintf(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((ProSolid)model_item.owner, model_item.id, &p_edge); TEST_CALL_REPORT("ProEdgeInit()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); status = ProEdgeToGeomitem((ProSolid)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); ProTKFprintf(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) { ProTKFprintf(fp, "Edge, translated to NURBS\n"); ProUtilCurvedataPrint(fp, (char*)" ", 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); ProTKFprintf(fp,"Edge, tesselated with %d points\n", num); for (i = 0; i < num ; i++) { ProTKFprintf(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); ProTKFprintf(fp,"Edge, UV data\n"); ProTKFprintf(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); ProTKFprintf(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]); ProTKFprintf(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((ProSolid)model_item.owner, model_item.id, &axis); TEST_CALL_REPORT("ProAxisInit()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); status = ProAxisToGeomitem((ProSolid)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); ProTKFprintf(fp,"\tAxis was created by surface %d\n", id); } break; case PRO_CSYS : /*--------------------------------------------------------------------*\ Get the geometry of the CSYS \*--------------------------------------------------------------------*/ status = ProCsysInit((ProSolid)model_item.owner,model_item.id,&p_csys); TEST_CALL_REPORT("ProCsysInit()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); status = ProCsysToGeomitem((ProSolid)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((ProSolid)model_item.owner,model_item.id,&p_curve); TEST_CALL_REPORT("ProCurveInit()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); status = ProCurveToGeomitem((ProSolid)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); ProTKFprintf(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) { ProTKFprintf(fp, "Curve, translated to NURBS\n"); ProUtilCurvedataPrint(fp, (char*)" ", 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<n; i++) { status = ProCurveIdGet(curvecomps[i].p_owner, &curve_id); TEST_CALL_REPORT("ProCurveIdGet()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); status = ProCurveIdGet(curvecomps[i].p_curve, &comp_crv_id); TEST_CALL_REPORT("ProCurveIdGet()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); ProTKFprintf(fp, "Curve %d, component %d, index %d, flip %d\n", curve_id, comp_crv_id, curvecomps[i].index, curvecomps[i].flip); } status = ProArrayFree((ProArray*)&curvecomps); TEST_CALL_REPORT("ProArrayFree()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); } #endif /* #ifndef PT_PRODUCTS_BUILD */ break; case PRO_POINT : /*--------------------------------------------------------------------*\ Get and dump directly the coordinates of the datum point \*--------------------------------------------------------------------*/ status = ProPointInit((ProSolid)model_item.owner, model_item.id, &point); TEST_CALL_REPORT("ProPointInit()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); status = ProPointIdGet(point, &geomitem.id); TEST_CALL_REPORT("ProPointIdGet()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); status = ProPointToGeomitem((ProSolid)model_item.owner, point, &geomitem); TEST_CALL_REPORT("ProPointToGeomitem()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); status = ProGeomitemToPoint(&geomitem, &point2); TEST_CALL_REPORT("ProGeomitemToPoint()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); status = ProPointCoordGet(point, xyz_point); TEST_CALL_REPORT("ProPointCoordGet()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); ProTKFprintf(fp,"Geometry for datum point = %6.2f, %6.2f, %6.2f\n", xyz_point[0], xyz_point[1], xyz_point[2]); break; case PRO_QUILT : #ifndef PT_PRODUCTS_BUILD status = ProQuiltInit((ProSolid)model_item.owner, model_item.id, &p_quilt); TEST_CALL_REPORT("ProQuiltInit()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); status = ProQuiltIdGet(p_quilt, &geomitem.id); TEST_CALL_REPORT("ProQuiltIdGet()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); status = ProQuiltToGeomitem((ProSolid)model_item.owner, p_quilt, &geomitem); TEST_CALL_REPORT("ProQuiltToGeomitem()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); status = ProGeomitemToQuilt(&geomitem, &p_quilt); TEST_CALL_REPORT("ProGeomitemToQuilt()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); ProTKFprintf(fp,"Quilt id %d\n", geomitem.id); #endif /* #ifndef PT_PRODUCTS_BUILD */ break; case PRO_SURFACE : /*--------------------------------------------------------------------*\ Get and dump the area of the surface \*--------------------------------------------------------------------*/ status = ProSurfaceInit(model_item.owner, model_item.id, &p_surface); TEST_CALL_REPORT("ProSurfaceInit()", "ProUtilGeomitemDump()", status, (status != PRO_TK_NO_ERROR)); status = ProSurfaceToGeomitem((ProSolid)model_item.owner, p_surface, &geomitem); TEST_CALL_REPORT("ProSurfaceToGeomitem()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); status = ProGeomitemToSurface(&geomitem, &p_surface); TEST_CALL_REPORT("ProGeomitemToSurface()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); status = ProSurfaceAreaEval(p_surface, &area); TEST_CALL_REPORT("ProSurfaceAreaEval()", "ProUtilGeomitemDump()", status, (status != PRO_TK_NO_ERROR && status != PRO_TK_OUT_OF_RANGE)); if(status == PRO_TK_NO_ERROR) ProTKFprintf(fp,"Surface area is %6.2f\n\n", area); /*--------------------------------------------------------------------*\ Get surface extremes \*--------------------------------------------------------------------*/ status = ProUtilCollectSurfaceContours(p_surface, &p_contours); if (status == PRO_TK_NO_ERROR) { ProArrayFree((ProArray*)&p_contours); /* Do not calculate extremes if surface doesn't have edges */ dir [0] = dir[1] = dir[2] = 0.7071; status = ProSurfaceExtremesEval(p_surface, dir, xyz_min, xyz_max); TEST_CALL_REPORT("ProSurfaceExtremesEval()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); ProTKFprintf(fp,"Surface extremes (min) %.2f %.2f %.2f\n", xyz_min[0], xyz_min[1], xyz_min[2]); ProTKFprintf(fp,"Surface extremes (max) %.2f %.2f %.2f\n\n", xyz_max[0], xyz_max[1], xyz_max[2]); } status = ProMdlTypeGet(model_item.owner, &mdltype); TEST_CALL_REPORT("ProMdlTypeGet()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR ); #ifndef PT_PRODUCTS_BUILD if (mdltype == PRO_MDL_PART) { status = ProSurfaceQuiltGet((ProSolid)model_item.owner ,p_surface, &p_quilt); TEST_CALL_REPORT(" ProSurfaceQuiltGet()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR && status != PRO_TK_E_NOT_FOUND); if (status == PRO_TK_NO_ERROR) ProTKFprintf(fp, "This surface belong to quilt\n"); } #endif /* #ifndef PT_PRODUCTS_BUILD */ /*--------------------------------------------------------------------*\ Get the geometrical equations of the surface \*--------------------------------------------------------------------*/ status = ProSurfaceDataGet(p_surface, &gitem_data); TEST_CALL_REPORT("ProSurfaceDataGet()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); if(status == PRO_TK_NO_ERROR) { /*--------------------------------------------------------------------*\ Dump the geometry of the surface \*--------------------------------------------------------------------*/ ProUtilGeomitemshapeDump(fp, gitem_data); } /*--------------------------------------------------------------------*\ Surface to NURBS \*--------------------------------------------------------------------*/ status = ProSurfaceToNURBS(p_surface, &p_surf_data); TEST_CALL_REPORT("ProSurfaceToNURBS()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); if(status == PRO_TK_NO_ERROR) { ProTKFprintf(fp, "Surface, translated to NURBS\n"); ProUtilSurfacedataPrint(fp, (char*)" ", p_surf_data); status = ProSurfaceDataFree(&p_surf_data); TEST_CALL_REPORT("ProSurfaceDataFree()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); } break; default :; } if (gitem_data != NULL) { status = ProGeomitemdataFree(&gitem_data); TEST_CALL_REPORT("ProGeomitemdataFree()", "ProUtilGeomitemDump()", status, status != PRO_TK_NO_ERROR); } return(0); } /*====================================================================*\ FUNCTION : ProUtilPointMindist() PURPOSE : Minimum distance between a point and an edge, curve, or surface. \*====================================================================*/ int ProUtilPointMindist( ProVector point, /* I - Input point in root coords */ ProSelection *item, /* I - Edge, Curve or Surface */ double *distance, /* O - Minimum distance */ double *closest) /* O - Closest point in root coords */ { ProError status; ProMatrix transform; ProVector local_point; double t; ProUvParam uv; ProCurve p_curve; ProEdge p_edge; ProSurface p_surface; ProAsmcomppath comp_path; ProModelitem model_item; status = ProSelectionAsmcomppathGet(*item, &comp_path); TEST_CALL_REPORT("ProSelectionAsmcomppathGet()", "ProUtilPointMindist()", status, status != PRO_TK_NO_ERROR); /*--------------------------------------------------------------------*\ Transform the distance point from root coords to the coords local to the selected item. \*--------------------------------------------------------------------*/ status = ProAsmcomppathTrfGet(&comp_path, PRO_B_FALSE, transform); TEST_CALL_REPORT("ProAsmcomppathTrfGet()", "ProUtilPointMindist()", status, status != PRO_TK_NO_ERROR); ProUtilPointTrans(transform, point, local_point); /*--------------------------------------------------------------------*\ Calculate the mininum distance \*--------------------------------------------------------------------*/ status = ProSelectionModelitemGet(*item, &model_item); TEST_CALL_REPORT("ProSelectionModelitemGet()", "ProUtilPointMindist()", status, status != PRO_TK_NO_ERROR); switch(model_item.type) { case PRO_EDGE : /*--------------------------------------------------------------------*\ Calculate the value of "t" for the nearest point on the edge \*--------------------------------------------------------------------*/ status = ProEdgeInit((ProSolid)model_item.owner, model_item.id, &p_edge); TEST_CALL_REPORT("ProEdgeInit()", "ProUtilPointMindist()", status, status != PRO_TK_NO_ERROR); if (status!= PRO_TK_NO_ERROR) return (1); status = ProEdgeParamEval(p_edge, local_point, &t); TEST_CALL_REPORT("ProEdgeParamEval()", "ProUtilPointMindist()", status, status != PRO_TK_NO_ERROR); if (status!= PRO_TK_NO_ERROR) return (1); /*--------------------------------------------------------------------*\ Calculate the location for that "t" value. \*--------------------------------------------------------------------*/ status = ProEdgeXyzdataEval(p_edge, t, closest, NULL, NULL, NULL); TEST_CALL_REPORT("ProEdgeXyzdataEval()", "ProUtilPointMindist()", status, status != PRO_TK_NO_ERROR ); if (status!= PRO_TK_NO_ERROR) return (1); break; case PRO_CURVE : /*--------------------------------------------------------------------*\ Calculate the value of "t" for the nearest point on the curve \*--------------------------------------------------------------------*/ status = ProCurveInit((ProSolid)model_item.owner,model_item.id,&p_curve); if (status!= PRO_TK_NO_ERROR) return (1); status = ProCurveParamEval(p_curve, local_point, &t); TEST_CALL_REPORT("ProCurveParamEval()", "ProUtilPointMindist()", status, status != PRO_TK_NO_ERROR); if (status!= PRO_TK_NO_ERROR) return (1); /*--------------------------------------------------------------------*\ Calculate the location for that "t" value. \*--------------------------------------------------------------------*/ status = ProCurveInit((ProSolid)model_item.owner,model_item.id,&p_curve); if (status!= PRO_TK_NO_ERROR) return (1); status = ProCurveXyzdataEval(p_curve, t,closest, NULL, NULL); TEST_CALL_REPORT("ProCurveXyzdataEval()", "ProUtilPointMindist()", status, status != PRO_TK_NO_ERROR ); if (status!= PRO_TK_NO_ERROR) return (1); break; case PRO_SURFACE : status = ProSurfaceInit(model_item.owner, model_item.id, &p_surface); TEST_CALL_REPORT("ProSurfaceInit()", "ProUtilPointMindist()", status, status != PRO_TK_NO_ERROR); if (status!= PRO_TK_NO_ERROR) return (1); /*--------------------------------------------------------------------*\ Calculate the value of "u" and "v" for the nearest point on the surface \*--------------------------------------------------------------------*/ status = ProSurfaceParamEval((ProSolid)model_item.owner, p_surface, local_point, uv); TEST_CALL_REPORT("ProSurfaceParamEval()", "ProUtilPointMindist()", status, status != PRO_TK_NO_ERROR); if (status!= PRO_TK_NO_ERROR) return (1); /*--------------------------------------------------------------------*\ Calculate the location for that "uv" value. \*--------------------------------------------------------------------*/ status = ProSurfaceXyzdataEval(p_surface, uv, closest, NULL, NULL, NULL); TEST_CALL_REPORT("ProSurfaceXyzdataEval()", "ProUtilPointMindist()", status, status != PRO_TK_NO_ERROR ); if (status!= PRO_TK_NO_ERROR) return (1); break; default : return(1); } /*--------------------------------------------------------------------*\ Transform the closest point back to root coordinates \*--------------------------------------------------------------------*/ status = ProAsmcomppathTrfGet(&comp_path, PRO_B_TRUE, transform); TEST_CALL_REPORT("ProAsmcomppathTrfGet()", "ProUtilPointMindist()", status, status != PRO_TK_NO_ERROR); ProUtilPointTrans(transform, closest, closest); *distance = ProUtilPointsDist(point, closest); return(0); } /*===========================================================================*\ Function : ProTestGeometryAtPoint Purpose : find what geometry a point is on \*===========================================================================*/ int ProTestGeometryAtPoint(ProAppData app_data, int b) { Pro3dPnt pnt; ProMdl model = ((ProMdl*)app_data)[0]; ProPart part; int i,p_count,edge_no=0,minId,k,l; ProSelection *p_sel_arr, select; ProError status; FILE *fp; ProCharLine fname; ProModelitem mod_item; ProUvParam uv_par; double uvpTemp; ProMdlType mdltype; edgeInfo *edgeInfoCollect; edgeInfo edgeInfo_indv; /*--------------------------------------------------------------------*\ Find out the model type \*--------------------------------------------------------------------*/ status = ProMdlTypeGet(model, &mdltype); TEST_CALL_REPORT("ProMdlTypeGet()", "ProTestGeometryAtPoint()", status, status != PRO_TK_NO_ERROR ); if (mdltype!=PRO_MDL_PART) { ProUtilMsgPrint("gen", "TEST %0s", "This function works on part only"); return (0); } part = (ProPart)model; ProUtilMsgPrint("gen", "TEST %0s", "Enter X coordinate:"); if (ProUtilDoubleGet(NULL, NULL, &pnt[0])==0) return (0); ProUtilMsgPrint("gen", "TEST %0s", "Enter Y coordinate:"); if (ProUtilDoubleGet(NULL, NULL, &pnt[1])==0) return (0); ProUtilMsgPrint("gen", "TEST %0s", "Enter Z coordinate:"); if (ProUtilDoubleGet(NULL, NULL, &pnt[2])==0) return (0); p_count = 0; status = ProGeometryAtPointFind(part, pnt, &p_sel_arr, &p_count); TEST_CALL_REPORT("ProGeometryAtPointFind()", "ProTestGeometryAtPoint()", status, status != PRO_TK_NO_ERROR && status != PRO_TK_E_NOT_FOUND); if ( p_count == 0 || status != PRO_TK_NO_ERROR) { ProUtilMsgPrint("gen", "TEST %0s", "Point does not lie on geometry"); return (0); } else ProUtilMsgPrint("gen", "TEST %0s", "Point lies on hilighted geometry"); ProTestQcrName((ProMdl*)&part, (char*)".pgm", fname); if ( (fp = PTApplsUnicodeFopen(fname,"a")) == NULL ) return(-1); ProTKFprintf(fp,"Point %0.2lf, %0.2lf, %0.2lf lies on the following geometry:\n", pnt[0],pnt[1],pnt[2]); status = ProArrayAlloc (0, sizeof(edgeInfo), 1, (ProArray*)&edgeInfoCollect); TEST_CALL_REPORT("ProArrayAlloc()", "ProTestGeometryAtPoint()", status, status != PRO_TK_NO_ERROR ); for (i=0; i<p_count; i++) { status = ProSelectionModelitemGet(p_sel_arr[i], &mod_item); TEST_CALL_REPORT("ProSelectionModelitemGet()", "ProTestGeometryAtPoint()", status, status != PRO_TK_NO_ERROR ); status = ProSelectionAlloc(NULL, &mod_item, &select); TEST_CALL_REPORT("ProSelectionAlloc()", "ProTestGeometryAtPoint()", status, status != PRO_TK_NO_ERROR ); status = ProSelectionHighlight(select, PRO_COLOR_HIGHLITE); TEST_CALL_REPORT("ProSelectionHighlight()", "ProTestGeometryAtPoint()", status, status != PRO_TK_NO_ERROR ); status = ProSelectionUvParamGet(p_sel_arr[i], uv_par); TEST_CALL_REPORT("ProSelectionUvParamGet()", "ProTestGeometryAtPoint()", status, status != PRO_TK_NO_ERROR ); if ( mod_item.type == PRO_EDGE ) { edgeInfo_indv.edgeId =mod_item.id; edgeInfo_indv.uvparam =uv_par[0]; ProArrayObjectAdd ((ProArray*)&edgeInfoCollect, edge_no, 1, &edgeInfo_indv); edge_no++; } else { ProTKFprintf(fp,"\tPRO_SURFACE Id [%d] UV parameters: %0.2lf, %0.2lf\n", mod_item.id,uv_par[0],uv_par[1]); } } if ( mod_item.type == PRO_EDGE ) { if(edge_no>0) { for (k=0; k<=edge_no-1; k++) { for (l=k+1; l<edge_no; l++) { if ( edgeInfoCollect[k].edgeId > edgeInfoCollect[l].edgeId) { minId =edgeInfoCollect[k].edgeId; edgeInfoCollect[k].edgeId = edgeInfoCollect[l].edgeId; edgeInfoCollect[l].edgeId = minId; uvpTemp = edgeInfoCollect[k].uvparam; edgeInfoCollect[k].uvparam = edgeInfoCollect[l].uvparam; edgeInfoCollect[l].uvparam = uvpTemp; } } } for (k=0; k<=edge_no-1; k++) { ProTKFprintf(fp, "\tPRO_EDGE Id[%d] T parameter: %0.2lf\n",edgeInfoCollect[k].edgeId,edgeInfoCollect[k].uvparam); } } else { ProTKFprintf(fp, "\tPRO_EDGE Id[%d] T parameter: %0.2lf\n",edgeInfoCollect[0].edgeId, edgeInfoCollect[0].uvparam); ProTKFprintf(fp, "\n"); } } for ( i = 0; i < p_count; i++ ) { status = ProSelectionFree(&p_sel_arr[i]); TEST_CALL_REPORT("ProSelectionFree()", "ProTestGeometryAtPoint()", status, status != PRO_TK_NO_ERROR ); } status = ProArrayFree( (ProArray *) &p_sel_arr ); TEST_CALL_REPORT("ProArrayFree()", "ProTestGeometryAtPoint()", status, status != PRO_TK_NO_ERROR ); fclose(fp); return(0); }