0030675: Visualization - remove redundant proxy classes in hierarchy of PrsMgr_Presen...
[occt.git] / src / GeomFill / GeomFill_Sweep.cxx
CommitLineData
b311480e 1// Created on: 1997-11-21
2// Created by: Philippe MANGIN
3// Copyright (c) 1997-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17// Modified by skv - Fri Feb 6 11:44:48 2004 OCC5073
18
42cf5bc1 19#include <AdvApprox_ApproxAFunction.hxx>
20#include <AdvApprox_PrefAndRec.hxx>
21#include <Approx_SweepApproximation.hxx>
22#include <ElCLib.hxx>
23#include <ElSLib.hxx>
24#include <Geom2d_BSplineCurve.hxx>
25#include <Geom2d_Curve.hxx>
26#include <Geom2d_Line.hxx>
27#include <Geom2d_TrimmedCurve.hxx>
28#include <Geom_BSplineSurface.hxx>
29#include <Geom_Circle.hxx>
30#include <Geom_ConicalSurface.hxx>
31#include <Geom_CylindricalSurface.hxx>
32#include <Geom_Line.hxx>
33#include <Geom_Plane.hxx>
34#include <Geom_RectangularTrimmedSurface.hxx>
35#include <Geom_SphericalSurface.hxx>
36#include <Geom_Surface.hxx>
37#include <Geom_SurfaceOfLinearExtrusion.hxx>
38#include <Geom_SurfaceOfRevolution.hxx>
39#include <Geom_ToroidalSurface.hxx>
40#include <Geom_TrimmedCurve.hxx>
41#include <GeomAbs_CurveType.hxx>
42#include <GeomAdaptor_Curve.hxx>
43#include <GeomConvert_ApproxSurface.hxx>
44#include <GeomFill_LocationLaw.hxx>
7fd59977 45#include <GeomFill_LocFunction.hxx>
42cf5bc1 46#include <GeomFill_SectionLaw.hxx>
47#include <GeomFill_Sweep.hxx>
48#include <GeomFill_SweepFunction.hxx>
49#include <GeomLib.hxx>
50#include <gp_Ax2.hxx>
7fd59977 51#include <gp_Circ.hxx>
42cf5bc1 52#include <gp_Dir.hxx>
53#include <gp_Dir2d.hxx>
7fd59977 54#include <gp_GTrsf.hxx>
42cf5bc1 55#include <gp_Lin.hxx>
7fd59977 56#include <gp_Mat.hxx>
42cf5bc1 57#include <gp_Pnt.hxx>
58#include <gp_Pnt2d.hxx>
9ba2c30f 59#include <gp_Sphere.hxx>
42cf5bc1 60#include <Precision.hxx>
61#include <Standard_ConstructionError.hxx>
62#include <Standard_ErrorHandler.hxx>
63#include <Standard_OutOfRange.hxx>
64#include <StdFail_NotDone.hxx>
7fd59977 65#include <TColgp_Array1OfPnt.hxx>
66#include <TColgp_Array2OfPnt.hxx>
67#include <TColgp_HArray2OfPnt.hxx>
7fd59977 68#include <TColStd_Array1OfInteger.hxx>
69#include <TColStd_Array1OfReal.hxx>
70#include <TColStd_Array2OfReal.hxx>
71
42cf5bc1 72//#include <GeomLib_Array1OfMat.hxx>
7fd59977 73//=======================================================================
74//class : GeomFill_Sweep_Eval
75//purpose: The evaluator for curve approximation
76//=======================================================================
7fd59977 77class GeomFill_Sweep_Eval : public AdvApprox_EvaluatorFunction
78{
79 public:
80 GeomFill_Sweep_Eval (GeomFill_LocFunction& theTool)
81 : theAncore(theTool) {}
82
83 virtual void Evaluate (Standard_Integer *Dimension,
84 Standard_Real StartEnd[2],
85 Standard_Real *Parameter,
86 Standard_Integer *DerivativeRequest,
87 Standard_Real *Result, // [Dimension]
88 Standard_Integer *ErrorCode);
89
90 private:
91 GeomFill_LocFunction& theAncore;
92};
93
94void GeomFill_Sweep_Eval::Evaluate (Standard_Integer *,/*Dimension*/
95 Standard_Real StartEnd[2],
96 Standard_Real *Parameter,
97 Standard_Integer *DerivativeRequest,
98 Standard_Real *Result,// [Dimension]
99 Standard_Integer *ErrorCode)
100{
101 theAncore.DN (*Parameter,
102 StartEnd[0],
103 StartEnd[1],
104 *DerivativeRequest,
105 Result[0],
106 ErrorCode[0]);
107}
108
109//===============================================================
110// Function : Create
111// Purpose :
112//===============================================================
113GeomFill_Sweep::GeomFill_Sweep(const Handle(GeomFill_LocationLaw)& Location,
114 const Standard_Boolean WithKpart)
115{
116 done = Standard_False;
117
118 myLoc = Location;
119 myKPart = WithKpart;
120 SetTolerance(1.e-4);
a31abc03 121 myForceApproxC1 = Standard_False;
7fd59977 122
123 myLoc->GetDomain(First, Last);
124 SFirst = SLast = 30.081996;
125 SError = RealLast();
126}
127
128//===============================================================
129// Function : SetDomain
130// Purpose :
131//===============================================================
132 void GeomFill_Sweep::SetDomain(const Standard_Real LocFirst,
133 const Standard_Real LocLast,
134 const Standard_Real SectionFirst,
135 const Standard_Real SectionLast)
136{
137 First = LocFirst;
138 Last = LocLast;
139 SFirst = SectionFirst;
140 SLast = SectionLast;
141}
142
143//===============================================================
144// Function : SetTolerance
145// Purpose :
146//===============================================================
147 void GeomFill_Sweep::SetTolerance(const Standard_Real Tolerance3d,
148 const Standard_Real BoundTolerance,
149 const Standard_Real Tolerance2d,
150 const Standard_Real ToleranceAngular)
151{
152 Tol3d = Tolerance3d;
153 BoundTol = BoundTolerance;
154 Tol2d =Tolerance2d;
155 TolAngular = ToleranceAngular;
156}
157
a31abc03 158//=======================================================================
159//Function : SetForceApproxC1
160//Purpose : Set the flag that indicates attempt to approximate
161// a C1-continuous surface if a swept surface proved
162// to be C0.
163//=======================================================================
164 void GeomFill_Sweep::SetForceApproxC1(const Standard_Boolean ForceApproxC1)
165{
166 myForceApproxC1 = ForceApproxC1;
167}
168
169
7fd59977 170//===============================================================
171// Function : ExchangeUV
172// Purpose :
173//===============================================================
174 Standard_Boolean GeomFill_Sweep::ExchangeUV() const
175{
176 return myExchUV;
177}
178
179//===============================================================
180// Function : UReversed
181// Purpose :
182//===============================================================
183 Standard_Boolean GeomFill_Sweep::UReversed() const
184{
185 return isUReversed;
186}
187
188//===============================================================
189// Function : VReversed
190// Purpose :
191//===============================================================
192 Standard_Boolean GeomFill_Sweep::VReversed() const
193{
194 return isVReversed;
195}
196
197//===============================================================
198// Function : Build
199// Purpose :
200//===============================================================
201 void GeomFill_Sweep::Build(const Handle(GeomFill_SectionLaw)& Section,
202 const GeomFill_ApproxStyle Methode,
203 const GeomAbs_Shape Continuity,
204 const Standard_Integer Degmax,
205 const Standard_Integer Segmax)
206{
207 // Inits
208 done = Standard_False;
209 myExchUV = Standard_False;
210 isUReversed = isVReversed = Standard_False;
211 mySec = Section;
212
213 if ((SFirst == SLast) && (SLast == 30.081996)) {
214 mySec->GetDomain(SFirst, SLast);
215 }
216
217 Standard_Boolean isKPart = Standard_False,
218 isProduct = Standard_False;
219
220 // Traitement des KPart
221 if (myKPart) isKPart = BuildKPart();
222
223 // Traitement des produits Formelles
224 if ((!isKPart) && (Methode == GeomFill_Location)) {
225 Handle(Geom_BSplineSurface) BS;
226 BS = mySec->BSplineSurface();
227 if (! BS.IsNull()) {
228 // Approx de la loi
229// isProduct = BuildProduct(Continuity, Degmax, Segmax);
230 }
231 }
232
233 if (isKPart || isProduct) {
234 // Approx du 2d
235 done = Build2d(Continuity, Degmax, Segmax);
236 }
237 else {
238 // Approx globale
239 done = BuildAll(Continuity, Degmax, Segmax);
240 }
241}
242
243//===============================================================
244// Function ::Build2d
245// Purpose :A venir...
246//===============================================================
247// Standard_Boolean GeomFill_Sweep::Build2d(const GeomAbs_Shape Continuity,
248 Standard_Boolean GeomFill_Sweep::Build2d(const GeomAbs_Shape ,
249// const Standard_Integer Degmax,
250 const Standard_Integer ,
251// const Standard_Integer Segmax)
252 const Standard_Integer )
253{
254 Standard_Boolean Ok = Standard_False;
255 if (myLoc->Nb2dCurves() == 0) {
256 Ok = Standard_True;
257 }
258 return Ok;
259}
260
261//===============================================================
262// Function : BuildAll
263// Purpose :
264//===============================================================
265 Standard_Boolean GeomFill_Sweep::BuildAll(const GeomAbs_Shape Continuity,
266 const Standard_Integer Degmax,
267 const Standard_Integer Segmax)
268{
269 Standard_Boolean Ok = Standard_False;
7fd59977 270
271 Handle(GeomFill_SweepFunction) Func
272 = new (GeomFill_SweepFunction) (mySec, myLoc, First, SFirst,
273 (SLast-SFirst)/(Last-First) );
274 Approx_SweepApproximation Approx( Func );
275
276 Approx.Perform(First, Last,
277 Tol3d, BoundTol, Tol2d, TolAngular,
278 Continuity, Degmax, Segmax);
279
280 if (Approx.IsDone()) {
281 Ok = Standard_True;
282
0797d9d3 283#ifdef OCCT_DEBUG
7fd59977 284 Approx.Dump(cout);
285#endif
286
287 // La surface
288 Standard_Integer UDegree,VDegree,NbUPoles,
289 NbVPoles,NbUKnots,NbVKnots;
290 Approx.SurfShape(UDegree,VDegree,NbUPoles,
291 NbVPoles,NbUKnots,NbVKnots);
292
293 TColgp_Array2OfPnt Poles(1,NbUPoles, 1,NbVPoles);
294 TColStd_Array2OfReal Weights(1,NbUPoles, 1,NbVPoles);
295 TColStd_Array1OfReal UKnots(1, NbUKnots),VKnots(1, NbVKnots);
296 TColStd_Array1OfInteger UMults(1, NbUKnots), VMults(1, NbVKnots);
297
298 Approx.Surface(Poles, Weights,
299 UKnots,VKnots,
300 UMults,VMults);
301
302 mySurface = new (Geom_BSplineSurface)
303 (Poles, Weights,
304 UKnots,VKnots,
305 UMults,VMults,
306 Approx.UDegree(), Approx.VDegree(),
307 mySec->IsUPeriodic());
308 SError = Approx. MaxErrorOnSurf();
a31abc03 309
310 if (myForceApproxC1 && !mySurface->IsCNv(1))
311 {
312 Standard_Real theTol = 1.e-4;
313 GeomAbs_Shape theUCont = GeomAbs_C1, theVCont = GeomAbs_C1;
314 Standard_Integer degU = 14, degV = 14;
315 Standard_Integer nmax = 16;
316 Standard_Integer thePrec = 1;
317
318 GeomConvert_ApproxSurface ConvertApprox(mySurface,theTol,theUCont,theVCont,
319 degU,degV,nmax,thePrec);
320 if (ConvertApprox.HasResult())
321 {
322 mySurface = ConvertApprox.Surface();
323 myCurve2d = new (TColGeom2d_HArray1OfCurve) (1, 2);
324 CError = new (TColStd_HArray2OfReal) (1,2, 1,2);
325
c5f3a425 326 Handle(Geom_BSplineSurface) BSplSurf (Handle(Geom_BSplineSurface)::DownCast(mySurface));
a31abc03 327
328 gp_Dir2d D(0., 1.);
329 gp_Pnt2d P(BSplSurf->UKnot(1), 0);
330 Handle(Geom2d_Line) LC1 = new (Geom2d_Line) (P, D);
331 Handle(Geom2d_TrimmedCurve) TC1 =
332 new (Geom2d_TrimmedCurve) (LC1, 0, BSplSurf->VKnot(BSplSurf->NbVKnots()));
333
334 myCurve2d->SetValue(1, TC1);
335 CError->SetValue(1, 1, 0.);
336 CError->SetValue(2, 1, 0.);
337
338 P.SetCoord(BSplSurf->UKnot(BSplSurf->NbUKnots()), 0);
339 Handle(Geom2d_Line) LC2 = new (Geom2d_Line) (P, D);
340 Handle(Geom2d_TrimmedCurve) TC2 =
341 new (Geom2d_TrimmedCurve) (LC2, 0, BSplSurf->VKnot(BSplSurf->NbVKnots()));
342
343 myCurve2d->SetValue(myCurve2d->Length(), TC2);
344 CError->SetValue(1, myCurve2d->Length(), 0.);
345 CError->SetValue(2, myCurve2d->Length(), 0.);
346
347 SError = theTol;
348 }
349 } //if (!mySurface->IsCNv(1))
7fd59977 350
351 // Les Courbes 2d
a31abc03 352 if (myCurve2d.IsNull())
353 {
354 myCurve2d = new (TColGeom2d_HArray1OfCurve) (1, 2+myLoc->TraceNumber());
355 CError = new (TColStd_HArray2OfReal) (1,2, 1, 2+myLoc->TraceNumber());
356 Standard_Integer kk,ii, ifin = 1, ideb;
357
358 if (myLoc->HasFirstRestriction()) {
359 ideb = 1;
360 }
361 else {
362 ideb = 2;
363 }
364 ifin += myLoc->TraceNumber();
365 if (myLoc->HasLastRestriction()) ifin++;
366
367 for (ii=ideb, kk=1; ii<=ifin; ii++, kk++) {
368 Handle(Geom2d_BSplineCurve) C
369 = new (Geom2d_BSplineCurve) (Approx.Curve2dPoles(kk),
370 Approx.Curves2dKnots(),
371 Approx.Curves2dMults(),
372 Approx.Curves2dDegree());
373 myCurve2d->SetValue(ii, C);
374 CError->SetValue(1, ii, Approx.Max2dError(kk));
375 CError->SetValue(2, ii, Approx.Max2dError(kk));
376 }
377
378 // Si les courbes de restriction, ne sont pas calcules, on prend
379 // les iso Bords.
380 if (! myLoc->HasFirstRestriction()) {
381 gp_Dir2d D(0., 1.);
382 gp_Pnt2d P(UKnots(UKnots.Lower()), 0);
383 Handle(Geom2d_Line) LC = new (Geom2d_Line) (P, D);
384 Handle(Geom2d_TrimmedCurve) TC = new (Geom2d_TrimmedCurve)
385 (LC, First, Last);
386
387 myCurve2d->SetValue(1, TC);
388 CError->SetValue(1, 1, 0.);
389 CError->SetValue(2, 1, 0.);
390 }
391
392 if (! myLoc->HasLastRestriction()) {
393 gp_Dir2d D(0., 1.);
394 gp_Pnt2d P(UKnots(UKnots.Upper()), 0);
395 Handle(Geom2d_Line) LC = new (Geom2d_Line) (P, D);
396 Handle(Geom2d_TrimmedCurve) TC =
397 new (Geom2d_TrimmedCurve) (LC, First, Last);
398 myCurve2d->SetValue(myCurve2d->Length(), TC);
399 CError->SetValue(1, myCurve2d->Length(), 0.);
400 CError->SetValue(2, myCurve2d->Length(), 0.);
401 }
402 } //if (myCurve2d.IsNull())
7fd59977 403 }
404 return Ok;
405}
406
407//===============================================================
408// Function : BuildProduct
409// Purpose : A venir...
410//===============================================================
411 Standard_Boolean GeomFill_Sweep::BuildProduct(const GeomAbs_Shape Continuity,
412 const Standard_Integer Degmax,
413 const Standard_Integer Segmax)
414{
415 Standard_Boolean Ok = Standard_False;
416
417 Handle(Geom_BSplineSurface) BSurf;
418 BSurf = Handle(Geom_BSplineSurface)::DownCast(
419 mySec->BSplineSurface()->Copy());
420 if (BSurf.IsNull()) return Ok; // Ce mode de construction est impossible
421
422
423 Standard_Integer NbIntervalC2, NbIntervalC3;
424 GeomFill_LocFunction Func(myLoc);
425
426 NbIntervalC2 = myLoc->NbIntervals(GeomAbs_C2);
427 NbIntervalC3 = myLoc->NbIntervals(GeomAbs_C3);
428 TColStd_Array1OfReal Param_de_decoupeC2 (1, NbIntervalC2+1);
429 myLoc->Intervals(Param_de_decoupeC2, GeomAbs_C2);
430 TColStd_Array1OfReal Param_de_decoupeC3 (1, NbIntervalC3+1);
431 myLoc->Intervals(Param_de_decoupeC3, GeomAbs_C3);
432
433
434 AdvApprox_PrefAndRec Preferentiel(Param_de_decoupeC2,
435 Param_de_decoupeC3);
436
437 Handle(TColStd_HArray1OfReal) ThreeDTol = new (TColStd_HArray1OfReal) (1,4);
438 ThreeDTol->Init(Tol3d); // A Affiner...
439
440 GeomFill_Sweep_Eval eval (Func);
441 AdvApprox_ApproxAFunction Approx(0, 0, 4,
442 ThreeDTol,
443 ThreeDTol,
444 ThreeDTol,
445 First,
446 Last,
447 Continuity,
448 Degmax,
449 Segmax,
450 eval,
451 Preferentiel);
0797d9d3 452#ifdef OCCT_DEBUG
7fd59977 453 Approx.Dump(cout);
454#endif
455
456 Ok = Approx.HasResult();
457 if (Ok) {
458/* TColgp_Array1OfMat TM(1, nbpoles);
459 Handle(TColgp_HArray2OfPnt) ResPoles;
460 ResPoles = Approx.Poles();
461
462 // Produit Tensoriel
463 for (ii=1; ii<=nbpoles; ii++) {
464 TM(ii).SetCols(ResPoles->Value(ii,2).XYZ(),
465 ResPoles->Value(ii,3).XYZ(),
466 ResPoles->Value(ii,4).XYZ());
467 TR(ii) = ResPoles->Value(ii,1);
468 }
469 GeomLib::TensorialProduct(BSurf, TM, TR,
470 Approx.Knots()->Array1(),
471 Approx.Multiplicities()->Array1());
472
473 // Somme
474 TColgp_Array1OfPnt TPoles(1, nbpoles);
475 for (ii=1; ii<=nbpoles; ii++) {
476 TPoles(ii) = ResPoles->Value(ii,1);
477 }
478 Handle(Geom_BsplineCurve) BS =
479 new (Geom_BsplineCurve) (Poles,
480 Approx.Knots()->Array1(),
481 Approx.Multiplicities()->Array1(),
482 Approx.Degree());
483 for (ii=1; ii<=BSurf->NbVKnots(); ii++)
484 BS->InsertKnot( BSurf->VKnot(ii),
485 BSurf->VMultiplicity(ii),
486 Precision::Confusion());
487 TColgp_Array2OfPnt SurfPoles (1, BSurf->NbUPoles());
488 for (ii=1;
489
490*/
491 mySurface = BSurf;
492 }
493 return Ok;
494}
495
496// Modified by skv - Thu Feb 5 18:05:03 2004 OCC5073 Begin
497// Conditions:
498// * theSec should be constant
499// * the type of section should be a line
500// * theLoc should represent a translation.
501
502static Standard_Boolean IsSweepParallelSpine (const Handle(GeomFill_LocationLaw) &theLoc,
503 const Handle(GeomFill_SectionLaw) &theSec,
504 const Standard_Real theTol)
505{
506 // Get the first and last transformations of the location
507 Standard_Real aFirst;
508 Standard_Real aLast;
509 gp_Vec VBegin;
510 gp_Vec VEnd;
511 gp_Mat M;
512 gp_GTrsf GTfBegin;
513 gp_Trsf TfBegin;
514 gp_GTrsf GTfEnd;
515 gp_Trsf TfEnd;
516
517 theLoc->GetDomain(aFirst, aLast);
518
519// Get the first transformation
520 theLoc->D0(aFirst, M, VBegin);
521
522 GTfBegin.SetVectorialPart(M);
523 GTfBegin.SetTranslationPart(VBegin.XYZ());
524
525 TfBegin.SetValues(GTfBegin(1,1), GTfBegin(1,2), GTfBegin(1,3), GTfBegin(1,4),
526 GTfBegin(2,1), GTfBegin(2,2), GTfBegin(2,3), GTfBegin(2,4),
7a8c6a36 527 GTfBegin(3,1), GTfBegin(3,2), GTfBegin(3,3), GTfBegin(3,4));
7fd59977 528
529// Get the last transformation
530 theLoc->D0(aLast, M, VEnd);
531
532 GTfEnd.SetVectorialPart(M);
533 GTfEnd.SetTranslationPart(VEnd.XYZ());
534
535 TfEnd.SetValues(GTfEnd(1,1), GTfEnd(1,2), GTfEnd(1,3), GTfEnd(1,4),
536 GTfEnd(2,1), GTfEnd(2,2), GTfEnd(2,3), GTfEnd(2,4),
7a8c6a36 537 GTfEnd(3,1), GTfEnd(3,2), GTfEnd(3,3), GTfEnd(3,4));
7fd59977 538
539 Handle(Geom_Surface) aSurf = theSec->BSplineSurface();
540 Standard_Real Umin;
541 Standard_Real Umax;
542 Standard_Real Vmin;
543 Standard_Real Vmax;
544
545 aSurf->Bounds(Umin, Umax, Vmin, Vmax);
546
547 // Get and transform the first section
548 Handle(Geom_Curve) FirstSection = theSec->ConstantSection();
549 GeomAdaptor_Curve ACFirst(FirstSection);
550
551 Standard_Real UFirst = ACFirst.FirstParameter();
552 gp_Lin L = ACFirst.Line();
553
554 L.Transform(TfBegin);
555
556 // Get and transform the last section
557 Handle(Geom_Curve) aLastSection = aSurf->VIso(Vmax);
558 Standard_Real aFirstParameter = aLastSection->FirstParameter();
559 gp_Pnt aPntLastSec = aLastSection->Value(aFirstParameter);
560
561 aPntLastSec.Transform(TfEnd);
562
563 gp_Pnt aPntFirstSec = ElCLib::Value( UFirst, L );
564 gp_Vec aVecSec( aPntFirstSec, aPntLastSec );
565 gp_Vec aVecSpine = VEnd - VBegin;
566
567 Standard_Boolean isParallel = aVecSec.IsParallel(aVecSpine, theTol);
568
569 return isParallel;
570}
571// Modified by skv - Thu Feb 5 18:05:01 2004 OCC5073 End
572
573//===============================================================
574// Function : BuildKPart
575// Purpose :
576//===============================================================
577 Standard_Boolean GeomFill_Sweep::BuildKPart()
578{
579 Standard_Boolean Ok = Standard_False;
580 Standard_Boolean isUPeriodic = Standard_False;
581 Standard_Boolean isVPeriodic = Standard_False;
582 Standard_Boolean IsTrsf = Standard_True;
583
584 isUPeriodic = mySec->IsUPeriodic();
585 Handle(Geom_Surface) S;
586 GeomAbs_CurveType SectionType;
587 gp_Vec V;
588 gp_Mat M;
589 Standard_Real levier, error = 0 ;
590 Standard_Real UFirst=0, VFirst=First, ULast=0, VLast=Last;
591 Standard_Real Tol = Min (Tol3d, BoundTol);
592
593 // (1) Trajectoire Rectilignes -------------------------
594 if (myLoc->IsTranslation(error)) {
595 // Donne de la translation
596 gp_Vec DP, DS;
597 myLoc->D0(1, M, DS);
598 myLoc->D0(0, M, V);
599 DP = DS - V;
600 DP.Normalize();
601 gp_GTrsf Tf;
602 gp_Trsf Tf2;
603 Tf.SetVectorialPart(M);
604 Tf.SetTranslationPart(V.XYZ());
605 try { // Pas joli mais il n'y as pas d'autre moyens de tester SetValues
606 OCC_CATCH_SIGNALS
607 Tf2.SetValues(Tf(1,1), Tf(1,2), Tf(1,3), Tf(1,4),
608 Tf(2,1), Tf(2,2), Tf(2,3), Tf(2,4),
7a8c6a36 609 Tf(3,1), Tf(3,2), Tf(3,3), Tf(3,4));
7fd59977 610 }
a738b534 611 catch (Standard_ConstructionError const&) {
7fd59977 612 IsTrsf = Standard_False;
613 }
614 if (!IsTrsf) {
615 return Standard_False;
616 }
617
618 // (1.1) Cas Extrusion
619 if (mySec->IsConstant(error)) {
620 Handle(Geom_Curve) Section;
621 Section = mySec->ConstantSection();
622 GeomAdaptor_Curve AC(Section);
623 SectionType = AC.GetType();
624 UFirst = AC.FirstParameter();
625 ULast = AC.LastParameter();
626 // (1.1.a) Cas Plan
627 if ( (SectionType == GeomAbs_Line) && IsTrsf) {
628// Modified by skv - Thu Feb 5 11:39:06 2004 OCC5073 Begin
629 if (!IsSweepParallelSpine(myLoc, mySec, Tol))
630 return Standard_False;
631// Modified by skv - Thu Feb 5 11:39:08 2004 OCC5073 End
632 gp_Lin L = AC.Line();
633 L.Transform(Tf2);
634 DS.SetXYZ(L.Position().Direction().XYZ());
635 DS.Normalize();
636 levier = Abs(DS.Dot(DP));
637 SError = error + levier * Abs(Last-First);
638 if (SError <= Tol) {
639 Ok = Standard_True;
640 gp_Ax2 AxisOfPlane (L.Location(), DS^DP, DS);
641 S = new (Geom_Plane) (AxisOfPlane);
642 }
643 else SError = 0.;
644 }
645
646 // (1.1.b) Cas Cylindrique
647 if ( (SectionType == GeomAbs_Circle) && IsTrsf) {
0f9f1f4e 648 const Standard_Real TolProd = 1.e-6;
649
7fd59977 650 gp_Circ C = AC.Circle();
651 C.Transform(Tf2);
652
653 DS.SetXYZ (C.Position().Direction().XYZ());
654 DS.Normalize();
655 levier = Abs(DS.CrossMagnitude(DP)) * C.Radius();
656 SError = levier * Abs(Last - First);
0f9f1f4e 657 if (SError <= TolProd) {
7fd59977 658 Ok = Standard_True;
659 gp_Ax3 axe (C.Location(), DP, C.Position().XDirection());
660 S = new (Geom_CylindricalSurface)
661 (axe, C.Radius());
662 if (C.Position().Direction().
663 IsOpposite(axe.Direction(), 0.1) ) {
664 Standard_Real f, l;
665 // L'orientation parametrique est inversee
c6541a0c
D
666 l = 2*M_PI - UFirst;
667 f = 2*M_PI - ULast;
7fd59977 668 UFirst = f;
669 ULast = l;
670 isUReversed = Standard_True;
671 }
672 }
673 else SError = 0.;
674 }
675
676 // (1.1.c) C'est bien une extrusion
677 if (!Ok) {
678 if (IsTrsf) {
679 Section->Transform(Tf2);
680 S = new (Geom_SurfaceOfLinearExtrusion)
681 (Section, DP);
682 SError = 0.;
683 Ok = Standard_True;
684 }
685 else { // extrusion sur BSpline
686
687 }
688 }
689 }
690
691 // (1.2) Cas conique
692 else if (mySec->IsConicalLaw(error)) {
693
694 gp_Pnt P1, P2, Centre0, Centre1, Centre2;
695 gp_Vec dsection;
696 Handle(Geom_Curve) Section;
697 GeomAdaptor_Curve AC;
698 gp_Circ C;
699 Standard_Real R1, R2;
700
701
702 Section = mySec->CirclSection(SLast);
703 Section->Transform(Tf2);
704 Section->Translate(Last*DP);
705 AC.Load(Section);
706 C = AC.Circle();
707 Centre2 = C.Location();
708 AC.D1(0, P2, dsection);
709 R2 = C.Radius();
710
711 Section = mySec->CirclSection(SFirst);
712 Section->Transform(Tf2);
713 Section->Translate(First*DP);
714 AC.Load(Section);
715 C = AC.Circle();
716 Centre1 = C.Location();
717 P1 = AC.Value(0);
718 R1 = C.Radius();
719
720 Section = mySec->CirclSection(SFirst - First*(SLast-SFirst)/(Last-First));
721 Section->Transform(Tf2);
722 AC.Load(Section);
723 C = AC.Circle();
724 Centre0 = C.Location();
725
726 Standard_Real Angle;
727 gp_Vec N(Centre1, P1);
728 if (N.Magnitude() < 1.e-9) {
729 gp_Vec Bis(Centre2, P2);
730 N = Bis;
731 }
732 gp_Vec L(P1, P2), Dir(Centre1,Centre2);
733
734 Angle = L.Angle(Dir);
c6541a0c 735 if ((Angle > 0.01) && (Angle < M_PI/2-0.01)) {
7fd59977 736 if (R2<R1) Angle = -Angle;
737 SError = error;
738 gp_Ax3 Axis(Centre0, Dir, N);
739 S = new (Geom_ConicalSurface)
740 (Axis, Angle, C.Radius());
741 // Calcul du glissement parametrique
742 VFirst = First / Cos(Angle);
743 VLast = Last / Cos(Angle);
744
745 // Bornes en U
746 UFirst = AC.FirstParameter();
747 ULast = AC.LastParameter();
748 gp_Vec diso;
749 gp_Pnt pbis;
750 S->VIso(VLast)->D1(0, pbis, diso);
751 if (diso.Magnitude()>1.e-9 && dsection.Magnitude()>1.e-9)
752 isUReversed = diso.IsOpposite(dsection, 0.1);
753 if (isUReversed ) {
754 Standard_Real f, l;
755 // L'orientation parametrique est inversee
c6541a0c
D
756 l = 2*M_PI - UFirst;
757 f = 2*M_PI - ULast;
7fd59977 758 UFirst = f;
759 ULast = l;
760 }
761
762 // C'est un cone
763 Ok = Standard_True;
764 }
765 }
766 }
767
768 // (2) Trajectoire Circulaire
769 if (myLoc->IsRotation(error)) {
770 if (mySec->IsConstant(error)) {
771 // La trajectoire
772 gp_Pnt Centre;
c6541a0c 773 isVPeriodic = (Abs(Last-First -2*M_PI) < 1.e-15);
7fd59977 774 Standard_Real RotRadius;
775 gp_Vec DP, DS, DN;
776 myLoc->D0(0.1, M, DS);
777 myLoc->D0(0, M, V);
778 myLoc->Rotation(Centre);
779
780 DP = DS - V;
781 DS.SetXYZ(V.XYZ() - Centre.XYZ());
782 RotRadius = DS.Magnitude();
783 if (RotRadius > 1.e-15) DS.Normalize();
784 else return Standard_False; // Pas de KPart, rotation degeneree
785 DN = DS ^ DP;
786 DN.Normalize();
787 DP = DN ^ DS;
788 DP.Normalize();
789
790 gp_GTrsf Tf;
791 gp_Trsf Tf2;
792 Tf.SetVectorialPart(M);
793 Tf.SetTranslationPart(V.XYZ());
794// try { // Pas joli mais il n'y as pas d'autre moyens de tester SetValues
795// OCC_CATCH_SIGNALS
796 Tf2.SetValues(Tf(1,1), Tf(1,2), Tf(1,3), Tf(1,4),
797 Tf(2,1), Tf(2,2), Tf(2,3), Tf(2,4),
7a8c6a36 798 Tf(3,1), Tf(3,2), Tf(3,3), Tf(3,4));
7fd59977 799// }
800// catch (Standard_ConstructionError) {
801// IsTrsf = Standard_False;
802// }
803 // La section
804 Handle(Geom_Curve) Section;
805 Section = mySec->ConstantSection();
806 GeomAdaptor_Curve AC(Section);
807 SectionType = AC.GetType();
808 UFirst = AC.FirstParameter();
809 ULast = AC.LastParameter();
810
811 // (2.1) Tore/Sphere ?
812 if ((SectionType == GeomAbs_Circle) && IsTrsf) {
813 gp_Circ C = AC.Circle();
814 Standard_Real Radius;
815 Standard_Boolean IsGoodSide = Standard_True;;
816 C.Transform(Tf2);
817 gp_Vec DC;
818 // On calcul le centre eventuel
819 DC.SetXYZ(C.Location().XYZ() - Centre.XYZ());
820 Centre.ChangeCoord() += (DC.Dot(DN))*DN.XYZ();
821 DC.SetXYZ(C.Location().XYZ() - Centre.XYZ());
822 Radius = DC.Magnitude(); //grand Rayon du tore
823 if ((Radius > Tol) && (DC.Dot(DS) < 0)) IsGoodSide = Standard_False;
824 if (Radius < Tol/100) DC = DS; // Pour definir le tore
825
826 // On verifie d'abord que le plan de la section est // a
827 // l'axe de rotation
828 gp_Vec NC;
829 NC.SetXYZ (C.Position().Direction().XYZ());
830 NC.Normalize();
831 error = Abs(NC.Dot(DN));
832 // Puis on evalue l'erreur commise sur la section,
833 // en pivotant son plan ( pour contenir l'axe de rotation)
834 error += Abs(NC.Dot(DS));
835 error *= C.Radius();
836 if (error <= Tol) {
837 SError = error;
107f794f 838 error += Radius;
839 if (Radius <= Tol) {
7fd59977 840 // (2.1.a) Sphere
b969ebe7 841 Standard_Real f = UFirst , l = ULast, aRadius = 0.0;
7fd59977 842 SError = error;
843 Centre.BaryCenter(1.0, C.Location(), 1.0);
9ba2c30f 844 gp_Ax3 AxisOfSphere(Centre, DN, DS);
107f794f 845 aRadius = C.Radius();
b969ebe7 846 gp_Sphere theSphere( AxisOfSphere, aRadius );
9ba2c30f 847 S = new Geom_SphericalSurface(theSphere);
7fd59977 848 // Pour les spheres on ne peut pas controler le parametre
849 // V (donc U car myExchUV = Standard_True)
850 // Il faut donc modifier UFirst, ULast...
9ba2c30f 851 Standard_Real fpar = AC.FirstParameter();
852 Standard_Real lpar = AC.LastParameter();
853 Handle(Geom_Curve) theSection = new Geom_TrimmedCurve(Section, fpar, lpar);
854 theSection->Transform(Tf2);
855 gp_Pnt FirstPoint = theSection->Value(theSection->FirstParameter());
856 gp_Pnt LastPoint = theSection->Value(theSection->LastParameter());
857 Standard_Real UfirstOnSec, VfirstOnSec, UlastOnSec, VlastOnSec;
858 ElSLib::Parameters(theSphere, FirstPoint, UfirstOnSec, VfirstOnSec);
859 ElSLib::Parameters(theSphere, LastPoint, UlastOnSec, VlastOnSec);
860 if (VfirstOnSec < VlastOnSec)
861 {
862 f = VfirstOnSec;
863 l = VlastOnSec;
864 }
865 else
866 {
7fd59977 867 // L'orientation parametrique est inversee
9ba2c30f 868 f = VlastOnSec;
869 l = VfirstOnSec;
7fd59977 870 isUReversed = Standard_True;
871 }
7fd59977 872
c6541a0c 873 if ( (f >= -M_PI/2) && (l <= M_PI/2)) {
7fd59977 874 Ok = Standard_True;
875 myExchUV = Standard_True;
876 UFirst = f;
877 ULast = l;
878 }
879 else { // On restaure ce qu'il faut
880 isUReversed = Standard_False;
881 }
882 }
883 else if (IsGoodSide) {
884 // (2.1.b) Tore
885 gp_Ax3 AxisOfTore(Centre, DN, DC);
886 S = new (Geom_ToroidalSurface) (AxisOfTore,
887 Radius , C.Radius());
888
889 // Pour les tores on ne peut pas controler le parametre
890 // V (donc U car myExchUV = Standard_True)
891 // Il faut donc modifier UFirst, ULast...
892 Handle(Geom_Circle) Iso;
893 Iso = Handle(Geom_Circle)::DownCast(S->UIso(0.));
894 gp_Ax2 axeiso;
895 axeiso = Iso->Circ().Position();
896
897 if (C.Position().Direction().
898 IsOpposite(axeiso.Direction(), 0.1) ) {
899 Standard_Real f, l;
900 // L'orientation parametrique est inversee
c6541a0c
D
901 l = 2*M_PI - UFirst;
902 f = 2*M_PI - ULast;
7fd59977 903 UFirst = f;
904 ULast = l;
905 isUReversed = Standard_True;
906 }
907 // On calcul le "glissement" parametrique.
908 Standard_Real rot;
909 rot = C.Position().XDirection().AngleWithRef
910 (axeiso.XDirection(), axeiso.Direction());
911 UFirst -= rot;
912 ULast -= rot;
913
914 myExchUV = Standard_True;
915 // Attention l'arete de couture dans le cas periodique
916 // n'est peut etre pas a la bonne place...
917 if (isUPeriodic && Abs(UFirst)>Precision::PConfusion())
918 isUPeriodic = Standard_False; //Pour trimmer la surface...
919 Ok = Standard_True;
920 }
921 }
922 else {
923 SError = 0.;
924 }
925 }
926 // (2.2) Cone / Cylindre
927 if ((SectionType == GeomAbs_Line) && IsTrsf) {
928 gp_Lin L = AC.Line();
929 L.Transform(Tf2);
930 gp_Vec DL;
931 DL.SetXYZ(L.Direction().XYZ());
932 levier = Max(Abs(AC.FirstParameter()), AC.LastParameter());
933 // si la line est ortogonale au cercle de rotation
934 SError = error + levier * Abs(DL.Dot(DP));
935 if (SError <= Tol) {
936 Standard_Boolean reverse;
937 gp_Lin Dir(Centre, DN);
938 Standard_Real aux;
939 aux = DL.Dot(DN);
940 reverse = (aux < 0); // On choisit ici le sens de parametrisation
941
942 // Calcul du centre du vecteur supportant la "XDirection"
943 gp_Pnt CentreOfSurf;
944 gp_Vec O1O2(Centre, L.Location()), trans;
945 trans = DN;
946 trans *= DN.Dot(O1O2);
947 CentreOfSurf = Centre.Translated(trans);
948 DS.SetXYZ(L.Location().XYZ() - CentreOfSurf.XYZ());
949
950 error = SError;
951 error += (DL.XYZ()).CrossMagnitude(DN.XYZ())*levier;
952 if (error <= Tol) {
953 // (2.2.a) Cylindre
954 // si la line est orthogonale au plan de rotation
955 SError = error;
956 gp_Ax3 Axis(CentreOfSurf, Dir.Direction(), DS);
957 S = new (Geom_CylindricalSurface)
958 (Axis, L.Distance(CentreOfSurf));
959 Ok = Standard_True;
960 myExchUV = Standard_True;
961 }
962 else {
963 // On evalue l'angle du cone
964 Standard_Real Angle = Abs(Dir.Angle(L));
c6541a0c 965 if (Angle > M_PI/2) Angle = M_PI -Angle;
7fd59977 966 if (reverse) Angle = -Angle;
967 aux = DS.Dot(DL);
968 if (aux < 0) {
969 Angle = - Angle;
970 }
c6541a0c 971 if (Abs(Abs(Angle) - M_PI/2) > 0.01) {
7fd59977 972 // (2.2.b) Cone
973 // si les 2 droites ne sont pas orthogonales
974 Standard_Real Radius = CentreOfSurf.Distance(L.Location());
975 gp_Ax3 Axis(CentreOfSurf, Dir.Direction(), DS);
976 S = new (Geom_ConicalSurface)
977 (Axis, Angle, Radius);
978 myExchUV = Standard_True;
979 Ok = Standard_True;
980 }
981 else {
982 // On n'as pas conclue, on remet l'erreur a 0.
983 SError = 0.;
984 }
985 }
986 if (Ok && reverse) {
987 // On reverse le parametre
988 Standard_Real uf, ul;
989 Handle(Geom_Line) CL = new (Geom_Line)(L);
990 uf = CL->ReversedParameter(ULast);
991 ul = CL->ReversedParameter(UFirst);
992 UFirst = uf;
993 ULast = ul;
994 isUReversed = Standard_True;
995 }
996 }
997 else SError = 0.;
998 }
999
1000 // (2.3) Revolution
1001 if (!Ok) {
1002 if (IsTrsf) {
1003 Section->Transform(Tf2);
1004 gp_Ax1 Axis (Centre, DN);
1005 S = new (Geom_SurfaceOfRevolution)
1006 (Section, Axis);
1007 myExchUV = Standard_True;
1008 SError = 0.;
1009 Ok = Standard_True;
1010 }
1011 }
1012 }
1013 }
1014
1015
1016 if (Ok) { // On trimme la surface
1017 if (myExchUV) {
1018 Standard_Boolean b;
1019 b = isUPeriodic; isUPeriodic = isVPeriodic; isVPeriodic = b;
1020 Standard_Real r;
1021 r = UFirst; UFirst = VFirst; VFirst = r;
1022 r = ULast; ULast = VLast; VLast = r;
1023 }
1024
1025 if (!isUPeriodic && !isVPeriodic)
1026 mySurface = new (Geom_RectangularTrimmedSurface)
1027 (S, UFirst, ULast, VFirst, VLast);
1028 else if (isUPeriodic) {
1029 if (isVPeriodic) mySurface = S;
1030 else mySurface = new (Geom_RectangularTrimmedSurface)
1031 (S, VFirst, VLast, Standard_False);
1032 }
1033 else
1034 mySurface = new (Geom_RectangularTrimmedSurface)
1035 (S,UFirst, ULast, Standard_True);
1036
0797d9d3 1037#ifdef OCCT_DEBUG
7fd59977 1038 if (isUPeriodic && !mySurface->IsUPeriodic())
1039 cout<<"Pb de periodicite en U" << endl;
1040 if (isUPeriodic && !mySurface->IsUClosed())
1041 cout<<"Pb de fermeture en U" << endl;
1042 if (isVPeriodic && !mySurface->IsVPeriodic())
1043 cout << "Pb de periodicite en V" << endl;
1044 if (isVPeriodic && !mySurface->IsVClosed())
1045 cout<<"Pb de fermeture en V" << endl;
1046#endif
1047 }
1048
1049
1050 return Ok;
1051}
1052
1053//===============================================================
1054// Function : IsDone
1055// Purpose :
1056//===============================================================
1057 Standard_Boolean GeomFill_Sweep::IsDone() const
1058{
1059 return done;
1060}
1061
1062//===============================================================
1063// Function :ErrorOnSurface
1064// Purpose :
1065//===============================================================
1066 Standard_Real GeomFill_Sweep::ErrorOnSurface() const
1067{
1068 return SError;
1069}
1070
1071//===============================================================
1072// Function ::ErrorOnRestriction
1073// Purpose :
1074//===============================================================
1075 void GeomFill_Sweep::ErrorOnRestriction(const Standard_Boolean IsFirst,
1076 Standard_Real& UError,
1077 Standard_Real& VError) const
1078{
1079 Standard_Integer ind;
1080 if (IsFirst) ind=1;
1081 else ind = myCurve2d->Length();
1082
1083 UError = CError->Value(1, ind);
1084 VError = CError->Value(2, ind);
1085}
1086
1087//===============================================================
1088// Function :ErrorOnTrace
1089// Purpose :
1090//===============================================================
1091 void GeomFill_Sweep::ErrorOnTrace(const Standard_Integer IndexOfTrace,
1092 Standard_Real& UError,
1093 Standard_Real& VError) const
1094{
1095 Standard_Integer ind = IndexOfTrace+1;
1096 if (IndexOfTrace > myLoc->TraceNumber())
9775fa61 1097 throw Standard_OutOfRange(" GeomFill_Sweep::ErrorOnTrace");
7fd59977 1098
1099 UError = CError->Value(1, ind);
1100 VError = CError->Value(2, ind);
1101}
1102
1103//===============================================================
1104// Function :Surface
1105// Purpose :
1106//===============================================================
1107 Handle(Geom_Surface) GeomFill_Sweep::Surface() const
1108{
1109 return mySurface;
1110}
1111
1112//===============================================================
1113// Function ::Restriction
1114// Purpose :
1115//===============================================================
1116 Handle(Geom2d_Curve) GeomFill_Sweep::Restriction(const Standard_Boolean IsFirst) const
1117{
1118 if (IsFirst)
1119 return myCurve2d->Value(1);
1120 return myCurve2d->Value(myCurve2d->Length());
1121
1122}
1123
1124//===============================================================
1125// Function :
1126// Purpose :
1127//===============================================================
1128 Standard_Integer GeomFill_Sweep::NumberOfTrace() const
1129{
1130 return myLoc->TraceNumber();
1131}
1132
1133//===============================================================
1134// Function :
1135// Purpose :
1136//===============================================================
1137 Handle(Geom2d_Curve)
1138 GeomFill_Sweep::Trace(const Standard_Integer IndexOfTrace) const
1139{
1140 Standard_Integer ind = IndexOfTrace+1;
1141 if (IndexOfTrace > myLoc->TraceNumber())
9775fa61 1142 throw Standard_OutOfRange(" GeomFill_Sweep::Trace");
7fd59977 1143 return myCurve2d->Value(ind);
1144}