aa3089560a93a38a1ab1bf1665cdc17fb56aadb3
[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   //pdn correction on range
157   for ( j=1; j <= len; j++ ) {
158     if ( resKnots->Value (j) < first ) resKnots->SetValue ( j, first );
159     if ( resKnots->Value (j) > last  ) resKnots->SetValue ( j, last );
160   }
161   
162   return resKnots;
163 }
164
165
166 //=======================================================================
167 //function : PreformSegment
168 //purpose  : 
169 //=======================================================================
170
171 Standard_Real ShapeAnalysis_TransferParametersProj::PreformSegment(const Standard_Real Param,
172                                                                    const Standard_Boolean To2d,
173                                                                    const Standard_Real First,
174                                                                    const Standard_Real Last)
175 {
176   Standard_Real linPar = ShapeAnalysis_TransferParameters::Perform(Param, To2d);
177   if( !myInitOK || 
178      (! myForceProj && myPrecision < myMaxTolerance && BRep_Tool::SameParameter(myEdge)))
179     return linPar;
180   
181   Standard_Real linDev, projDev;
182   
183   ShapeAnalysis_Curve sac;
184   gp_Pnt pproj;
185   Standard_Real ppar;
186   if(To2d) {
187     gp_Pnt p1 = myCurve->Value(Param).Transformed(myLocation.Inverted());
188     Handle(Adaptor3d_HSurface) AdS = myAC3d.GetSurface();
189     Handle(Geom2dAdaptor_HCurve) AC2d  = new Geom2dAdaptor_HCurve(myCurve2d,First,Last);
190     Adaptor3d_CurveOnSurface Ad1(AC2d,AdS);
191     projDev = sac.Project(Ad1,p1,myPrecision,pproj,ppar);//pdn
192     linDev = p1.Distance(Ad1.Value(linPar));
193   }
194   else {
195     gp_Pnt p1 = myAC3d.Value(Param).Transformed(myLocation);
196     projDev = sac.Project(myCurve,p1,myPrecision,pproj,ppar,First,Last,Standard_False);
197     linDev = p1.Distance(myCurve->Value(linPar));
198   }
199   
200   if ( linDev <= projDev ||  (linDev < myPrecision && linDev <= 2 * projDev ) ) 
201     ppar = linPar;
202   return ppar;
203 }
204
205
206 //=======================================================================
207 //function : Perform
208 //purpose  : 
209 //=======================================================================
210
211 Standard_Real ShapeAnalysis_TransferParametersProj::Perform(const Standard_Real Knot,
212                                                             const Standard_Boolean To2d) 
213 {
214   if( !myInitOK || 
215      (! myForceProj && myPrecision < myMaxTolerance && BRep_Tool::SameParameter(myEdge)))
216     return ShapeAnalysis_TransferParameters::Perform(Knot, To2d);
217   
218   Standard_Real res;
219   if(To2d) 
220     res = PreformSegment(Knot,To2d,myAC3d.FirstParameter(),myAC3d.LastParameter());
221   else 
222     res = PreformSegment(Knot,To2d,myFirst,myLast);
223
224   //pdn correction on range
225   Standard_Real first = (To2d ? myAC3d.FirstParameter() : myFirst);
226   Standard_Real last  = (To2d ? myAC3d.LastParameter() : myLast);
227   if ( res < first ) res = first;
228   if ( res > last  ) res = last;
229   return res;
230 }
231
232
233 //=======================================================================
234 //function : CorrectParameter
235 //purpose  : auxilary
236 //=======================================================================
237 static Standard_Real CorrectParameter(const Handle(Geom2d_Curve) crv,
238                                       const Standard_Real param)
239 {
240   if(crv->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) {
241     Handle(Geom2d_TrimmedCurve) tmp = Handle(Geom2d_TrimmedCurve)::DownCast (crv);
242     return CorrectParameter(tmp->BasisCurve(),param);
243   } 
244   else if(crv->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))) {
245     Handle(Geom2d_OffsetCurve) tmp = Handle(Geom2d_OffsetCurve)::DownCast (crv);
246     return CorrectParameter(tmp->BasisCurve(),param);
247   } 
248   else if(crv->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) {
249     Handle(Geom2d_BSplineCurve) bspline = Handle(Geom2d_BSplineCurve)::DownCast (crv);
250     for(Standard_Integer j = bspline->FirstUKnotIndex(); j <= bspline->LastUKnotIndex(); j++) {
251       Standard_Real valknot = bspline->Knot(j);
252       if( Abs(valknot-param)<Precision::PConfusion() )
253         return valknot;
254     }
255   }
256   return param;
257 }
258     
259   
260 //=======================================================================
261 //function : TransferRange
262 //purpose  : 
263 //=======================================================================
264
265 void ShapeAnalysis_TransferParametersProj::TransferRange(TopoDS_Edge& newEdge,
266                                                          const Standard_Real prevPar,
267                                                          const Standard_Real currPar,
268                                                          const Standard_Boolean Is2d) 
269 {
270   if( !myInitOK || 
271      (! myForceProj && myPrecision < myMaxTolerance && BRep_Tool::SameParameter(myEdge))) {
272     ShapeAnalysis_TransferParameters::TransferRange(newEdge,prevPar,currPar,Is2d);
273     return;
274   }
275
276   BRep_Builder B;
277   Standard_Boolean samerange = Standard_True;
278   ShapeBuild_Edge sbe;
279   sbe.CopyRanges(newEdge,myEdge);
280   gp_Pnt p1;
281   gp_Pnt p2;
282   Standard_Real alpha = 0, beta = 1;
283   Standard_Real preci = Precision::PConfusion();
284   Standard_Real firstPar, lastPar;
285   if(prevPar < currPar) {
286     firstPar = prevPar;
287     lastPar  = currPar;
288   }
289   else {
290     firstPar = currPar;
291     lastPar  = prevPar;
292   }
293   if(Is2d) {
294     p1 = myAC3d.Value(firstPar).Transformed(myLocation);
295     p2 = myAC3d.Value(lastPar).Transformed(myLocation);
296     Standard_Real fact = myAC3d.LastParameter() - myAC3d.FirstParameter();
297     if( fact > Epsilon(myAC3d.LastParameter()) ) {
298       alpha = ( firstPar - myAC3d.FirstParameter() ) / fact;
299       beta  = ( lastPar - myAC3d.FirstParameter() ) / fact;
300     }
301   }
302   else {
303     p1 = myCurve->Value(firstPar);
304     p2 = myCurve->Value(lastPar);
305     Standard_Real fact = myLast - myFirst;
306     if( fact > Epsilon(myLast) ) {
307       alpha = ( firstPar - myFirst ) / fact;
308       beta  = ( lastPar - myFirst ) / fact;
309     }
310   }
311   const Standard_Boolean useLinearFirst = (alpha < preci);
312   const Standard_Boolean useLinearLast = (1-beta < preci);
313   TopLoc_Location EdgeLoc = myEdge.Location();
314   ShapeAnalysis_Curve sac;
315   gp_Pnt pproj;
316   Standard_Real ppar1,ppar2;
317   BRep_ListOfCurveRepresentation& tolist = (*((Handle(BRep_TEdge)*)&newEdge.TShape()))->ChangeCurves();
318   Handle(BRep_GCurve) toGC;
319   for (BRep_ListIteratorOfListOfCurveRepresentation toitcr (tolist); toitcr.More(); toitcr.Next()) {
320     toGC = Handle(BRep_GCurve)::DownCast(toitcr.Value());
321     if ( toGC.IsNull() ) continue;
322     TopLoc_Location loc = ( EdgeLoc * toGC->Location() ).Inverted();
323     if ( toGC->IsCurve3D() ) {
324       if (!Is2d) {
325         ppar1 = firstPar;
326         ppar2 = lastPar;
327       } 
328       else {
329         Handle(Geom_Curve) C3d = toGC->Curve3D();
330         if (C3d.IsNull()) continue;
331         Standard_Real first = toGC->First();
332         Standard_Real last  = toGC->Last();
333         Standard_Real len = last -first;
334         gp_Pnt ploc1 = p1.Transformed(loc);
335         gp_Pnt ploc2 = p2.Transformed(loc); 
336         GeomAdaptor_Curve GAC(C3d,first,last);
337         // CATIA bplseitli.model FAC1155 - Copy: protection for degenerated edges(3d case for symmetry)
338         Standard_Real linFirst = first+alpha*len;
339         Standard_Real linLast  = first+beta*len;
340         Standard_Real dist1 = sac.NextProject(linFirst,GAC,ploc1,myPrecision,pproj,ppar1);
341         Standard_Real dist2 = sac.NextProject(linLast,GAC,ploc2,myPrecision,pproj,ppar2);
342         Standard_Boolean useLinear = Abs(ppar1-ppar2) < preci;
343         
344         gp_Pnt pos1 = C3d->Value ( linFirst );
345         gp_Pnt pos2 = C3d->Value ( linLast );
346         Standard_Real d01 = pos1.Distance ( ploc1 );
347         Standard_Real d02 = pos2.Distance ( ploc2 );
348         if ( useLinearFirst || useLinear || d01 <= dist1 || ( d01 < myPrecision && d01 <= 2 * dist1 ) ) 
349           ppar1 = linFirst;
350         if ( useLinearLast || useLinear || d02 <= dist2 || ( d02 < myPrecision && d02 <= 2 * dist2 ) ) 
351           ppar2 = linLast;
352       }
353       if(ppar1 > ppar2) {
354         Standard_Real tmpP = ppar2; ppar2 = ppar1; ppar1 = tmpP;
355       }
356       if(ppar2-ppar1 < preci) {
357         if(ppar1-toGC->First() < preci)
358           ppar2+=2*preci;
359         else if(toGC->Last()-ppar2 < preci)
360           ppar1-=2*preci;
361         else {
362           ppar1 -= preci;
363           ppar2 += preci;
364         }
365       }
366       toGC->SetRange ( ppar1, ppar2);
367       //if(fabs(ppar1- firstPar) > Precision::PConfusion() || 
368         //     fabs(ppar2 - lastPar) >Precision::PConfusion()) // by LSS
369       if(ppar1!=firstPar || ppar2!=lastPar)
370         samerange = Standard_False;
371       
372     }
373     else if (toGC->IsCurveOnSurface()) { //continue;  || 
374
375       Standard_Boolean localLinearFirst = useLinearFirst;
376       Standard_Boolean localLinearLast  = useLinearLast;
377       Handle(Geom2d_Curve) C2d = toGC->PCurve();
378       Standard_Real first = toGC->First();
379       Standard_Real last  = toGC->Last();
380       Standard_Real len = last -first;
381       Handle(Geom2dAdaptor_HCurve) AC2d  = new Geom2dAdaptor_HCurve(toGC->PCurve(),first,last);
382       Handle(GeomAdaptor_HSurface) AdS = new GeomAdaptor_HSurface( toGC->Surface());
383       Adaptor3d_CurveOnSurface Ad1(AC2d,AdS);
384       ShapeAnalysis_Curve sac1;
385       
386       //gp_Pnt p1 = Ad1.Value(prevPar);
387       //gp_Pnt p2 = Ad1.Value(currPar);
388       gp_Pnt ploc1 = p1.Transformed(loc);
389       gp_Pnt ploc2 = p2.Transformed(loc);
390       // CATIA bplseitli.model FAC1155 - Copy: protection for degenerated edges
391       Standard_Real linFirst = first+alpha*len;
392       Standard_Real linLast  = first+beta*len;
393       Standard_Real dist1 = sac1.NextProject(linFirst, Ad1, ploc1, myPrecision,pproj,ppar1);
394       Standard_Real dist2 = sac1.NextProject(linLast, Ad1, ploc2, myPrecision,pproj,ppar2);
395
396       Standard_Boolean isFirstOnEnd = (ppar1-first)/len < Precision::PConfusion();
397       Standard_Boolean isLastOnEnd = (last-ppar2)/len < Precision::PConfusion();
398       Standard_Boolean useLinear = Abs(ppar1-ppar2) < Precision::PConfusion();
399       if(isFirstOnEnd && ! localLinearFirst)
400         localLinearFirst = Standard_True;
401       if(isLastOnEnd && ! localLinearLast)
402         localLinearLast  = Standard_True;
403
404       gp_Pnt pos1 = Ad1.Value ( linFirst );
405       gp_Pnt pos2 = Ad1.Value ( linLast );
406       Standard_Real d01 = pos1.Distance ( ploc1 );
407       Standard_Real d02 = pos2.Distance ( ploc2 );
408       if ( localLinearFirst || useLinear || d01 <= dist1 || ( d01 < myPrecision && d01 <= 2 * dist1 ) ) 
409         ppar1 = linFirst;
410       if ( localLinearLast  || useLinear || d02 <= dist2 || ( d02 < myPrecision && d02 <= 2 * dist2 ) ) 
411         ppar2 = linLast;
412
413       if(ppar1 > ppar2) {
414         Standard_Real tmpP = ppar2; ppar2 = ppar1; ppar1 = tmpP;
415       }
416       ppar1 = CorrectParameter(C2d,ppar1);
417       ppar2 = CorrectParameter(C2d,ppar2);
418       if(ppar2-ppar1 < preci) {
419         if(ppar1-toGC->First() < preci)
420           ppar2+=2*preci;
421         else if(toGC->Last()-ppar2 < preci)
422           ppar1-=2*preci;
423         else {
424           ppar1 -= preci;
425           ppar2 += preci;
426         }
427       }
428       toGC->SetRange ( ppar1, ppar2);
429       //if(fabs(ppar1 - firstPar) > Precision::PConfusion() || 
430         //    fabs(ppar2 -lastPar) > Precision::PConfusion())// by LSS
431       if(ppar1 != firstPar || ppar2 != lastPar)
432             samerange = Standard_False;
433     }
434   }
435   B.SameRange(newEdge, samerange);
436 }
437
438
439 //=======================================================================
440 //function : IsSameRange
441 //purpose  : 
442 //=======================================================================
443
444 Standard_Boolean ShapeAnalysis_TransferParametersProj::IsSameRange() const
445 {
446
447   if( !myInitOK || 
448      (! myForceProj && myPrecision < myMaxTolerance && BRep_Tool::SameParameter(myEdge)))
449     return ShapeAnalysis_TransferParameters::IsSameRange();
450   else
451     return Standard_False;
452 }
453
454
455 //=======================================================================
456 //function : ForceProjection
457 //purpose  : 
458 //=======================================================================
459
460 Standard_Boolean& ShapeAnalysis_TransferParametersProj::ForceProjection() 
461 {
462   return myForceProj;
463 }
464
465 //=======================================================================
466 //function : CopyNMVertex
467 //purpose  : 
468 //=======================================================================
469
470 TopoDS_Vertex ShapeAnalysis_TransferParametersProj::CopyNMVertex (const TopoDS_Vertex& theV,
471                                    const TopoDS_Edge& toedge, 
472                                    const TopoDS_Edge& fromedge)
473 {
474   TopoDS_Vertex anewV;
475   if(theV.Orientation() != TopAbs_INTERNAL &&
476      theV.Orientation() != TopAbs_EXTERNAL)
477     return anewV;
478   
479   TopLoc_Location fromLoc;
480   Standard_Real f1,l1;
481   const Handle(Geom_Curve)& C1 = BRep_Tool::Curve(fromedge,fromLoc,f1,l1);
482   fromLoc = fromLoc.Predivided(theV.Location());
483   
484   Standard_Real f2,l2;
485   Handle(Geom_Curve) C2 = BRep_Tool::Curve(toedge,f2,l2);
486   
487   anewV = TopoDS::Vertex(theV.EmptyCopied());
488   gp_Pnt apv = BRep_Tool::Pnt(anewV);
489   
490    BRep_ListOfPointRepresentation& alistrep = 
491     (*((Handle(BRep_TVertex)*)&anewV.TShape()))->ChangePoints();
492   
493   BRep_ListIteratorOfListOfPointRepresentation itpr
494           ((*((Handle(BRep_TVertex)*) &theV.TShape()))->Points());
495   
496   Standard_Real aOldPar = RealLast();
497   Standard_Boolean hasRepr = Standard_False;
498   for ( ;itpr.More(); itpr.Next()) {
499     const Handle(BRep_PointRepresentation)& pr = itpr.Value();
500     if(pr.IsNull())
501       continue;
502     if(pr->IsPointOnCurve(C1,fromLoc)) {
503       aOldPar = pr->Parameter();
504       hasRepr =Standard_True;
505       continue;
506     }
507     else if(pr->IsPointOnSurface()) {
508       Handle(BRep_PointOnSurface) aOld = Handle(BRep_PointOnSurface)::DownCast(pr);
509       Handle(BRep_PointOnSurface) aPS = new BRep_PointOnSurface(aOld->Parameter(),
510                                                                   aOld->Parameter2(),
511                                                                   aOld->Surface(),
512                                                                   aOld->Location());
513       alistrep.Append(aPS);
514       continue;
515     }
516     else if(pr->IsPointOnCurveOnSurface()) {
517       Standard_Boolean found = Standard_False;
518       BRep_ListIteratorOfListOfCurveRepresentation fromitcr
519         ((*((Handle(BRep_TEdge)*)&fromedge.TShape()))->ChangeCurves());
520       
521       for( ;fromitcr.More() && !found; fromitcr.Next()) {
522         Handle(BRep_GCurve) fromGC = Handle(BRep_GCurve)::DownCast(fromitcr.Value());
523         if ( fromGC.IsNull() || !fromGC->IsCurveOnSurface()) continue;
524         
525         TopLoc_Location aL = fromGC->Location();
526         aL.Predivided(theV.Location());
527         Handle(Geom_Surface) surface1 = fromGC->Surface();
528         Handle(Geom2d_Curve) ac2d1 = fromGC->PCurve();
529         if (pr->IsPointOnCurveOnSurface(ac2d1,surface1,aL)) {
530       found = Standard_True;
531           if(!hasRepr) {
532             aOldPar = pr->Parameter();
533           }
534         }
535       }
536       if(found) continue;
537     }
538     if(pr->IsPointOnCurve()) {
539       Handle(BRep_PointOnCurve) aPRep = new BRep_PointOnCurve(pr->Parameter(),pr->Curve(),pr->Location());
540       alistrep.Append(aPRep);
541     }
542     else if(pr->IsPointOnCurveOnSurface() ) {
543       Handle(BRep_PointOnCurveOnSurface) aPonCS = 
544         new BRep_PointOnCurveOnSurface(pr->Parameter(),pr->PCurve(),pr->Surface(),pr->Location()); 
545       alistrep.Append(aPonCS);
546     }
547   }
548   Standard_Real apar = aOldPar;
549   Standard_Real aTol = BRep_Tool::Tolerance(theV);
550   if(!hasRepr || (fabs(f1-f2) > Precision::PConfusion() || fabs(l1-l2)> Precision::PConfusion())) {
551     gp_Pnt projP;
552     ShapeAnalysis_Curve sae;
553     Standard_Real adist = sae.Project(C2,apv,Precision::Confusion(),projP,apar);
554     if(aTol < adist)
555       aTol = adist;
556   }
557   BRep_Builder aB;
558   aB.UpdateVertex(anewV,apar,toedge,aTol);
559   
560   //update tolerance
561   Standard_Boolean needUpdate = Standard_False;
562   gp_Pnt aPV = (*((Handle(BRep_TVertex)*)&anewV.TShape()))->Pnt();
563   TopLoc_Location toLoc = toedge.Location();
564   BRep_ListIteratorOfListOfCurveRepresentation toitcr
565         ((*((Handle(BRep_TEdge)*)&toedge.TShape()))->ChangeCurves());
566       
567   for( ;toitcr.More() ; toitcr.Next()) {
568         Handle(BRep_GCurve) toGC = Handle(BRep_GCurve)::DownCast(toitcr.Value());
569         if ( toGC.IsNull() || !toGC->IsCurveOnSurface()) continue;
570         
571         TopLoc_Location aL = (toLoc*toGC->Location()).Predivided(theV.Location());
572         //aL.Predivided(theV.Location());
573         Handle(Geom_Surface) surface1 = toGC->Surface();
574         Handle(Geom2d_Curve) ac2d1 = toGC->PCurve();
575         gp_Pnt2d aP2d = ac2d1->Value(apar);
576     gp_Pnt aP3d = surface1->Value(aP2d.X(),aP2d.Y());
577     aP3d.Transform(aL.Transformation());
578     Standard_Real adist = aPV.Distance(aP3d);
579     if(adist > aTol) {
580       aTol = adist;
581       needUpdate = Standard_True;
582     }
583
584   } 
585   if(needUpdate)
586     aB.UpdateVertex(anewV,aTol);
587   return anewV;
588 }
589
590 //=======================================================================
591 //function : CopyNMVertex
592 //purpose  : 
593 //=======================================================================
594
595 TopoDS_Vertex ShapeAnalysis_TransferParametersProj::CopyNMVertex (const TopoDS_Vertex& theV,
596                                    const TopoDS_Face& toFace, 
597                                    const TopoDS_Face& fromFace)
598 {
599   TopoDS_Vertex anewV;
600   if(theV.Orientation() != TopAbs_INTERNAL &&
601      theV.Orientation() != TopAbs_EXTERNAL)
602     return anewV;
603   
604
605   TopLoc_Location fromLoc;
606   TopLoc_Location toLoc;
607   Handle(Geom_Surface) fromSurf = BRep_Tool::Surface(fromFace,fromLoc);
608   Handle(Geom_Surface) toSurf = BRep_Tool::Surface(toFace,toLoc);
609   fromLoc = fromLoc.Predivided(theV.Location());
610   
611   anewV = TopoDS::Vertex(theV.EmptyCopied());
612   gp_Pnt apv = BRep_Tool::Pnt(anewV);
613   
614   
615   BRep_ListOfPointRepresentation& alistrep = 
616     (*((Handle(BRep_TVertex)*)&anewV.TShape()))->ChangePoints();
617   
618   BRep_ListIteratorOfListOfPointRepresentation itpr
619           ((*((Handle(BRep_TVertex)*) &theV.TShape()))->Points());
620   
621   Standard_Boolean hasRepr = Standard_False;
622   Standard_Real apar1=0., apar2=0.;
623   for ( ;itpr.More(); itpr.Next()) {
624     const Handle(BRep_PointRepresentation)& pr = itpr.Value();
625     if(pr.IsNull())
626       continue;
627     TopLoc_Location aLoc = pr->Location();
628     if( pr->IsPointOnCurveOnSurface()) {
629       Handle(BRep_PointOnCurveOnSurface) aPonCS = 
630             new BRep_PointOnCurveOnSurface(pr->Parameter(),pr->PCurve(),pr->Surface(),aLoc); 
631       alistrep.Append(aPonCS);
632     }
633     else if(pr->IsPointOnCurve()) {
634       Handle(BRep_PointOnCurve) aPRep = new BRep_PointOnCurve(pr->Parameter(),pr->Curve(),aLoc);
635       alistrep.Append(aPRep);
636     }
637     else if(pr->IsPointOnSurface()) {
638       Handle(BRep_PointOnSurface) aOld = Handle(BRep_PointOnSurface)::DownCast(pr);
639       
640       if(pr->IsPointOnSurface(fromSurf,fromLoc)) {
641         apar1= aOld->Parameter();
642         apar2 = aOld->Parameter2();
643         hasRepr = Standard_True;
644       }
645       else {
646         Handle(BRep_PointOnSurface) aPS = new BRep_PointOnSurface(aOld->Parameter(),
647                                                                     aOld->Parameter2(),
648                                                                     aOld->Surface(),
649                                                                     aOld->Location());
650         alistrep.Append(aPS);
651       }
652     }
653     
654   }
655   Standard_Real aTol = BRep_Tool::Tolerance(anewV);
656   if(!hasRepr || (fromSurf != toSurf || fromLoc != toLoc)) {
657     Handle(Geom_Surface) aS = BRep_Tool::Surface(toFace);
658     Handle(ShapeAnalysis_Surface) aSurfTool = new ShapeAnalysis_Surface(aS);
659     gp_Pnt2d aP2d = aSurfTool->ValueOfUV(apv,Precision::Confusion());
660     apar1 = aP2d.X();
661     apar2 = aP2d.Y();
662     
663     if(aTol < aSurfTool->Gap())
664       aTol = aSurfTool->Gap() + 0.1*Precision::Confusion();
665     //Handle(BRep_PointOnSurface) aPS = new BRep_PointOnSurface(aP2d.X(),aP2d.Y(),toSurf,toLoc);
666     //alistrep.Append(aPS);
667   }
668   
669   BRep_Builder aB;
670   aB.UpdateVertex(anewV,apar1,apar2,toFace,aTol);
671   return anewV;
672 }
673