0031430: Offset surfaces on C1 surfaces (with multiplicity equal to degree) may still...
[occt.git] / src / Geom / Geom_RectangularTrimmedSurface.cxx
1 // Created on: 1993-03-10
2 // Created by: JCV
3 // Copyright (c) 1993-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 // *******************************************************************
19
20 #include <ElCLib.hxx>
21 #include <Geom_BezierSurface.hxx>
22 #include <Geom_BSplineSurface.hxx>
23 #include <Geom_ConicalSurface.hxx>
24 #include <Geom_Curve.hxx>
25 #include <Geom_CylindricalSurface.hxx>
26 #include <Geom_Geometry.hxx>
27 #include <Geom_OffsetSurface.hxx>
28 #include <Geom_Plane.hxx>
29 #include <Geom_RectangularTrimmedSurface.hxx>
30 #include <Geom_SphericalSurface.hxx>
31 #include <Geom_Surface.hxx>
32 #include <Geom_SurfaceOfLinearExtrusion.hxx>
33 #include <Geom_SurfaceOfRevolution.hxx>
34 #include <Geom_ToroidalSurface.hxx>
35 #include <Geom_TrimmedCurve.hxx>
36 #include <Geom_UndefinedDerivative.hxx>
37 #include <Geom_UndefinedValue.hxx>
38 #include <gp_GTrsf2d.hxx>
39 #include <gp_Pnt.hxx>
40 #include <gp_Trsf.hxx>
41 #include <gp_Vec.hxx>
42 #include <Precision.hxx>
43 #include <Standard_ConstructionError.hxx>
44 #include <Standard_NoSuchObject.hxx>
45 #include <Standard_RangeError.hxx>
46 #include <Standard_Type.hxx>
47
48 IMPLEMENT_STANDARD_RTTIEXT(Geom_RectangularTrimmedSurface,Geom_BoundedSurface)
49
50 typedef Geom_RectangularTrimmedSurface RectangularTrimmedSurface;
51 typedef gp_Ax1  Ax1;
52 typedef gp_Ax2  Ax2;
53 typedef gp_Pnt  Pnt;
54 typedef gp_Trsf Trsf;
55 typedef gp_Vec  Vec;
56
57 //=======================================================================
58 //function : Copy
59 //purpose  : 
60 //=======================================================================
61
62 Handle(Geom_Geometry) Geom_RectangularTrimmedSurface::Copy () const {
63
64   Handle(Geom_RectangularTrimmedSurface) S;
65
66   if ( isutrimmed && isvtrimmed ) 
67     S = new RectangularTrimmedSurface (basisSurf,
68                                        utrim1   , utrim2,
69                                        vtrim1   , vtrim2,
70                                        Standard_True     , Standard_True   );
71   else if ( isutrimmed)
72     S = new RectangularTrimmedSurface (basisSurf,
73                                        utrim1   , utrim2,
74                                        Standard_True,      Standard_True   );
75   else if (isvtrimmed)
76     S = new RectangularTrimmedSurface (basisSurf,
77                                        vtrim1   , vtrim2,
78                                        Standard_False    , Standard_True   );
79
80   return S;
81 }
82
83
84 //=======================================================================
85 //function : Geom_RectangularTrimmedSurface
86 //purpose  : 
87 //=======================================================================
88
89 Geom_RectangularTrimmedSurface::Geom_RectangularTrimmedSurface (
90
91 const Handle(Geom_Surface)& S, 
92 const Standard_Real             U1, 
93 const Standard_Real             U2, 
94 const Standard_Real             V1,
95 const Standard_Real             V2,
96 const Standard_Boolean          USense,
97 const Standard_Boolean          VSense)
98
99 : utrim1 (U1),
100   vtrim1(V1),
101   utrim2 (U2),
102   vtrim2 (V2),
103   isutrimmed (Standard_True),
104   isvtrimmed (Standard_True)
105 {
106
107   // kill trimmed basis surfaces
108   Handle(Geom_RectangularTrimmedSurface) T =
109     Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
110   if (!T.IsNull())
111     basisSurf = Handle(Geom_Surface)::DownCast(T->BasisSurface()->Copy());
112   else
113     basisSurf = Handle(Geom_Surface)::DownCast(S->Copy());
114
115   Handle(Geom_OffsetSurface) O =
116     Handle(Geom_OffsetSurface)::DownCast(basisSurf);
117   if (!O.IsNull()) 
118   {
119     Handle(Geom_RectangularTrimmedSurface) S2 = 
120            new Geom_RectangularTrimmedSurface( O->BasisSurface(),U1,U2, V1, V2, USense, VSense);
121     basisSurf = new Geom_OffsetSurface(S2, O->Offset(), Standard_True);
122   }  
123
124   SetTrim( U1, U2, V1, V2, USense, VSense);
125 }
126
127
128 //=======================================================================
129 //function : Geom_RectangularTrimmedSurface
130 //purpose  : 
131 //=======================================================================
132
133 Geom_RectangularTrimmedSurface::Geom_RectangularTrimmedSurface (
134
135  const Handle(Geom_Surface)& S,
136  const Standard_Real                  Param1, 
137  const Standard_Real                  Param2,
138  const Standard_Boolean               UTrim,
139  const Standard_Boolean               Sense
140 ) {
141
142   // kill trimmed basis surfaces
143   Handle(Geom_RectangularTrimmedSurface) T =
144     Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
145   if (!T.IsNull())
146     basisSurf = Handle(Geom_Surface)::DownCast(T->BasisSurface()->Copy());
147   else
148     basisSurf = Handle(Geom_Surface)::DownCast(S->Copy());
149
150   Handle(Geom_OffsetSurface) O =
151     Handle(Geom_OffsetSurface)::DownCast(basisSurf);
152   if (!O.IsNull()) 
153   {
154     Handle(Geom_RectangularTrimmedSurface) S2 = 
155            new Geom_RectangularTrimmedSurface( O->BasisSurface(),Param1,Param2, UTrim, Sense);
156     basisSurf = new Geom_OffsetSurface(S2, O->Offset(), Standard_True);
157   }  
158
159   SetTrim(Param1, Param2, UTrim, Sense);
160 }
161
162
163 //=======================================================================
164 //function : SetTrim
165 //purpose  : 
166 //=======================================================================
167
168 void Geom_RectangularTrimmedSurface::SetTrim (const Standard_Real    U1, 
169                                               const Standard_Real    U2, 
170                                               const Standard_Real    V1,
171                                               const Standard_Real    V2, 
172                                               const Standard_Boolean USense, 
173                                               const Standard_Boolean VSense ) {
174
175   SetTrim( U1, U2, V1, V2, Standard_True, Standard_True, USense, VSense);
176 }
177
178
179
180 //=======================================================================
181 //function : SetTrim
182 //purpose  : 
183 //=======================================================================
184
185 void Geom_RectangularTrimmedSurface::SetTrim (const Standard_Real    Param1,
186                                               const Standard_Real    Param2,
187                                               const Standard_Boolean UTrim, 
188                                               const Standard_Boolean Sense  ) {
189
190   // dummy arguments to call general SetTrim
191   Standard_Real dummy_a = 0.;
192   Standard_Real dummy_b = 0.;
193   Standard_Boolean dummy_Sense = Standard_True;
194
195   if ( UTrim) {
196     SetTrim( Param1        , Param2        , 
197              dummy_a       , dummy_b       ,
198              Standard_True , Standard_False,
199              Sense         , dummy_Sense    );
200   }
201   else {
202     SetTrim( dummy_a       , dummy_b      ,
203              Param1        , Param2       ,
204              Standard_False, Standard_True,
205              dummy_Sense   , Sense         );
206   }
207 }
208
209
210 //=======================================================================
211 //function : SetTrim
212 //purpose  : 
213 //=======================================================================
214
215 void Geom_RectangularTrimmedSurface::SetTrim(const Standard_Real U1,
216                                              const Standard_Real U2,
217                                              const Standard_Real V1,
218                                              const Standard_Real V2,
219                                              const Standard_Boolean UTrim,
220                                              const Standard_Boolean VTrim,
221                                              const Standard_Boolean USense,
222                                              const Standard_Boolean VSense) {
223   
224   Standard_Boolean UsameSense = Standard_True;
225   Standard_Boolean VsameSense = Standard_True;
226   Standard_Real Udeb, Ufin, Vdeb, Vfin;
227
228   basisSurf->Bounds(Udeb, Ufin, Vdeb, Vfin);
229
230   // Trimming the U-Direction
231   isutrimmed = UTrim;
232   if (!UTrim) {
233     utrim1 = Udeb;
234     utrim2 = Ufin;
235   }
236   else {
237     if ( U1 == U2)
238       throw Standard_ConstructionError("Geom_RectangularTrimmedSurface::U1==U2");
239
240     if (basisSurf->IsUPeriodic()) {
241       UsameSense = USense;
242       
243       // set uTrim1 in the range Udeb , Ufin
244       // set uTrim2 in the range uTrim1 , uTrim1 + Period()
245       utrim1 = U1;
246       utrim2 = U2;
247       ElCLib::AdjustPeriodic(Udeb, Ufin, 
248                              Min(Abs(utrim2-utrim1)/2,Precision::PConfusion()), 
249                              utrim1, utrim2);
250     }
251     else {
252       if (U1 < U2) {
253         UsameSense = USense;
254         utrim1 = U1;
255         utrim2 = U2;
256       }
257       else {
258         UsameSense = !USense;
259         utrim1 = U2;
260         utrim2 = U1;
261       }
262       
263       if ((Udeb-utrim1 > Precision::PConfusion()) ||
264           (utrim2-Ufin > Precision::PConfusion()))
265         throw Standard_ConstructionError("Geom_RectangularTrimmedSurface::U parameters out of range");
266
267     }
268   }
269
270   // Trimming the V-Direction
271   isvtrimmed = VTrim;
272   if (!VTrim) {
273     vtrim1 = Vdeb;
274     vtrim2 = Vfin;
275   }
276   else {
277     if ( V1 == V2)
278       throw Standard_ConstructionError("Geom_RectangularTrimmedSurface::V1==V2");
279
280     if (basisSurf->IsVPeriodic()) {
281       VsameSense = VSense;
282
283       // set vTrim1 in the range Vdeb , Vfin
284       // set vTrim2 in the range vTrim1 , vTrim1 + Period()
285       vtrim1 = V1;
286       vtrim2 = V2;
287       ElCLib::AdjustPeriodic(Vdeb, Vfin,  
288                              Min(Abs(vtrim2-vtrim1)/2,Precision::PConfusion()), 
289                              vtrim1, vtrim2);
290     }
291     else {
292       if (V1 < V2) {
293         VsameSense = VSense;
294         vtrim1 = V1;
295         vtrim2 = V2;
296       }
297       else {
298         VsameSense = !VSense;
299         vtrim1 = V2;
300         vtrim2 = V1;
301       }
302       
303       if ((Vdeb-vtrim1 > Precision::PConfusion()) ||
304           (vtrim2-Vfin > Precision::PConfusion()))
305         throw Standard_ConstructionError("Geom_RectangularTrimmedSurface::V parameters out of range");
306
307     }
308   }
309
310   if (!UsameSense) UReverse();
311   if (!VsameSense) VReverse();
312 }
313
314
315 //=======================================================================
316 //function : UReverse
317 //purpose  : 
318 //=======================================================================
319
320 void Geom_RectangularTrimmedSurface::UReverse () 
321 {
322   Standard_Real U1 = basisSurf->UReversedParameter(utrim2);
323   Standard_Real U2 = basisSurf->UReversedParameter(utrim1);
324   basisSurf->UReverse();
325   SetTrim(U1,U2,vtrim1,vtrim2,
326           isutrimmed,isvtrimmed,
327           Standard_True,Standard_True);
328 }
329
330
331 //=======================================================================
332 //function : UReversedParameter
333 //purpose  : 
334 //=======================================================================
335
336 Standard_Real Geom_RectangularTrimmedSurface::UReversedParameter( const Standard_Real U) const {
337
338   return basisSurf->UReversedParameter(U);
339 }
340
341
342 //=======================================================================
343 //function : VReverse
344 //purpose  : 
345 //=======================================================================
346
347 void Geom_RectangularTrimmedSurface::VReverse () 
348 {
349   Standard_Real V1 = basisSurf->VReversedParameter(vtrim2);
350   Standard_Real V2 = basisSurf->VReversedParameter(vtrim1);
351   basisSurf->VReverse();
352   SetTrim(utrim1,utrim2,V1,V2,
353           isutrimmed,isvtrimmed,
354           Standard_True,Standard_True);
355 }
356
357
358 //=======================================================================
359 //function : VReversedParameter
360 //purpose  : 
361 //=======================================================================
362
363 Standard_Real Geom_RectangularTrimmedSurface::VReversedParameter( const Standard_Real V) const {
364
365   return basisSurf->VReversedParameter( V);
366 }
367
368
369 //=======================================================================
370 //function : BasisSurface
371 //purpose  : 
372 //=======================================================================
373
374 Handle(Geom_Surface) Geom_RectangularTrimmedSurface::BasisSurface () const
375 {
376   return basisSurf;
377 }
378
379
380 //=======================================================================
381 //function : Continuity
382 //purpose  : 
383 //=======================================================================
384
385 GeomAbs_Shape Geom_RectangularTrimmedSurface::Continuity () const {
386
387   return basisSurf->Continuity();
388 }
389
390
391 //=======================================================================
392 //function : D0
393 //purpose  : 
394 //=======================================================================
395
396 void Geom_RectangularTrimmedSurface::D0
397   (const Standard_Real U, const Standard_Real V,
398          Pnt& P ) const { 
399       
400    basisSurf->D0 (U, V, P);
401 }
402
403
404 //=======================================================================
405 //function : D1
406 //purpose  : 
407 //=======================================================================
408
409 void Geom_RectangularTrimmedSurface::D1 
410   (const Standard_Real U, const Standard_Real V, 
411          Pnt& P, 
412          Vec& D1U, Vec& D1V) const {
413
414   basisSurf->D1 (U, V, P, D1U, D1V);
415 }
416
417
418 //=======================================================================
419 //function : D2
420 //purpose  : 
421 //=======================================================================
422
423 void Geom_RectangularTrimmedSurface::D2 
424   (const Standard_Real U, const Standard_Real V,
425          Pnt& P, 
426          Vec& D1U, Vec& D1V, 
427          Vec& D2U, Vec& D2V, Vec& D2UV) const {
428
429   basisSurf->D2 (U, V, P, D1U, D1V, D2U, D2V, D2UV);
430 }
431
432
433 //=======================================================================
434 //function : D3
435 //purpose  : 
436 //=======================================================================
437
438 void Geom_RectangularTrimmedSurface::D3 
439   (const Standard_Real U, const Standard_Real V, 
440    Pnt& P, 
441    Vec& D1U, Vec& D1V, 
442    Vec& D2U, Vec& D2V, Vec& D2UV, 
443    Vec& D3U, Vec& D3V, Vec& D3UUV, Vec& D3UVV) const {
444
445   basisSurf->D3 (U, V, P, D1U, D1V, D2U, D2V, D2UV, D3U, D3V, D3UUV, D3UVV);
446 }
447
448
449 //=======================================================================
450 //function : DN
451 //purpose  : 
452 //=======================================================================
453
454 Vec Geom_RectangularTrimmedSurface::DN 
455   (const Standard_Real    U , const Standard_Real    V,
456    const Standard_Integer Nu, const Standard_Integer Nv) const {
457
458   return basisSurf->DN (U, V, Nu, Nv);
459 }
460
461
462 //=======================================================================
463 //function : Bounds
464 //purpose  : 
465 //=======================================================================
466
467 void Geom_RectangularTrimmedSurface::Bounds (Standard_Real& U1,
468                                              Standard_Real& U2, 
469                                              Standard_Real& V1, 
470                                              Standard_Real& V2) const {
471
472   U1 = utrim1;  
473   U2 = utrim2;  
474   V1 = vtrim1; 
475   V2 = vtrim2;
476 }
477
478
479 //=======================================================================
480 //function : UIso
481 //purpose  : 
482 //=======================================================================
483
484 Handle(Geom_Curve) Geom_RectangularTrimmedSurface::UIso (const Standard_Real U) const {
485   
486   Handle(Geom_Curve) C = basisSurf->UIso (U);
487
488   if ( isvtrimmed) {
489     Handle(Geom_TrimmedCurve) Ct;
490     Ct = new Geom_TrimmedCurve (C, vtrim1, vtrim2, Standard_True);
491     return Ct;
492   }
493   else {
494     return C;
495   }
496 }
497
498
499 //=======================================================================
500 //function : VIso
501 //purpose  : 
502 //=======================================================================
503
504 Handle(Geom_Curve) Geom_RectangularTrimmedSurface::VIso (const Standard_Real V) const {
505  
506   Handle(Geom_Curve) C = basisSurf->VIso (V);
507   
508   if ( isutrimmed) {
509     Handle(Geom_TrimmedCurve) Ct;
510     Ct = new Geom_TrimmedCurve (C, utrim1, utrim2, Standard_True);
511     return Ct;
512   }
513   else {
514     return C;
515   }
516 }
517
518
519 //=======================================================================
520 //function : IsCNu
521 //purpose  : 
522 //=======================================================================
523
524 Standard_Boolean Geom_RectangularTrimmedSurface::IsCNu (const Standard_Integer N) const {
525
526   Standard_RangeError_Raise_if (N < 0," ");
527   return basisSurf->IsCNu (N);  
528 }
529
530
531 //=======================================================================
532 //function : IsCNv
533 //purpose  : 
534 //=======================================================================
535
536 Standard_Boolean Geom_RectangularTrimmedSurface::IsCNv (const Standard_Integer N) const {
537
538   Standard_RangeError_Raise_if (N < 0," ");
539   return basisSurf->IsCNv (N);  
540 }
541
542
543 //=======================================================================
544 //function : Transform
545 //purpose  : 
546 //=======================================================================
547
548 void Geom_RectangularTrimmedSurface::Transform (const Trsf& T) 
549 {
550   basisSurf->Transform (T);
551   basisSurf->TransformParameters(utrim1,vtrim1,T);
552   basisSurf->TransformParameters(utrim2,vtrim2,T);
553 }
554
555
556 //=======================================================================
557 //function : IsUPeriodic
558 //purpose  : 
559 // 24/11/98: pmn : Compare la periode a la longeur de l'intervalle
560 //=======================================================================
561
562 Standard_Boolean Geom_RectangularTrimmedSurface::IsUPeriodic () const 
563 {
564   if (basisSurf->IsUPeriodic() &&  !isutrimmed) 
565     return Standard_True;
566   return Standard_False;
567 }
568
569
570 //=======================================================================
571 //function : UPeriod
572 //purpose  : 
573 //=======================================================================
574
575 Standard_Real Geom_RectangularTrimmedSurface::UPeriod() const
576 {
577   return basisSurf->UPeriod();
578 }
579
580
581 //=======================================================================
582 //function : IsVPeriodic
583 //purpose  : 
584 //=======================================================================
585
586 Standard_Boolean Geom_RectangularTrimmedSurface::IsVPeriodic () const 
587
588   if (basisSurf->IsVPeriodic() && !isvtrimmed)
589     return Standard_True;
590   return Standard_False;
591 }
592
593
594 //=======================================================================
595 //function : VPeriod
596 //purpose  : 
597 //=======================================================================
598
599 Standard_Real Geom_RectangularTrimmedSurface::VPeriod() const
600 {
601    return basisSurf->VPeriod(); 
602 }
603
604
605 //=======================================================================
606 //function : IsUClosed
607 //purpose  : 
608 //=======================================================================
609
610 Standard_Boolean Geom_RectangularTrimmedSurface::IsUClosed () const { 
611
612   if (isutrimmed)  
613     return Standard_False;
614   else             
615     return basisSurf->IsUClosed();
616 }
617
618
619 //=======================================================================
620 //function : IsVClosed
621 //purpose  : 
622 //=======================================================================
623
624 Standard_Boolean Geom_RectangularTrimmedSurface::IsVClosed () const { 
625
626   if (isvtrimmed) 
627     return Standard_False;
628   else   
629     return basisSurf->IsVClosed();
630 }
631
632 //=======================================================================
633 //function : TransformParameters
634 //purpose  : 
635 //=======================================================================
636
637 void Geom_RectangularTrimmedSurface::TransformParameters(Standard_Real& U,
638                                                          Standard_Real& V,
639                                                          const gp_Trsf& T) 
640 const
641 {
642   basisSurf->TransformParameters(U,V,T);
643 }
644
645 //=======================================================================
646 //function : ParametricTransformation
647 //purpose  : 
648 //=======================================================================
649
650 gp_GTrsf2d Geom_RectangularTrimmedSurface::ParametricTransformation
651 (const gp_Trsf& T) const
652 {
653   return basisSurf->ParametricTransformation(T);
654 }
655
656 //=======================================================================
657 //function : DumpJson
658 //purpose  : 
659 //=======================================================================
660 void Geom_RectangularTrimmedSurface::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
661 {
662   OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
663
664   OCCT_DUMP_BASE_CLASS (theOStream, theDepth, Geom_BoundedSurface)
665
666   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, basisSurf.get())
667
668   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, utrim1)
669   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, vtrim1)
670   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, utrim2)
671   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, vtrim2)
672   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, isutrimmed)
673   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, isvtrimmed)
674 }