- case POS_LEFT: {
- // point is most close to a segment
- gp_Vec p0p1( point, xyz[ pos._index ] );
- gp_Vec p1p2( xyz[ pos._index ], xyz[ pos._index+1 ]); // segment vector
- p1p2.Normalize();
- double projDist = p0p1 * p1p2; // distance projected to the segment
- gp_Vec projVec = p1p2 * projDist;
- gp_Vec distVec = p0p1 - projVec;
- // cout << distVec.Magnitude() << ", SEG " << face->GetNode(pos._index)->GetID()
- // << " - " << face->GetNodeWrap(pos._index+1)->GetID() << endl;
- return distVec.Magnitude();
- }
- case POS_RIGHT: {
- // point is inside the face
- double distToFacePlane = tmpPnt.Y();
- // cout << distToFacePlane << ", INSIDE " << endl;
- return Abs( distToFacePlane );
- }
- case POS_VERTEX: {
- // point is most close to a node
- gp_Vec distVec( point, xyz[ pos._index ]);
- // cout << distVec.Magnitude() << " VERTEX " << face->GetNode(pos._index)->GetID() << endl;
- return distVec.Magnitude();
- }
- default:;
+ PointPos pos = *posIt;
+ if ( pos._name != pntPosSet.begin()->_name )
+ break;
+ switch ( pos._name )
+ {
+ case POS_LEFT: // point is most close to an edge
+ {
+ gp_Vec edge( xyz[ pos._index ], xyz[ pos._index+1 ]);
+ gp_Vec n1p ( xyz[ pos._index ], point );
+ double u = ( edge * n1p ) / edge.SquareMagnitude(); // param [0,1] on the edge
+ // projection of the point on the edge
+ gp_XYZ proj = xyz[ pos._index ] + u * edge.XYZ();
+ double dist2 = point.SquareDistance( proj );
+ if ( dist2 < minDist2 )
+ {
+ if ( closestPnt ) *closestPnt = proj;
+ minDist2 = dist2;
+ }
+ break;
+ }
+
+ case POS_RIGHT: // point is inside the face
+ {
+ double distToFacePlane = Abs( tmpPnt.Y() );
+ if ( closestPnt )
+ {
+ if ( distToFacePlane < std::numeric_limits<double>::min() ) {
+ *closestPnt = point.XYZ();
+ }
+ else {
+ tmpPnt.SetY( 0 );
+ trsf.Inverted().Transforms( tmpPnt );
+ *closestPnt = tmpPnt;
+ }
+ }
+ return distToFacePlane;
+ }
+
+ case POS_VERTEX: // point is most close to a node
+ {
+ double dist2 = point.SquareDistance( xyz[ pos._index ]);
+ if ( dist2 < minDist2 )
+ {
+ if ( closestPnt ) *closestPnt = xyz[ pos._index ];
+ minDist2 = dist2;
+ }
+ break;
+ }
+ default:;
+ return badDistance;
+ }