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