cgma
|
00001 //- Class: TDFacetBoundaryEdge 00002 //- Description: Tool data for storing additional information at 00003 //- the boundary of a facet set 00004 //- Owner: Steve Owen 00005 //- Checked by: 00006 //- Version: 00007 00008 #include "TDFacetBoundaryEdge.hpp" 00009 #include "TDFacetBoundaryPoint.hpp" 00010 #include "CubitFacetEdge.hpp" 00011 #include "CastTo.hpp" 00012 #include "CubitFacet.hpp" 00013 #include "CubitPoint.hpp" 00014 #include "FacetEvalTool.hpp" 00015 #include "ChollaDebug.hpp" 00016 #include "CubitMessage.hpp" 00017 TDFacetBoundaryEdge::TDFacetBoundaryEdge() 00018 { 00019 edgePtr = NULL; 00020 nextEdgePtr = NULL; 00021 prevEdgePtr = NULL; 00022 } 00023 00024 TDFacetBoundaryEdge::~TDFacetBoundaryEdge() 00025 { 00026 int ii; 00027 for (ii=0; ii<edgeDataList.size(); ii++) 00028 { 00029 BoundaryEdgeData *bed_ptr = edgeDataList.get_and_step(); 00030 delete bed_ptr; 00031 } 00032 } 00033 00034 00035 //------------------------------------------------------------------------- 00036 // Purpose : create a new facet boundary edge 00037 // 00038 // Special Notes : 00039 // 00040 // Creator : Steve Owen 00041 // 00042 // Creation Date : 05/01 00043 //------------------------------------------------------------------------- 00044 CubitStatus TDFacetBoundaryEdge::add_facet_boundary_edge( 00045 CubitFacetEdge *edge_ptr ) 00046 { 00047 ToolData *td; 00048 td = edge_ptr->get_TD(&TDFacetBoundaryEdge::is_facet_boundary_edge); 00049 if ( td == NULL ) 00050 { 00051 TDFacetBoundaryEdge *td_gm = new TDFacetBoundaryEdge; 00052 edge_ptr->add_TD( td_gm); 00053 td_gm->set_edge( edge_ptr ); 00054 } 00055 else 00056 { 00057 TDFacetBoundaryEdge *td_gm = CAST_TO(td, TDFacetBoundaryEdge); 00058 td_gm->set_edge( edge_ptr ); 00059 } 00060 return CUBIT_SUCCESS; 00061 } 00062 00063 //------------------------------------------------------------------------- 00064 // Purpose : get the facet boundary edge from an edge 00065 // 00066 // Special Notes : 00067 // 00068 // Creator : Steve Owen 00069 // 00070 // Creation Date : 05/01 00071 //------------------------------------------------------------------------- 00072 TDFacetBoundaryEdge* TDFacetBoundaryEdge::get_facet_boundary_edge( 00073 CubitFacetEdge *edge_ptr ) 00074 { 00075 ToolData *td; 00076 td = edge_ptr->get_TD(&TDFacetBoundaryEdge::is_facet_boundary_edge); 00077 if ( td != NULL ) 00078 { 00079 TDFacetBoundaryEdge *td_gm = CAST_TO(td, TDFacetBoundaryEdge); 00080 return td_gm; 00081 } 00082 return (TDFacetBoundaryEdge*) NULL; 00083 } 00084 00085 //------------------------------------------------------------------------- 00086 // Purpose : add facet representing a new surface adjacent this edge 00087 // 00088 // Special Notes : pass in a list of facets and pick the ones that have 00089 // this edge as one of its edges 00090 // 00091 // Creator : Steve Owen 00092 // 00093 // Creation Date : 05/01 00094 //------------------------------------------------------------------------- 00095 void TDFacetBoundaryEdge::add_surf_facet( DLIList<CubitFacet *> &facet_list) 00096 { 00097 CubitFacet *facet_ptr; 00098 int found = 0; 00099 int ii,jj; 00100 for (ii=0; ii< facet_list.size(); ii++) 00101 { 00102 facet_ptr = facet_list.get_and_step(); 00103 if (facet_ptr->edge( 0 ) == edgePtr || 00104 facet_ptr->edge( 1 ) == edgePtr || 00105 facet_ptr->edge( 2 ) == edgePtr) 00106 { 00107 // check if has already been added 00108 00109 found = 0; 00110 BoundaryEdgeData *bed_ptr; 00111 for (jj=0; jj<edgeDataList.size() && !found; jj++) 00112 { 00113 bed_ptr = edgeDataList.get_and_step(); 00114 if(bed_ptr->adjFacet == facet_ptr) 00115 { 00116 found = 1; 00117 } 00118 } 00119 if (!found) 00120 { 00121 // add a new bed and facet 00122 00123 BoundaryEdgeData *new_bed_ptr = new BoundaryEdgeData; 00124 new_bed_ptr->adjFacet = facet_ptr; 00125 new_bed_ptr->surfID = -1; 00126 edgeDataList.append( new_bed_ptr ); 00127 } 00128 } 00129 } 00130 } 00131 00132 //====================================================================== 00133 // Function: control_points (PUBLIC) 00134 // Description: set the Bezier control points on the edge. The first 00135 // and last control points are assumed to be the end points 00136 // of the edge, so they are not passed into this function. 00137 // order-1 points should be passed in. The order of the 00138 // bezier is returned. 00139 // Author: sjowen 00140 // Date: 8/00 00141 //====================================================================== 00142 void TDFacetBoundaryEdge::control_points( 00143 CubitVector *ctrl_pts, int order, int surf_id ) 00144 { 00145 assert(order<=4 && order >=0); 00146 int found = 0; 00147 BoundaryEdgeData *bed_ptr = NULL; 00148 for (int ii=0; ii<edgeDataList.size(); ii++) 00149 { 00150 bed_ptr = edgeDataList.get_and_step(); 00151 if(bed_ptr->surfID == surf_id) 00152 found = 1; 00153 } 00154 if (0 == found) { 00155 PRINT_ERROR("The surf_id does not match any in the list.\n"); 00156 return; 00157 } 00158 00159 int jj; 00160 for(jj=0; jj<order-1; jj++){ 00161 bed_ptr->bezierCtrlPts[jj] = ctrl_pts[jj]; 00162 } 00163 } 00164 00165 //====================================================================== 00166 // Function: control_points (PUBLIC) 00167 // Description: return the Bezier control points (including the end points) 00168 // The order of the bezier is returned. 00169 // Author: sjowen 00170 // Date: 8/00 00171 //====================================================================== 00172 int TDFacetBoundaryEdge::control_points( CubitVector *ctrl_pts, int surf_id ) 00173 { 00174 ctrl_pts[0] = edgePtr->point(0)->coordinates(); 00175 00176 int ii; 00177 int found = 0; 00178 BoundaryEdgeData *bed_ptr = NULL; 00179 for (ii=0; ii<edgeDataList.size(); ii++) 00180 { 00181 bed_ptr = edgeDataList.get_and_step(); 00182 if(bed_ptr->surfID == surf_id) 00183 found = 1; 00184 } 00185 if (0 == found) { 00186 PRINT_ERROR("The surf_id does not match any in the list.\n"); 00187 return -1; 00188 } 00189 00190 for(int i=0; i<3; i++) { 00191 ctrl_pts[i+1] = bed_ptr->bezierCtrlPts[i]; 00192 } 00193 ctrl_pts[4] = edgePtr->point(1)->coordinates(); 00194 return 4; 00195 } 00196 00197 //====================================================================== 00198 // Function: control_points (PUBLIC) 00199 // Description: return the control points on the edge of a facet based 00200 // on its edge use direction 00201 // Author: sjowen 00202 // Date: 8/00 00203 //====================================================================== 00204 CubitStatus TDFacetBoundaryEdge::control_points( 00205 CubitFacet *facet, CubitVector *ctrl_pts ) 00206 { 00207 // find the edge on the facet 00208 00209 int index = -1; 00210 CubitBoolean found = CUBIT_FALSE; 00211 for (int i=0; i<3 && !found; i++) { 00212 if (edgePtr == facet->edge(i)) { 00213 index = i; 00214 found = CUBIT_TRUE; 00215 } 00216 } 00217 if (!found) { 00218 return CUBIT_FAILURE; 00219 } 00220 00221 // locate the facet in the boundary edge data 00222 00223 found = CUBIT_FALSE; 00224 BoundaryEdgeData *bed_ptr = NULL; 00225 for (int ii=0; ii<edgeDataList.size(); ii++) 00226 { 00227 bed_ptr = edgeDataList.get_and_step(); 00228 if(bed_ptr->adjFacet == facet) 00229 found = CUBIT_TRUE; 00230 } 00231 if (!found) // the facet does not match any in the list 00232 return CUBIT_FAILURE; 00233 00234 // retreive the control points 00235 00236 switch (facet->edge_use(index)) { 00237 case 1: 00238 ctrl_pts[0] = edgePtr->point(0)->coordinates(); 00239 ctrl_pts[1] = bed_ptr->bezierCtrlPts[0]; 00240 ctrl_pts[2] = bed_ptr->bezierCtrlPts[1]; 00241 ctrl_pts[3] = bed_ptr->bezierCtrlPts[2]; 00242 ctrl_pts[4] = edgePtr->point(1)->coordinates(); 00243 break; 00244 case -1: 00245 ctrl_pts[0] = edgePtr->point(1)->coordinates(); 00246 ctrl_pts[1] = bed_ptr->bezierCtrlPts[2]; 00247 ctrl_pts[2] = bed_ptr->bezierCtrlPts[1]; 00248 ctrl_pts[3] = bed_ptr->bezierCtrlPts[0]; 00249 ctrl_pts[4] = edgePtr->point(0)->coordinates(); 00250 break; 00251 default: 00252 return CUBIT_FAILURE; 00253 } 00254 return CUBIT_SUCCESS; 00255 } 00256 00257 //====================================================================== 00258 // Function: get_control_points (PUBLIC) 00259 // Description: get control points oriented with respect to the 00260 // point_ptr (ie. point_ptr is the first control point 00261 // on the edge) 00262 // Note: only gets and sets the middle three control points. The 00263 // other 2 are the edge vertices. 00264 // Author: sjowen 00265 // Date: 05/01 00266 //====================================================================== 00267 void TDFacetBoundaryEdge::get_control_points( CubitPoint *point_ptr, 00268 CubitVector ctrl_pts[3], 00269 int surf_id ) 00270 { 00271 CubitBoolean found = CUBIT_FALSE; 00272 BoundaryEdgeData *bed_ptr = NULL; 00273 for (int ii=0; ii<edgeDataList.size(); ii++) 00274 { 00275 bed_ptr = edgeDataList.get_and_step(); 00276 if(bed_ptr->surfID == surf_id) 00277 found = CUBIT_TRUE; 00278 } 00279 if (0 == found) { 00280 PRINT_ERROR("The surf_id does not match any in the list.\n"); 00281 return; 00282 } 00283 00284 if (point_ptr == edgePtr->point(0)) 00285 { 00286 ctrl_pts[0] = bed_ptr->bezierCtrlPts[0]; 00287 ctrl_pts[1] = bed_ptr->bezierCtrlPts[1]; 00288 ctrl_pts[2] = bed_ptr->bezierCtrlPts[2]; 00289 } 00290 else if(point_ptr == edgePtr->point(1)) 00291 { 00292 ctrl_pts[0] = bed_ptr->bezierCtrlPts[2]; 00293 ctrl_pts[1] = bed_ptr->bezierCtrlPts[1]; 00294 ctrl_pts[2] = bed_ptr->bezierCtrlPts[0]; 00295 } 00296 else 00297 { 00298 assert(0); // point_ptr does not match either point 00299 } 00300 } 00301 00302 //====================================================================== 00303 // Function: set_control_points (PUBLIC) 00304 // Description: set control points oriented with respect to the 00305 // point_ptr (ie. point_ptr is the first control point 00306 // on the edge) 00307 // Note: only gets and sets the middle three control points. The 00308 // other 2 are the edge vertices. 00309 // Author: sjowen 00310 // Date: 05/01 00311 //====================================================================== 00312 void TDFacetBoundaryEdge::set_control_points( CubitPoint *point_ptr, 00313 CubitVector ctrl_pts[3], 00314 int surf_id ) 00315 { 00316 CubitBoolean found = CUBIT_FALSE; 00317 BoundaryEdgeData *bed_ptr = NULL; 00318 for (int ii=0; ii<edgeDataList.size(); ii++) 00319 { 00320 bed_ptr = edgeDataList.get_and_step(); 00321 if(bed_ptr->surfID == surf_id) 00322 found = CUBIT_TRUE; 00323 } 00324 if (0 == found) { 00325 PRINT_ERROR("The surf_id does not match any in the list.\n"); 00326 return; 00327 } 00328 00329 if (point_ptr == edgePtr->point(0)) 00330 { 00331 bed_ptr->bezierCtrlPts[0] = ctrl_pts[0]; 00332 bed_ptr->bezierCtrlPts[1] = ctrl_pts[1]; 00333 bed_ptr->bezierCtrlPts[2] = ctrl_pts[2]; 00334 } 00335 else if(point_ptr == edgePtr->point(1)) 00336 { 00337 bed_ptr->bezierCtrlPts[0] = ctrl_pts[2]; 00338 bed_ptr->bezierCtrlPts[1] = ctrl_pts[1]; 00339 bed_ptr->bezierCtrlPts[2] = ctrl_pts[0]; 00340 } 00341 else 00342 { 00343 assert(0); // point_ptr does not match either point 00344 } 00345 } 00346 00347 //------------------------------------------------------------------------- 00348 // Purpose : set the surface id of associated with one of the 00349 // facets adjacent to this edge 00350 // 00351 // Special Notes : 00352 // 00353 // Creator : Steve Owen 00354 // 00355 // Creation Date : 05/01 00356 //------------------------------------------------------------------------- 00357 void TDFacetBoundaryEdge::set_surf_id( CubitFacet *facet_ptr, int surf_id ) 00358 { 00359 int found = 0; 00360 int ii; 00361 BoundaryEdgeData *bed_ptr; 00362 for (ii=0; ii<edgeDataList.size() && !found; ii++) 00363 { 00364 bed_ptr = edgeDataList.get_and_step(); 00365 if (bed_ptr->adjFacet == facet_ptr) 00366 { 00367 found = 1; 00368 bed_ptr->surfID = surf_id; 00369 } 00370 } 00371 assert(found); // couldn't find the facet adjacent the surface 00372 } 00373 00374 //------------------------------------------------------------------------- 00375 // Purpose : determine if this edge is internal to the surface 00376 // (ie. surfID on both facets is the same) 00377 // 00378 // Special Notes : Assumes surface ids have been set 00379 // 00380 // Creator : Steve Owen 00381 // 00382 // Creation Date : 05/01 00383 //------------------------------------------------------------------------- 00384 CubitBoolean TDFacetBoundaryEdge::is_internal_edge() 00385 { 00386 if (edgeDataList.size() != 2) 00387 return CUBIT_FALSE; 00388 BoundaryEdgeData *bed0_ptr = edgeDataList.get_and_step(); 00389 BoundaryEdgeData *bed1_ptr = edgeDataList.get_and_step(); 00390 if (bed0_ptr->surfID == bed1_ptr->surfID) 00391 { 00392 return CUBIT_TRUE; 00393 } 00394 return CUBIT_FALSE; 00395 } 00396 00397 //=========================================================================== 00398 //Function Name: init_control_points 00399 // 00400 //Member Type: PRIVATE 00401 //Descriptoin: compute the control points for an edge 00402 //=========================================================================== 00403 CubitStatus TDFacetBoundaryEdge::init_control_points( double min_dot ) 00404 { 00405 int ii; 00406 CubitStatus stat = CUBIT_SUCCESS; 00407 CubitVector N0, N3; 00408 for (ii=0; ii<edgeDataList.size(); ii++) 00409 { 00410 // get the normals specific to this facet. 00411 00412 BoundaryEdgeData *bed_ptr = edgeDataList.get_and_step(); 00413 TDFacetBoundaryPoint *td_fbp0 = 00414 TDFacetBoundaryPoint::get_facet_boundary_point( edgePtr->point( 0 ) ); 00415 TDFacetBoundaryPoint *td_fbp1 = 00416 TDFacetBoundaryPoint::get_facet_boundary_point( edgePtr->point( 1 ) ); 00417 if (!td_fbp0 || !td_fbp1) 00418 return CUBIT_FAILURE; 00419 stat = td_fbp0->get_normal( bed_ptr->adjFacet, N0 ); 00420 if (stat != CUBIT_SUCCESS) 00421 return stat; 00422 td_fbp1->get_normal( bed_ptr->adjFacet, N3 ); 00423 if (stat != CUBIT_SUCCESS) 00424 return stat; 00425 00426 // determine the curve tangents 00427 00428 CubitVector T0, T3; 00429 int tool_id = bed_ptr->adjFacet->tool_id(); 00430 stat = compute_curve_tangent( tool_id, edgePtr, min_dot, T0, T3 ); 00431 if (stat != CUBIT_SUCCESS) 00432 return stat; 00433 00434 // init the control points 00435 00436 CubitVector P0 = edgePtr->point(0)->coordinates(); 00437 CubitVector P3 = edgePtr->point(1)->coordinates(); 00438 stat = FacetEvalTool::init_edge_control_points( P0, P3, N0, N3, T0, T3, 00439 bed_ptr->bezierCtrlPts ); 00440 if (stat != CUBIT_SUCCESS) 00441 return stat; 00442 } 00443 return CUBIT_SUCCESS; 00444 } 00445 00446 //=========================================================================== 00447 //Function Name: merge_control_points 00448 // 00449 //Member Type: PRIVATE 00450 //Descriptoin: merge the control points - find average location for all 00451 //=========================================================================== 00452 CubitStatus TDFacetBoundaryEdge::merge_control_points() 00453 { 00454 int ii, jj; 00455 CubitVector ctrl_pts[3]; 00456 for (ii=0; ii<edgeDataList.size(); ii++) 00457 { 00458 BoundaryEdgeData *bed_ptr = edgeDataList.get_and_step(); 00459 for (jj=0; jj<3; jj++) 00460 ctrl_pts[jj] += bed_ptr->bezierCtrlPts[jj]; 00461 } 00462 for (ii=0; ii<3; ii++) 00463 ctrl_pts[ii] = ctrl_pts[ii] / edgeDataList.size(); 00464 edgePtr->control_points( ctrl_pts, 4 ); 00465 return CUBIT_SUCCESS; 00466 } 00467 00468 //=========================================================================== 00469 //Function Name: compute_curve_tangent 00470 // 00471 //Member Type: PRIVATE 00472 //Descriptoin: compute the tangents to the endpoints of a feature edge. 00473 //=========================================================================== 00474 CubitStatus TDFacetBoundaryEdge::compute_curve_tangent( 00475 int tool_id, 00476 CubitFacetEdge *edge, 00477 double /*min_dot*/, 00478 CubitVector &T0, 00479 CubitVector &T3 ) 00480 { 00481 int mydebug = 0; 00482 00483 CubitPoint *p0 = edge->point( 0 ); 00484 CubitPoint *p1 = edge->point( 1 ); 00485 CubitFacetEdge *prev_edge = NULL; //next_feature_edge( tool_id, edge, p0 ); 00486 00487 //If ther is a previous edge that this one should be C1 with, get 00488 // it, and make this one C1 with it. 00489 if(get_prev_edge()){ 00490 prev_edge = get_prev_edge(); 00491 } 00492 00493 if (prev_edge == NULL) // could be end of a hard line 00494 { 00495 T0 = p1->coordinates() - p0->coordinates(); 00496 T0.normalize(); 00497 } 00498 else 00499 { 00500 00501 if(mydebug){ 00502 dcolor(CUBIT_WHITE_INDEX); 00503 dedraw(prev_edge); 00504 dcolor(CUBIT_MAGENTA_INDEX); 00505 dedraw(edge); 00506 dview(); 00507 } 00508 00509 CubitPoint *p2 = prev_edge->other_point( p0 ); 00510 if (p2) 00511 { 00512 T0 = (p0->coordinates() - p2->coordinates()) + 00513 (p1->coordinates() - p0->coordinates()); 00514 } 00515 else // fall back to chord 00516 { 00517 T0=p1->coordinates()-p0->coordinates(); 00518 } 00519 T0.normalize(); 00520 } 00521 00522 00523 CubitFacetEdge *next_edge = NULL; //next_feature_edge( tool_id, edge, p1 ); 00524 //If ther is a next edge that this one should be C1 with, get 00525 // it, and make this one C1 with it. 00526 if(get_next_edge()){ 00527 next_edge = get_next_edge(); 00528 } 00529 if (next_edge == NULL) // could be end of a hard line 00530 { 00531 T3 = p1->coordinates() - p0->coordinates(); 00532 T3.normalize(); 00533 } 00534 else 00535 { 00536 if(mydebug){ 00537 dcolor(CUBIT_YELLOW_INDEX); 00538 dedraw(next_edge); 00539 dcolor(CUBIT_GREEN_INDEX); 00540 dedraw(edge); 00541 dview(); 00542 } 00543 CubitPoint *p2 = next_edge->other_point( p1 ); 00544 if (p2) 00545 { 00546 T3 = (p2->coordinates() - p1->coordinates()) + 00547 (p1->coordinates() - p0->coordinates()); 00548 } 00549 else 00550 { 00551 T3 = p1->coordinates() - p0->coordinates(); 00552 } 00553 T3.normalize(); 00554 } 00555 00556 return CUBIT_SUCCESS; 00557 } 00558 00559 00560 //=========================================================================== 00561 //Function Name: next_feature_edge 00562 // 00563 //Member Type: PRIVATE 00564 //Descriptoin: given a facet boundary edge and one of its nodes, find the 00565 // next edge on the same surface 00566 //=========================================================================== 00567 CubitFacetEdge *TDFacetBoundaryEdge::next_feature_edge( 00568 int tool_id, 00569 CubitFacetEdge *this_edge, 00570 CubitPoint *p0 ) 00571 { 00572 CubitFacetEdge *next_edge = NULL; 00573 00574 DLIList<CubitFacetEdge*> edge_list; 00575 p0->edges( edge_list ); 00576 int ii; 00577 00578 CubitFacetEdge *edge_ptr = NULL; 00579 TDFacetBoundaryEdge *td_fbe; 00580 for (ii=0; ii<edge_list.size() && next_edge == NULL; ii++) 00581 { 00582 edge_ptr = edge_list.get_and_step(); 00583 if (edge_ptr != this_edge) 00584 { 00585 td_fbe = TDFacetBoundaryEdge::get_facet_boundary_edge( edge_ptr ); 00586 if (td_fbe != NULL && td_fbe->is_at_surf( tool_id )) 00587 { 00588 next_edge = edge_ptr; 00589 } 00590 } 00591 } 00592 00593 return next_edge; 00594 } 00595 00596 //=========================================================================== 00597 //Function Name: is_at_surf 00598 // 00599 //Member Type: PRIVATE 00600 //Descriptoin: return whether the given edge has one of its adjacent 00601 // faces on the given surface 00602 //=========================================================================== 00603 CubitBoolean TDFacetBoundaryEdge::is_at_surf( int surf_id ) 00604 { 00605 CubitBoolean found = CUBIT_FALSE; 00606 BoundaryEdgeData *bed_ptr; 00607 for (int ii=0; ii<edgeDataList.size() && !found; ii++) 00608 { 00609 bed_ptr = edgeDataList.get_and_step(); 00610 if(bed_ptr->surfID == surf_id || 00611 bed_ptr->adjFacet->tool_id() == surf_id) 00612 found = CUBIT_TRUE; 00613 } 00614 return found; 00615 }