0024947: Redesign OCCT legacy type system -- automatic
[occt.git] / src / ShapeExtend / ShapeExtend_CompositeSurface.cxx
1 // Created on: 1999-04-27
2 // Created by: Pavel DURANDIN
3 // Copyright (c) 1999-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <ShapeExtend_CompositeSurface.ixx>
18 #include <Precision.hxx>
19 #include <Geom_Surface.hxx>
20
21 //=======================================================================
22 //function : ShapeExtend_CompositeSurface
23 //purpose  : 
24 //=======================================================================
25
26 ShapeExtend_CompositeSurface::ShapeExtend_CompositeSurface()
27 {
28 }
29
30 //=======================================================================
31 //function : Constructor
32 //purpose  : 
33 //=======================================================================
34
35 ShapeExtend_CompositeSurface::ShapeExtend_CompositeSurface(const Handle(TColGeom_HArray2OfSurface)& GridSurf,
36                                                            const ShapeExtend_Parametrisation param)
37 {
38   Init ( GridSurf, param );
39 }
40
41 //=======================================================================
42 //function : Constructor
43 //purpose  : 
44 //=======================================================================
45
46 ShapeExtend_CompositeSurface::ShapeExtend_CompositeSurface(const Handle(TColGeom_HArray2OfSurface)& GridSurf,
47                                                            const TColStd_Array1OfReal &UJoints,
48                                                            const TColStd_Array1OfReal &VJoints)
49 {
50   Init ( GridSurf, UJoints, VJoints );
51 }
52
53 //=======================================================================
54 //function : Init
55 //purpose  : 
56 //=======================================================================
57
58 Standard_Boolean ShapeExtend_CompositeSurface::Init (const Handle(TColGeom_HArray2OfSurface)& GridSurf,
59                                                      const ShapeExtend_Parametrisation param)
60 {
61   if ( GridSurf.IsNull() ) return Standard_False;
62   myPatches = GridSurf;
63   ComputeJointValues ( param );
64   return CheckConnectivity ( Precision::Confusion() );
65 }
66
67 //=======================================================================
68 //function : Init
69 //purpose  : 
70 //=======================================================================
71
72 Standard_Boolean ShapeExtend_CompositeSurface::Init (const Handle(TColGeom_HArray2OfSurface)& GridSurf,
73                                                      const TColStd_Array1OfReal &UJoints,
74                                                      const TColStd_Array1OfReal &VJoints)
75 {
76   if ( GridSurf.IsNull() ) return Standard_False;
77   myPatches = GridSurf;
78   
79   Standard_Boolean ok = Standard_True;
80   if ( ! SetUJointValues ( UJoints ) || ! SetVJointValues ( VJoints ) ) {
81     ok = Standard_False;
82     ComputeJointValues ( ShapeExtend_Natural );
83 #ifdef OCCT_DEBUG
84     cout << "Warning: ShapeExtend_CompositeSurface::Init: bad joint values" << endl;
85 #endif
86   }
87   
88   return ( CheckConnectivity ( Precision::Confusion() ) ? ok : Standard_False );
89 }
90
91 //=======================================================================
92 //function : NbUPatches
93 //purpose  : 
94 //=======================================================================
95
96 Standard_Integer ShapeExtend_CompositeSurface::NbUPatches() const
97 {
98   return myPatches->ColLength();
99 }
100
101 //=======================================================================
102 //function : NbVPatches
103 //purpose  : 
104 //=======================================================================
105
106 Standard_Integer ShapeExtend_CompositeSurface::NbVPatches() const
107 {
108   return myPatches->RowLength();
109 }
110
111 //=======================================================================
112 //function : Patch
113 //purpose  : 
114 //=======================================================================
115
116 const Handle(Geom_Surface)& ShapeExtend_CompositeSurface::Patch(const Standard_Integer i,
117                                                                  const Standard_Integer j) const
118 {
119   return myPatches->Value(i,j);
120 }
121
122 //=======================================================================
123 //function : Patches
124 //purpose  : 
125 //=======================================================================
126
127 const Handle(TColGeom_HArray2OfSurface)& ShapeExtend_CompositeSurface::Patches() const
128 {
129   return myPatches;
130 }
131
132 //=======================================================================
133 //function : UJointValues
134 //purpose  : 
135 //=======================================================================
136
137 Handle(TColStd_HArray1OfReal) ShapeExtend_CompositeSurface::UJointValues() const
138 {
139   return myUJointValues;
140 }
141
142 //=======================================================================
143 //function : VJointValues
144 //purpose  : 
145 //=======================================================================
146
147 Handle(TColStd_HArray1OfReal) ShapeExtend_CompositeSurface::VJointValues() const
148 {
149   return myVJointValues;
150 }
151
152 //=======================================================================
153 //function : UJointValue
154 //purpose  : 
155 //=======================================================================
156
157 Standard_Real ShapeExtend_CompositeSurface::UJointValue(const Standard_Integer i) const
158 {
159   return myUJointValues->Value(i);
160 }
161
162 //=======================================================================
163 //function : VJointValue
164 //purpose  : 
165 //=======================================================================
166
167 Standard_Real ShapeExtend_CompositeSurface::VJointValue(const Standard_Integer i) const
168 {
169   return myVJointValues->Value(i);
170 }
171
172 //=======================================================================
173 //function : SetUJointValues
174 //purpose  : 
175 //=======================================================================
176
177 Standard_Boolean ShapeExtend_CompositeSurface::SetUJointValues (const TColStd_Array1OfReal &UJoints)
178 {
179   Standard_Integer NbU = NbUPatches();
180   if ( UJoints.Length() != NbU+1 ) return Standard_False;
181
182   Handle(TColStd_HArray1OfReal) UJointValues = new TColStd_HArray1OfReal(1,NbU+1);
183   for ( Standard_Integer i=1, j=UJoints.Lower(); i <= NbU+1; i++, j++ ) {
184     UJointValues->SetValue ( i, UJoints(j) );
185     if ( i >1 && UJoints(j) - UJoints(j-1) < Precision::PConfusion() ) 
186       return Standard_False;
187   }
188   myUJointValues = UJointValues;
189   return Standard_True;
190 }
191
192 //=======================================================================
193 //function : SetVJointValues
194 //purpose  : 
195 //=======================================================================
196
197 Standard_Boolean ShapeExtend_CompositeSurface::SetVJointValues (const TColStd_Array1OfReal &VJoints)
198 {
199   Standard_Integer NbV = NbVPatches();
200   if ( VJoints.Length() != NbV+1 ) return Standard_False;
201
202   Handle(TColStd_HArray1OfReal) VJointValues = new TColStd_HArray1OfReal(1,NbV+1);
203   for ( Standard_Integer i=1, j=VJoints.Lower(); i <= NbV+1; i++, j++ ) {
204     VJointValues->SetValue ( i, VJoints(j) );
205     if ( i >1 && VJoints(j) - VJoints(j-1) < Precision::PConfusion() ) 
206       return Standard_False;
207   }
208   myVJointValues = VJointValues;
209   return Standard_True;
210 }
211
212 //=======================================================================
213 //function : SetUFirstValue
214 //purpose  : 
215 //=======================================================================
216
217 void ShapeExtend_CompositeSurface::SetUFirstValue (const Standard_Real UFirst)
218 {
219   if ( myUJointValues.IsNull() ) return;
220   
221   Standard_Real shift = UFirst - myUJointValues->Value(1);
222   Standard_Integer NbU = myUJointValues->Length();
223   for ( Standard_Integer i=1; i <= NbU; i++ ) {
224     myUJointValues->SetValue ( i, myUJointValues->Value(i) + shift );
225   }
226 }
227
228 //=======================================================================
229 //function : SetVFirstValue
230 //purpose  : 
231 //=======================================================================
232
233 void ShapeExtend_CompositeSurface::SetVFirstValue (const Standard_Real VFirst)
234 {
235   if ( myVJointValues.IsNull() ) return;
236   
237   Standard_Real shift = VFirst - myVJointValues->Value(1);
238   Standard_Integer NbV = myVJointValues->Length();
239   for ( Standard_Integer i=1; i <= NbV; i++ ) {
240     myVJointValues->SetValue ( i, myVJointValues->Value(i) + shift );
241   }
242 }
243
244 //=======================================================================
245 //function : LocateUParameter
246 //purpose  : 
247 //=======================================================================
248
249 Standard_Integer ShapeExtend_CompositeSurface::LocateUParameter(const Standard_Real U) const
250 {
251   Standard_Integer nbPatch = NbUPatches();
252   for(Standard_Integer i = 2; i <= nbPatch; i++)
253     if (U < myUJointValues->Value(i)) return i-1;
254   return nbPatch;
255 }
256
257 //=======================================================================
258 //function : LocateVParameter
259 //purpose  : 
260 //=======================================================================
261
262 Standard_Integer ShapeExtend_CompositeSurface::LocateVParameter(const Standard_Real V) const
263 {
264   Standard_Integer nbPatch = NbVPatches();
265   for(Standard_Integer i = 2; i <= nbPatch; i++)
266     if (V < myVJointValues->Value(i)) return i-1;
267   return nbPatch;
268 }
269
270 //=======================================================================
271 //function : LocateUVPoint
272 //purpose  : 
273 //=======================================================================
274
275 void ShapeExtend_CompositeSurface::LocateUVPoint(const gp_Pnt2d& pnt,
276                                                  Standard_Integer& i,
277                                                  Standard_Integer& j) const
278 {
279   i = LocateUParameter(pnt.X());
280   j = LocateVParameter(pnt.Y());
281 }
282
283 //=======================================================================
284 //function : Patch
285 //purpose  : 
286 //=======================================================================
287
288 const Handle(Geom_Surface)& ShapeExtend_CompositeSurface::Patch(const Standard_Real U, 
289                                                                 const Standard_Real V) const
290 {
291   return myPatches->Value ( LocateUParameter(U), LocateVParameter(V) );
292 }
293
294 //=======================================================================
295 //function : Patch
296 //purpose  : 
297 //=======================================================================
298
299 const Handle(Geom_Surface)& ShapeExtend_CompositeSurface::Patch(const gp_Pnt2d& pnt) const
300 {
301   return myPatches->Value ( LocateUParameter(pnt.X()), LocateVParameter(pnt.Y()) );
302 }
303
304 //=======================================================================
305 //function : ULocalToGlobal
306 //purpose  : 
307 //=======================================================================
308
309 Standard_Real ShapeExtend_CompositeSurface::ULocalToGlobal (const Standard_Integer i,
310                                                             const Standard_Integer j,
311                                                             const Standard_Real u) const
312 {
313   Standard_Real u1, u2, v1, v2;
314   myPatches->Value(i,j)->Bounds ( u1, u2, v1, v2 );
315   Standard_Real scale = ( myUJointValues->Value(i+1) - myUJointValues->Value(i) ) / ( u2 - u1 );
316   return u * scale + ( myUJointValues->Value(i) - u1 * scale ); // ! this formula is stable if u1 is infinite
317 }
318
319 //=======================================================================
320 //function : VLocalToGlobal
321 //purpose  : 
322 //=======================================================================
323
324 Standard_Real ShapeExtend_CompositeSurface::VLocalToGlobal (const Standard_Integer i,
325                                                             const Standard_Integer j,
326                                                             const Standard_Real v) const
327 {
328   Standard_Real u1, u2, v1, v2;
329   myPatches->Value(i,j)->Bounds ( u1, u2, v1, v2 );
330   Standard_Real scale = ( myVJointValues->Value(j+1) - myVJointValues->Value(j) ) / ( v2 - v1 );
331   return v * scale + ( myVJointValues->Value(j) - v1 * scale ); // ! this formula is stable if v1 is infinite
332 }
333
334 //=======================================================================
335 //function : LocalToGlobal
336 //purpose  : 
337 //=======================================================================
338
339 gp_Pnt2d ShapeExtend_CompositeSurface::LocalToGlobal (const Standard_Integer i,
340                                                       const Standard_Integer j,
341                                                       const gp_Pnt2d &uv) const
342 {
343   Standard_Real u1, u2, v1, v2;
344   myPatches->Value(i,j)->Bounds ( u1, u2, v1, v2 );
345   Standard_Real scaleu = ( myUJointValues->Value(i+1) - myUJointValues->Value(i) ) / ( u2 - u1 );
346   Standard_Real scalev = ( myVJointValues->Value(j+1) - myVJointValues->Value(j) ) / ( v2 - v1 );
347   return gp_Pnt2d ( uv.X() * scaleu + ( myUJointValues->Value(i) - u1 * scaleu ), // ! this formula is stable if u1 or v1 is infinite
348                     uv.Y() * scalev + ( myVJointValues->Value(j) - v1 * scalev ) );
349 }
350
351 //=======================================================================
352 //function : UGlobalToLocal
353 //purpose  : 
354 //=======================================================================
355
356 Standard_Real ShapeExtend_CompositeSurface::UGlobalToLocal (const Standard_Integer i,
357                                                             const Standard_Integer j,
358                                                             const Standard_Real U) const
359 {
360   Standard_Real u1, u2, v1, v2;
361   myPatches->Value(i,j)->Bounds ( u1, u2, v1, v2 );
362   Standard_Real scale = ( u2 - u1 ) / ( myUJointValues->Value(i+1) - myUJointValues->Value(i) );
363   return U * scale + ( u1 - myUJointValues->Value(i) * scale ); // ! this formula is stable if u1 is infinite
364 }
365
366 //=======================================================================
367 //function : VGlobalToLocal
368 //purpose  : 
369 //=======================================================================
370
371 Standard_Real ShapeExtend_CompositeSurface::VGlobalToLocal (const Standard_Integer i,
372                                                             const Standard_Integer j,
373                                                             const Standard_Real V) const
374 {
375   Standard_Real u1, u2, v1, v2;
376   myPatches->Value(i,j)->Bounds ( u1, u2, v1, v2 );
377   Standard_Real scale = ( v2 - v1 ) / ( myVJointValues->Value(j+1) - myVJointValues->Value(j) );
378   return V * scale + ( v1 - myVJointValues->Value(j) * scale ); // ! this formula is stable if v1 is infinite
379 }
380
381 //=======================================================================
382 //function : GlobalToLocal
383 //purpose  : 
384 //=======================================================================
385
386 gp_Pnt2d ShapeExtend_CompositeSurface::GlobalToLocal (const Standard_Integer i,
387                                                       const Standard_Integer j,
388                                                       const gp_Pnt2d &UV) const
389 {
390   Standard_Real u1, u2, v1, v2;
391   myPatches->Value(i,j)->Bounds ( u1, u2, v1, v2 );
392   Standard_Real scaleu = ( u2 - u1 ) / ( myUJointValues->Value(i+1) - myUJointValues->Value(i) );
393   Standard_Real scalev = ( v2 - v1 ) / ( myVJointValues->Value(j+1) - myVJointValues->Value(j) );
394   return gp_Pnt2d ( UV.X() * scaleu + ( u1 - myUJointValues->Value(i) * scaleu ), // ! this formula is stable if u1 or v1 is infinite
395                     UV.Y() * scalev + ( v1 - myVJointValues->Value(j) * scalev ) );
396 }
397
398 //=======================================================================
399 //function : GlobalToLocalTransformation
400 //purpose  : 
401 //=======================================================================
402
403 Standard_Boolean ShapeExtend_CompositeSurface::GlobalToLocalTransformation (const Standard_Integer i,
404                                                                             const Standard_Integer j,
405                                                                             Standard_Real &uFact,
406                                                                             gp_Trsf2d &Trsf) const
407 {
408   Standard_Real u1, u2, v1, v2;
409   myPatches->Value(i,j)->Bounds ( u1, u2, v1, v2 );
410
411   Standard_Real scaleu = ( u2 - u1 ) / ( myUJointValues->Value(i+1) - myUJointValues->Value(i) );
412   Standard_Real scalev = ( v2 - v1 ) / ( myVJointValues->Value(j+1) - myVJointValues->Value(j) );
413   gp_Vec2d shift ( u1 / scaleu - myUJointValues->Value(i),
414                    v1 / scalev - myVJointValues->Value(j) );
415
416   uFact = scaleu / scalev;
417   gp_Trsf2d Shift, Scale;
418   if ( shift.X() != 0. || shift.Y() != 0. ) Shift.SetTranslation ( shift );
419   if ( scalev != 1. ) Scale.SetScale ( gp_Pnt2d(0,0), scalev );
420   Trsf = Scale * Shift;
421   return uFact != 1. || Trsf.Form() != gp_Identity;
422 }
423
424 //=======================================================================
425 // Inherited methods (from Geom_Geometry and Geom_Surface)
426 //=======================================================================
427
428 //=======================================================================
429 //function : Transform
430 //purpose  : 
431 //=======================================================================
432
433 void ShapeExtend_CompositeSurface::Transform (const gp_Trsf &T)
434 {
435   if ( myPatches.IsNull() ) return;
436   for ( Standard_Integer i=1; i <= NbUPatches(); i++ ) 
437     for ( Standard_Integer j=1; j <= NbVPatches(); j++ ) 
438       Patch(i,j)->Transform ( T );
439 }
440
441 //=======================================================================
442 //function : Copy
443 //purpose  : 
444 //=======================================================================
445
446 Handle(Geom_Geometry) ShapeExtend_CompositeSurface::Copy () const
447 {
448   Handle(ShapeExtend_CompositeSurface) surf = new ShapeExtend_CompositeSurface;
449   if ( myPatches.IsNull() ) return surf;
450   
451   Handle(TColGeom_HArray2OfSurface) patches = 
452     new TColGeom_HArray2OfSurface ( 1, NbUPatches(), 1, NbVPatches() );
453   for ( Standard_Integer i=1; i <= NbUPatches(); i++ ) 
454     for ( Standard_Integer j=1; j <= NbVPatches(); j++ ) 
455       patches->SetValue ( i, j, Handle(Geom_Surface)::DownCast ( Patch(i,j)->Copy() ) );
456   surf->Init ( patches );
457   return surf;
458 }
459     
460 //=======================================================================
461 //function : UReverse
462 //purpose  : 
463 //=======================================================================
464
465 void ShapeExtend_CompositeSurface::UReverse () 
466 {
467 }
468
469 //=======================================================================
470 //function : UReversedParameter
471 //purpose  : 
472 //=======================================================================
473
474 Standard_Real ShapeExtend_CompositeSurface::UReversedParameter (const Standard_Real U) const
475 {
476   return U;
477 }
478
479 //=======================================================================
480 //function : VReverse
481 //purpose  : 
482 //=======================================================================
483
484 void ShapeExtend_CompositeSurface::VReverse () 
485 {
486 }
487
488 //=======================================================================
489 //function : VReversedParameter
490 //purpose  : 
491 //=======================================================================
492
493 Standard_Real ShapeExtend_CompositeSurface::VReversedParameter (const Standard_Real V) const
494 {
495   return V;
496 }
497
498 //=======================================================================
499 //function : Bounds
500 //purpose  : 
501 //=======================================================================
502
503 void ShapeExtend_CompositeSurface::Bounds(Standard_Real& U1,
504                                            Standard_Real& U2,
505                                            Standard_Real& V1,
506                                            Standard_Real& V2) const
507 {
508   U1 = UJointValue(1);
509   V1 = VJointValue(1);
510   U2 = UJointValue(NbUPatches()+1);
511   V2 = VJointValue(NbVPatches()+1);
512 }
513
514 //=======================================================================
515 //function : IsUPeriodic
516 //purpose  : 
517 //=======================================================================
518
519 Standard_Boolean ShapeExtend_CompositeSurface::IsUPeriodic () const
520 {
521   return Standard_False;
522 }
523
524 //=======================================================================
525 //function : IsVPeriodic
526 //purpose  : 
527 //=======================================================================
528
529 Standard_Boolean ShapeExtend_CompositeSurface::IsVPeriodic () const 
530 {
531   return Standard_False;
532 }
533
534 //=======================================================================
535 //function : UIso
536 //purpose  : 
537 //=======================================================================
538
539 Handle(Geom_Curve) ShapeExtend_CompositeSurface::UIso (const Standard_Real ) const
540 {
541   Handle(Geom_Curve) dummy;
542   return dummy;
543 }
544
545 //=======================================================================
546 //function : VIso
547 //purpose  : 
548 //=======================================================================
549
550 Handle(Geom_Curve) ShapeExtend_CompositeSurface::VIso (const Standard_Real ) const
551 {
552   Handle(Geom_Curve) dummy;
553   return dummy;
554 }
555
556 //=======================================================================
557 //function : Continuity
558 //purpose  : 
559 //=======================================================================
560
561 GeomAbs_Shape ShapeExtend_CompositeSurface::Continuity () const
562 {
563   return GeomAbs_C0;
564 }
565
566 //=======================================================================
567 //function : IsCNu
568 //purpose  : 
569 //=======================================================================
570
571 Standard_Boolean ShapeExtend_CompositeSurface::IsCNu (const Standard_Integer N) const
572 {
573   return N <=0;
574 }
575
576 //=======================================================================
577 //function : IsCNv
578 //purpose  : 
579 //=======================================================================
580
581 Standard_Boolean ShapeExtend_CompositeSurface::IsCNv (const Standard_Integer N) const
582 {
583   return N <=0;
584 }
585
586 //=======================================================================
587 //function : IsUClosed
588 //purpose  : 
589 //=======================================================================
590
591 Standard_Boolean ShapeExtend_CompositeSurface::IsUClosed () const
592 {
593   return myUClosed;
594 }
595
596 //=======================================================================
597 //function : IsVClosed
598 //purpose  : 
599 //=======================================================================
600
601 Standard_Boolean ShapeExtend_CompositeSurface::IsVClosed () const
602 {
603   return myVClosed;
604 }
605
606 //=======================================================================
607 //function : D0
608 //purpose  : 
609 //=======================================================================
610
611 void ShapeExtend_CompositeSurface::D0 (const Standard_Real U,
612                                        const Standard_Real V,
613                                        gp_Pnt& P) const
614 {
615   Standard_Integer i = LocateUParameter ( U );
616   Standard_Integer j = LocateVParameter ( V );
617   gp_Pnt2d uv = GlobalToLocal ( i, j, gp_Pnt2d ( U, V ) );
618   myPatches->Value(i,j)->D0 ( uv.X(), uv.Y(), P );
619 }
620   
621 //=======================================================================
622 //function : D1
623 //purpose  : 
624 //=======================================================================
625
626 void ShapeExtend_CompositeSurface::D1 (const Standard_Real U,
627                                        const Standard_Real V,
628                                        gp_Pnt& P,
629                                        gp_Vec& D1U,
630                                        gp_Vec& D1V) const
631 {
632   Standard_Integer i = LocateUParameter ( U );
633   Standard_Integer j = LocateVParameter ( V );
634   gp_Pnt2d uv = GlobalToLocal ( i, j, gp_Pnt2d ( U, V ) );
635   myPatches->Value(i,j)->D1 ( uv.X(), uv.Y(), P, D1U, D1V );
636 }
637
638 //=======================================================================
639 //function : D2
640 //purpose  : 
641 //=======================================================================
642
643 void ShapeExtend_CompositeSurface::D2 (const Standard_Real U,
644                                        const Standard_Real V,
645                                        gp_Pnt& P,
646                                        gp_Vec& D1U,
647                                        gp_Vec& D1V,
648                                        gp_Vec& D2U,
649                                        gp_Vec& D2V,
650                                        gp_Vec& D2UV) const
651 {
652   Standard_Integer i = LocateUParameter ( U );
653   Standard_Integer j = LocateVParameter ( V );
654   gp_Pnt2d uv = GlobalToLocal ( i, j, gp_Pnt2d ( U, V ) );
655   myPatches->Value(i,j)->D2 ( uv.X(), uv.Y(), P, D1U, D1V, D2U, D2V, D2UV );
656 }
657
658 //=======================================================================
659 //function : D3
660 //purpose  : 
661 //=======================================================================
662
663 void ShapeExtend_CompositeSurface::D3 (const Standard_Real U,
664                                        const Standard_Real V,
665                                        gp_Pnt& P,
666                                        gp_Vec& D1U,
667                                        gp_Vec& D1V,
668                                        gp_Vec& D2U,
669                                        gp_Vec& D2V,
670                                        gp_Vec& D2UV,
671                                        gp_Vec& D3U,
672                                        gp_Vec& D3V,
673                                        gp_Vec& D3UUV,
674                                        gp_Vec& D3UVV) const
675 {
676   Standard_Integer i = LocateUParameter ( U );
677   Standard_Integer j = LocateVParameter ( V );
678   gp_Pnt2d uv = GlobalToLocal ( i, j, gp_Pnt2d ( U, V ) );
679   myPatches->Value(i,j)->D3 ( uv.X(), uv.Y(), P, D1U, D1V, D2U, D2V, D2UV, D3U, D3V, D3UUV, D3UVV );
680 }
681
682 //=======================================================================
683 //function : DN
684 //purpose  : 
685 //=======================================================================
686
687 gp_Vec ShapeExtend_CompositeSurface::DN (const Standard_Real U,
688                                          const Standard_Real V,
689                                          const Standard_Integer Nu,
690                                          const Standard_Integer Nv) const
691 {
692   Standard_Integer i = LocateUParameter ( U );
693   Standard_Integer j = LocateVParameter ( V );
694   gp_Pnt2d uv = GlobalToLocal ( i, j, gp_Pnt2d ( U, V ) );
695   return myPatches->Value(i,j)->DN ( uv.X(), uv.Y(), Nu, Nv );
696 }
697
698 //=======================================================================
699 //function : Value
700 //purpose  : 
701 //=======================================================================
702
703 gp_Pnt ShapeExtend_CompositeSurface::Value (const gp_Pnt2d& pnt) const
704 {
705   Standard_Integer i = LocateUParameter ( pnt.X() );
706   Standard_Integer j = LocateVParameter ( pnt.Y() );
707   gp_Pnt2d uv = GlobalToLocal ( i, j, pnt );
708   gp_Pnt point;
709   myPatches->Value(i,j)->D0 ( uv.X(), uv.Y(), point );
710   return point;
711 }
712
713 //=======================================================================
714 //function : ComputeJointValues
715 //purpose  : 
716 //=======================================================================
717
718 void ShapeExtend_CompositeSurface::ComputeJointValues (const ShapeExtend_Parametrisation param)
719 {
720   Standard_Integer NbU = NbUPatches();
721   Standard_Integer NbV = NbVPatches();
722   myUJointValues = new TColStd_HArray1OfReal(1,NbU+1);
723   myVJointValues = new TColStd_HArray1OfReal(1,NbV+1);
724   
725   if ( param == ShapeExtend_Natural ) {
726     Standard_Real U1, U2, V1, V2, U=0, V=0;
727     Standard_Integer i; // svv Jan 10 2000 : porting on DEC
728     for ( i = 1; i <= NbU; i++ ) {
729       myPatches->Value(i,1)->Bounds(U1,U2,V1,V2);
730       if ( i ==1 ) myUJointValues->SetValue ( 1, U = U1 );
731       U += ( U2 - U1 );
732       myUJointValues->SetValue ( i+1, U );
733     }
734     for ( i = 1; i <= NbV; i++ ) {
735       myPatches->Value(1,i)->Bounds(U1,U2,V1,V2);
736       if ( i ==1 ) myVJointValues->SetValue ( 1, V = V1 );
737       V += ( V2 - V1 );
738       myVJointValues->SetValue ( i+1, V );
739     }
740   }
741   else {
742     Standard_Real stepu = 1., stepv = 1.; // suppose param == ShapeExtend_Uniform
743     if ( param == ShapeExtend_Unitary ) {
744       stepu /= NbU; 
745       stepv /= NbV;
746     }
747     Standard_Integer i; // svv Jan 10 2000 : porting on DEC
748     for ( i=0; i <= NbU; i++ )
749       myUJointValues->SetValue ( i+1, i * stepu );
750     for ( i=0; i <= NbV; i++ )
751       myVJointValues->SetValue ( i+1, i * stepv );
752   }
753 }
754
755 //=======================================================================
756 //function : CheckConnectivity
757 //purpose  : 
758 //=======================================================================
759
760 static inline Standard_Real LimitValue (const Standard_Real &par)
761 {
762   return Precision::IsInfinite(par) ? ( par <0 ? -10000. : 10000. ) : par;
763 }
764
765 static void GetLimitedBounds (const Handle(Geom_Surface) &surf,
766                               Standard_Real &U1, Standard_Real &U2,
767                               Standard_Real &V1, Standard_Real &V2)
768 {
769   surf->Bounds ( U1, U2, V1, V2 );
770   U1 = LimitValue ( U1 );
771   U2 = LimitValue ( U2 );
772   V1 = LimitValue ( V1 );
773   V2 = LimitValue ( V2 );
774 }
775      
776 Standard_Boolean ShapeExtend_CompositeSurface::CheckConnectivity (const Standard_Real Prec)
777 {
778   const Standard_Integer NPOINTS = 23;
779   Standard_Boolean ok = Standard_True;
780   Standard_Integer NbU = NbUPatches();
781   Standard_Integer NbV = NbVPatches();
782   
783   // check in u direction
784   Standard_Integer i,j; // svv Jan 10 2000 : porting on DEC
785   for ( i=1, j = NbU; i <= NbU; j = i++ ) {
786     Standard_Real maxdist2 = 0.;
787     for ( Standard_Integer k=1; k <= NbV; k++ ) {
788       Handle(Geom_Surface) sj = myPatches->Value(j,k);
789       Handle(Geom_Surface) si = myPatches->Value(i,k);
790       Standard_Real Uj1, Uj2, Vj1, Vj2;
791       GetLimitedBounds ( sj, Uj1, Uj2, Vj1, Vj2 );
792       Standard_Real Ui1, Ui2, Vi1, Vi2;
793       GetLimitedBounds ( si, Ui1, Ui2, Vi1, Vi2 );
794       Standard_Real stepj = ( Vj2 - Vj1 ) / ( NPOINTS - 1 );
795       Standard_Real stepi = ( Vi2 - Vi1 ) / ( NPOINTS - 1 );
796       for ( Standard_Integer isample=0; isample < NPOINTS; isample++ ) {
797         Standard_Real parj = Vj1 + stepj * isample;
798         Standard_Real pari = Vi1 + stepi * isample;
799         Standard_Real dist2 = sj->Value ( Uj2, parj ).SquareDistance ( si->Value ( Ui1, pari ) );
800         if ( maxdist2 < dist2 ) maxdist2 = dist2;
801       }
802     }
803     if ( i==1 ) myUClosed = ( maxdist2 <= Prec*Prec );
804     else if ( maxdist2 > Prec*Prec ) ok = Standard_False;
805   }
806   
807   // check in v direction
808   for ( i=1, j = NbV; i <= NbV; j = i++ ) {
809     Standard_Real maxdist2 = 0.;
810     for ( Standard_Integer k=1; k <= NbU; k++ ) {
811       Handle(Geom_Surface) sj = myPatches->Value(k,j);
812       Handle(Geom_Surface) si = myPatches->Value(k,i);
813       Standard_Real Uj1, Uj2, Vj1, Vj2;
814       GetLimitedBounds ( sj, Uj1, Uj2, Vj1, Vj2 );
815       Standard_Real Ui1, Ui2, Vi1, Vi2;
816       GetLimitedBounds ( si, Ui1, Ui2, Vi1, Vi2 );
817       Standard_Real stepj = ( Uj2 - Uj1 ) / ( NPOINTS - 1 );
818       Standard_Real stepi = ( Ui2 - Ui1 ) / ( NPOINTS - 1 );
819       for ( Standard_Integer isample=0; isample < NPOINTS; isample++ ) {
820         Standard_Real parj = Uj1 + stepj * isample;
821         Standard_Real pari = Ui1 + stepi * isample;
822         Standard_Real dist2 = sj->Value ( parj, Vj2 ).SquareDistance ( si->Value ( pari, Vi1 ) );
823         if ( maxdist2 < dist2 ) maxdist2 = dist2;
824       }
825     }
826     if ( i==1 ) myVClosed = ( maxdist2 <= Prec*Prec );
827     else if ( maxdist2 > Prec*Prec ) ok = Standard_False;
828   }
829
830 #ifdef OCCT_DEBUG
831   if ( ! ok ) cout << "Warning: ShapeExtend_CompositeSurface: not connected in 3d" << endl;
832 #endif
833   return ok;
834 }