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