Integration of OCCT 6.5.0 from SVN
[occt.git] / src / ShapeAnalysis / ShapeAnalysis_TransferParametersProj.cxx
1 #include <ShapeAnalysis_TransferParametersProj.ixx>
2 #include <Geom2dAdaptor_HCurve.hxx>
3 #include <Geom2d_Curve.hxx>
4 #include <Adaptor3d_CurveOnSurface.hxx>
5 #include <Geom_Surface.hxx>
6 #include <GeomAdaptor_HSurface.hxx>
7 #include <BRep_Tool.hxx>
8 #include <TColStd_HArray1OfReal.hxx>
9 #include <TopLoc_Location.hxx>
10 #include <ShapeAnalysis_Edge.hxx>
11 #include <TColgp_SequenceOfPnt.hxx>
12 #include <ShapeAnalysis_Curve.hxx>
13 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
14 #include <BRep_TEdge.hxx>
15 #include <BRep_GCurve.hxx>
16 #include <BRep_ListOfCurveRepresentation.hxx>
17 #include <BRep_ListOfCurveRepresentation.hxx>
18 #include <Precision.hxx>
19 #include <ShapeBuild_Edge.hxx>
20 #include <BRep_Builder.hxx>
21 #include <GeomAdaptor_Curve.hxx>
22 #include <ShapeAnalysis.hxx>
23 #include <Geom2d_TrimmedCurve.hxx>
24 #include <Geom2d_OffsetCurve.hxx>
25 #include <Geom2d_BSplineCurve.hxx>
26 #include <BRep_ListOfPointRepresentation.hxx>
27 #include <BRep_TVertex.hxx>
28 #include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
29 #include <BRep_PointRepresentation.hxx>
30 #include <BRep_PointOnSurface.hxx>
31 #include <BRep_PointOnCurve.hxx>
32 #include <BRep_PointOnCurveOnSurface.hxx>
33 #include <TopoDS.hxx>  
34 #include <ShapeAnalysis_Surface.hxx>
35 //=======================================================================
36 //function : ShapeAnalysis_TransferParametersProj
37 //purpose  : 
38 //=======================================================================
39
40 ShapeAnalysis_TransferParametersProj::ShapeAnalysis_TransferParametersProj()
41 {
42   myMaxTolerance = 1; //Precision::Infinite(); ?? pdn
43   myForceProj = Standard_False;
44   myInitOK = Standard_False;
45 }
46
47
48 //=======================================================================
49 //function : ShapeAnalysis_TransferParametersProj
50 //purpose  : 
51 //=======================================================================
52
53 ShapeAnalysis_TransferParametersProj::ShapeAnalysis_TransferParametersProj(const TopoDS_Edge& E,
54                                                                            const TopoDS_Face& F)
55 {
56   myMaxTolerance = 1; //Precision::Infinite(); ?? pdn
57   myForceProj = Standard_False;
58   Init(E,F);
59 }
60
61
62 //=======================================================================
63 //function : Init
64 //purpose  : 
65 //=======================================================================
66
67 void ShapeAnalysis_TransferParametersProj::Init(const TopoDS_Edge& E,
68                                                 const TopoDS_Face& F)
69 {
70   myInitOK = Standard_False;
71   ShapeAnalysis_TransferParameters::Init(E,F);
72   myEdge = E;
73   myPrecision = BRep_Tool::Tolerance(E); // it is better - skl OCC2851
74   //myPrecision = Precision::Confusion();
75
76   myCurve = BRep_Tool::Curve (E, myFirst, myLast);
77   if ( myCurve.IsNull() ) { myFirst = 0.; myLast = 1.; return;}
78     
79   if ( F.IsNull() ) return;
80     
81   Standard_Real f2d, l2d;
82   ShapeAnalysis_Edge sae;
83   if(sae.PCurve (E, F, myCurve2d, f2d, l2d, Standard_False)) {
84       
85     Handle(Geom2dAdaptor_HCurve) AC2d  = new Geom2dAdaptor_HCurve(myCurve2d,f2d,l2d);
86     Handle(Geom_Surface) aSurface = BRep_Tool::Surface(F,myLocation);
87     Handle(GeomAdaptor_HSurface) AdS = new GeomAdaptor_HSurface(aSurface);
88     
89     Adaptor3d_CurveOnSurface Ad1(AC2d,AdS);
90     myAC3d = Ad1;//new Adaptor3d_CurveOnSurface(AC2d,AdS);
91     myInitOK = Standard_True;
92   }
93 }
94
95
96 //=======================================================================
97 //function : Perform
98 //purpose  : 
99 //=======================================================================
100
101 Handle(TColStd_HSequenceOfReal) ShapeAnalysis_TransferParametersProj::Perform
102           (const Handle(TColStd_HSequenceOfReal)& Knots,
103            const Standard_Boolean To2d) 
104 {
105   //pdn
106   if( !myInitOK || 
107      (! myForceProj && myPrecision < myMaxTolerance && BRep_Tool::SameParameter(myEdge)))
108     return ShapeAnalysis_TransferParameters::Perform(Knots,To2d);
109   
110   Handle(TColStd_HSequenceOfReal) resKnots = new TColStd_HSequenceOfReal;
111
112   Standard_Integer len = Knots->Length();
113   Standard_Real preci = 2*Precision::PConfusion();
114
115   Standard_Real first = (To2d ? myAC3d.FirstParameter() : myFirst);
116   Standard_Real last  = (To2d ? myAC3d.LastParameter() : myLast);
117   Standard_Real maxPar = first;
118   Standard_Real lastPar = last;
119   Standard_Real prevPar = maxPar;
120
121   Standard_Integer j; // svv Jan 10 2000 : porting on DEC
122   for(j = 1; j <= len; j++) {
123     Standard_Real par = PreformSegment(Knots->Value(j),To2d,prevPar,lastPar);
124     prevPar = par;
125     if(prevPar > lastPar)
126       prevPar -= preci;
127     resKnots->Append(par);
128     if(par > maxPar)
129       maxPar = par;
130   }
131   
132   //pdn correcting on periodic
133   if(myCurve->IsClosed())
134     for(j = len; j >=1; j--) 
135       if(resKnots->Value(j) < maxPar)
136         resKnots->SetValue(j,(To2d ? myAC3d.LastParameter() : myCurve->LastParameter())-(len-j)*preci);
137       else
138         break;
139   //pdn correction on range
140   for ( j=1; j <= len; j++ ) {
141     if ( resKnots->Value (j) < first ) resKnots->SetValue ( j, first );
142     if ( resKnots->Value (j) > last  ) resKnots->SetValue ( j, last );
143   }
144   
145   return resKnots;
146 }
147
148
149 //=======================================================================
150 //function : PreformSegment
151 //purpose  : 
152 //=======================================================================
153
154 Standard_Real ShapeAnalysis_TransferParametersProj::PreformSegment(const Standard_Real Param,
155                                                                    const Standard_Boolean To2d,
156                                                                    const Standard_Real First,
157                                                                    const Standard_Real Last)
158 {
159   Standard_Real linPar = ShapeAnalysis_TransferParameters::Perform(Param, To2d);
160   if( !myInitOK || 
161      (! myForceProj && myPrecision < myMaxTolerance && BRep_Tool::SameParameter(myEdge)))
162     return linPar;
163   
164   Standard_Real linDev, projDev;
165   
166   ShapeAnalysis_Curve sac;
167   gp_Pnt pproj;
168   Standard_Real ppar;
169   if(To2d) {
170     gp_Pnt p1 = myCurve->Value(Param).Transformed(myLocation.Inverted());
171     Handle(Adaptor3d_HSurface) AdS = myAC3d.GetSurface();
172     Handle(Geom2dAdaptor_HCurve) AC2d  = new Geom2dAdaptor_HCurve(myCurve2d,First,Last);
173     Adaptor3d_CurveOnSurface Ad1(AC2d,AdS);
174     projDev = sac.Project(Ad1,p1,myPrecision,pproj,ppar);//pdn
175     linDev = p1.Distance(Ad1.Value(linPar));
176   }
177   else {
178     gp_Pnt p1 = myAC3d.Value(Param).Transformed(myLocation);
179     projDev = sac.Project(myCurve,p1,myPrecision,pproj,ppar,First,Last,Standard_False);
180     linDev = p1.Distance(myCurve->Value(linPar));
181   }
182   
183   if ( linDev <= projDev ||  (linDev < myPrecision && linDev <= 2 * projDev ) ) 
184     ppar = linPar;
185   return ppar;
186 }
187
188
189 //=======================================================================
190 //function : Perform
191 //purpose  : 
192 //=======================================================================
193
194 Standard_Real ShapeAnalysis_TransferParametersProj::Perform(const Standard_Real Knot,
195                                                             const Standard_Boolean To2d) 
196 {
197   if( !myInitOK || 
198      (! myForceProj && myPrecision < myMaxTolerance && BRep_Tool::SameParameter(myEdge)))
199     return ShapeAnalysis_TransferParameters::Perform(Knot, To2d);
200   
201   Standard_Real res;
202   if(To2d) 
203     res = PreformSegment(Knot,To2d,myAC3d.FirstParameter(),myAC3d.LastParameter());
204   else 
205     res = PreformSegment(Knot,To2d,myFirst,myLast);
206
207   //pdn correction on range
208   Standard_Real first = (To2d ? myAC3d.FirstParameter() : myFirst);
209   Standard_Real last  = (To2d ? myAC3d.LastParameter() : myLast);
210   if ( res < first ) res = first;
211   if ( res > last  ) res = last;
212   return res;
213 }
214
215
216 //=======================================================================
217 //function : CorrectParameter
218 //purpose  : auxilary
219 //=======================================================================
220 static Standard_Real CorrectParameter(const Handle(Geom2d_Curve) crv,
221                                       const Standard_Real param)
222 {
223   if(crv->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) {
224     Handle(Geom2d_TrimmedCurve) tmp = Handle(Geom2d_TrimmedCurve)::DownCast (crv);
225     return CorrectParameter(tmp->BasisCurve(),param);
226   } 
227   else if(crv->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))) {
228     Handle(Geom2d_OffsetCurve) tmp = Handle(Geom2d_OffsetCurve)::DownCast (crv);
229     return CorrectParameter(tmp->BasisCurve(),param);
230   } 
231   else if(crv->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) {
232     Handle(Geom2d_BSplineCurve) bspline = Handle(Geom2d_BSplineCurve)::DownCast (crv);
233     for(Standard_Integer j = bspline->FirstUKnotIndex(); j <= bspline->LastUKnotIndex(); j++) {
234       Standard_Real valknot = bspline->Knot(j);
235       if( Abs(valknot-param)<Precision::PConfusion() )
236         return valknot;
237     }
238   }
239   return param;
240 }
241     
242   
243 //=======================================================================
244 //function : TransferRange
245 //purpose  : 
246 //=======================================================================
247
248 void ShapeAnalysis_TransferParametersProj::TransferRange(TopoDS_Edge& newEdge,
249                                                          const Standard_Real prevPar,
250                                                          const Standard_Real currPar,
251                                                          const Standard_Boolean Is2d) 
252 {
253   if( !myInitOK || 
254      (! myForceProj && myPrecision < myMaxTolerance && BRep_Tool::SameParameter(myEdge))) {
255     ShapeAnalysis_TransferParameters::TransferRange(newEdge,prevPar,currPar,Is2d);
256     return;
257   }
258
259   BRep_Builder B;
260   Standard_Boolean samerange = Standard_True;
261   ShapeBuild_Edge sbe;
262   sbe.CopyRanges(newEdge,myEdge);
263   gp_Pnt p1;
264   gp_Pnt p2;
265   Standard_Real alpha = 0, beta = 1;
266   Standard_Real preci = Precision::PConfusion();
267   Standard_Real firstPar, lastPar;
268   if(prevPar < currPar) {
269     firstPar = prevPar;
270     lastPar  = currPar;
271   }
272   else {
273     firstPar = currPar;
274     lastPar  = prevPar;
275   }
276   if(Is2d) {
277     p1 = myAC3d.Value(firstPar).Transformed(myLocation);
278     p2 = myAC3d.Value(lastPar).Transformed(myLocation);
279     Standard_Real fact = myAC3d.LastParameter() - myAC3d.FirstParameter();
280     if( fact > Epsilon(myAC3d.LastParameter()) ) {
281       alpha = ( firstPar - myAC3d.FirstParameter() ) / fact;
282       beta  = ( lastPar - myAC3d.FirstParameter() ) / fact;
283     }
284   }
285   else {
286     p1 = myCurve->Value(firstPar);
287     p2 = myCurve->Value(lastPar);
288     Standard_Real fact = myLast - myFirst;
289     if( fact > Epsilon(myLast) ) {
290       alpha = ( firstPar - myFirst ) / fact;
291       beta  = ( lastPar - myFirst ) / fact;
292     }
293   }
294   const Standard_Boolean useLinearFirst = (alpha < preci);
295   const Standard_Boolean useLinearLast = (1-beta < preci);
296   TopLoc_Location EdgeLoc = myEdge.Location();
297   ShapeAnalysis_Curve sac;
298   gp_Pnt pproj;
299   Standard_Real ppar1,ppar2;
300   BRep_ListOfCurveRepresentation& tolist = (*((Handle(BRep_TEdge)*)&newEdge.TShape()))->ChangeCurves();
301   Handle(BRep_GCurve) toGC;
302   for (BRep_ListIteratorOfListOfCurveRepresentation toitcr (tolist); toitcr.More(); toitcr.Next()) {
303     toGC = Handle(BRep_GCurve)::DownCast(toitcr.Value());
304     if ( toGC.IsNull() ) continue;
305     TopLoc_Location loc = ( EdgeLoc * toGC->Location() ).Inverted();
306     if ( toGC->IsCurve3D() ) {
307       if (!Is2d) {
308         ppar1 = firstPar;
309         ppar2 = lastPar;
310       } 
311       else {
312         Handle(Geom_Curve) C3d = toGC->Curve3D();
313         if (C3d.IsNull()) continue;
314         Standard_Real first = toGC->First();
315         Standard_Real last  = toGC->Last();
316         Standard_Real len = last -first;
317         gp_Pnt ploc1 = p1.Transformed(loc);
318         gp_Pnt ploc2 = p2.Transformed(loc); 
319         GeomAdaptor_Curve GAC(C3d,first,last);
320         // CATIA bplseitli.model FAC1155 - Copy: protection for degenerated edges(3d case for symmetry)
321         Standard_Real linFirst = first+alpha*len;
322         Standard_Real linLast  = first+beta*len;
323         Standard_Real dist1 = sac.NextProject(linFirst,GAC,ploc1,myPrecision,pproj,ppar1);
324         Standard_Real dist2 = sac.NextProject(linLast,GAC,ploc2,myPrecision,pproj,ppar2);
325         Standard_Boolean useLinear = Abs(ppar1-ppar2) < preci;
326         
327         gp_Pnt pos1 = C3d->Value ( linFirst );
328         gp_Pnt pos2 = C3d->Value ( linLast );
329         Standard_Real d01 = pos1.Distance ( ploc1 );
330         Standard_Real d02 = pos2.Distance ( ploc2 );
331         if ( useLinearFirst || useLinear || d01 <= dist1 || ( d01 < myPrecision && d01 <= 2 * dist1 ) ) 
332           ppar1 = linFirst;
333         if ( useLinearLast || useLinear || d02 <= dist2 || ( d02 < myPrecision && d02 <= 2 * dist2 ) ) 
334           ppar2 = linLast;
335       }
336       if(ppar1 > ppar2) {
337         Standard_Real tmpP = ppar2; ppar2 = ppar1; ppar1 = tmpP;
338       }
339       if(ppar2-ppar1 < preci) {
340         if(ppar1-toGC->First() < preci)
341           ppar2+=2*preci;
342         else if(toGC->Last()-ppar2 < preci)
343           ppar1-=2*preci;
344         else {
345           ppar1 -= preci;
346           ppar2 += preci;
347         }
348       }
349       toGC->SetRange ( ppar1, ppar2);
350       //if(fabs(ppar1- firstPar) > Precision::PConfusion() || 
351         //     fabs(ppar2 - lastPar) >Precision::PConfusion()) // by LSS
352       if(ppar1!=firstPar || ppar2!=lastPar)
353         samerange = Standard_False;
354       
355     }
356     else if (toGC->IsCurveOnSurface()) { //continue;  || 
357
358       Standard_Boolean localLinearFirst = useLinearFirst;
359       Standard_Boolean localLinearLast  = useLinearLast;
360       Handle(Geom2d_Curve) C2d = toGC->PCurve();
361       Standard_Real first = toGC->First();
362       Standard_Real last  = toGC->Last();
363       Standard_Real len = last -first;
364       Handle(Geom2dAdaptor_HCurve) AC2d  = new Geom2dAdaptor_HCurve(toGC->PCurve(),first,last);
365       Handle(GeomAdaptor_HSurface) AdS = new GeomAdaptor_HSurface( toGC->Surface());
366       Adaptor3d_CurveOnSurface Ad1(AC2d,AdS);
367       ShapeAnalysis_Curve sac1;
368       
369       //gp_Pnt p1 = Ad1.Value(prevPar);
370       //gp_Pnt p2 = Ad1.Value(currPar);
371       gp_Pnt ploc1 = p1.Transformed(loc);
372       gp_Pnt ploc2 = p2.Transformed(loc);
373       // CATIA bplseitli.model FAC1155 - Copy: protection for degenerated edges
374       Standard_Real linFirst = first+alpha*len;
375       Standard_Real linLast  = first+beta*len;
376       Standard_Real dist1 = sac1.NextProject(linFirst, Ad1, ploc1, myPrecision,pproj,ppar1);
377       Standard_Real dist2 = sac1.NextProject(linLast, Ad1, ploc2, myPrecision,pproj,ppar2);
378
379       Standard_Boolean isFirstOnEnd = (ppar1-first)/len < Precision::PConfusion();
380       Standard_Boolean isLastOnEnd = (last-ppar2)/len < Precision::PConfusion();
381       Standard_Boolean useLinear = Abs(ppar1-ppar2) < Precision::PConfusion();
382       if(isFirstOnEnd && ! localLinearFirst)
383         localLinearFirst = Standard_True;
384       if(isLastOnEnd && ! localLinearLast)
385         localLinearLast  = Standard_True;
386
387       gp_Pnt pos1 = Ad1.Value ( linFirst );
388       gp_Pnt pos2 = Ad1.Value ( linLast );
389       Standard_Real d01 = pos1.Distance ( ploc1 );
390       Standard_Real d02 = pos2.Distance ( ploc2 );
391       if ( localLinearFirst || useLinear || d01 <= dist1 || ( d01 < myPrecision && d01 <= 2 * dist1 ) ) 
392         ppar1 = linFirst;
393       if ( localLinearLast  || useLinear || d02 <= dist2 || ( d02 < myPrecision && d02 <= 2 * dist2 ) ) 
394         ppar2 = linLast;
395
396       if(ppar1 > ppar2) {
397         Standard_Real tmpP = ppar2; ppar2 = ppar1; ppar1 = tmpP;
398       }
399       ppar1 = CorrectParameter(C2d,ppar1);
400       ppar2 = CorrectParameter(C2d,ppar2);
401       if(ppar2-ppar1 < preci) {
402         if(ppar1-toGC->First() < preci)
403           ppar2+=2*preci;
404         else if(toGC->Last()-ppar2 < preci)
405           ppar1-=2*preci;
406         else {
407           ppar1 -= preci;
408           ppar2 += preci;
409         }
410       }
411       toGC->SetRange ( ppar1, ppar2);
412       //if(fabs(ppar1 - firstPar) > Precision::PConfusion() || 
413         //    fabs(ppar2 -lastPar) > Precision::PConfusion())// by LSS
414       if(ppar1 != firstPar || ppar2 != lastPar)
415             samerange = Standard_False;
416     }
417   }
418   B.SameRange(newEdge, samerange);
419 }
420
421
422 //=======================================================================
423 //function : IsSameRange
424 //purpose  : 
425 //=======================================================================
426
427 Standard_Boolean ShapeAnalysis_TransferParametersProj::IsSameRange() const
428 {
429
430   if( !myInitOK || 
431      (! myForceProj && myPrecision < myMaxTolerance && BRep_Tool::SameParameter(myEdge)))
432     return ShapeAnalysis_TransferParameters::IsSameRange();
433   else
434     return Standard_False;
435 }
436
437
438 //=======================================================================
439 //function : ForceProjection
440 //purpose  : 
441 //=======================================================================
442
443 Standard_Boolean& ShapeAnalysis_TransferParametersProj::ForceProjection() 
444 {
445   return myForceProj;
446 }
447
448 //=======================================================================
449 //function : CopyNMVertex
450 //purpose  : 
451 //=======================================================================
452
453 TopoDS_Vertex ShapeAnalysis_TransferParametersProj::CopyNMVertex (const TopoDS_Vertex& theV,
454                                    const TopoDS_Edge& toedge, 
455                                    const TopoDS_Edge& fromedge)
456 {
457   TopoDS_Vertex anewV;
458   if(theV.Orientation() != TopAbs_INTERNAL &&
459      theV.Orientation() != TopAbs_EXTERNAL)
460     return anewV;
461   
462   TopLoc_Location fromLoc;
463   Standard_Real f1,l1;
464   const Handle(Geom_Curve)& C1 = BRep_Tool::Curve(fromedge,fromLoc,f1,l1);
465   fromLoc = fromLoc.Predivided(theV.Location());
466   
467   Standard_Real f2,l2;
468   Handle(Geom_Curve) C2 = BRep_Tool::Curve(toedge,f2,l2);
469   
470   anewV = TopoDS::Vertex(theV.EmptyCopied());
471   gp_Pnt apv = BRep_Tool::Pnt(anewV);
472   
473    BRep_ListOfPointRepresentation& alistrep = 
474     (*((Handle(BRep_TVertex)*)&anewV.TShape()))->ChangePoints();
475   
476   BRep_ListIteratorOfListOfPointRepresentation itpr
477           ((*((Handle(BRep_TVertex)*) &theV.TShape()))->Points());
478   
479   Standard_Real aOldPar = RealLast();
480   Standard_Boolean hasRepr = Standard_False;
481   for ( ;itpr.More(); itpr.Next()) {
482     const Handle(BRep_PointRepresentation)& pr = itpr.Value();
483     if(pr.IsNull())
484       continue;
485     if(pr->IsPointOnCurve(C1,fromLoc)) {
486       aOldPar = pr->Parameter();
487       hasRepr =Standard_True;
488       continue;
489     }
490     else if(pr->IsPointOnSurface()) {
491       Handle(BRep_PointOnSurface) aOld = Handle(BRep_PointOnSurface)::DownCast(pr);
492       Handle(BRep_PointOnSurface) aPS = new BRep_PointOnSurface(aOld->Parameter(),
493                                                                   aOld->Parameter2(),
494                                                                   aOld->Surface(),
495                                                                   aOld->Location());
496       alistrep.Append(aPS);
497       continue;
498     }
499     else if(pr->IsPointOnCurveOnSurface()) {
500       Standard_Boolean found = Standard_False;
501       BRep_ListIteratorOfListOfCurveRepresentation fromitcr
502         ((*((Handle(BRep_TEdge)*)&fromedge.TShape()))->ChangeCurves());
503       
504       for( ;fromitcr.More() && !found; fromitcr.Next()) {
505         Handle(BRep_GCurve) fromGC = Handle(BRep_GCurve)::DownCast(fromitcr.Value());
506         if ( fromGC.IsNull() || !fromGC->IsCurveOnSurface()) continue;
507         
508         TopLoc_Location aL = fromGC->Location();
509         aL.Predivided(theV.Location());
510         Handle(Geom_Surface) surface1 = fromGC->Surface();
511         Handle(Geom2d_Curve) ac2d1 = fromGC->PCurve();
512         if (pr->IsPointOnCurveOnSurface(ac2d1,surface1,aL)) {
513       found = Standard_True;
514           if(!hasRepr) {
515             aOldPar = pr->Parameter();
516           }
517         }
518       }
519       if(found) continue;
520     }
521     if(pr->IsPointOnCurve()) {
522       Handle(BRep_PointOnCurve) aPRep = new BRep_PointOnCurve(pr->Parameter(),pr->Curve(),pr->Location());
523       alistrep.Append(aPRep);
524     }
525     else if(pr->IsPointOnCurveOnSurface() ) {
526       Handle(BRep_PointOnCurveOnSurface) aPonCS = 
527         new BRep_PointOnCurveOnSurface(pr->Parameter(),pr->PCurve(),pr->Surface(),pr->Location()); 
528       alistrep.Append(aPonCS);
529     }
530   }
531   Standard_Real apar = aOldPar;
532   Standard_Real aTol = BRep_Tool::Tolerance(theV);
533   if(!hasRepr || (fabs(f1-f2) > Precision::PConfusion() || fabs(l1-l2)> Precision::PConfusion())) {
534     gp_Pnt projP;
535     ShapeAnalysis_Curve sae;
536     Standard_Real adist = sae.Project(C2,apv,Precision::Confusion(),projP,apar);
537     if(aTol < adist)
538       aTol = adist;
539   }
540   BRep_Builder aB;
541   aB.UpdateVertex(anewV,apar,toedge,aTol);
542   
543   //update tolerance
544   Standard_Boolean needUpdate = Standard_False;
545   gp_Pnt aPV = (*((Handle(BRep_TVertex)*)&anewV.TShape()))->Pnt();
546   TopLoc_Location toLoc = toedge.Location();
547   BRep_ListIteratorOfListOfCurveRepresentation toitcr
548         ((*((Handle(BRep_TEdge)*)&toedge.TShape()))->ChangeCurves());
549       
550   for( ;toitcr.More() ; toitcr.Next()) {
551         Handle(BRep_GCurve) toGC = Handle(BRep_GCurve)::DownCast(toitcr.Value());
552         if ( toGC.IsNull() || !toGC->IsCurveOnSurface()) continue;
553         
554         TopLoc_Location aL = (toLoc*toGC->Location()).Predivided(theV.Location());
555         //aL.Predivided(theV.Location());
556         Handle(Geom_Surface) surface1 = toGC->Surface();
557         Handle(Geom2d_Curve) ac2d1 = toGC->PCurve();
558         gp_Pnt2d aP2d = ac2d1->Value(apar);
559     gp_Pnt aP3d = surface1->Value(aP2d.X(),aP2d.Y());
560     aP3d.Transform(aL.Transformation());
561     Standard_Real adist = aPV.Distance(aP3d);
562     if(adist > aTol) {
563       aTol = adist;
564       needUpdate = Standard_True;
565     }
566
567   } 
568   if(needUpdate)
569     aB.UpdateVertex(anewV,aTol);
570   return anewV;
571 }
572
573 //=======================================================================
574 //function : CopyNMVertex
575 //purpose  : 
576 //=======================================================================
577
578 TopoDS_Vertex ShapeAnalysis_TransferParametersProj::CopyNMVertex (const TopoDS_Vertex& theV,
579                                    const TopoDS_Face& toFace, 
580                                    const TopoDS_Face& fromFace)
581 {
582   TopoDS_Vertex anewV;
583   if(theV.Orientation() != TopAbs_INTERNAL &&
584      theV.Orientation() != TopAbs_EXTERNAL)
585     return anewV;
586   
587
588   TopLoc_Location fromLoc;
589   TopLoc_Location toLoc;
590   Handle(Geom_Surface) fromSurf = BRep_Tool::Surface(fromFace,fromLoc);
591   Handle(Geom_Surface) toSurf = BRep_Tool::Surface(toFace,toLoc);
592   fromLoc = fromLoc.Predivided(theV.Location());
593   
594   anewV = TopoDS::Vertex(theV.EmptyCopied());
595   gp_Pnt apv = BRep_Tool::Pnt(anewV);
596   
597   
598   BRep_ListOfPointRepresentation& alistrep = 
599     (*((Handle(BRep_TVertex)*)&anewV.TShape()))->ChangePoints();
600   
601   BRep_ListIteratorOfListOfPointRepresentation itpr
602           ((*((Handle(BRep_TVertex)*) &theV.TShape()))->Points());
603   
604   Standard_Boolean hasRepr = Standard_False;
605   Standard_Real apar1=0., apar2=0.;
606   for ( ;itpr.More(); itpr.Next()) {
607     const Handle(BRep_PointRepresentation)& pr = itpr.Value();
608     if(pr.IsNull())
609       continue;
610     TopLoc_Location aLoc = pr->Location();
611     if( pr->IsPointOnCurveOnSurface()) {
612       Handle(BRep_PointOnCurveOnSurface) aPonCS = 
613             new BRep_PointOnCurveOnSurface(pr->Parameter(),pr->PCurve(),pr->Surface(),aLoc); 
614       alistrep.Append(aPonCS);
615     }
616     else if(pr->IsPointOnCurve()) {
617       Handle(BRep_PointOnCurve) aPRep = new BRep_PointOnCurve(pr->Parameter(),pr->Curve(),aLoc);
618       alistrep.Append(aPRep);
619     }
620     else if(pr->IsPointOnSurface()) {
621       Handle(BRep_PointOnSurface) aOld = Handle(BRep_PointOnSurface)::DownCast(pr);
622       
623       if(pr->IsPointOnSurface(fromSurf,fromLoc)) {
624         apar1= aOld->Parameter();
625         apar2 = aOld->Parameter2();
626         hasRepr = Standard_True;
627       }
628       else {
629         Handle(BRep_PointOnSurface) aPS = new BRep_PointOnSurface(aOld->Parameter(),
630                                                                     aOld->Parameter2(),
631                                                                     aOld->Surface(),
632                                                                     aOld->Location());
633         alistrep.Append(aPS);
634       }
635     }
636     
637   }
638   Standard_Real aTol = BRep_Tool::Tolerance(anewV);
639   if(!hasRepr || (fromSurf != toSurf || fromLoc != toLoc)) {
640     Handle(Geom_Surface) aS = BRep_Tool::Surface(toFace);
641     Handle(ShapeAnalysis_Surface) aSurfTool = new ShapeAnalysis_Surface(aS);
642     gp_Pnt2d aP2d = aSurfTool->ValueOfUV(apv,Precision::Confusion());
643     apar1 = aP2d.X();
644     apar2 = aP2d.Y();
645     
646     if(aTol < aSurfTool->Gap())
647       aTol = aSurfTool->Gap() + 0.1*Precision::Confusion();
648     //Handle(BRep_PointOnSurface) aPS = new BRep_PointOnSurface(aP2d.X(),aP2d.Y(),toSurf,toLoc);
649     //alistrep.Append(aPS);
650   }
651   
652   BRep_Builder aB;
653   aB.UpdateVertex(anewV,apar1,apar2,toFace,aTol);
654   return anewV;
655 }
656