cgma
TDFacetBoundaryEdge.cpp
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines