+ return chn.size() > 1;
+ }
+ //================================================================================
+ /*!
+ * \brief Try to heal a polygon whose ends are not connected
+ */
+ bool Hexahedron::closePolygon( _Face* polygon, vector<_Node*>& chainNodes ) const
+ {
+ int i = -1, nbLinks = polygon->_links.size();
+ if ( nbLinks < 3 )
+ return false;
+ vector< _OrientedLink > newLinks;
+ // find a node lying on the same FACE as the last one
+ _Node* node = polygon->_links.back().LastNode();
+ int avoidFace = node->IsLinked( polygon->_links.back().FirstNode()->_intPoint );
+ for ( i = nbLinks - 2; i >= 0; --i )
+ if ( node->IsLinked( polygon->_links[i].FirstNode()->_intPoint, avoidFace ))
+ break;
+ if ( i >= 0 )
+ {
+ for ( ; i < nbLinks; ++i )
+ newLinks.push_back( polygon->_links[i] );
+ }
+ else
+ {
+ // find a node lying on the same FACE as the first one
+ node = polygon->_links[0].FirstNode();
+ avoidFace = node->IsLinked( polygon->_links[0].LastNode()->_intPoint );
+ for ( i = 1; i < nbLinks; ++i )
+ if ( node->IsLinked( polygon->_links[i].LastNode()->_intPoint, avoidFace ))
+ break;
+ if ( i < nbLinks )
+ for ( nbLinks = i + 1, i = 0; i < nbLinks; ++i )
+ newLinks.push_back( polygon->_links[i] );
+ }
+ if ( newLinks.size() > 1 )
+ {
+ polygon->_links.swap( newLinks );
+ chainNodes.clear();
+ chainNodes.push_back( polygon->_links.back().LastNode() );
+ chainNodes.push_back( polygon->_links[0].FirstNode() );
+ return true;
+ }
+ return false;
+ }
+ //================================================================================
+ /*!
+ * \brief Checks transition at the 1st node of a link
+ */
+ bool Hexahedron::is1stNodeOut( _Link& link /*int iLink*/ ) const
+ {
+ // new version is for the case: tangent transition at the 1st node
+ bool isOut = false;
+ if ( link._fIntNodes.size() > 1 )
+ {
+ // check transition at the next intersection
+ switch ( link._fIntPoints[1]->_transition ) {
+ case Trans_OUT: return false;
+ case Trans_IN : return true;
+ default: ; // tangent transition
+ }
+ }
+ gp_Pnt p1 = link._nodes[0]->Point();
+ gp_Pnt p2 = link._nodes[1]->Point();
+ gp_Pnt testPnt = 0.8 * p1.XYZ() + 0.2 * p2.XYZ();
+
+ TGeomID faceID = link._fIntPoints[0]->_faceIDs[0];
+ const TopoDS_Face& face = TopoDS::Face( _grid->_shapes( faceID ));
+ TopLoc_Location loc;
+ GeomAPI_ProjectPointOnSurf& proj =
+ _grid->_helper->GetProjector( face, loc, 0.1*_grid->_tol );
+ testPnt.Transform( loc );
+ proj.Perform( testPnt );
+ if ( proj.IsDone() &&
+ proj.NbPoints() > 0 &&
+ proj.LowerDistance() > _grid->_tol )
+ {
+ Quantity_Parameter u,v;
+ proj.LowerDistanceParameters( u,v );
+ gp_Dir normal;
+ if ( GeomLib::NormEstim( BRep_Tool::Surface( face, loc ),
+ gp_Pnt2d( u,v ),
+ 0.1*_grid->_tol,
+ normal ) < 3 )
+ {
+ if ( face.Orientation() == TopAbs_REVERSED )
+ normal.Reverse();
+ gp_Vec v( proj.NearestPoint(), testPnt );
+ return v * normal > 0;
+ }
+ }
+ // if ( !_hexLinks[ iLink ]._nodes[0]->Node() ) // no node
+ // return true;
+ // if ( !_hexLinks[ iLink ]._nodes[0]->_intPoint ) // no intersection with geometry
+ // return false;
+ // switch ( _hexLinks[ iLink ]._nodes[0]->FaceIntPnt()->_transition ) {
+ // case Trans_OUT: return true;
+ // case Trans_IN : return false;
+ // default: ; // tangent transition
+ // }
+
+// // ijk of a GridLine corresponding to the link
+// int iDir = iLink / 4;
+// int indSub = iLink % 4;
+// LineIndexer li = _grid->GetLineIndexer( iDir );
+// li.SetIJK( _i,_j,_k );
+// size_t lineIndex[4] = { li.LineIndex (),
+// li.LineIndex10(),
+// li.LineIndex01(),
+// li.LineIndex11() };
+// GridLine& line = _grid->_lines[ iDir ][ lineIndex[ indSub ]];
+
+// // analyze transition of previous ip
+// bool isOut = true;
+// multiset< F_IntersectPoint >::const_iterator ip = line._intPoints.begin();
+// for ( ; ip != line._intPoints.end(); ++ip )
+// {
+// if ( &(*ip) == _hexLinks[ iLink ]._nodes[0]->_intPoint )
+// break;
+// switch ( ip->_transition ) {
+// case Trans_OUT: isOut = true;
+// case Trans_IN : isOut = false;
+// default:;
+// }
+// }
+// #ifdef _DEBUG_
+// if ( ip == line._intPoints.end() )
+// cout << "BUG: Wrong GridLine. IKJ = ( "<< _i << " " << _j << " " << _k << " )" << endl;
+// #endif
+ return isOut;