The 3D ACIS® Modeler (ACIS) is Spatial’s prominent 3D solid modeling engine. 3D InterOp is a CAD data translation framework (Interoperability)
PHLV5 CPP Example 1
From DocR20
| Code. C++ Example 1 |
|---|
// system include files #include <stdlib.h> #include <string.h> // base header files #include "position.hxx" // kernel header files #include "acis.hxx" #include "api.hxx" #include "kernapi.hxx" #include "body.hxx" #include "transfrm.hxx" #include "curdef.hxx" // phlv5 header files #include "phlv5_api.hxx" #include "phlv5_opts.hxx" #include "phlv5_edge.hxx" #include "phlv5_seg.hxx" // error function static FILE *errorFile; void outcome_check(outcome res, char* string) { if (res.ok()) return; fprintf(errorFile,"%s: %s\n",string,find_err_mess(res.error_number())); } void main() { // Set the appropriate path errorFile = fopen("error.txt","w"); if (!errorFile) return; // Open SAT file; to run this you need a SAT file with this name in your working directory FILE *helpFile = fopen("sample.sat", "r"); if (!helpFile) return; // Initialize the modeler and the precise hidden line component outcome res = api_start_modeller(0); outcome_check(res, "error initializing modeler"); if (!res.ok()) return; res = api_initialize_hidden_line_removal(); outcome_check(res, "error initializing hidden line component"); if (!res.ok()) return; // Get the body from the SAT file ENTITY_LIST bodyList; res = api_restore_entity_list(helpFile, TRUE, bodyList); outcome_check(res, "error restoring bodyList"); fclose(helpFile); // If we have a good SAT file; than do a precise hidden line if (res.ok()) { // Set up viewing data SPAposition eyePos(0.0, 0.0, 1e10); // eye position SPAposition targetPos(0.0, 0.0, 0.0); // target position logical pFlag = 0; // perspective/parallel view // Token's can be passed into the API to inact persistence of the phl data; 0 means no persistence int token = 0; // Specify PHLV5 options ... logical self_calibrate_resolutions = TRUE; // this is default; we will calculate the general and // sag resolutions for you based on model extents double smooth_cosine = 0.95; // default is 0.00 which means do not detect any smooth lines // we wish to pick-up smooth lines so use this value as the cosine // of the angle between the two edges logical use_surface_approximations = TRUE; // this is default; we use the surface approximations to speed // up the hidden line algorithm phlv5_options *phlv5Opt = new phlv5_options(); phlv5Opt->set_self_calibrate(self_calibrate_resolutions); phlv5Opt->set_smooth_cosine(smooth_cosine); phlv5Opt->set_self_approx_surface(use_surface_approximations); // Note: the "set_hidden_line_style" is not an option used by the C++ API // Calculate the precise hidden line ENTITY_LIST edgeList; res = api_phlv5_compute(bodyList, token, eyePos, targetPos, pFlag, edgeList, phlv5Opt); outcome_check(res,"error computing phlv5"); ACIS_DELETE phlv5Opt; // If the result is OK, anaylize the output if (res.ok()) { // Open up a file pointer to dump hidden line data FILE* dfp = fopen("hidden_line_data.txt", "w"); // Loop through the PHLV5_EDGE(s) for (int edge_index = 0; edge_index < edgeList.count(); edge_index++) { PHLV5_EDGE* phlv5Edge = (PHLV5_EDGE*) edgeList[edge_index]; // Process the segment data ENTITY_LIST segList; phlv5Edge->GetSegmentList(segList); // Even though we loop here, on the current version of phlv5 there is only // one segment per edge. Write your application to loop however. for (int seg_index = 0; seg_index < segList.count(); seg_index++) { PHLV5_SEGMENT* seg = (PHLV5_SEGMENT*) segList[seg_index]; if (seg == 0) continue; fprintf(dfp, "Segment: \n"); // Visibility Information ... fprintf(dfp, "Visibility: "); if (seg->visibility() == PHLV5_SEGMENT_VIS) fprintf(dfp, "Visible\n"); if (seg->visibility() == PHLV5_SEGMENT_OCC) fprintf(dfp, "Occluded\n"); if (seg->visibility() == PHLV5_SEGMENT_HID) fprintf(dfp, "Hidden\n"); if (seg->visibility() == PHLV5_SEGMENT_VIS_SMOOTH) fprintf(dfp, "Visible Smooth\n"); if (seg->visibility() == PHLV5_SEGMENT_HID_SMOOTH) fprintf(dfp, "Hidden Smooth\n"); // State Information ... fprintf(dfp, "In/Out Bit: "); if (seg->state() == PHLV5_SEGMENT_INN) fprintf(dfp, "In\n"); if (seg->state() == PHLV5_SEGMENT_OUT) fprintf(dfp, "Out\n"); // Curve information; only call the curve if you absolutely need // a true modeling curve. This is a performance hit if this phlv5 edge // happens to be a silhouette line. Use the polyline data for quick and // fast rendering. CURVE* curvePtr = phlv5Edge->GetCurve(); // First make sure we did not return a NULL curve if (curvePtr != NULL) { // Get the visibility parameters - this is the start // and end of the visibility segment of the curve SPAparameter start_parm = seg->start_pt(); SPAparameter end_parm = seg->end_pt(); // Check for a reversed edge if (phlv5Edge->GetSense() > 0) { SPAparameter temp = - start_parm; start_parm = - end_parm; end_parm = temp; } // Evaluate the curve at the start, middle and end of // it's visibility curve const &curve = curvePtr->equation(); SPAposition start = curve.eval_position(start_parm); SPAposition middle = curve.eval_position((start_parm + end_parm) / 2.0); SPAposition end = curve.eval_position(end_parm); // Apply any body transformation BODY* bodyPtr = phlv5Edge->GetBody(); SPAtransf sketch_transform; if (bodyPtr->transform()) sketch_transform = bodyPtr->transform()->transform(); start *= sketch_transform; middle *= sketch_transform; end *= sketch_transform; // Remember these positions are in world coordinates; you will need to have the view of your // display set to the same view that the api_phlv5_compute received as a calculation view fprintf(dfp, "Curve evaluation positions: \n"); fprintf(dfp, "Start position: %lf %lf %lf\n", start.x(), start.y(), start.z()); fprintf(dfp, "Middle position: %lf %lf %lf\n", middle.x(), middle.y(), middle.z()); fprintf(dfp, "End position: %lf %lf %lf\n", end.x(), end.y(), end.z()); } } // We can also get polyline data back from the phlv5 edge. This is // the fastest way to render your model. Note, we do not have to // apply any body transformation to it. However, it is still in // world coordinates. float* f_pts; int n; n = phlv5Edge->GetNPoints(); f_pts = phlv5Edge->GetTabPoint(); fprintf(dfp, "Polyline positions: \n"); // We will only write the first and last positions to file if (n > 0) { fprintf(dfp, "Start position: %lf %lf %lf\n", f_pts[0], f_pts[1], f_pts[2]); fprintf(dfp, "End position: %lf %lf %lf\n", f_pts[(n-1)*3], f_pts[(n-1)*3+1], f_pts[(n-1)*3+2]); } // Note: we do not delete the f_pts } fclose(dfp); } // If we did not pass in a token to make the phlv5 data persistent - we // want to delete these entities if (token == 0) { for (int index = 0; index < edgeList.count(); index++) api_del_entity((ENTITY*)edgeList[index]); } edgeList.clear(); } // Delete our model for (int index = 0;index < bodyList.count();index++) { res = api_del_entity(bodyList[index]); outcome_check(res,"error deleting body from bodyList"); } bodyList.clear(); // Terminate the component, stop the modeler and shut down res = api_terminate_hidden_line_removal(); outcome_check(res,"error terminating hidden line component"); res = api_stop_modeller(); outcome_check(res,"error stopping modeler"); fclose(errorFile); exit(0); } |
