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