/*****************************************************************************\ FILE : Ug3DSection.c PURPOSE : Pro/TOOLKIT User Guide Examples related to 3d sections HISTORY.. DATE BUILD AUTHOR MODIFICATIONS 04-Dec-97 H-02-02 Philippe $$1 Created from old userguide code 10-Dec-97 H-03-31 Philippe $$2 add includes 30-Dec-97 H-03-33 KS $$3 Initialized trf matrix to NULL 02-Mar-99 I-03-03 jeff $$4 Wrapped PI's define inside ifndef \*****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /*---------------------------External Functions------------------------------*/ extern void ProUtil2DPointTrans(); extern double *ProUtilLineLineX(); /*--------------------------Globlal Definition ------------------------------*/ typedef struct mtrx_data{ ProVector x_axis[2]; ProVector y_axis[2]; ProMatrix sec_trf; ProMatrix sk_mtrx; ProSelection sk_plane; double angle; }Matrix_data; static wchar_t msgfile[PRO_NAME_SIZE]; ProSelection *temp2 = NULL; ProSelection *temp1 = NULL; #ifndef PI # define PI 3.141592 #endif /* --------------------------Function Prototypes ----------------------------*/ ProError UserSelectSketchPlaneRefs(ProSelection **sketch_refs); ProError UserSelectProjectionEntities(ProSelection **proj_refs); ProError UserSelectOffsetDistances(double *offset_vals); ProError UserCreateTrfMatrix(Matrix_data *m_data); /* =============================================================== *\ Function: UserSectionBuild(ProSection section, ProSelection *sketch_refs) Purpose: Creates 3D section \* =============================================================== */ ProError UserSectionBuild(ProSection section, ProSelection *sketch_refs) { ProSelection *proj_ents; int status, i, num_errors, err_counter, proj_ids[2]; int ctr_line_id, rt_line_id, lt_line_id, top_line_id, btm_line_id; int upper_arc_id, lower_arc_id, ent_id[1], c_ent_id[2], proj_ent_id[2]; int ll_dim_id, tl_dim_id, ua_dim_id, la_dim_id, cl_dim_id, proj_dim_id[2]; ProWSecerror sec_errors; Pro2dLinedef line; Pro2dClinedef c_line; Pro2dLinedef *left_linedef, *btm_linedef; ProSectionPointType pt_type[1], proj_pt_type[2]; Pro2dArcdef arc; Pro2dPnt place_pnt; ProMsg wmsg; char msg[PRO_PATH_SIZE]; double offsets[2]; Matrix_data matrix_data; ProStringToWstring(msgfile, "msg_ug3dsketch.txt"); /* =============================================================== *\ Obtain projection entity handles as ProSelection structures \* =============================================================== */ status = UserSelectProjectionEntities(&proj_ents); ERROR_CHECK("UserSelectrojectionEntities", "UserSectionBuild", status); /* =============================================================== *\ Project reference edges onto section \* =============================================================== */ for (i = 0; i < 2; i++) { status = ProSectionEntityFromProjection(section, proj_ents[i], &proj_ids[i]); ERROR_CHECK("ProSectionEntityFromProjection", "UserSectionBuild", status); if (status != PRO_TK_NO_ERROR) return(status); } /* =============================================================== *\ Create section csys from edges, and obtion transformation matrix between sketch plane csys and section csys \* =============================================================== */ status = ProSectionEntityGet(section, proj_ids[0], (Pro2dEntdef **)&btm_linedef); ERROR_CHECK("ProSectionEntityGet", "UserSectionBuild", status); for (i = 0; i < 2; i++) { matrix_data.x_axis[0][i] = btm_linedef->end1[i]; matrix_data.x_axis[1][i] = btm_linedef->end2[i]; matrix_data.x_axis[i][2] = 0.0; } status = ProSectionEntityGet(section, proj_ids[1], (Pro2dEntdef **)&left_linedef); ERROR_CHECK("ProSectionEntityGet", "UserSectionBuild", status); for (i = 0; i < 2; i++) { matrix_data.y_axis[0][i] = left_linedef->end1[i]; matrix_data.y_axis[1][i] = left_linedef->end2[i]; matrix_data.y_axis[i][2] = 0.0; } status = ProSectionLocationGet(section, matrix_data.sk_mtrx); ERROR_CHECK("ProSectionLocationGet", "UserCreateTrfMatrix", status); status = ProSelectionCopy(sketch_refs[0], &(matrix_data.sk_plane)); ERROR_CHECK("ProSelectionCopy", "UserSectionBuild", status) ; status = UserCreateTrfMatrix(&matrix_data); ERROR_CHECK("UseCreateTrfMatrix", "UserSectionBuild", status); /* =============================================================== *\ Obtain offset values from projection entities \* =============================================================== */ status = UserSelectOffsetDistances(offsets); ERROR_CHECK("UserSelectOffsetDistances", "UserSectionBuild", status); /* =============================================================== *\ Add center line ... \* =============================================================== */ c_line.type = PRO_2D_CENTER_LINE; c_line.end1[0] = 0.0; c_line.end1[1] = 0.0; c_line.end2[0] = 0.0; c_line.end2[1] = 1.0; ProUtil2DPointTrans(matrix_data.sec_trf, c_line.end1, c_line.end1); ProUtil2DPointTrans(matrix_data.sec_trf, c_line.end2, c_line.end2); status = ProSectionEntityAdd(section, (Pro2dEntdef*)&c_line, &ctr_line_id); ERROR_CHECK("UserSectionEntityAdd - 1", "UserSectionBuild", status); /* =============================================================== *\ Add left vertical line ... \* =============================================================== */ line.type = PRO_2D_LINE; line.end1[0] = offsets[1]; line.end1[1] = offsets[0]; line.end2[0] = offsets[1]; line.end2[1] = offsets[0] + 50.0; ProUtil2DPointTrans(matrix_data.sec_trf, line.end1, line.end1); ProUtil2DPointTrans(matrix_data.sec_trf, line.end2, line.end2); status = ProSectionEntityAdd(section, (Pro2dEntdef*)&line, <_line_id); ERROR_CHECK("UserSectionEntityAdd - 1", "UserSectionBuild", status); /* =============================================================== *\ Add top line ... \* =============================================================== */ line.type = PRO_2D_LINE; line.end1[0] = offsets[1]; line.end1[1] = offsets[0] + 50.0; line.end2[0] = offsets[1] + 25.0; line.end2[1] = offsets[0] + 50.0; ProUtil2DPointTrans(matrix_data.sec_trf, line.end1, line.end1); ProUtil2DPointTrans(matrix_data.sec_trf, line.end2, line.end2); status = ProSectionEntityAdd(section, (Pro2dEntdef*)&line, &top_line_id); ERROR_CHECK("UserSectionEntityAdd - 2", "UserSectionBuild", status); /* =============================================================== *\ Add upper arc ... \* =============================================================== */ arc.type = PRO_2D_ARC; arc.center[0] = offsets[1] + 40.0; arc.center[1] = offsets[0] + 50.0; arc.start_angle = PI + matrix_data.angle; arc.end_angle = 1.5*PI + matrix_data.angle; arc.radius = 15.0; ProUtil2DPointTrans(matrix_data.sec_trf, arc.center, arc.center); status = ProSectionEntityAdd(section, (Pro2dEntdef*)&arc, &upper_arc_id); ERROR_CHECK("UserSectionEntityAdd - 3", "UserSectionBuild", status); /* =============================================================== *\ Add right vertical line ... \* =============================================================== */ line.type = PRO_2D_LINE; line.end1[0] = offsets[1] + 40.0; line.end1[1] = offsets[0] + 35.0; line.end2[0] = offsets[1] + 40.0; line.end2[1] = offsets[0] + 10.0; ProUtil2DPointTrans(matrix_data.sec_trf, line.end1, line.end1); ProUtil2DPointTrans(matrix_data.sec_trf, line.end2, line.end2); status = ProSectionEntityAdd(section, (Pro2dEntdef*)&line, &rt_line_id); ERROR_CHECK("UserSectionEntityAdd - 4", "UserSectionBuild", status); /* =============================================================== *\ Add lower arc ... \* =============================================================== */ arc.type = PRO_2D_ARC; arc.center[0] = offsets[1] + 40.0; arc.center[1] = offsets[0]; arc.start_angle = 0.5*PI + matrix_data.angle; arc.end_angle = PI + matrix_data.angle; arc.radius = 10.0; ProUtil2DPointTrans(matrix_data.sec_trf, arc.center, arc.center); status = ProSectionEntityAdd(section, (Pro2dEntdef*)&arc, &lower_arc_id); ERROR_CHECK("UserSectionEntityAdd - 5", "UserSectionBuild", status); /* =============================================================== *\ Add bottom line ... \* =============================================================== */ line.type = PRO_2D_LINE; line.end1[0] = offsets[1] + 30.0; line.end1[1] = offsets[0]; line.end2[0] = offsets[1]; line.end2[1] = offsets[0]; ProUtil2DPointTrans(matrix_data.sec_trf, line.end1, line.end1); ProUtil2DPointTrans(matrix_data.sec_trf, line.end2, line.end2); status = ProSectionEntityAdd(section, (Pro2dEntdef*)&line, &btm_line_id); ERROR_CHECK("UserSectionEntityAdd - 6", "UserSectionBuild", status); /* =============================================================== *\ Add dimension for left line \* =============================================================== */ ent_id[0] = lt_line_id; pt_type[0] = PRO_ENT_WHOLE; place_pnt[0] = offsets[1] - 2.0; place_pnt[1] = offsets[0] + 25.0; ProUtil2DPointTrans(matrix_data.sec_trf, place_pnt, place_pnt); status = ProSecdimCreate(section, ent_id, pt_type, 1, PRO_TK_DIM_LINE, place_pnt, &ll_dim_id); ERROR_CHECK("ProSecdimCreate - 1", "UserSectionBuild", status); /* =============================================================== *\ Add dimension for top line \* =============================================================== */ ent_id[0] = top_line_id; pt_type[0] = PRO_ENT_WHOLE; place_pnt[0] = offsets[1] + 13.0; place_pnt[1] = offsets[0] + 52.0; ProUtil2DPointTrans(matrix_data.sec_trf, place_pnt, place_pnt); status = ProSecdimCreate(section, ent_id, pt_type, 1, PRO_TK_DIM_LINE, place_pnt, &tl_dim_id); ERROR_CHECK("ProSecdimCreate - 2", "UserSectionBuild", status); /* =============================================================== *\ Add dimension for upper arc \* =============================================================== */ ent_id[0] = upper_arc_id; pt_type[0] = PRO_ENT_WHOLE; place_pnt[0] = offsets[1] + 42.0; place_pnt[1] = offsets[0] + 42.0; ProUtil2DPointTrans(matrix_data.sec_trf, place_pnt, place_pnt); status = ProSecdimCreate(section, ent_id, pt_type, 1, PRO_TK_DIM_RAD, place_pnt, &ua_dim_id); ERROR_CHECK("ProSecdimCreate - 3", "UserSectionBuild", status); /* =============================================================== *\ Add dimension for lower arc \* =============================================================== */ ent_id[0] = lower_arc_id; pt_type[0] = PRO_ENT_WHOLE; place_pnt[0] = offsets[1] +42.0; place_pnt[1] = offsets[0] + 5.0; ProUtil2DPointTrans(matrix_data.sec_trf, place_pnt, place_pnt); status = ProSecdimCreate(section, ent_id, pt_type, 1, PRO_TK_DIM_RAD, place_pnt, &la_dim_id); ERROR_CHECK("ProSecdimCreate - 4", "UserSectionBuild", status); /* =============================================================== *\ Add section dimension between center line and left line \* =============================================================== */ c_ent_id[0] = ctr_line_id; c_ent_id[1] = lt_line_id; proj_pt_type[0] = PRO_ENT_WHOLE; proj_pt_type[1] = PRO_ENT_WHOLE; place_pnt[0] = offsets[1] - 2.0; place_pnt[1] = offsets[0] + 15.0; ProUtil2DPointTrans(matrix_data.sec_trf, place_pnt, place_pnt); status = ProSecdimCreate(section, c_ent_id, proj_pt_type, 2, PRO_TK_DIM_LINE_LINE, place_pnt, &cl_dim_id); ERROR_CHECK("ProSecdimCreate - 5", "UserSectionBuild", status); status = ProSecdimValueSet(section, cl_dim_id, offsets[1]); ERROR_CHECK("ProSecdimValueSet", "UserSectionBuild", status); /* =============================================================== *\ Add section dimension between center line and left projection entity \* =============================================================== */ proj_ent_id[0] = ctr_line_id; proj_ent_id[1] = proj_ids[1]; proj_pt_type[0] = PRO_ENT_WHOLE; proj_pt_type[1] = PRO_ENT_WHOLE; place_pnt[0] = -2.0; place_pnt[1] = 15.0; ProUtil2DPointTrans(matrix_data.sec_trf, place_pnt, place_pnt); status = ProSecdimCreate(section, proj_ent_id, proj_pt_type, 2, PRO_TK_DIM_LINE_LINE, place_pnt, &proj_dim_id[0]); ERROR_CHECK("ProSecdimCreate - 5", "UserSectionBuild", status); status = ProSecdimValueSet(section, proj_dim_id[0], 0.0); ERROR_CHECK("ProSecdimValueSet", "UserSectionBuild", status); /* =============================================================== *\ Add section dimension between bottom proj ent and bottom line \* =============================================================== */ proj_ent_id[0] = btm_line_id; proj_ent_id[1] = proj_ids[0]; proj_pt_type[0] = PRO_ENT_WHOLE; proj_pt_type[1] = PRO_ENT_WHOLE; place_pnt[0] = offsets[1] + 20.0; place_pnt[1] = offsets[0] - 3.0; ProUtil2DPointTrans(matrix_data.sec_trf, place_pnt, place_pnt); status = ProSecdimCreate(section, proj_ent_id, proj_pt_type, 2, PRO_TK_DIM_LINE_LINE, place_pnt, &proj_dim_id[1]); ERROR_CHECK("ProSecdimCreate - 6", "UserSectionBuild", status); status = ProSecdimValueSet(section, proj_dim_id[1], offsets[0]); ERROR_CHECK("ProSecdimValueSet", "UserSectionBuild", status); /* =============================================================== *\ Solve and regenerate the section \* =============================================================== */ status = ProSecerrorAlloc(&sec_errors); ERROR_CHECK("ProSecerrorAlloc", "UserSectionBuild", status); status = ProSectionSolve(section, &sec_errors); if (status != 0) { printf("ProSectionSolve returned %d\n", status); printf("See error file for more information\n\n"); status = ProSecerrorCount(&sec_errors, &num_errors); for(err_counter = 0; err_counter < num_errors; err_counter++) { status = ProSecerrorMsgGet(sec_errors, err_counter, wmsg); ProWstringToString(msg, wmsg); printf("Error %d message : %s\n", err_counter, msg); } ProSecerrorFree(&sec_errors); return(-1); } status = ProSectionRegenerate(section, &sec_errors); if (status != 0) { printf("ProSectionRegenerate returned %d\n", status); status = ProSecerrorCount(&sec_errors, &num_errors); for(err_counter = 0; err_counter < num_errors; err_counter++) { status = ProSecerrorMsgGet(sec_errors, err_counter, wmsg); ProWstringToString(msg, wmsg); printf("Error %d message : %s\n", err_counter, msg); } ProSecerrorFree(&sec_errors); return(-1); } status = ProSelectionFree(&(matrix_data.sk_plane)); ERROR_CHECK("ProSelectionFree", "UserSectionBuild", status); free(temp1); free(temp2); return(status); } /* =============================================================== *\ Function: UserSelectSketchPlaneRefs Purpose: Select references for sketch plane and orientation plane \* =============================================================== */ ProError UserSelectSketchPlaneRefs(ProSelection **sketch_refs) { ProSelection *sel; int num_sel; ProError status; if (temp1 == NULL) temp1 = (ProSelection *)calloc(2, sizeof(ProSelection)); ProStringToWstring(msgfile, "msg_ug3dsketch.txt"); status = ProMessageDisplay(msgfile, "USER Select sketch plane"); ERROR_CHECK("ProMessageDisplay", "UserSectionBuild", status); status = ProSelect("surface", 1, NULL, NULL, NULL, NULL, &sel, &num_sel); ERROR_CHECK("ProSelect", "UserSectionBuild", status); status = ProSelectionCopy(sel[0],&temp1[0]); ERROR_CHECK("ProSelectionCopy", "UserSectionBuild", status); status = ProMessageDisplay(msgfile, "USER Select top plane for orientation"); ERROR_CHECK("ProMessageDisplay", "UserSectionBuild", status); status = ProSelect("surface", 1, NULL, NULL, NULL, NULL, &sel, &num_sel); ERROR_CHECK("ProSelect", "UserSectionBuild", status); status = ProSelectionCopy(sel[0], &temp1[1]); ERROR_CHECK("ProSelectionCopy", "UserSectionBuild", status); *sketch_refs = temp1; return(status); } /* =============================================================== *\ Function: UserSelectProjectionEntities Purpose: Select projection entity references from existing geometry \* =============================================================== */ ProError UserSelectProjectionEntities(ProSelection **proj_refs) { ProSelection *sel; int num_sel; ProError status; if (temp2== NULL) temp2= (ProSelection *)calloc(2, sizeof(ProSelection)); /* =============================================================== *\ Prompt user to select reference geometry \* =============================================================== */ status = ProMessageDisplay(msgfile, "USER Select first projection reference (bottom edge of sketch plane)"); ERROR_CHECK("ProMessageDisplay", "UserSectionBuild", status); status = ProSelect("edge", 1, NULL, NULL, NULL, NULL, &sel, &num_sel); ERROR_CHECK("ProSelect", "UserSectionBuild", status); if (status != PRO_TK_NO_ERROR || num_sel < 1) return(status); status = ProSelectionCopy(sel[0], &temp2[0]); ERROR_CHECK("ProSelectionCopy", "UserSectionBuild", status); status = ProMessageDisplay(msgfile, "USER Select second projection reference (left edge of sketch plane)"); ERROR_CHECK("ProMessageDisplay", "UserSectionBuild", status); status = ProSelect("edge", 1, NULL, NULL, NULL, NULL, &sel, &num_sel); ERROR_CHECK("ProSelect", "UserSectionBuild", status); if (status != PRO_TK_NO_ERROR || num_sel < 1) return(status); status = ProSelectionCopy(sel[0], &temp2[1]); ERROR_CHECK("ProSelectionCopy", "UserSectionBuild", status); *proj_refs = temp2; return(status); } ProError UserSelectOffsetDistances(double *offset_vals) { ProError status; status = ProMessageDisplay(msgfile, "USER Enter offset distance from first projection reference"); ERROR_CHECK("ProMessageDisplay", "UserSelectOffsetDistances", status); status = ProMessageDoubleRead(NULL, &offset_vals[0]); ERROR_CHECK("ProMessageDoubleRead", "UserSelectOffsetDistances", status); status = ProMessageDisplay(msgfile, "USER Enter offset distance from second projection reference"); ERROR_CHECK("ProMessageDisplay", "UserSelectOffsetDistances", status); status = ProMessageDoubleRead(NULL, &offset_vals[1]); ERROR_CHECK("ProMessageDoubleRead", "UserSelectOffsetDistances", status); return(status); } ProError UserCreateTrfMatrix(Matrix_data *m_data) { ProPoint3d origin; double sel_pnt[3], proj_sel_pnt[3], sel_vect[3]; double x_plane[3]; ProVector x, y, sk_plane_norm; ProVector d1[2], d2[2], norm; int status; ProMatrix inv_sk_mtrx; ProModelitem sk_modelitem; ProSurface sk_surf; ProUvParam sk_param; /* =============================================================== *\ Project point selected on sketch plane onto section \* =============================================================== */ ProUtilMatrixInvert(m_data->sk_mtrx, inv_sk_mtrx); status = ProSelectionUvParamGet(m_data->sk_plane, sk_param); ERROR_CHECK("ProSelectionUvParamGet", "UserCreateTrfMatrix", status); status = ProSelectionModelitemGet(m_data->sk_plane, &sk_modelitem); ERROR_CHECK("ProSelectionModelitemGet", "UserCreateTrfMatrix", status); status = ProGeomitemToSurface((ProGeomitem *)&sk_modelitem, &sk_surf); ERROR_CHECK("ProGeomitemToSurface", "UserCreateTrfMatrix", status); status = ProSurfaceXyzdataEval(sk_surf, sk_param, sel_pnt, d1, d2, norm); ERROR_CHECK("ProSurfaceXyzdataEval", "UserCreateTrfMatrix", status); ProUtilPointTrans(inv_sk_mtrx, sel_pnt, proj_sel_pnt); proj_sel_pnt[2] = 0.0; /* =============================================================== *\ Create x and y vectors of transformation matrix such that selected point on sketch plane is in first quadrant \* =============================================================== */ ProUtilLineLineX(m_data->x_axis, m_data->y_axis, origin); ProUtilVectorDiff(proj_sel_pnt, origin, sel_vect); sel_vect[2] = 0.0; ProUtilVectorNormalize(sel_vect, sel_vect); ProUtilVectorDiff(m_data->x_axis[0], m_data->x_axis[1], x); ProUtilVectorNormalize(x, x); ProUtilVectorDiff(m_data->y_axis[0], m_data->y_axis[1], y); ProUtilVectorNormalize(y, y); /* ========= Selected point should be in first quadrant ======= */ if ((ProUtilVectorDot(x,sel_vect)) < 0.0) ProUtilVectorScale(-1.0, x, x); if ((ProUtilVectorDot(y,sel_vect)) < 0.0) ProUtilVectorScale(-1.0, y, y); /* ========= Make sure surface normal is properly oriented ======= */ /* ========= with respect to x and y ============================= */ ProUtilVectorCross(x, y, sk_plane_norm); ProUtilVectorTrans(m_data->sk_mtrx, sk_plane_norm, sk_plane_norm); ProUtilMatrixCopy(NULL, m_data->sec_trf); if ((ProUtilVectorDot(sk_plane_norm, m_data->sk_mtrx[2])) < 0.0) { ProUtilVectorCopy(y, m_data->sec_trf[0]); ProUtilVectorCopy(x, m_data->sec_trf[1]); ProUtilVectorCopy(NULL, m_data->sec_trf[2]); ProUtilVectorCopy(origin, m_data->sec_trf[3]); } else { ProUtilVectorCopy(x, m_data->sec_trf[0]); ProUtilVectorCopy(y, m_data->sec_trf[1]); ProUtilVectorCopy(NULL, m_data->sec_trf[2]); ProUtilVectorCopy(origin, m_data->sec_trf[3]); } m_data->sec_trf[2][2] = m_data->sec_trf[3][3] = 1.0; /* =============================================================== *\ Calculate rotation angle \* =============================================================== */ x_plane[0] = 1.0; x_plane[1] = x_plane[2] = 0.0; ProUtilVectorCross(x_plane, m_data->sk_mtrx[0], norm); ProUtilVectorCross(m_data->sec_trf[0], m_data->sec_trf[1], sk_plane_norm); m_data->angle = fabs(acos(ProUtilVectorDot(x_plane, m_data->sec_trf[0]))); if (ProUtilVectorDot(norm, sk_plane_norm) < 0.0) m_data->angle *= -1.0; return(status); }