- // switch ( myVolumeNbNodes ) {
- // case 4:
- // case 5:
- // case 10:
- // case 13:
- // // only the bottom of a reversed tetrahedron can be internal
- // return ( myVolForward || faceIndex != 0 );
- // case 6:
- // case 15:
- // case 12:
- // // in a forward prism, the top is internal, in a reversed one - bottom
- // return ( myVolForward ? faceIndex != 1 : faceIndex != 0 );
- // case 8:
- // case 20:
- // case 27: {
- // // in a forward hexahedron, even face normal is external, odd - internal
- // bool odd = faceIndex % 2;
- // return ( myVolForward ? !odd : odd );
+ // compare orientation of links of the facet with myFwdLinks
+ ori = 0;
+ setFace( faceIndex );
+ vector< NLink > links( myCurFace.myNbNodes ), links2;
+ for ( int i = 0; i < myCurFace.myNbNodes && !ori; ++i )
+ {
+ NLink link( myCurFace.myNodes[i], myCurFace.myNodes[i+1] );
+ std::map<Link, int>::iterator l2o = me->myFwdLinks.find( link );
+ if ( l2o != me->myFwdLinks.end() )
+ ori = link.myOri * l2o->second * -1;
+ links[ i ] = link;
+ }
+ while ( !ori ) // the facet has no common links with already oriented facets
+ {
+ // orient and collect links of other non-oriented facets
+ for ( size_t iF = 0; iF < myPolyFacetOri.size(); ++iF )
+ {
+ if ( me->myPolyFacetOri[ iF ] ) continue; // already oriented
+ setFace( iF );
+ links2.clear();
+ ori = 0;
+ for ( int i = 0; i < myCurFace.myNbNodes && !ori; ++i )
+ {
+ NLink link( myCurFace.myNodes[i], myCurFace.myNodes[i+1] );
+ std::map<Link, int>::iterator l2o = me->myFwdLinks.find( link );
+ if ( l2o != me->myFwdLinks.end() )
+ ori = link.myOri * l2o->second * -1;
+ links2.push_back( link );
+ }
+ if ( ori ) // one more facet oriented
+ {
+ me->myPolyFacetOri[ iF ] = ori;
+ for ( size_t i = 0; i < links2.size(); ++i )
+ me->myFwdLinks.insert( make_pair( links2[i], links2[i].myOri * ori ));
+ break;
+ }
+ }
+ if ( !ori )
+ return false; // error in algorithm: infinite loop
+
+ // try to orient the facet again
+ ori = 0;
+ for ( size_t i = 0; i < links.size() && !ori; ++i )
+ {
+ std::map<Link, int>::iterator l2o = me->myFwdLinks.find( links[i] );
+ if ( l2o != me->myFwdLinks.end() )
+ ori = links[i].myOri * l2o->second * -1;
+ }
+ me->myPolyFacetOri[ faceIndex ] = ori;
+ }
+
+ return ori > 0;
+}
+
+//=======================================================================
+//function : projectNodesToNormal
+//purpose : compute min and max projections of all nodes to normal of a facet.
+//=======================================================================
+
+bool SMDS_VolumeTool::projectNodesToNormal( int faceIndex,
+ double& minProj,
+ double& maxProj ) const
+{
+ minProj = std::numeric_limits<double>::max();
+ maxProj = std::numeric_limits<double>::min();
+
+ XYZ normal;
+ if ( !GetFaceNormal( faceIndex, normal.x, normal.y, normal.z ))
+ return false;
+ XYZ p0 ( myCurFace.myNodes[0] );
+ for ( size_t i = 0; i < myVolumeNodes.size(); ++i )
+ {
+ if ( std::find( myCurFace.myNodes.begin() + 1,
+ myCurFace.myNodes.end(),
+ myVolumeNodes[ i ] ) != myCurFace.myNodes.end() )
+ continue; // node of the faceIndex-th facet
+
+ double proj = normal.Dot( XYZ( myVolumeNodes[ i ]) - p0 );
+ if ( proj < minProj ) minProj = proj;
+ if ( proj > maxProj ) maxProj = proj;
+ }
+ const double tol = 1e-7;
+ minProj += tol;
+ maxProj -= tol;
+ bool diffSize = ( minProj * maxProj < 0 );
+ // if ( diffSize )
+ // {
+ // minProj = -minProj;