MeshKit
1.0
|
00001 #include "meshkit/MeshRefine2D.hpp" 00002 00003 using namespace Jaal; 00004 00006 00007 int MeshRefine2D :: initialize() 00008 { 00009 insertedNodes.clear(); 00010 insertedFaces.clear(); 00011 return 0; 00012 } 00013 00015 00016 int MeshRefine2D :: finalize() 00017 { 00018 mesh->prune(); 00019 return 0; 00020 } 00021 00023 00024 void 00025 MeshRefine2D::RefinedEdgeMap::clear() 00026 { 00027 std::map<Vertex*, vector<RefinedEdge> >::const_iterator it; 00028 00029 for( it = refined_edges.begin(); it != refined_edges.end(); ++it) { 00030 const vector<RefinedEdge> &refedges = it->second; 00031 for( size_t i = 0; i < refedges.size(); i++) 00032 delete refedges[i].edge; 00033 } 00034 refined_edges.clear(); 00035 } 00036 00038 bool 00039 MeshRefine2D::RefinedEdgeMap::hasEdge( Vertex *v1, Vertex *v2) const 00040 { 00041 Vertex *vmin = std::min(v1,v2); 00042 00043 std::map<Vertex*, vector<RefinedEdge> >::const_iterator it; 00044 it = refined_edges.find(vmin); 00045 00046 if( it == refined_edges.end() ) return 0; 00047 00048 const vector<RefinedEdge> &refedges = it->second; 00049 for( unsigned int i = 0; i < refedges.size(); i++) { 00050 Vertex *ev1 = refedges[i].edge->getNodeAt(0); 00051 Vertex *ev2 = refedges[i].edge->getNodeAt(1); 00052 if( ev1 == v1 && ev2 == v2) return 1; 00053 if( ev1 == v2 && ev2 == v1) return 1; 00054 } 00055 00056 return 0; 00057 } 00058 00060 00061 bool 00062 MeshRefine2D::RefinedEdgeMap::allow_edge_refinement( const Edge *edge) const 00063 { 00064 if( edge->isBoundary() || edge->isConstrained() ) 00065 if( boundary_split_flag == 0) return 0; 00066 00067 return 1; 00068 } 00069 00071 00072 Vertex* 00073 MeshRefine2D::RefinedEdgeMap::setVertexOnEdge( Vertex *v1, Vertex *v2) 00074 { 00075 if( hasEdge(v1,v2) ) return NULL; 00076 00077 RefinedEdge refedge; 00078 Edge *edge = new Edge(v1,v2); 00079 00080 Point3D p3d; 00081 if( allow_edge_refinement(edge) ) { 00082 Vertex::mid_point(v1, v2, p3d); 00083 Vertex *v = Vertex::newObject(); 00084 v->setXYZCoords( p3d ); 00085 refedge.edge = edge; 00086 refedge.midVertex = v; 00087 Vertex *vmin = std::min(v1,v2); 00088 refined_edges[vmin].push_back( refedge ); 00089 return v; 00090 } 00091 00092 return NULL; 00093 } 00094 00096 00097 Vertex* MeshRefine2D::RefinedEdgeMap::getVertexOnEdge( Vertex *v1, Vertex *v2 ) const 00098 { 00099 Vertex *vmin = std::min(v1,v2); 00100 00101 std::map<Vertex*, vector<RefinedEdge> >::const_iterator it; 00102 it = refined_edges.find(vmin); 00103 00104 if( it == refined_edges.end() ) return NULL; 00105 const vector<RefinedEdge> &refedges = it->second; 00106 for( unsigned int i = 0; i < refedges.size(); i++) { 00107 Vertex *ev1 = refedges[i].edge->getNodeAt(0); 00108 Vertex *ev2 = refedges[i].edge->getNodeAt(1); 00109 if( ev1 == v1 && ev2 == v2) return refedges[i].midVertex; 00110 if( ev1 == v2 && ev2 == v1) return refedges[i].midVertex; 00111 } 00112 00113 return NULL; 00114 } 00115 00117 00118 void MeshRefine2D::append_new_node( Vertex *vertex) 00119 { 00120 mesh->addNode( vertex ); 00121 insertedNodes.push_back( vertex ); 00122 } 00123 00125 00126 Face* MeshRefine2D::append_new_triangle( Vertex *v0, Vertex *v1 , Vertex *v2) 00127 { 00128 NodeSequence pnodes(3); 00129 pnodes[0] = v0; 00130 pnodes[1] = v1; 00131 pnodes[2] = v2; 00132 00133 Face *face = Face::newObject(); 00134 face->setNodes( pnodes ); 00135 mesh->addFace(face); 00136 insertedFaces.push_back( face ); 00137 return face; 00138 } 00139 00141 00142 Face* MeshRefine2D::append_new_quad( Vertex *v0, Vertex *v1 , Vertex *v2, Vertex *v3) 00143 { 00144 NodeSequence pnodes(4); 00145 pnodes[0] = v0; 00146 pnodes[1] = v1; 00147 pnodes[2] = v2; 00148 pnodes[3] = v3; 00149 00150 Face *face = Face::newObject(); 00151 face->setNodes( pnodes ); 00152 mesh->addFace(face); 00153 insertedFaces.push_back( face ); 00154 return face; 00155 } 00156 00158 00159 int Sqrt3Refine2D :: execute() 00160 { 00161 CentroidRefine2D refine(mesh); 00162 SwapTriEdges eflip(mesh); 00163 00164 for ( int itime = 0; itime < numIterations; itime++) { 00165 refine.execute(); 00166 eflip.apply_rule(SwapEdges::DEGREE_REDUCTION_RULE); 00167 } 00168 00169 return 0; 00170 } 00171 00173 00174 int LongestEdgeRefine2D :: atomicOp( const Face *oldface) 00175 { 00176 vector<double> elen(3); 00177 00178 double maxlen = 0.0; 00179 for( int i = 0; i < 3; i++) { 00180 Vertex *v1 = oldface->getNodeAt(i+1); 00181 Vertex *v2 = oldface->getNodeAt(i+2); 00182 elen[i] = Vertex::length(v1, v2); 00183 maxlen = std::max(elen[i], maxlen); 00184 } 00185 00186 for( int i = 0; i < 3; i++) { 00187 if( elen[i]/maxlen > 0.90 ) { 00188 Vertex *v1 = oldface->getNodeAt( i+1 ); 00189 Vertex *v2 = oldface->getNodeAt( i+2 ); 00190 edgemap->setVertexOnEdge(v1,v2); 00191 } 00192 } 00193 00194 return 0; 00195 } 00196 00198 00199 int LongestEdgeRefine2D::execute() 00200 { 00201 edgemap = new RefinedEdgeMap; 00202 00203 size_t numfaces = mesh->getSize(2); 00204 00205 size_t ncount = 0; 00206 for( size_t i = 0; i < numfaces; i++) { 00207 Face *face = mesh->getFaceAt(i); 00208 double ratio = face->getAspectRatio(); 00209 if( ratio < cutOffAspectRatio) { 00210 int err = atomicOp( face ); 00211 if( !err ) ncount++; 00212 } 00213 } 00214 00215 if( ncount ) { 00216 ConsistencyRefine2D consistency(mesh, edgemap); 00217 consistency.execute(); 00218 finalize(); 00219 } else 00220 cout << "Warning: No Edge was refined " << endl; 00221 00222 edgemap->clear(); 00223 00224 delete edgemap; 00225 00226 00227 return 0; 00228 } 00229 00231 00232 int ConsistencyRefine2D :: execute() 00233 { 00234 hangingVertex.resize(3); 00235 edge0.set(0); 00236 edge1.set(1); 00237 edge2.set(2); 00238 00239 makeConsistent(); 00240 00241 finalize(); 00242 00243 return 0; 00244 } 00245 00246 //############################################################################# 00247 00248 void ConsistencyRefine2D :: subDivideQuad2Tri( const NodeSequence &connect) 00249 { 00250 assert( connect.size() == 4 ); 00251 //******************************************************************** 00252 // Subdivide a quadrilateral cell into two triangles. We can choose 00253 // either quadrilateral diagonal for spliiting, but we choose to 00254 // select quadrilateral which gives, maximum of minimum aspect 00255 // ratio of the resulting two triangles .... 00256 //******************************************************************* 00257 double diagonal[2]; 00258 00259 Vertex *v0 = connect[0]; 00260 Vertex *v1 = connect[1]; 00261 Vertex *v2 = connect[2]; 00262 Vertex *v3 = connect[3]; 00263 00264 diagonal[0] = Vertex::length( v0, v3 ); 00265 diagonal[1] = Vertex::length( v1, v2 ); 00266 00267 if( diagonal[0] < diagonal[1] ) { 00268 append_new_triangle( v0, v1, v3); 00269 append_new_triangle( v0, v3, v2); 00270 } else { 00271 append_new_triangle( v0, v1, v2); 00272 append_new_triangle( v1, v3, v2); 00273 } 00274 } 00275 00276 //############################################################################# 00277 00278 void ConsistencyRefine2D :: makeConsistent1( Face *oldface) 00279 { 00280 //------------------------------------------------------------------ 00281 // When only one edge is inconsistent, we can direcly join the 00282 // hanging node to the opposite node of the triangle. Therefore 00283 // one additional triangle is generated with this case. 00284 //------------------------------------------------------------------ 00285 if( oldface->getSize(0) != 3 ) return; 00286 00287 Vertex *n1 = oldface->getNodeAt(0); 00288 Vertex *n2 = oldface->getNodeAt(1); 00289 Vertex *n3 = oldface->getNodeAt(2); 00290 00291 remove_it( oldface ); 00292 00293 // If the only hanging vertex lies of the edge0. i.e. opposite to the 00294 // vertex 0 of the existing triangle. 00295 if( bitvec == edge0) { 00296 append_new_triangle(n1, n2, hangingVertex[0] ); 00297 00298 // Create a new triangle .... 00299 append_new_triangle(n3, n1, hangingVertex[0] ); 00300 return; 00301 } 00302 00303 00304 // If the only hanging vertex lies of the edge1. i.e. opposite to the 00305 // vertex 1 of the existing triangle. 00306 if( bitvec == edge1) { 00307 // Replace the existing triangle .... 00308 append_new_triangle(n2, n3, hangingVertex[1] ); 00309 00310 // Create a new triangle .... 00311 append_new_triangle(n2, hangingVertex[1], n1 ); 00312 return; 00313 } 00314 00315 // If the only hanging vertex lies of the edge2. i.e. opposite to the 00316 // vertex 2 of the existing triangle. 00317 if( bitvec == edge2) { 00318 // Replace the existing triangle .... 00319 append_new_triangle(n3, n1, hangingVertex[2] ); 00320 00321 // Create a new triangle .... 00322 append_new_triangle(n3, hangingVertex[2], n2 ); 00323 return; 00324 } 00325 00326 } 00327 00328 //############################################################################# 00329 00330 void ConsistencyRefine2D :: refineEdge0(const Face *oldface) 00331 { 00332 Vertex *n1 = oldface->getNodeAt(0); 00333 Vertex *n2 = oldface->getNodeAt(1); 00334 Vertex *n3 = oldface->getNodeAt(2); 00335 00336 append_new_triangle(n1, hangingVertex[2], hangingVertex[1] ); 00337 00338 // One Quadrilateral is created, divide into 2 triangles. 00339 NodeSequence qnodes(4); 00340 qnodes[0] = hangingVertex[2]; 00341 qnodes[1] = n2; 00342 qnodes[2] = hangingVertex[1]; 00343 qnodes[3] = n3; 00344 00345 subDivideQuad2Tri( qnodes ); 00346 } 00347 00348 //############################################################################# 00349 00350 void ConsistencyRefine2D :: refineEdge1(const Face *oldface) 00351 { 00352 Vertex *n1 = oldface->getNodeAt( 0 ); 00353 Vertex *n2 = oldface->getNodeAt( 1 ); 00354 Vertex *n3 = oldface->getNodeAt( 2 ); 00355 00356 append_new_triangle(n2, hangingVertex[0], hangingVertex[2] ); 00357 00358 // One Quadrilateral is created, divide into 2 triangles. 00359 NodeSequence qnodes(4); 00360 qnodes[0] = n1; 00361 qnodes[1] = hangingVertex[2]; 00362 qnodes[2] = n3; 00363 qnodes[3] = hangingVertex[0]; 00364 00365 subDivideQuad2Tri( qnodes ); 00366 } 00367 00368 00369 //############################################################################# 00370 00371 void ConsistencyRefine2D :: refineEdge2(const Face *oldface) 00372 { 00373 Vertex *n1 = oldface->getNodeAt(0); 00374 Vertex *n2 = oldface->getNodeAt(1); 00375 Vertex *n3 = oldface->getNodeAt(2); 00376 00377 append_new_triangle(n3, hangingVertex[1], hangingVertex[0] ); 00378 00379 NodeSequence qnodes(4); 00380 qnodes[0] = n1; 00381 qnodes[1] = n2; 00382 qnodes[2] = hangingVertex[1]; 00383 qnodes[3] = hangingVertex[0]; 00384 00385 subDivideQuad2Tri( qnodes ); 00386 } 00387 00388 //############################################################################# 00389 00390 void ConsistencyRefine2D :: makeConsistent2( Face *oldface) 00391 { 00392 //-------------------------------------------------------------------- 00393 // When there are two edges which are inconsistent, then we create 00394 // one triangle and one quadrilateral. This quadrilateral is further 00395 // divided into 2 triangle, which produces better aspect ratio. 00396 // Therefore, three triangles are generated in this procedure. 00397 //-------------------------------------------------------------------- 00398 // Find out which edge is consistent ... 00399 bitvec.flip(); 00400 00401 if( bitvec == edge0) refineEdge0(oldface); 00402 if( bitvec == edge1) refineEdge1(oldface); 00403 if( bitvec == edge2) refineEdge2(oldface); 00404 00405 remove_it( oldface ); 00406 00407 } 00408 00409 //############################################################################# 00410 00411 void ConsistencyRefine2D :: makeConsistent3( Face *oldface) 00412 { 00413 Vertex *n1 = oldface->getNodeAt(0); 00414 Vertex *n2 = oldface->getNodeAt(1); 00415 Vertex *n3 = oldface->getNodeAt(2); 00416 00417 // First Triangle Using 0(old), 1,2(new): Replace existing triangle 00418 append_new_triangle( n1, hangingVertex[2], hangingVertex[1] ); 00419 00420 // Second Triangle Using 1(old), 2,0(new): Create new triangle 00421 append_new_triangle( n2, hangingVertex[0], hangingVertex[2] ); 00422 00423 // Second Triangle Using 2(old), 1,0(new): Create new triangle 00424 append_new_triangle( n3, hangingVertex[1], hangingVertex[0] ); 00425 00426 // All new only : Create new triangle 00427 append_new_triangle( hangingVertex[0], hangingVertex[1], hangingVertex[2] ); 00428 00429 remove_it(oldface); 00430 00431 } 00432 00433 //############################################################################# 00434 00435 void ConsistencyRefine2D :: checkFaceConsistency( Face *oldface ) 00436 { 00437 bitvec.reset(); 00438 00439 for( int i = 0; i < 3; i++) { 00440 Vertex *v1 = oldface->getNodeAt( i+1 ); 00441 Vertex *v2 = oldface->getNodeAt( i+2 ); 00442 hangingVertex[i] = edgemap->getVertexOnEdge( v1, v2 ); 00443 if( hangingVertex[i] ) bitvec.set(i); 00444 } 00445 00446 } 00447 00448 //############################################################################# 00449 00450 int ConsistencyRefine2D :: atomicOp(Face *oldface) 00451 { 00452 checkFaceConsistency( oldface ); 00453 00454 switch( bitvec.count() ) { 00455 case 1: 00456 numfacesRefined++; 00457 makeConsistent1( oldface ); 00458 break; 00459 case 2: 00460 numfacesRefined++; 00461 makeConsistent2( oldface ); 00462 break; 00463 case 3: 00464 numfacesRefined++; 00465 makeConsistent3( oldface ); 00466 break; 00467 } 00468 00469 00470 remove_it( oldface ); 00471 00472 return 0; 00473 } 00474 00475 //############################################################################# 00476 void ConsistencyRefine2D :: makeConsistent() 00477 { 00478 //********************************************************************** 00479 // The previous step, will leave some hanging nodes. So adjacent cells 00480 // will be forced to refined. All the hanging nodes are attached 00481 // directly to the opposite node of the triangle, thus creating two 00482 // triangle. This may produce some bad triangle, which could be 00483 // improved using edge swapping algorithm. In this process, only new 00484 // edges are created and no new vertices are introduced. 00485 //********************************************************************** 00486 00487 size_t numfaces = mesh->getSize(2); 00488 00489 for( size_t i = 0; i < numfaces ; i++) 00490 atomicOp( mesh->getFaceAt(i) ); 00491 } 00492 00493 //############################################################################# 00494 00495 int CentroidRefine2D::refine_tri(Face *oldface) 00496 { 00497 Vertex *vcenter = Vertex::newObject(); 00498 Point3D pc; 00499 oldface->getAvgPos( pc ); 00500 vcenter->setXYZCoords( pc ); 00501 00502 Vertex *v1 = oldface->getNodeAt( 0 ); 00503 Vertex *v2 = oldface->getNodeAt( 1 ); 00504 Vertex *v3 = oldface->getNodeAt( 2 ); 00505 00506 append_new_node( vcenter ); 00507 append_new_triangle( vcenter, v1, v2); 00508 append_new_triangle( vcenter, v2, v3); 00509 append_new_triangle( vcenter, v3, v1); 00510 00511 remove_it( oldface ); 00512 return 0; 00513 } 00514 00516 00517 int CentroidRefine2D::refine_quad(Face *oldface) 00518 { 00519 Vertex *vcenter = Vertex::newObject(); 00520 Point3D pc; 00521 oldface->getAvgPos( pc ); 00522 vcenter->setXYZCoords( pc ); 00523 00524 Vertex *v0 = oldface->getNodeAt( 0 ); 00525 Vertex *v1 = oldface->getNodeAt( 1 ); 00526 Vertex *v2 = oldface->getNodeAt( 2 ); 00527 Vertex *v3 = oldface->getNodeAt( 3 ); 00528 00529 append_new_triangle( vcenter, v0, v1); 00530 append_new_triangle( vcenter, v1, v3); 00531 append_new_triangle( vcenter, v3, v2); 00532 append_new_triangle( vcenter, v2, v0); 00533 00534 remove_it( oldface ); 00535 00536 return 0; 00537 } 00538 00540 00541 int CentroidRefine2D::atomicOp(Face *oldface) 00542 { 00543 if( !oldface->isActive() ) return 1; 00544 00545 if( oldface->getSize(0) == 3 ) return refine_tri( oldface ); 00546 if( oldface->getSize(0) == 4 ) return refine_quad( oldface ); 00547 00548 cout << "Warning: Element not supported for refinement " << endl; 00549 00550 return 1; 00551 } 00552 00554 00555 int CentroidRefine2D::execute() 00556 { 00557 00558 for( int it = 0; it < numIterations; it++) { 00559 size_t numfaces = mesh->getSize(2); 00560 for( size_t i = 0; i < numfaces; i++) 00561 atomicOp( mesh->getFaceAt(i) ); 00562 } 00563 00564 mesh->prune(); 00565 mesh->enumerate(0); 00566 mesh->enumerate(2); 00567 00568 assert( mesh->isSimple() ); 00569 00570 return 0; 00571 } 00572 00574 00575 int ObtuseRefine2D :: atomicOp( const Face *oldface) 00576 { 00577 /* 00578 int err; 00579 SimpleArray<iBase_EntityHandle> facenodes; 00580 iMesh_getEntAdj(mesh, facehandle, iBase_VERTEX, ARRAY_INOUT(facenodes), &err); 00581 00582 Point3D pv0, pv1, pv2; 00583 Point3D vec1, vec2; 00584 00585 iBase_EntityHandle vmid; 00586 double angle; 00587 for( int i = 0; i < 3; i++) { 00588 getVertexCoords( facenodes[(i+0)%3], pv0); 00589 getVertexCoords( facenodes[(i+1)%3], pv1); 00590 getVertexCoords( facenodes[(i+2)%3], pv2); 00591 vec1 = Math::create_vector( pv2, pv0); 00592 vec2 = Math::create_vector( pv1, pv0); 00593 angle = Math::getVectorAngle(vec1, vec2); 00594 if( angle > cutoffAngle) { 00595 setVertexOnEdge(facenodes[(i+1)%2], facenodes[(i+2)%2], vmid ); 00596 return 0; 00597 } 00598 } 00599 */ 00600 00601 return 1; 00602 } 00603 00605 int ObtuseRefine2D :: execute() 00606 { 00607 edgemap = new RefinedEdgeMap; 00608 00609 initialize(); 00610 00611 size_t numfaces = mesh->getSize(2); 00612 00613 size_t ncount = 0; 00614 for( size_t i = 0; i < numfaces; i++) { 00615 int err = atomicOp( mesh->getFaceAt(i) ); 00616 if( !err ) ncount++; 00617 } 00618 00619 if( ncount ) { 00620 ConsistencyRefine2D refine(mesh, edgemap); 00621 refine.execute(); 00622 finalize(); 00623 } else 00624 cout << "Warning: No triangle was refined " << endl; 00625 00626 edgemap->clear(); 00627 delete edgemap; 00628 00629 return 0; 00630 } 00631 00633 00634 int Refine2D14::refine_quad(Face *oldface) 00635 { 00636 Vertex *v0 = oldface->getNodeAt( 0 ); 00637 Vertex *v1 = oldface->getNodeAt( 1 ); 00638 Vertex *v2 = oldface->getNodeAt( 2 ); 00639 Vertex *v3 = oldface->getNodeAt( 3 ); 00640 00641 edgemap->setVertexOnEdge( v0,v1 ); 00642 edgemap->setVertexOnEdge( v2,v3 ); 00643 edgemap->setVertexOnEdge( v0,v2 ); 00644 edgemap->setVertexOnEdge( v1,v3 ); 00645 00646 Vertex *v01 = edgemap->getVertexOnEdge( v0,v1 ); 00647 Vertex *v23 = edgemap->getVertexOnEdge( v2,v3 ); 00648 Vertex *v02 = edgemap->getVertexOnEdge( v0,v2 ); 00649 Vertex *v13 = edgemap->getVertexOnEdge( v1,v3 ); 00650 00651 Vertex *vcenter = Vertex::newObject(); 00652 Point3D pc; 00653 oldface->getAvgPos( pc ); 00654 vcenter->setXYZCoords( pc ); 00655 00656 append_new_quad( v0, v01, v02, vcenter); 00657 append_new_quad( v01, v1, vcenter, v13); 00658 append_new_quad( v02, vcenter, v2, v23); 00659 append_new_quad(vcenter, v13, v23, v3 ); 00660 00661 remove_it( oldface ); 00662 00663 return 0; 00664 } 00665 00667 00668 int Refine2D14:: refine_tri( Face *oldface) 00669 { 00670 Vertex *v0 = oldface->getNodeAt( 0 ); 00671 Vertex *v1 = oldface->getNodeAt( 1 ); 00672 Vertex *v2 = oldface->getNodeAt( 2 ); 00673 00674 edgemap->setVertexOnEdge(v0,v1); 00675 edgemap->setVertexOnEdge(v1,v2); 00676 edgemap->setVertexOnEdge(v2,v0); 00677 00678 Vertex *v01 = edgemap->getVertexOnEdge( v0, v1 ); 00679 Vertex *v12 = edgemap->getVertexOnEdge( v1, v2 ); 00680 Vertex *v20 = edgemap->getVertexOnEdge( v2, v0 ); 00681 00682 assert( v01 ); 00683 assert( v12 ); 00684 assert( v20 ); 00685 00686 append_new_triangle( v0, v01, v20); 00687 append_new_triangle( v01, v1, v12); 00688 append_new_triangle( v12, v2, v20); 00689 append_new_triangle( v01, v12, v20); 00690 00691 remove_it( oldface ); 00692 00693 return 0; 00694 00695 } 00696 00698 00699 int Refine2D14::atomicOp(Face *oldface) 00700 { 00701 if( oldface->getSize(0) == 3 ) return refine_tri( oldface ); 00702 if( oldface->getSize(0) == 4 ) return refine_quad( oldface ); 00703 00704 cout << "Warning: Element not supported for refinement " << endl; 00705 return 1; 00706 } 00707 00709 00710 int Refine2D14 ::execute() 00711 { 00712 edgemap = new RefinedEdgeMap; 00713 initialize(); 00714 00715 size_t numfaces = mesh->getSize(2); 00716 00717 size_t ncount = 0; 00718 for( size_t i = 0; i < numfaces; i++) { 00719 int err = atomicOp( mesh->getFaceAt(i) ); 00720 if( !err ) ncount++; 00721 } 00722 00723 if( ncount ) { 00724 ConsistencyRefine2D refine(mesh, edgemap); 00725 refine.execute(); 00726 MeshRefine2D::finalize(); 00727 } 00728 00729 edgemap->clear(); 00730 00731 delete edgemap; 00732 return 0; 00733 } 00734 00736 00737 int GradeRefine2D :: initialize() 00738 { 00739 return 0; 00740 } 00741 00743 00744 int GradeRefine2D :: atomicOp( const Vertex *apexVertex) 00745 { 00746 /* 00747 SimpleArray<iBase_EntityHandle> vneighs; 00748 iMesh_getEntAdj(mesh, apexVertex, iBase_VERTEX, ARRAY_INOUT(vneighs), &err); 00749 00750 size_t numNeighs = vneighs.size(); 00751 00752 if( numNeighs == 0 ) return 0; 00753 00754 vector<double> elen; 00755 elen.resize( numNeighs); 00756 00757 for( int i = 0; i < numNeighs; i++) 00758 elen[i] = length( vertex, vneighs[i] ); 00759 00760 sort( elen.begin(), elen.end() ); 00761 00762 double median_value = elen[numNeighs/2]; 00763 00764 for( int i = 0; i < numNeighs; i++) { 00765 if( elen[i] > 0.90*median_value) 00766 setVertexOnEdge( vertex, vneighs[i]); 00767 } 00768 */ 00769 return 1; 00770 } 00772 00773 int GradeRefine2D :: finalize() 00774 { 00775 return 0; 00776 } 00777 00779 00780 int GradeRefine2D :: execute() 00781 { 00782 edgemap = new RefinedEdgeMap; 00783 00784 initialize(); 00785 00786 size_t numnodes = mesh->getSize(0); 00787 00788 size_t ncount = 0; 00789 for( size_t i = 0; i < numnodes; i++) { 00790 int err = atomicOp( mesh->getNodeAt(i) ); 00791 if( !err ) ncount++; 00792 } 00793 00794 if( ncount ) { 00795 ConsistencyRefine2D refine(mesh, edgemap); 00796 refine.execute(); 00797 finalize(); 00798 } 00799 00800 edgemap->clear(); 00801 delete edgemap; 00802 00803 return ncount; 00804 } 00805 00807 00808 #ifdef TEST_MESHREFINE 00809 int main(int argc, char **argv) 00810 { 00811 iMesh_Instance mesh = read_off_file( "model.off"); 00812 00813 // LongestEdgeRefine2D meshrefine; 00814 Refine2D14 meshrefine; 00815 meshrefine.setBoundarySplitFlag(0); 00816 meshrefine.setMesh( mesh ); 00817 meshrefine.execute(); 00818 00819 write_off_file( mesh, "refine.off"); 00820 00821 return 0; 00822 } 00823 00824 #endif 00825