cgma
|
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