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