cgma
FaceterFacetData.cpp
Go to the documentation of this file.
00001 #include "CubitFacet.hpp"
00002 #include "CubitPoint.hpp"
00003 #include "CubitPointData.hpp"
00004 #include "CubitVector.hpp"
00005 #include "GeometryDefines.h"
00006 #include "CubitPlane.hpp"
00007 #include "CubitFacetEdge.hpp"
00008 #include "FaceterFacetData.hpp"
00009 #include "CastTo.hpp"
00010 #include "ToolData.hpp"
00011 #include "GfxDebug.hpp"
00012 #include "CubitMessage.hpp"
00013 
00014 #ifndef CUBIT_MAX 
00015 #define CUBIT_MAX(a,b) (((a) > (b)) ? (a) : (b))
00016 #endif
00017 #ifndef CUBIT_MIN 
00018 #define CUBIT_MIN(a,b) (((a) < (b)) ? (a) : (b))
00019 #endif
00020 #define min3(a,b,c) CUBIT_MIN((CUBIT_MIN((a),(b))),(c))
00021 #define max3(a,b,c) CUBIT_MAX((CUBIT_MAX((a),(b))),(c))
00022 static int counter_id = 0;
00023 
00024 //===========================================================================
00025 //Function Name: FaceterFacetData
00026 //
00027 //Member Type:  PUBLIC
00028 //Description:  constructor
00029 //===========================================================================
00030 FaceterFacetData::FaceterFacetData( CubitPoint *p1, CubitPoint *p2,
00031                                     CubitPoint *p3 )
00032 {
00033   assert( p1 && p2 && p3 );
00034   assert( p1 != p2 && p1 != p3 && p2 != p3 );
00035   myOwner = NULL;
00036   pointArray[0] = p1;
00037   pointArray[1] = p2;
00038   pointArray[2] = p3;
00039   p1->add_facet(this);
00040   p2->add_facet(this);
00041   p3->add_facet(this);
00042 
00043   edgeArray[0] = NULL;
00044   edgeArray[1] = NULL;
00045   edgeArray[2] = NULL;
00046   edgeUse[0] = edgeUse[1] = edgeUse[2] = 0;
00047   patchCtrlPts = NULL;
00048 
00049   //CubitVector temp = normal();
00050   //cachedNormal = new CubitVector(temp);
00051   plane();
00052   counter_id++;
00053   entityId = counter_id;
00054 
00055   // define the bounding box
00056 
00057   CubitVector bbox_min, bbox_max;
00058   bbox_min.x(min3(p1->x(),p2->x(),p3->x()));
00059   bbox_min.y(min3(p1->y(),p2->y(),p3->y()));
00060   bbox_min.z(min3(p1->z(),p2->z(),p3->z()));
00061   bbox_max.x(max3(p1->x(),p2->x(),p3->x()));
00062   bbox_max.y(max3(p1->y(),p2->y(),p3->y()));
00063   bbox_max.z(max3(p1->z(),p2->z(),p3->z()));
00064   bBox.reset(bbox_min,bbox_max);
00065 
00066 }
00067 
00068 //===========================================================================
00069 //Function Name: ~FaceterFacetData
00070 //
00071 //Member Type:  PUBLIC
00072 //Description:  destructor
00073 //===========================================================================
00074 FaceterFacetData::~FaceterFacetData()
00075 {
00076 }
00077 
00078 
00079 //===========================================================================
00080 //Function Name: closest_point
00081 //
00082 //Member Type:  PUBLIC
00083 //Description:  return the closest point on plane defined by the facet
00084 //===========================================================================
00085 CubitStatus FaceterFacetData::closest_point(const CubitVector &point, 
00086                                           CubitVector &closest_point )
00087 {
00088   if( cachedPlane )
00089   {
00090     closest_point = cachedPlane->project( point );
00091     return CUBIT_SUCCESS;
00092   }
00093   
00094   CubitVector normal_vec = normal();
00095   CubitVector P0 = pointArray[0]->coordinates();
00096   CubitVector point_to_P0 = point - P0;
00097   CubitVector P0_to_projection;
00098   //Store the normal squared the the dot product of the normal and vector to the point.
00099   double normal_length_sq = normal_vec.length_squared();
00100   //If the normal is zero, get out!
00101   if ( normal_length_sq < CUBIT_RESABS )
00102      return CUBIT_FAILURE;
00103   double point_to_P0_dot_norm = point_to_P0%normal_vec;
00104   //Use P0_to_projection as a temporary to store half the equation.
00105   P0_to_projection = (point_to_P0_dot_norm/normal_length_sq)*normal_vec;
00106   P0_to_projection = point_to_P0 - P0_to_projection;
00107   //Now we have the vector from P0, to the closest point.  Add the vector 
00108   //to P0, and you have the location!
00109   closest_point = P0 + P0_to_projection;
00110   return CUBIT_SUCCESS;
00111 }
00112 
00113 //-------------------------------------------------------------------------
00114 // Purpose       : Local modification functions.
00115 //
00116 // Special Notes : 
00117 //
00118 // Creator       : Jason Kraftcheck
00119 //
00120 // Creation Date : 03/25/00
00121 //-------------------------------------------------------------------------
00122 CubitPoint* FaceterFacetData::split_edge( CubitPoint* edge1_pt, 
00123                                     CubitPoint* edge2_pt,
00124                                     const CubitVector& position )
00125 {
00126   CubitPointData* new_pt = new CubitPointData(position);
00127   
00128     // split triangles
00129   
00130   DLIList<CubitFacet*> facets;
00131   edge1_pt->shared_facets( edge2_pt, facets );
00132   
00133   facets.reset();
00134   for ( int i = facets.size(); i--; ) {
00135 
00136     CubitFacet* facet = facets.get_and_step();
00137     FaceterFacetData* facet_d = dynamic_cast<FaceterFacetData*>(facet);
00138     assert(!!facet_d);
00139    
00140  
00141       // fix up existing facet
00142     
00143     int pt2_index = facet->point_index( edge2_pt );
00144     bool edge_reversed = ( edge1_pt == facet->point( (pt2_index+1) % 3 ) );
00145     int edge_index = (pt2_index + 2 - edge_reversed) % 3;
00146     
00147     facet->update_plane();
00148     edge2_pt->remove_facet( facet );
00149     facet_d->set_point( new_pt, pt2_index );
00150     new_pt->add_facet( facet );
00151     
00152 
00153       // make new facet
00154       
00155     CubitPoint* other_pt = facet->point( edge_index );
00156     if ( edge_reversed )
00157       new FaceterFacetData( other_pt, edge2_pt, new_pt );
00158     else
00159       new FaceterFacetData( other_pt, new_pt, edge2_pt );
00160   }
00161        
00162   return new_pt; 
00163 }
00164 
00165 //-------------------------------------------------------------------------
00166 // Purpose       : insert a point into the facet
00167 //
00168 // Special Notes : create two new facets and return them
00169 //
00170 // Creator       : 
00171 //
00172 // Creation Date : 
00173 //-------------------------------------------------------------------------
00174 CubitPoint* FaceterFacetData::insert_point( const CubitVector& position,
00175                                           CubitFacet*& new_tri1,
00176                                           CubitFacet*& new_tri2 )  
00177 {
00178   if( DEBUG_FLAG(110 ) ) 
00179   {
00180     GfxDebug::draw_facet(this, CUBIT_WHITE_INDEX);
00181     GfxDebug::flush();
00182   }
00183   CubitPoint* new_point = (CubitPoint *) new CubitPointData( position );
00184   
00185   new_tri1 = (CubitFacet *)
00186     new FaceterFacetData( pointArray[1], pointArray[2], new_point );
00187   new_tri2 = (CubitFacet *)
00188     new FaceterFacetData( pointArray[2], pointArray[0], new_point );
00189   
00190   pointArray[2]->remove_facet( this );
00191   pointArray[2] = new_point;
00192   new_point->add_facet( this );
00193 
00194   if( DEBUG_FLAG(110) )
00195   {
00196     CubitVector temp_vector = new_point->coordinates();
00197     GfxDebug::draw_facet(this, CUBIT_MAGENTA_INDEX);
00198     GfxDebug::flush();
00199     GfxDebug::draw_facet(new_tri1, CUBIT_MAGENTA_INDEX);
00200     GfxDebug::flush();
00201     GfxDebug::draw_facet(new_tri2, CUBIT_MAGENTA_INDEX);
00202     GfxDebug::flush();
00203     GfxDebug::draw_point(temp_vector, CUBIT_CYAN_INDEX);
00204     GfxDebug::flush();
00205   }
00206   
00207   if( cachedPlane && 
00208       (cachedPlane->distance(position) > CUBIT_RESABS) )
00209   {
00210     delete cachedPlane;
00211     cachedPlane = 0;
00212   }
00213   
00214   if (isBackwards)
00215   {
00216     new_tri1->is_backwards( 1 );
00217     new_tri2->is_backwards( 1 );
00218   }
00219   return new_point;
00220 }
00221 
00222 
00223 //-------------------------------------------------------------------------
00224 // Purpose       : reorient the facet
00225 //
00226 // Special Notes :  This function should only be used if it is acceptable 
00227 //                  to change the underlying data representation of the 
00228 //                  facets  (for example the Sierra facet representation 
00229 //                  cannot change and will not permit changing of the
00230 //                  node orders on a facet) 
00231 //
00232 //                  Also note that if this function is used, the isBackwards
00233 //                  flag on the facet should be set appropriately.
00234 //
00235 // Creator       : Steve Owen
00236 //
00237 // Creation Date : 06/28/00
00238 //-------------------------------------------------------------------------
00239 void FaceterFacetData::flip()
00240 {
00241   CubitPoint *pt_tmp = pointArray[1];
00242   pointArray[1] = pointArray[2];
00243   pointArray[2] = pt_tmp;
00244 
00245   CubitFacetEdge *ed_tmp = edgeArray[1];
00246   edgeArray[1] = edgeArray[2];
00247   edgeArray[2] = ed_tmp;
00248 
00249   for (int ii=0; ii<3; ii++)
00250   {
00251     if (edgeUse[ii] == -1)
00252       edgeUse[ii] = 1;
00253     else if(edgeUse[ii] == 1)
00254       edgeUse[ii] = -1;
00255   }
00256   if (cachedPlane)
00257   {
00258     CubitVector normal = cachedPlane->normal();
00259     normal = -normal;
00260     cachedPlane->normal( normal );
00261   }
00262 }
00263 
00264 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines