cgma
|
00001 #include "PST_Data.hpp" 00002 #include "GMem.hpp" 00003 #include "GfxDebug.hpp" 00004 #include "GeometryDefines.h" 00005 #include "CubitMessage.hpp" 00006 00007 #define PST_MAX_LIST_LEN 1000 00008 // Used only for debugging. Has no effect 00009 // if compiled -DNDEBUG. 00010 00011 const double RESABS_SQR = GEOMETRY_RESABS * GEOMETRY_RESABS; 00012 00013 00014 /************************************************************************* 00015 * PST_Point 00016 ************************************************************************/ 00017 00018 PST_Point::~PST_Point() 00019 { 00020 while( edge_ ) 00021 delete edge_; 00022 } 00023 00024 PST_Edge* PST_Point::common( PST_Point* pt ) 00025 { 00026 if( edge_ ) 00027 { 00028 #ifndef NDEBUG 00029 int debug = 0; 00030 #endif 00031 00032 PST_Edge* e = edge_; 00033 do 00034 { 00035 if( e->other(pt) == this ) 00036 return e; 00037 e = next( e ); 00038 00039 #ifndef NDEBUG 00040 assert( ++debug < PST_MAX_LIST_LEN ); 00041 #endif 00042 } while( e && e != edge_ ); 00043 } 00044 return 0; 00045 } 00046 00047 00048 int PST_Point::faces( DLIList<PST_Face*>* list ) 00049 { 00050 int count = 0; 00051 if( edge() ) 00052 { 00053 PST_Edge* e = edge(); 00054 do 00055 { 00056 if (e->forward()->face()) 00057 e->forward()->face()->private_mark_ = true; 00058 if (e->reverse()->face()) 00059 e->reverse()->face()->private_mark_ = true; 00060 e = e->next(this); 00061 } while( e != edge() ); 00062 00063 do 00064 { 00065 if( e->forward()->face() && e->forward()->face()->private_mark_ ) 00066 { 00067 count++; 00068 e->forward()->face()->private_mark_ = false; 00069 if( list ) list->append(e->forward()->face()); 00070 } 00071 if( e->reverse()->face() && e->reverse()->face()->private_mark_ ) 00072 { 00073 count++; 00074 e->reverse()->face()->private_mark_ = false; 00075 if( list ) list->append(e->reverse()->face()); 00076 } 00077 e = e->next(this); 00078 } while( e != edge() ); 00079 } 00080 00081 return count; 00082 } 00083 00084 /************************************************************************* 00085 * PST_Face 00086 ************************************************************************/ 00087 00088 void PST_Face::append_points( DLIList<PST_Point*>& result_list ) 00089 { 00090 PST_CoEdge* ce = coedge_; 00091 #ifndef NDEBUG 00092 int debug = 0; 00093 #endif 00094 do 00095 { 00096 result_list.append( ce->end_point() ); 00097 ce = ce->next(); 00098 00099 #ifndef NDEBUG 00100 assert( ++debug < PST_MAX_LIST_LEN ); 00101 #endif 00102 } while( ce != coedge_ ); 00103 } 00104 00105 PST_Point* PST_Face::opposite( PST_Edge* edge ) 00106 { 00107 PST_CoEdge* ce = coedge_; 00108 #ifndef NDEBUG 00109 int debug = 0; 00110 #endif 00111 do 00112 { 00113 if( ce->edge() == edge ) 00114 return ce->next()->end_point(); 00115 ce = ce->next(); 00116 00117 #ifndef NDEBUG 00118 assert( ++debug < PST_MAX_LIST_LEN ); 00119 #endif 00120 } while( ce != coedge_ ); 00121 00122 return 0; 00123 } 00124 00125 PST_Edge* PST_Face::opposite( PST_Point* point ) 00126 { 00127 PST_CoEdge* ce = coedge_; 00128 #ifndef NDEBUG 00129 int debug = 0; 00130 #endif 00131 do 00132 { 00133 if( ce->start_point() == point ) 00134 return ce->next()->edge(); 00135 ce = ce->next(); 00136 00137 #ifndef NDEBUG 00138 assert( ++debug < PST_MAX_LIST_LEN ); 00139 #endif 00140 } while( ce != coedge_ ); 00141 00142 return 0; 00143 } 00144 00145 bool PST_Face::two_edges( PST_Point* point, PST_Edge*& e1, PST_Edge*& e2 ) 00146 { 00147 e1 = e2 = 0; 00148 PST_CoEdge* ce = coedge_; 00149 #ifndef NDEBUG 00150 int debug = 0; 00151 #endif 00152 do 00153 { 00154 if( ce->end_point() == point ) 00155 { 00156 if( e1 || e2 ) 00157 return false; 00158 e1 = ce->edge(); 00159 e2 = ce->next()->edge(); 00160 } 00161 ce = ce->next(); 00162 00163 #ifndef NDEBUG 00164 assert( ++debug < PST_MAX_LIST_LEN ); 00165 #endif 00166 } while( ce != coedge_ ); 00167 00168 return e1 && e2; 00169 } 00170 00171 00172 bool PST_Face::calculate_plane() 00173 { 00174 update_plane_ = 0; 00175 00176 // Use Newell's method 00177 00178 CubitVector dif, sum, ref(0.,0.,0.); 00179 CubitVector norm(0.,0.,0.); 00180 00181 // For each coedge... 00182 00183 PST_CoEdge* ce = coedge_; 00184 int count = 0; 00185 do 00186 { 00187 count++; 00188 const CubitVector& pt1 = ce->start_coord(); 00189 const CubitVector& pt2 = ce->end_coord(); 00190 dif = pt2 - pt1; 00191 sum = pt2 + pt1; 00192 ref += pt1; 00193 norm += CubitVector( dif.y()*sum.z(), dif.z()*sum.x(), dif.x()*sum.y() ); 00194 ce = ce->next(); 00195 00196 assert( count < PST_MAX_LIST_LEN ); 00197 } while( ce != coedge_ ); 00198 00199 // Degenerate? 00200 00201 double len = norm.length(); 00202 if( len > CUBIT_RESABS ) 00203 { 00204 double d = (ref % norm) / (count * len); 00205 norm /= -len; //reverse and normalize 00206 00207 plane_.normal( norm ); 00208 plane_.coefficient( d ); 00209 00210 return true; 00211 } 00212 else 00213 { 00214 plane_.normal( CubitVector(0.,0.,0.) ); 00215 plane_.coefficient( 0. ); 00216 00217 return false; 00218 } 00219 } 00220 00221 00222 00223 /************************************************************************* 00224 * PST_CoEdge 00225 ************************************************************************/ 00226 PST_CoEdge* PST_CoEdge::previous() 00227 { 00228 if( !next_ ) 00229 return 0; 00230 00231 PST_CoEdge* coedge = this; 00232 #ifndef NDEBUG 00233 int debug = 0; 00234 #endif 00235 while( coedge->next_ != this ) 00236 { 00237 coedge = coedge->next_; 00238 #ifndef NDEBUG 00239 assert( ++debug < PST_MAX_LIST_LEN ); 00240 #endif 00241 } 00242 return coedge; 00243 } 00244 00245 /************************************************************************* 00246 * PST_Edge 00247 ************************************************************************/ 00248 00249 PST_Edge::~PST_Edge() 00250 { 00251 // Update list "head" pointers on points, if necessary. 00252 if( start_point() ) 00253 remove_start_point(); 00254 if( end_point() ) 00255 remove_end_point(); 00256 00257 // Destroy parent facets 00258 for ( int i = 0; i < 2; i++ ) 00259 { 00260 PST_CoEdge* coedge = i ? reverse() : forward(); 00261 if ( coedge->face() ) 00262 { 00263 PST_Face* face = coedge->face(); 00264 face->coedge_ = 0; 00265 00266 PST_CoEdge* first = coedge; 00267 do { 00268 assert(coedge->face() == face); 00269 coedge->face_ = 0; 00270 PST_CoEdge* next = coedge->next(); 00271 coedge->next_ = 0; 00272 coedge = next; 00273 } while( first != coedge ); 00274 delete face ; 00275 } 00276 } 00277 } 00278 00279 double PST_Edge::closest_on_line( const CubitVector& P ) 00280 { 00281 CubitVector B = start_coord(); 00282 CubitVector M = end_coord() - B; 00283 if( M.length_squared() < RESABS_SQR ) 00284 return 0.0; 00285 return ( M % ( P - B ) ) / ( M % M ); 00286 } 00287 00288 double PST_Edge::closest_on_edge( const CubitVector& p ) 00289 { 00290 double t = closest_on_line( p ); 00291 if( t < 0.0 ) 00292 t = 0.0; 00293 else if( t > 1.0 ) 00294 t = 1.0; 00295 return t; 00296 } 00297 00298 double PST_Edge::closest_on_line( const CubitVector& B2, 00299 const CubitVector& M2 ) 00300 { 00301 CubitVector B1 = start_coord(); 00302 CubitVector M1 = direction(); 00303 00304 if( M1.length_squared() < RESABS_SQR ) 00305 return 0.0; 00306 00307 if( M2.length_squared() < RESABS_SQR ) 00308 return closest_on_line( B2 ); 00309 00310 CubitVector cross = M2 * M1; 00311 if( cross.length_squared() < CUBIT_RESABS ) //parallel 00312 return 0.0; 00313 00314 CubitVector N = M2 * cross; 00315 double D = -( N % B2 ); 00316 return -( N % B1 + D ) / ( N % M1 ); 00317 } 00318 00319 00320 PST_Edge* PST_Edge::other( PST_Point* point, PST_Face* face ) 00321 { 00322 PST_Edge *result = 0; 00323 for( PST_Edge* e = point->next(this); e != this; e = point->next(e) ) 00324 { 00325 if( e->forward()->face() == face || e->reverse()->face() == face ) 00326 { 00327 if( result && result != e ) 00328 return 0; 00329 result = e; 00330 } 00331 } 00332 return result; 00333 } 00334 00335 /************************************************************************* 00336 * Construction Methods 00337 ************************************************************************/ 00338 00339 PST_Face* PST_Edge::create_face( PST_Point* pt1, PST_Point* pt2, PST_Point* pt3 ) 00340 { 00341 // It is trivial to generalize this function for creating 00342 // faces with an arbitrary number of sides, but I just 00343 // want triangles. 00344 const int size = 3; 00345 PST_Point* p[size] = { pt1, pt2, pt3 }; 00346 00347 int i; 00348 PST_Edge* e[size]; 00349 PST_CoEdge* c[size]; 00350 00351 // Initialize edge and coedge arrays, creating 00352 // edges if necessary. 00353 for( i = 0; i < size; i++ ) 00354 { 00355 e[i] = p[i]->common( p[(i+1)%size] ); 00356 if( !e[i] ) 00357 { 00358 e[i] = new PST_Edge( p[i], p[(i+1)%size] ); 00359 c[i] = e[i]->forward(); 00360 } 00361 else 00362 { 00363 c[i] = e[i]->start_point() == p[i] ? e[i]->forward() : e[i]->reverse(); 00364 00365 // If the co-edge in the appropriate direction is already 00366 // part of a face (other than the boundary face), then we 00367 // can't proceed. 00368 // if( !c[i]->face()->boundary() ) 00369 if( c[i]->face() ) 00370 { 00371 while( --i >= 0 ) 00372 if( ! c[i]->face() ) 00373 delete e[i]; 00374 return 0; 00375 } 00376 } 00377 } 00378 00379 PST_Face* result = new PST_Face( c[0] ); 00380 for ( i = 0; i < size; i++ ) 00381 { 00382 int next = (i + 1) % size; 00383 c[i]->face_ = result; 00384 c[i]->next_ = c[next]; 00385 } 00386 return result; 00387 00388 } 00389 00390 00391 PST_Edge* PST_Edge::split_face( PST_Point* start, PST_Point* end, PST_Face* face ) 00392 { 00393 if( !start->edge_ || !end->edge_ ) 00394 return 0; 00395 00396 if( ! face ) 00397 { 00398 PST_Edge* start_edge = start->edge(); 00399 do 00400 { 00401 PST_Face* curr_face = start_edge->forward()->face(); 00402 PST_Face* rev_face = start_edge->reverse()->face(); 00403 while( true ) 00404 { 00405 PST_CoEdge* coe = curr_face->coedge_; 00406 do 00407 { 00408 if( coe->other( end ) ) 00409 { 00410 if( face ) return 0; 00411 00412 face = curr_face; 00413 curr_face = rev_face; 00414 break; 00415 } 00416 coe = coe->next(); 00417 } while( coe != curr_face->coedge_ ); 00418 00419 if( curr_face == rev_face ) 00420 break; 00421 else 00422 curr_face = rev_face; 00423 } 00424 00425 start_edge = start_edge->next(start); 00426 } while( start_edge != start->edge() ); 00427 00428 if( !face ) return 0; 00429 } 00430 00431 PST_CoEdge* start_coedge = 0; 00432 PST_CoEdge* end_coedge = 0; 00433 00434 PST_CoEdge* coedge = face->coedge_; 00435 do 00436 { 00437 if( coedge->end_point() == start ) 00438 { 00439 start_coedge = coedge; 00440 break; 00441 } 00442 coedge = coedge->next(); 00443 } while( coedge != face->coedge_ ); 00444 00445 if( ! start_coedge ) 00446 return 0; 00447 00448 coedge = start_coedge->next(); 00449 PST_CoEdge* stop = start_coedge; 00450 do 00451 { 00452 if( coedge->end_point() == start ) 00453 { 00454 start_coedge = coedge; 00455 } 00456 00457 if( coedge->end_point() == end ) 00458 { 00459 end_coedge = coedge; 00460 break; 00461 } 00462 00463 coedge = coedge->next(); 00464 } while( coedge != stop ); 00465 00466 if( ! end_coedge ) 00467 return 0; 00468 00469 00470 return split_face( start_coedge, end_coedge ); 00471 } 00472 00473 PST_Edge* PST_Edge::split_face( PST_CoEdge* coedge1, PST_CoEdge* coedge2 ) 00474 { 00475 PST_Point* point1 = coedge1->end_point(); 00476 PST_Point* point2 = coedge2->end_point(); 00477 00478 if( (coedge1->edge() == coedge2->edge() ) || 00479 (coedge1->face() != coedge2->face() ) || 00480 (point1 == point2 ) || 00481 ( point1->common( point2 ) ) ) 00482 return 0; 00483 00484 PST_Edge* new_edge = new PST_Edge( point1, point2 ); 00485 new_edge->forward_.next_ = coedge2->next_; 00486 new_edge->reverse_.next_ = coedge1->next_; 00487 coedge1->next_ = new_edge->forward(); 00488 coedge2->next_ = new_edge->reverse(); 00489 00490 PST_Face* old_face = coedge1->face(); 00491 PST_Face* new_face = new PST_Face( new_edge->forward(), old_face ); 00492 //new_face->boundary(0); 00493 old_face->coedge_ = new_edge->reverse(); 00494 new_edge->reverse_.face_ = old_face; 00495 00496 coedge1 = new_edge->forward(); 00497 do 00498 { 00499 coedge1->face_ = new_face; 00500 coedge1 = coedge1->next(); 00501 } while( coedge1 != new_edge->forward() ); 00502 00503 return new_edge; 00504 } 00505 00506 00507 PST_Edge* PST_Edge::insert_in_face( PST_Point* end, 00508 PST_CoEdge* after_this ) 00509 { 00510 if( end->edge_ ) 00511 return 0; 00512 00513 PST_Point* start = after_this->end_point(); 00514 PST_Edge* new_edge = new PST_Edge( start, end ); 00515 new_edge->forward_.next_ = new_edge->reverse(); 00516 new_edge->reverse_.next_ = after_this->next_; 00517 new_edge->forward_.face_ = new_edge->reverse_.face_ = after_this->face_; 00518 after_this->next_ = new_edge->forward(); 00519 after_this->face_->modified(true); 00520 return new_edge; 00521 } 00522 00523 00524 PST_Edge* PST_Edge::split( PST_Point* point ) 00525 { 00526 if( point->edge_ ) 00527 return 0; 00528 00529 PST_Edge* new_edge = new PST_Edge( point, end_ ); 00530 00531 if (forward()->face()) { 00532 new_edge->forward_.face_ = forward_.face_; 00533 new_edge->forward_.next_ = forward_.next_; 00534 forward_.next_ = new_edge->forward(); 00535 forward_.face_->modified(true); 00536 } 00537 if (reverse()->face()) { 00538 new_edge->reverse_.face_ = reverse_.face_; 00539 new_edge->reverse_.next_ = reverse(); 00540 reverse_.previous()->next_ = new_edge->reverse(); 00541 reverse_.face_->modified(true); 00542 } 00543 00544 set_end_point(point); 00545 00546 return new_edge; 00547 } 00548 00549 00550 void PST_Edge::set_point( PST_Point* pt, 00551 PST_Point*& ptr, 00552 PST_Edge*& next ) 00553 { 00554 if( ptr ) 00555 remove_point( ptr, next ); 00556 00557 00558 if( pt->edge_ ) 00559 { 00560 if( pt->edge()->start_point() == pt ) 00561 { 00562 next = pt->edge()->start_next_; 00563 pt->edge()->start_next_ = this; 00564 } 00565 else 00566 { 00567 assert( pt->edge()->end_point() == pt ); 00568 next = pt->edge()->end_next_; 00569 pt->edge()->end_next_ = this; 00570 } 00571 } 00572 else 00573 { 00574 next = this; 00575 pt->edge_ = this; 00576 } 00577 00578 ptr = pt; 00579 } 00580 00581 void PST_Edge::remove_point( PST_Point*& ptr, PST_Edge*& next ) 00582 { 00583 if( next == this ) 00584 { 00585 ptr->edge_ = 0; 00586 next= 0; 00587 ptr = 0; 00588 return; 00589 } 00590 00591 PST_Edge* prev = next; 00592 while( prev->next(ptr) != this ) 00593 { 00594 prev = prev->next(ptr); 00595 assert( prev != next ); 00596 } 00597 00598 if( prev->start_next_ == this ) 00599 { 00600 prev->start_next_ = next; 00601 } 00602 else 00603 { 00604 assert(prev->end_next_ == this); 00605 prev->end_next_ = next; 00606 } 00607 00608 if( ptr->edge_ == this ) 00609 ptr->edge_ = next; 00610 } 00611 00612 00613 void PST_Point::debug_draw( int color, bool flush ) 00614 { 00615 GfxDebug::draw_point( float(x()), float(y()), float(z()), color ); 00616 if( flush ) 00617 GfxDebug::flush(); 00618 } 00619 00620 void PST_Edge::debug_draw( int color, bool flush ) 00621 { 00622 GfxDebug::draw_line( 00623 float(start_coord().x()), float(start_coord().y()), float(start_coord().z()), 00624 float( end_coord().x()), float( end_coord().y()), float( end_coord().z()), 00625 color ); 00626 if( flush ) GfxDebug::flush(); 00627 } 00628 00629 void PST_Face::debug_draw( int color, bool flush ) 00630 { 00631 PST_CoEdge* coedge = first_coedge(); 00632 do 00633 { 00634 coedge->edge()->debug_draw( color, false ); 00635 coedge = coedge->next(); 00636 } while( coedge != first_coedge() ); 00637 if( flush ) GfxDebug::flush(); 00638 } 00639 00640 void PST_Edge::make_gmem( GMem& gmem, DLIList<PST_Face*>& facets ) 00641 { 00642 DLIList<PST_Point*> point_list, temp_list; 00643 int i, j, pcount, fcount; 00644 00645 for( i = facets.size(); i--; ) 00646 { 00647 PST_Face* facet = facets.get_and_step(); 00648 // if( facet->boundary() ) 00649 // continue; 00650 00651 temp_list.clean_out(); 00652 facet->append_points( temp_list ); 00653 for( j = temp_list.size(); j--; ) 00654 { 00655 temp_list.get_and_step()->mark = -1; 00656 } 00657 } 00658 00659 pcount = 0; 00660 fcount = 0; 00661 for( i = facets.size(); i--; ) 00662 { 00663 PST_Face* facet = facets.get_and_step(); 00664 // if( facet->boundary() ) 00665 // continue; 00666 00667 temp_list.clean_out(); 00668 facet->append_points( temp_list ); 00669 fcount += temp_list.size() + 1; 00670 for( j = temp_list.size(); j--; ) 00671 { 00672 PST_Point* pt_ptr = temp_list.get_and_step(); 00673 if( pt_ptr->mark == -1 ) 00674 { 00675 pt_ptr->mark = pcount++; 00676 point_list.append( pt_ptr ); 00677 } 00678 } 00679 } 00680 00681 gmem.allocate_tri( facets.size() ); 00682 gmem.pointListCount = point_list.size(); 00683 GPoint* pt_array = gmem.point_list(); 00684 00685 point_list.reset(); 00686 for( i = 0; i < point_list.size(); i++ ) 00687 { 00688 PST_Point* pt_ptr = point_list.get_and_step(); 00689 pt_array[i].x = float(pt_ptr->x()); 00690 pt_array[i].y = float(pt_ptr->y()); 00691 pt_array[i].z = float(pt_ptr->z()); 00692 } 00693 00694 gmem.fListCount = facets.size() * 4; 00695 int* offset = gmem.facet_list(); 00696 for( i = facets.size(); i--; ) 00697 { 00698 // if( facets.get()->boundary() ) 00699 // continue; 00700 00701 temp_list.clean_out(); 00702 facets.get_and_step()->append_points( temp_list ); 00703 *(offset++) = temp_list.size(); 00704 for( j = temp_list.size(); j--; ) 00705 { 00706 *(offset++) = temp_list.get_and_step()->mark; 00707 } 00708 } 00709 } 00710 00711 void PST_Edge::make_gmem( GMem& gmem, DLIList<PST_Edge*>& edges ) 00712 { 00713 DLIList<PST_Face*> face_list; 00714 PST_Edge::faces( edges, face_list ); 00715 make_gmem( gmem, face_list ); 00716 } 00717 00718 void PST_Point::debug_draw_points( DLIList<PST_Point*>& point_list, int color, bool flush ) 00719 { 00720 for( int p = point_list.size(); p--; ) 00721 point_list.get_and_step()->debug_draw(color, false); 00722 if( flush ) GfxDebug::flush(); 00723 } 00724 00725 void PST_Edge::debug_draw_points( DLIList<PST_Edge*>& edge_list, 00726 int color, int boundary_color, bool flush ) 00727 { 00728 if( ! boundary_color ) boundary_color = color; 00729 00730 DLIList<PST_Point*> point_list; 00731 DLIList<PST_Point*> boundary_list; 00732 PST_Edge::points( edge_list, point_list ); 00733 for( int i = point_list.size(); i--; ) 00734 { 00735 PST_Point* pt = point_list.step_and_get(); 00736 PST_Edge* e = pt->edge(); 00737 do 00738 { 00739 if( !e->forward()->face() || !e->reverse()->face() ) 00740 break; 00741 e = e->next(pt); 00742 } while( e != pt->edge() ); 00743 if( !e->forward()->face() || !e->reverse()->face() ) 00744 { 00745 point_list.change_to( 0 ); 00746 boundary_list.append( pt ); 00747 } 00748 } 00749 point_list.remove_all_with_value(0); 00750 00751 PST_Point::debug_draw_points( point_list, color, false ); 00752 PST_Point::debug_draw_points( boundary_list, boundary_color, flush ); 00753 } 00754 00755 void PST_Edge::debug_draw_edges( DLIList<PST_Edge*>& edge_list, 00756 int color, int boundary_color, 00757 bool flush ) 00758 { 00759 if( !boundary_color ) boundary_color = color; 00760 00761 for( int e = edge_list.size(); e--; ) 00762 { 00763 PST_Edge* edge_ptr = edge_list.get_and_step(); 00764 int c = !edge_ptr->forward()->face() || !edge_ptr->reverse()->face() 00765 ? boundary_color : color; 00766 edge_ptr->debug_draw( c, false ); 00767 } 00768 if( flush ) GfxDebug::flush(); 00769 } 00770 00771 void PST_Edge::debug_draw_faces( DLIList<PST_Edge*>& edge_list, int color, bool flush ) 00772 { 00773 DLIList<PST_Face*> face_list; 00774 PST_Edge::faces( edge_list, face_list ); 00775 PST_Face::debug_draw_faces( face_list, color, flush ); 00776 } 00777 00778 void PST_Edge::faces( DLIList<PST_Edge*>& edges, DLIList<PST_Face*>& faces ) 00779 { 00780 int e; 00781 for( e = edges.size(); e--; ) 00782 { 00783 PST_Edge* edge_ptr = edges.get_and_step(); 00784 if( edge_ptr->forward()->face() ) 00785 edge_ptr->forward()->face()->private_mark_ = 1; 00786 if( edge_ptr->reverse()->face() ) 00787 edge_ptr->reverse()->face()->private_mark_ = 1; 00788 } 00789 for( e = edges.size(); e--; ) 00790 { 00791 PST_Edge* edge_ptr = edges.get_and_step(); 00792 PST_Face* fface_ptr = edge_ptr->forward()->face(); 00793 PST_Face* rface_ptr = edge_ptr->reverse()->face(); 00794 if( fface_ptr && fface_ptr->private_mark_ ) 00795 { 00796 fface_ptr->private_mark_ = 0; 00797 faces.append( fface_ptr ); 00798 } 00799 if( rface_ptr && rface_ptr->private_mark_ ) 00800 { 00801 rface_ptr->private_mark_ = 0; 00802 faces.append( rface_ptr ); 00803 } 00804 } 00805 } 00806 00807 void PST_Edge::edges( DLIList<PST_Face*>& faces, DLIList<PST_Edge*>& edges ) 00808 { 00809 int f; 00810 for( f = faces.size(); f--; ) 00811 { 00812 PST_CoEdge* first = faces.get_and_step()->first_coedge(); 00813 PST_CoEdge* coedge = first; 00814 do 00815 { 00816 coedge->edge()->private_mark_ = 1; 00817 coedge = coedge->next(); 00818 } while( coedge != first ); 00819 } 00820 00821 for( f = faces.size(); f--; ) 00822 { 00823 PST_CoEdge* first = faces.get_and_step()->first_coedge(); 00824 PST_CoEdge* coedge = first; 00825 do 00826 { 00827 if( coedge->edge()->private_mark_ ) 00828 { 00829 coedge->edge()->private_mark_ = 0; 00830 edges.append( coedge->edge() ); 00831 } 00832 coedge = coedge->next(); 00833 } while( coedge != first ); 00834 } 00835 } 00836 00837 void PST_Edge::edges( DLIList<PST_Point*>& pts, DLIList<PST_Edge*>& edges ) 00838 { 00839 int p; 00840 for( p = pts.size(); p--; ) 00841 { 00842 PST_Point* pt = pts.get_and_step(); 00843 PST_Edge* edge = pt->edge(); 00844 if( edge ) do 00845 { 00846 edge->private_mark_ = 1; 00847 edge = edge->next( pt ); 00848 } while( edge != pt->edge() ); 00849 } 00850 00851 for( p = pts.size(); p--; ) 00852 { 00853 PST_Point* pt = pts.get_and_step(); 00854 PST_Edge* edge = pt->edge(); 00855 if( edge ) do 00856 { 00857 if( edge->private_mark_ ) 00858 { 00859 edge->private_mark_ = 0; 00860 edges.append( edge ); 00861 } 00862 edge = edge->next( pt ); 00863 } while( edge != pt->edge() ); 00864 } 00865 } 00866 00867 00868 void PST_Edge::points( DLIList<PST_Edge*>& edges, DLIList<PST_Point*>& points ) 00869 { 00870 int e; 00871 for( e = edges.size(); e--; ) 00872 { 00873 PST_Edge* edge_ptr = edges.get_and_step(); 00874 edge_ptr->start_point()->private_mark_ = 1; 00875 edge_ptr->end_point()->private_mark_ = 1; 00876 } 00877 for( e = edges.size(); e--; ) 00878 { 00879 PST_Edge* edge_ptr = edges.get_and_step(); 00880 PST_Point* sp = edge_ptr->start_point(); 00881 PST_Point* ep = edge_ptr->end_point(); 00882 if( sp->private_mark_ ) 00883 { 00884 sp->private_mark_ = 0; 00885 points.append( sp ); 00886 } 00887 if( ep->private_mark_ ) 00888 { 00889 ep->private_mark_ = 0; 00890 points.append( ep ); 00891 } 00892 } 00893 } 00894 00895 void PST_Face::debug_draw_faces( DLIList<PST_Face*>& face_list, int color, bool flush ) 00896 { 00897 for( int f = face_list.size(); f--; ) 00898 face_list.get_and_step()->debug_draw( color, false ); 00899 if( flush ) GfxDebug::flush(); 00900 } 00901 00902 void PST_Edge::make_facets( GMem& gmem, double tolerance, 00903 DLIList<PST_Edge*>& edge_list ) 00904 { 00905 assert(gmem.fListCount % 4 == 0); 00906 std::vector<double> points(gmem.pointListCount*3); 00907 std::vector<int> facets(gmem.fListCount*3/4); 00908 int i; 00909 GPoint* pitor = gmem.point_list(); 00910 std::vector<double>::iterator ditor = points.begin(); 00911 for ( i = gmem.pointListCount; i--; ) 00912 { 00913 *ditor++ = pitor->x; 00914 *ditor++ = pitor->y; 00915 *ditor++ = pitor->z; 00916 pitor++; 00917 } 00918 00919 int* fitor = gmem.facet_list(); 00920 std::vector<int>::iterator iitor = facets.begin(); 00921 for ( i = 0; i < gmem.fListCount; i += 4 ) 00922 { 00923 assert( *fitor++ == 3 ); 00924 *iitor++ = *fitor++; 00925 *iitor++ = *fitor++; 00926 *iitor++ = *fitor++; 00927 } 00928 00929 make_facets( points, facets, tolerance, edge_list ); 00930 } 00931 00932 void PST_Edge::make_facets( 00933 const std::vector<double>& coordinates, 00934 const std::vector<int>& connections, 00935 double tolerance, 00936 DLIList<PST_Edge*>& edge_list ) 00937 { 00938 DLIList<PST_Face*> face_list; 00939 double tol_sqr = tolerance * tolerance; 00940 int i, j, k, numcoords, numtriangles; 00941 00942 numcoords = coordinates.size()/3; 00943 numtriangles = connections.size()/3; 00944 //The list of points created. 00945 PST_Point** ptlist = new PST_Point*[numcoords]; 00946 00947 //The list of indices into ptlist, where the index into this 00948 //list is the same as the index into the point list, and 00949 //the value in this list is the index of the corresponding 00950 //point in ptlist. This is used because some points will 00951 //be merged due to the tolerance. 00952 int* ptindex_list = new int[numcoords]; 00953 00954 //Create the points 00955 k = 0; 00956 for( i = 0; i < numcoords; i++ ) 00957 { 00958 CubitVector pos( coordinates[3*i], coordinates[3*i+1], coordinates[3*i+2] ); 00959 00960 //Check if we need to merge this point with a different point 00961 for( j = 0; j < k; j++ ) 00962 { 00963 if( (*(ptlist[j]) - pos).length_squared() <= tol_sqr ) 00964 break; 00965 } 00966 if( j == k ) 00967 { 00968 ptlist[k] = new PST_Point( pos ); 00969 ptlist[k++]->sequence = i; 00970 } 00971 ptindex_list[i] = j; 00972 } 00973 00974 int fail_count = 0; 00975 for ( i = 0; i < numtriangles; i++ ) 00976 { 00977 int i1 = ptindex_list[connections[3*i ]]; 00978 int i2 = ptindex_list[connections[3*i+1]]; 00979 int i3 = ptindex_list[connections[3*i+2]]; 00980 if ( i1 == i2 || i2 == i3 || i3 == i1 ) 00981 { 00982 PRINT_ERROR("Degenerate facet encountered in PST_Edge::make_facets()\n"); 00983 fail_count++; 00984 } 00985 else 00986 { 00987 PST_Face* new_face 00988 = PST_Edge::create_face( ptlist[i1], ptlist[i2], ptlist[i3] ); 00989 if( new_face ){ 00990 face_list.append(new_face); 00991 new_face->sequence = i; 00992 } 00993 else{ 00994 fail_count++; 00995 } 00996 } 00997 } 00998 00999 if( fail_count > 0 ) 01000 PRINT_ERROR("Failed to construct %d facets in PST_Data::make_facets(..)\n", 01001 fail_count); 01002 01003 delete [] ptindex_list; 01004 delete [] ptlist; 01005 01006 if(fail_count == 0) 01007 { 01008 PST_Edge::edges( face_list, edge_list ); 01009 validate( edge_list, true ); 01010 bool debug1 = false; 01011 if (debug1) 01012 debug_draw_edges( edge_list, CUBIT_BLUE_INDEX, CUBIT_RED_INDEX, true ); 01013 } 01014 } 01015 01016 int PST_Point::validate(CubitBoolean print) 01017 { 01018 if( edge_ && !edge_->other(this) ) 01019 { 01020 if( print ) 01021 { 01022 PRINT_INFO("Bad point->edge link. Point %p, Edge %p.\n", (void*)this, (void*)edge_); 01023 } 01024 return 1; 01025 } 01026 return 0; 01027 } 01028 01029 int PST_Edge::validate(CubitBoolean print) 01030 { 01031 int result = 0; 01032 int count = 0; 01033 PST_Edge* edge = 0; 01034 01035 if( !start_ ) 01036 { 01037 if( print ) PRINT_ERROR("Edge %p has null start point.\n", (void*)this); 01038 result++; 01039 } 01040 else 01041 { 01042 result += start_->validate(print); 01043 01044 edge = this; 01045 count = 0; 01046 do 01047 { 01048 if( count++ > PST_MAX_LIST_LEN ) 01049 { 01050 if( print ) 01051 { 01052 PRINT_ERROR("Bad edge list around Point %p.\n", (void*)start_); 01053 } 01054 result++; 01055 break; 01056 } 01057 edge = edge->next( start_ ); 01058 } while( edge != this ); 01059 } 01060 01061 01062 if( !end_ ) 01063 { 01064 if( print ) PRINT_ERROR("Edge %p has null end point.\n", (void*)this); 01065 result++; 01066 } 01067 else 01068 { 01069 result += end_->validate(print); 01070 01071 count = 0; 01072 edge = this; 01073 do 01074 { 01075 if( count++ > PST_MAX_LIST_LEN ) 01076 { 01077 if( print ) 01078 { 01079 PRINT_ERROR("Bad edge list around Point %p.\n", (void*)end_); 01080 } 01081 result++; 01082 break; 01083 } 01084 edge = edge->next( end_ ); 01085 } while( edge != this ); 01086 } 01087 01088 if (forward_.face_ && !forward_.next_) 01089 { 01090 if( print ) 01091 PRINT_ERROR("Forward CoEdge on Edge %p as Face %p but no next().\n", 01092 (void*)this, (void*)forward_.face_); 01093 count++; 01094 } 01095 01096 if (reverse_.face_ && !reverse_.next_) 01097 { 01098 if( print ) 01099 PRINT_ERROR("Reverse CoEdge on Edge %p as Face %p but no next().\n", 01100 (void*)this, (void*)reverse_.face_); 01101 count++; 01102 } 01103 01104 if (!forward_.face_ && forward_.next_) 01105 { 01106 if( print ) 01107 PRINT_ERROR("Forward CoEdge on Edge %p as %p as next CoEdge but no Face.\n", 01108 (void*)this, (void*)forward_.next_); 01109 count++; 01110 } 01111 01112 if (!reverse_.face_ && reverse_.next_) 01113 { 01114 if( print ) 01115 PRINT_ERROR("Reverse CoEdge on Edge %p as %p as next CoEdge but no Face.\n", 01116 (void*)this, (void*)reverse_.next_); 01117 count++; 01118 } 01119 01120 return result; 01121 } 01122 01123 int PST_CoEdge::validate( CubitBoolean print ) 01124 { 01125 int result = 0; 01126 if( ! edge_ ) 01127 { 01128 if( print ) PRINT_ERROR("Coedge %p has null edge.\n", (void*)this); 01129 result++; 01130 } 01131 else 01132 { 01133 if( ! edge_->other( this ) ) 01134 { 01135 if( print ) 01136 PRINT_ERROR( "Inconsistent coedge->edge link. CoEdge: %p Edge: %p\n", 01137 (void*)edge_, (void*)this ); 01138 result++; 01139 } 01140 result += edge_->validate(print); 01141 } 01142 return result; 01143 } 01144 01145 int PST_Face::validate( CubitBoolean print ) 01146 { 01147 PST_CoEdge* coe = coedge_; 01148 01149 if( !coedge_ ) 01150 { 01151 if(print) PRINT_ERROR("Face %p has null loop.\n", (void*)this); 01152 return 1; 01153 } 01154 01155 int count = 0; 01156 int result = 0; 01157 do 01158 { 01159 if( count++ > PST_MAX_LIST_LEN ) 01160 { 01161 if( print ) PRINT_ERROR("Face %p loop is infinite.\n", (void*)this); 01162 result++; 01163 break; 01164 } 01165 01166 if( coe->face() != this ) 01167 { 01168 if( print ) 01169 PRINT_ERROR("Loop for face %p contains face %p on edge %p.\n", 01170 (void*)this, (void*)coe->face(), (void*)coe->edge() ); 01171 result++; 01172 } 01173 01174 if( coe->edge() ) 01175 { 01176 result += coe->edge()->validate( print ); 01177 } 01178 else 01179 { 01180 if( print ) 01181 PRINT_ERROR("Coedge %p in face %p has null edge.\n", (void*)coe, (void*)this); 01182 result++; 01183 } 01184 01185 if( ! coe->next() ) 01186 { 01187 if( print ) 01188 PRINT_ERROR("Null coedge after coedge %p in face %p.\n", (void*)coe, (void*)this ); 01189 result++; 01190 break; 01191 } 01192 01193 coe = coe->next(); 01194 01195 } while( coe != coedge_ ); 01196 01197 return result; 01198 } 01199 01200 int PST_Edge::validate( DLIList<PST_Edge*>& edges, CubitBoolean print ) 01201 { 01202 DLIList<PST_Face*> faces; 01203 PST_Edge::faces( edges, faces ); 01204 01205 int result = 0; 01206 for( int f = faces.size(); f--; ) 01207 result += faces.get_and_step()->validate(print); 01208 return result; 01209 } 01210 01211 void PST_Face::print() 01212 { 01213 if( ! coedge_ ) 01214 { 01215 PRINT_ERROR("Face %p has null coedge.\n", (void*)this); 01216 return; 01217 } 01218 01219 PRINT_INFO("Face CoEdge Edge Start Pt End Pt\n" 01220 "---------- ----------- ----------- ----------- -----------\n" ); 01221 PST_CoEdge* coe = coedge_; 01222 PRINT_INFO("%10p %10p %10p %10p %10p\n", 01223 (void*)this, (void*)coe, (void*)coe->edge(), (void*)coe->start_point(), (void*)coe->end_point() ); 01224 coe = coe->next(); 01225 while( coe && coe != coedge_ ) 01226 { 01227 PRINT_INFO(" %10p %10p %10p %10p\n", 01228 (void*)coe, (void*)coe->edge(), (void*)coe->start_point(), (void*)coe->end_point() ); 01229 coe = coe->next(); 01230 } 01231 } 01232 01233 void PST_Edge::print() 01234 { 01235 PRINT_INFO("Edge %p: Points: Start: %p End: %p Faces: Forward: %p Reverse: %p\n", 01236 (void*)this, (void*)start_, (void*)end_, (void*)forward_.face_, (void*)reverse_.face_ ); 01237 } 01238 01239 void PST_Point::print() 01240 { 01241 PRINT_INFO("Point %p : ( %f, %f, %f )", (void*)this , x(), y(), z() ); 01242 01243 if( edge_ ) 01244 { 01245 PRINT_INFO(" Edges:"); 01246 int count = 0; 01247 PST_Edge* edge = edge_; 01248 do 01249 { 01250 if( count ) 01251 { 01252 PRINT_INFO("\t%8p", (void*)edge); 01253 } 01254 else 01255 { 01256 PRINT_INFO("\n\t%8p", (void*)edge); 01257 } 01258 01259 count = (count + 1) % 4; 01260 edge = edge->next(this); 01261 01262 } while( edge && edge != edge_ ); 01263 01264 } 01265 PRINT_INFO("\n"); 01266 } 01267 01268 01269 PST_Entity::~PST_Entity() 01270 { } 01271