0024684: Command fixshape hangs up on the attached shape
[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
19#include <GeomFill_Sweep.ixx>
20#include <GeomFill_SweepFunction.hxx>
21#include <GeomFill_LocFunction.hxx>
22
23#include <Standard_ErrorHandler.hxx>
24
25#include <gp_Pnt2d.hxx>
26#include <gp_Dir2d.hxx>
27#include <gp_Pnt.hxx>
28#include <gp_Dir.hxx>
29#include <gp_Lin.hxx>
30#include <gp_Circ.hxx>
31#include <gp_GTrsf.hxx>
32#include <gp_Mat.hxx>
33#include <gp_Ax2.hxx>
34
35#include <TColgp_Array1OfPnt.hxx>
36#include <TColgp_Array2OfPnt.hxx>
37#include <TColgp_HArray2OfPnt.hxx>
38//#include <GeomLib_Array1OfMat.hxx>
39#include <TColStd_Array1OfInteger.hxx>
40#include <TColStd_Array1OfReal.hxx>
41#include <TColStd_Array2OfReal.hxx>
42
43#include <GeomAbs_CurveType.hxx>
44#include <GeomAdaptor_Curve.hxx>
45#include <GeomLib.hxx>
46
47#include <Geom2d_Line.hxx>
48#include <Geom2d_BSplineCurve.hxx>
49#include <Geom2d_TrimmedCurve.hxx>
50
51#include <Geom_Circle.hxx>
52#include <Geom_Line.hxx>
53#include <Geom_BSplineSurface.hxx>
54#include <Geom_Plane.hxx>
55#include <Geom_SurfaceOfLinearExtrusion.hxx>
56#include <Geom_CylindricalSurface.hxx>
57#include <Geom_ConicalSurface.hxx>
58#include <Geom_ToroidalSurface.hxx>
59#include <Geom_SphericalSurface.hxx>
60#include <Geom_SurfaceOfRevolution.hxx>
61#include <Geom_RectangularTrimmedSurface.hxx>
62
63#include <Approx_SweepApproximation.hxx>
64#include <AdvApprox_PrefAndRec.hxx>
65#include <AdvApprox_ApproxAFunction.hxx>
a31abc03 66#include <GeomConvert_ApproxSurface.hxx>
7fd59977 67
68#include <Precision.hxx>
69#include <ElCLib.hxx>
70
71//=======================================================================
72//class : GeomFill_Sweep_Eval
73//purpose: The evaluator for curve approximation
74//=======================================================================
75
76class GeomFill_Sweep_Eval : public AdvApprox_EvaluatorFunction
77{
78 public:
79 GeomFill_Sweep_Eval (GeomFill_LocFunction& theTool)
80 : theAncore(theTool) {}
81
82 virtual void Evaluate (Standard_Integer *Dimension,
83 Standard_Real StartEnd[2],
84 Standard_Real *Parameter,
85 Standard_Integer *DerivativeRequest,
86 Standard_Real *Result, // [Dimension]
87 Standard_Integer *ErrorCode);
88
89 private:
90 GeomFill_LocFunction& theAncore;
91};
92
93void GeomFill_Sweep_Eval::Evaluate (Standard_Integer *,/*Dimension*/
94 Standard_Real StartEnd[2],
95 Standard_Real *Parameter,
96 Standard_Integer *DerivativeRequest,
97 Standard_Real *Result,// [Dimension]
98 Standard_Integer *ErrorCode)
99{
100 theAncore.DN (*Parameter,
101 StartEnd[0],
102 StartEnd[1],
103 *DerivativeRequest,
104 Result[0],
105 ErrorCode[0]);
106}
107
108//===============================================================
109// Function : Create
110// Purpose :
111//===============================================================
112GeomFill_Sweep::GeomFill_Sweep(const Handle(GeomFill_LocationLaw)& Location,
113 const Standard_Boolean WithKpart)
114{
115 done = Standard_False;
116
117 myLoc = Location;
118 myKPart = WithKpart;
119 SetTolerance(1.e-4);
a31abc03 120 myForceApproxC1 = Standard_False;
7fd59977 121
122 myLoc->GetDomain(First, Last);
123 SFirst = SLast = 30.081996;
124 SError = RealLast();
125}
126
127//===============================================================
128// Function : SetDomain
129// Purpose :
130//===============================================================
131 void GeomFill_Sweep::SetDomain(const Standard_Real LocFirst,
132 const Standard_Real LocLast,
133 const Standard_Real SectionFirst,
134 const Standard_Real SectionLast)
135{
136 First = LocFirst;
137 Last = LocLast;
138 SFirst = SectionFirst;
139 SLast = SectionLast;
140}
141
142//===============================================================
143// Function : SetTolerance
144// Purpose :
145//===============================================================
146 void GeomFill_Sweep::SetTolerance(const Standard_Real Tolerance3d,
147 const Standard_Real BoundTolerance,
148 const Standard_Real Tolerance2d,
149 const Standard_Real ToleranceAngular)
150{
151 Tol3d = Tolerance3d;
152 BoundTol = BoundTolerance;
153 Tol2d =Tolerance2d;
154 TolAngular = ToleranceAngular;
155}
156
a31abc03 157//=======================================================================
158//Function : SetForceApproxC1
159//Purpose : Set the flag that indicates attempt to approximate
160// a C1-continuous surface if a swept surface proved
161// to be C0.
162//=======================================================================
163 void GeomFill_Sweep::SetForceApproxC1(const Standard_Boolean ForceApproxC1)
164{
165 myForceApproxC1 = ForceApproxC1;
166}
167
168
7fd59977 169//===============================================================
170// Function : ExchangeUV
171// Purpose :
172//===============================================================
173 Standard_Boolean GeomFill_Sweep::ExchangeUV() const
174{
175 return myExchUV;
176}
177
178//===============================================================
179// Function : UReversed
180// Purpose :
181//===============================================================
182 Standard_Boolean GeomFill_Sweep::UReversed() const
183{
184 return isUReversed;
185}
186
187//===============================================================
188// Function : VReversed
189// Purpose :
190//===============================================================
191 Standard_Boolean GeomFill_Sweep::VReversed() const
192{
193 return isVReversed;
194}
195
196//===============================================================
197// Function : Build
198// Purpose :
199//===============================================================
200 void GeomFill_Sweep::Build(const Handle(GeomFill_SectionLaw)& Section,
201 const GeomFill_ApproxStyle Methode,
202 const GeomAbs_Shape Continuity,
203 const Standard_Integer Degmax,
204 const Standard_Integer Segmax)
205{
206 // Inits
207 done = Standard_False;
208 myExchUV = Standard_False;
209 isUReversed = isVReversed = Standard_False;
210 mySec = Section;
211
212 if ((SFirst == SLast) && (SLast == 30.081996)) {
213 mySec->GetDomain(SFirst, SLast);
214 }
215
216 Standard_Boolean isKPart = Standard_False,
217 isProduct = Standard_False;
218
219 // Traitement des KPart
220 if (myKPart) isKPart = BuildKPart();
221
222 // Traitement des produits Formelles
223 if ((!isKPart) && (Methode == GeomFill_Location)) {
224 Handle(Geom_BSplineSurface) BS;
225 BS = mySec->BSplineSurface();
226 if (! BS.IsNull()) {
227 // Approx de la loi
228// isProduct = BuildProduct(Continuity, Degmax, Segmax);
229 }
230 }
231
232 if (isKPart || isProduct) {
233 // Approx du 2d
234 done = Build2d(Continuity, Degmax, Segmax);
235 }
236 else {
237 // Approx globale
238 done = BuildAll(Continuity, Degmax, Segmax);
239 }
240}
241
242//===============================================================
243// Function ::Build2d
244// Purpose :A venir...
245//===============================================================
246// Standard_Boolean GeomFill_Sweep::Build2d(const GeomAbs_Shape Continuity,
247 Standard_Boolean GeomFill_Sweep::Build2d(const GeomAbs_Shape ,
248// const Standard_Integer Degmax,
249 const Standard_Integer ,
250// const Standard_Integer Segmax)
251 const Standard_Integer )
252{
253 Standard_Boolean Ok = Standard_False;
254 if (myLoc->Nb2dCurves() == 0) {
255 Ok = Standard_True;
256 }
257 return Ok;
258}
259
260//===============================================================
261// Function : BuildAll
262// Purpose :
263//===============================================================
264 Standard_Boolean GeomFill_Sweep::BuildAll(const GeomAbs_Shape Continuity,
265 const Standard_Integer Degmax,
266 const Standard_Integer Segmax)
267{
268 Standard_Boolean Ok = Standard_False;
7fd59977 269
270 Handle(GeomFill_SweepFunction) Func
271 = new (GeomFill_SweepFunction) (mySec, myLoc, First, SFirst,
272 (SLast-SFirst)/(Last-First) );
273 Approx_SweepApproximation Approx( Func );
274
275 Approx.Perform(First, Last,
276 Tol3d, BoundTol, Tol2d, TolAngular,
277 Continuity, Degmax, Segmax);
278
279 if (Approx.IsDone()) {
280 Ok = Standard_True;
281
282#if DEB
283 Approx.Dump(cout);
284#endif
285
286 // La surface
287 Standard_Integer UDegree,VDegree,NbUPoles,
288 NbVPoles,NbUKnots,NbVKnots;
289 Approx.SurfShape(UDegree,VDegree,NbUPoles,
290 NbVPoles,NbUKnots,NbVKnots);
291
292 TColgp_Array2OfPnt Poles(1,NbUPoles, 1,NbVPoles);
293 TColStd_Array2OfReal Weights(1,NbUPoles, 1,NbVPoles);
294 TColStd_Array1OfReal UKnots(1, NbUKnots),VKnots(1, NbVKnots);
295 TColStd_Array1OfInteger UMults(1, NbUKnots), VMults(1, NbVKnots);
296
297 Approx.Surface(Poles, Weights,
298 UKnots,VKnots,
299 UMults,VMults);
300
301 mySurface = new (Geom_BSplineSurface)
302 (Poles, Weights,
303 UKnots,VKnots,
304 UMults,VMults,
305 Approx.UDegree(), Approx.VDegree(),
306 mySec->IsUPeriodic());
307 SError = Approx. MaxErrorOnSurf();
a31abc03 308
309 if (myForceApproxC1 && !mySurface->IsCNv(1))
310 {
311 Standard_Real theTol = 1.e-4;
312 GeomAbs_Shape theUCont = GeomAbs_C1, theVCont = GeomAbs_C1;
313 Standard_Integer degU = 14, degV = 14;
314 Standard_Integer nmax = 16;
315 Standard_Integer thePrec = 1;
316
317 GeomConvert_ApproxSurface ConvertApprox(mySurface,theTol,theUCont,theVCont,
318 degU,degV,nmax,thePrec);
319 if (ConvertApprox.HasResult())
320 {
321 mySurface = ConvertApprox.Surface();
322 myCurve2d = new (TColGeom2d_HArray1OfCurve) (1, 2);
323 CError = new (TColStd_HArray2OfReal) (1,2, 1,2);
324
325 const Handle(Geom_BSplineSurface)& BSplSurf =
326 Handle(Geom_BSplineSurface)::DownCast(mySurface);
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);
452#if DEB
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),
527 GTfBegin(3,1), GTfBegin(3,2), GTfBegin(3,3), GTfBegin(3,4),
528 1.e-12, 1.e-14);
529
530// Get the last transformation
531 theLoc->D0(aLast, M, VEnd);
532
533 GTfEnd.SetVectorialPart(M);
534 GTfEnd.SetTranslationPart(VEnd.XYZ());
535
536 TfEnd.SetValues(GTfEnd(1,1), GTfEnd(1,2), GTfEnd(1,3), GTfEnd(1,4),
537 GTfEnd(2,1), GTfEnd(2,2), GTfEnd(2,3), GTfEnd(2,4),
538 GTfEnd(3,1), GTfEnd(3,2), GTfEnd(3,3), GTfEnd(3,4),
539 1.e-12, 1.e-14);
540
541 Handle(Geom_Surface) aSurf = theSec->BSplineSurface();
542 Standard_Real Umin;
543 Standard_Real Umax;
544 Standard_Real Vmin;
545 Standard_Real Vmax;
546
547 aSurf->Bounds(Umin, Umax, Vmin, Vmax);
548
549 // Get and transform the first section
550 Handle(Geom_Curve) FirstSection = theSec->ConstantSection();
551 GeomAdaptor_Curve ACFirst(FirstSection);
552
553 Standard_Real UFirst = ACFirst.FirstParameter();
554 gp_Lin L = ACFirst.Line();
555
556 L.Transform(TfBegin);
557
558 // Get and transform the last section
559 Handle(Geom_Curve) aLastSection = aSurf->VIso(Vmax);
560 Standard_Real aFirstParameter = aLastSection->FirstParameter();
561 gp_Pnt aPntLastSec = aLastSection->Value(aFirstParameter);
562
563 aPntLastSec.Transform(TfEnd);
564
565 gp_Pnt aPntFirstSec = ElCLib::Value( UFirst, L );
566 gp_Vec aVecSec( aPntFirstSec, aPntLastSec );
567 gp_Vec aVecSpine = VEnd - VBegin;
568
569 Standard_Boolean isParallel = aVecSec.IsParallel(aVecSpine, theTol);
570
571 return isParallel;
572}
573// Modified by skv - Thu Feb 5 18:05:01 2004 OCC5073 End
574
575//===============================================================
576// Function : BuildKPart
577// Purpose :
578//===============================================================
579 Standard_Boolean GeomFill_Sweep::BuildKPart()
580{
581 Standard_Boolean Ok = Standard_False;
582 Standard_Boolean isUPeriodic = Standard_False;
583 Standard_Boolean isVPeriodic = Standard_False;
584 Standard_Boolean IsTrsf = Standard_True;
585
586 isUPeriodic = mySec->IsUPeriodic();
587 Handle(Geom_Surface) S;
588 GeomAbs_CurveType SectionType;
589 gp_Vec V;
590 gp_Mat M;
591 Standard_Real levier, error = 0 ;
592 Standard_Real UFirst=0, VFirst=First, ULast=0, VLast=Last;
593 Standard_Real Tol = Min (Tol3d, BoundTol);
594
595 // (1) Trajectoire Rectilignes -------------------------
596 if (myLoc->IsTranslation(error)) {
597 // Donne de la translation
598 gp_Vec DP, DS;
599 myLoc->D0(1, M, DS);
600 myLoc->D0(0, M, V);
601 DP = DS - V;
602 DP.Normalize();
603 gp_GTrsf Tf;
604 gp_Trsf Tf2;
605 Tf.SetVectorialPart(M);
606 Tf.SetTranslationPart(V.XYZ());
607 try { // Pas joli mais il n'y as pas d'autre moyens de tester SetValues
608 OCC_CATCH_SIGNALS
609 Tf2.SetValues(Tf(1,1), Tf(1,2), Tf(1,3), Tf(1,4),
610 Tf(2,1), Tf(2,2), Tf(2,3), Tf(2,4),
611 Tf(3,1), Tf(3,2), Tf(3,3), Tf(3,4),
612 1.e-12, 1.e-14);
613 }
614 catch (Standard_ConstructionError) {
615 IsTrsf = Standard_False;
616 }
617 if (!IsTrsf) {
618 return Standard_False;
619 }
620
621 // (1.1) Cas Extrusion
622 if (mySec->IsConstant(error)) {
623 Handle(Geom_Curve) Section;
624 Section = mySec->ConstantSection();
625 GeomAdaptor_Curve AC(Section);
626 SectionType = AC.GetType();
627 UFirst = AC.FirstParameter();
628 ULast = AC.LastParameter();
629 // (1.1.a) Cas Plan
630 if ( (SectionType == GeomAbs_Line) && IsTrsf) {
631// Modified by skv - Thu Feb 5 11:39:06 2004 OCC5073 Begin
632 if (!IsSweepParallelSpine(myLoc, mySec, Tol))
633 return Standard_False;
634// Modified by skv - Thu Feb 5 11:39:08 2004 OCC5073 End
635 gp_Lin L = AC.Line();
636 L.Transform(Tf2);
637 DS.SetXYZ(L.Position().Direction().XYZ());
638 DS.Normalize();
639 levier = Abs(DS.Dot(DP));
640 SError = error + levier * Abs(Last-First);
641 if (SError <= Tol) {
642 Ok = Standard_True;
643 gp_Ax2 AxisOfPlane (L.Location(), DS^DP, DS);
644 S = new (Geom_Plane) (AxisOfPlane);
645 }
646 else SError = 0.;
647 }
648
649 // (1.1.b) Cas Cylindrique
650 if ( (SectionType == GeomAbs_Circle) && IsTrsf) {
651 gp_Circ C = AC.Circle();
652 C.Transform(Tf2);
653
654 DS.SetXYZ (C.Position().Direction().XYZ());
655 DS.Normalize();
656 levier = Abs(DS.CrossMagnitude(DP)) * C.Radius();
657 SError = levier * Abs(Last - First);
658 if (SError <= Tol) {
659 Ok = Standard_True;
660 gp_Ax3 axe (C.Location(), DP, C.Position().XDirection());
661 S = new (Geom_CylindricalSurface)
662 (axe, C.Radius());
663 if (C.Position().Direction().
664 IsOpposite(axe.Direction(), 0.1) ) {
665 Standard_Real f, l;
666 // L'orientation parametrique est inversee
c6541a0c
D
667 l = 2*M_PI - UFirst;
668 f = 2*M_PI - ULast;
7fd59977 669 UFirst = f;
670 ULast = l;
671 isUReversed = Standard_True;
672 }
673 }
674 else SError = 0.;
675 }
676
677 // (1.1.c) C'est bien une extrusion
678 if (!Ok) {
679 if (IsTrsf) {
680 Section->Transform(Tf2);
681 S = new (Geom_SurfaceOfLinearExtrusion)
682 (Section, DP);
683 SError = 0.;
684 Ok = Standard_True;
685 }
686 else { // extrusion sur BSpline
687
688 }
689 }
690 }
691
692 // (1.2) Cas conique
693 else if (mySec->IsConicalLaw(error)) {
694
695 gp_Pnt P1, P2, Centre0, Centre1, Centre2;
696 gp_Vec dsection;
697 Handle(Geom_Curve) Section;
698 GeomAdaptor_Curve AC;
699 gp_Circ C;
700 Standard_Real R1, R2;
701
702
703 Section = mySec->CirclSection(SLast);
704 Section->Transform(Tf2);
705 Section->Translate(Last*DP);
706 AC.Load(Section);
707 C = AC.Circle();
708 Centre2 = C.Location();
709 AC.D1(0, P2, dsection);
710 R2 = C.Radius();
711
712 Section = mySec->CirclSection(SFirst);
713 Section->Transform(Tf2);
714 Section->Translate(First*DP);
715 AC.Load(Section);
716 C = AC.Circle();
717 Centre1 = C.Location();
718 P1 = AC.Value(0);
719 R1 = C.Radius();
720
721 Section = mySec->CirclSection(SFirst - First*(SLast-SFirst)/(Last-First));
722 Section->Transform(Tf2);
723 AC.Load(Section);
724 C = AC.Circle();
725 Centre0 = C.Location();
726
727 Standard_Real Angle;
728 gp_Vec N(Centre1, P1);
729 if (N.Magnitude() < 1.e-9) {
730 gp_Vec Bis(Centre2, P2);
731 N = Bis;
732 }
733 gp_Vec L(P1, P2), Dir(Centre1,Centre2);
734
735 Angle = L.Angle(Dir);
c6541a0c 736 if ((Angle > 0.01) && (Angle < M_PI/2-0.01)) {
7fd59977 737 if (R2<R1) Angle = -Angle;
738 SError = error;
739 gp_Ax3 Axis(Centre0, Dir, N);
740 S = new (Geom_ConicalSurface)
741 (Axis, Angle, C.Radius());
742 // Calcul du glissement parametrique
743 VFirst = First / Cos(Angle);
744 VLast = Last / Cos(Angle);
745
746 // Bornes en U
747 UFirst = AC.FirstParameter();
748 ULast = AC.LastParameter();
749 gp_Vec diso;
750 gp_Pnt pbis;
751 S->VIso(VLast)->D1(0, pbis, diso);
752 if (diso.Magnitude()>1.e-9 && dsection.Magnitude()>1.e-9)
753 isUReversed = diso.IsOpposite(dsection, 0.1);
754 if (isUReversed ) {
755 Standard_Real f, l;
756 // L'orientation parametrique est inversee
c6541a0c
D
757 l = 2*M_PI - UFirst;
758 f = 2*M_PI - ULast;
7fd59977 759 UFirst = f;
760 ULast = l;
761 }
762
763 // C'est un cone
764 Ok = Standard_True;
765 }
766 }
767 }
768
769 // (2) Trajectoire Circulaire
770 if (myLoc->IsRotation(error)) {
771 if (mySec->IsConstant(error)) {
772 // La trajectoire
773 gp_Pnt Centre;
c6541a0c 774 isVPeriodic = (Abs(Last-First -2*M_PI) < 1.e-15);
7fd59977 775 Standard_Real RotRadius;
776 gp_Vec DP, DS, DN;
777 myLoc->D0(0.1, M, DS);
778 myLoc->D0(0, M, V);
779 myLoc->Rotation(Centre);
780
781 DP = DS - V;
782 DS.SetXYZ(V.XYZ() - Centre.XYZ());
783 RotRadius = DS.Magnitude();
784 if (RotRadius > 1.e-15) DS.Normalize();
785 else return Standard_False; // Pas de KPart, rotation degeneree
786 DN = DS ^ DP;
787 DN.Normalize();
788 DP = DN ^ DS;
789 DP.Normalize();
790
791 gp_GTrsf Tf;
792 gp_Trsf Tf2;
793 Tf.SetVectorialPart(M);
794 Tf.SetTranslationPart(V.XYZ());
795// try { // Pas joli mais il n'y as pas d'autre moyens de tester SetValues
796// OCC_CATCH_SIGNALS
797 Tf2.SetValues(Tf(1,1), Tf(1,2), Tf(1,3), Tf(1,4),
798 Tf(2,1), Tf(2,2), Tf(2,3), Tf(2,4),
799 Tf(3,1), Tf(3,2), Tf(3,3), Tf(3,4),
800 1.e-14, 1.e-15);
801// }
802// catch (Standard_ConstructionError) {
803// IsTrsf = Standard_False;
804// }
805 // La section
806 Handle(Geom_Curve) Section;
807 Section = mySec->ConstantSection();
808 GeomAdaptor_Curve AC(Section);
809 SectionType = AC.GetType();
810 UFirst = AC.FirstParameter();
811 ULast = AC.LastParameter();
812
813 // (2.1) Tore/Sphere ?
814 if ((SectionType == GeomAbs_Circle) && IsTrsf) {
815 gp_Circ C = AC.Circle();
816 Standard_Real Radius;
817 Standard_Boolean IsGoodSide = Standard_True;;
818 C.Transform(Tf2);
819 gp_Vec DC;
820 // On calcul le centre eventuel
821 DC.SetXYZ(C.Location().XYZ() - Centre.XYZ());
822 Centre.ChangeCoord() += (DC.Dot(DN))*DN.XYZ();
823 DC.SetXYZ(C.Location().XYZ() - Centre.XYZ());
824 Radius = DC.Magnitude(); //grand Rayon du tore
825 if ((Radius > Tol) && (DC.Dot(DS) < 0)) IsGoodSide = Standard_False;
826 if (Radius < Tol/100) DC = DS; // Pour definir le tore
827
828 // On verifie d'abord que le plan de la section est // a
829 // l'axe de rotation
830 gp_Vec NC;
831 NC.SetXYZ (C.Position().Direction().XYZ());
832 NC.Normalize();
833 error = Abs(NC.Dot(DN));
834 // Puis on evalue l'erreur commise sur la section,
835 // en pivotant son plan ( pour contenir l'axe de rotation)
836 error += Abs(NC.Dot(DS));
837 error *= C.Radius();
838 if (error <= Tol) {
839 SError = error;
840 error += Radius + Abs(RotRadius - C.Radius())/2;
841 if (error <= Tol) {
842 // (2.1.a) Sphere
843 Standard_Real f = UFirst , l = ULast;
844 SError = error;
845 Centre.BaryCenter(1.0, C.Location(), 1.0);
846 gp_Ax3 AxisOfSphere(Centre, DN, DS);
847 S = new (Geom_SphericalSurface)
848 (AxisOfSphere, (RotRadius + C.Radius())/2 );
849 // Pour les spheres on ne peut pas controler le parametre
850 // V (donc U car myExchUV = Standard_True)
851 // Il faut donc modifier UFirst, ULast...
852 if (C.Position().Direction().
853 IsOpposite(AxisOfSphere.YDirection(), 0.1) ) {
854 // L'orientation parametrique est inversee
c6541a0c
D
855 l = 2*M_PI - UFirst;
856 f = 2*M_PI - ULast;
7fd59977 857 isUReversed = Standard_True;
858 }
859 // On calcul le "glissement" parametrique.
860 Standard_Real rot;
861 rot = C.Position().XDirection().AngleWithRef
862 (AxisOfSphere.XDirection(), AxisOfSphere.YDirection());
863 f -= rot;
864 l -= rot;
865
c6541a0c 866 if ( (f >= -M_PI/2) && (l <= M_PI/2)) {
7fd59977 867 Ok = Standard_True;
868 myExchUV = Standard_True;
869 UFirst = f;
870 ULast = l;
871 }
872 else { // On restaure ce qu'il faut
873 isUReversed = Standard_False;
874 }
875 }
876 else if (IsGoodSide) {
877 // (2.1.b) Tore
878 gp_Ax3 AxisOfTore(Centre, DN, DC);
879 S = new (Geom_ToroidalSurface) (AxisOfTore,
880 Radius , C.Radius());
881
882 // Pour les tores on ne peut pas controler le parametre
883 // V (donc U car myExchUV = Standard_True)
884 // Il faut donc modifier UFirst, ULast...
885 Handle(Geom_Circle) Iso;
886 Iso = Handle(Geom_Circle)::DownCast(S->UIso(0.));
887 gp_Ax2 axeiso;
888 axeiso = Iso->Circ().Position();
889
890 if (C.Position().Direction().
891 IsOpposite(axeiso.Direction(), 0.1) ) {
892 Standard_Real f, l;
893 // L'orientation parametrique est inversee
c6541a0c
D
894 l = 2*M_PI - UFirst;
895 f = 2*M_PI - ULast;
7fd59977 896 UFirst = f;
897 ULast = l;
898 isUReversed = Standard_True;
899 }
900 // On calcul le "glissement" parametrique.
901 Standard_Real rot;
902 rot = C.Position().XDirection().AngleWithRef
903 (axeiso.XDirection(), axeiso.Direction());
904 UFirst -= rot;
905 ULast -= rot;
906
907 myExchUV = Standard_True;
908 // Attention l'arete de couture dans le cas periodique
909 // n'est peut etre pas a la bonne place...
910 if (isUPeriodic && Abs(UFirst)>Precision::PConfusion())
911 isUPeriodic = Standard_False; //Pour trimmer la surface...
912 Ok = Standard_True;
913 }
914 }
915 else {
916 SError = 0.;
917 }
918 }
919 // (2.2) Cone / Cylindre
920 if ((SectionType == GeomAbs_Line) && IsTrsf) {
921 gp_Lin L = AC.Line();
922 L.Transform(Tf2);
923 gp_Vec DL;
924 DL.SetXYZ(L.Direction().XYZ());
925 levier = Max(Abs(AC.FirstParameter()), AC.LastParameter());
926 // si la line est ortogonale au cercle de rotation
927 SError = error + levier * Abs(DL.Dot(DP));
928 if (SError <= Tol) {
929 Standard_Boolean reverse;
930 gp_Lin Dir(Centre, DN);
931 Standard_Real aux;
932 aux = DL.Dot(DN);
933 reverse = (aux < 0); // On choisit ici le sens de parametrisation
934
935 // Calcul du centre du vecteur supportant la "XDirection"
936 gp_Pnt CentreOfSurf;
937 gp_Vec O1O2(Centre, L.Location()), trans;
938 trans = DN;
939 trans *= DN.Dot(O1O2);
940 CentreOfSurf = Centre.Translated(trans);
941 DS.SetXYZ(L.Location().XYZ() - CentreOfSurf.XYZ());
942
943 error = SError;
944 error += (DL.XYZ()).CrossMagnitude(DN.XYZ())*levier;
945 if (error <= Tol) {
946 // (2.2.a) Cylindre
947 // si la line est orthogonale au plan de rotation
948 SError = error;
949 gp_Ax3 Axis(CentreOfSurf, Dir.Direction(), DS);
950 S = new (Geom_CylindricalSurface)
951 (Axis, L.Distance(CentreOfSurf));
952 Ok = Standard_True;
953 myExchUV = Standard_True;
954 }
955 else {
956 // On evalue l'angle du cone
957 Standard_Real Angle = Abs(Dir.Angle(L));
c6541a0c 958 if (Angle > M_PI/2) Angle = M_PI -Angle;
7fd59977 959 if (reverse) Angle = -Angle;
960 aux = DS.Dot(DL);
961 if (aux < 0) {
962 Angle = - Angle;
963 }
c6541a0c 964 if (Abs(Abs(Angle) - M_PI/2) > 0.01) {
7fd59977 965 // (2.2.b) Cone
966 // si les 2 droites ne sont pas orthogonales
967 Standard_Real Radius = CentreOfSurf.Distance(L.Location());
968 gp_Ax3 Axis(CentreOfSurf, Dir.Direction(), DS);
969 S = new (Geom_ConicalSurface)
970 (Axis, Angle, Radius);
971 myExchUV = Standard_True;
972 Ok = Standard_True;
973 }
974 else {
975 // On n'as pas conclue, on remet l'erreur a 0.
976 SError = 0.;
977 }
978 }
979 if (Ok && reverse) {
980 // On reverse le parametre
981 Standard_Real uf, ul;
982 Handle(Geom_Line) CL = new (Geom_Line)(L);
983 uf = CL->ReversedParameter(ULast);
984 ul = CL->ReversedParameter(UFirst);
985 UFirst = uf;
986 ULast = ul;
987 isUReversed = Standard_True;
988 }
989 }
990 else SError = 0.;
991 }
992
993 // (2.3) Revolution
994 if (!Ok) {
995 if (IsTrsf) {
996 Section->Transform(Tf2);
997 gp_Ax1 Axis (Centre, DN);
998 S = new (Geom_SurfaceOfRevolution)
999 (Section, Axis);
1000 myExchUV = Standard_True;
1001 SError = 0.;
1002 Ok = Standard_True;
1003 }
1004 }
1005 }
1006 }
1007
1008
1009 if (Ok) { // On trimme la surface
1010 if (myExchUV) {
1011 Standard_Boolean b;
1012 b = isUPeriodic; isUPeriodic = isVPeriodic; isVPeriodic = b;
1013 Standard_Real r;
1014 r = UFirst; UFirst = VFirst; VFirst = r;
1015 r = ULast; ULast = VLast; VLast = r;
1016 }
1017
1018 if (!isUPeriodic && !isVPeriodic)
1019 mySurface = new (Geom_RectangularTrimmedSurface)
1020 (S, UFirst, ULast, VFirst, VLast);
1021 else if (isUPeriodic) {
1022 if (isVPeriodic) mySurface = S;
1023 else mySurface = new (Geom_RectangularTrimmedSurface)
1024 (S, VFirst, VLast, Standard_False);
1025 }
1026 else
1027 mySurface = new (Geom_RectangularTrimmedSurface)
1028 (S,UFirst, ULast, Standard_True);
1029
1030#if DEB
1031 if (isUPeriodic && !mySurface->IsUPeriodic())
1032 cout<<"Pb de periodicite en U" << endl;
1033 if (isUPeriodic && !mySurface->IsUClosed())
1034 cout<<"Pb de fermeture en U" << endl;
1035 if (isVPeriodic && !mySurface->IsVPeriodic())
1036 cout << "Pb de periodicite en V" << endl;
1037 if (isVPeriodic && !mySurface->IsVClosed())
1038 cout<<"Pb de fermeture en V" << endl;
1039#endif
1040 }
1041
1042
1043 return Ok;
1044}
1045
1046//===============================================================
1047// Function : IsDone
1048// Purpose :
1049//===============================================================
1050 Standard_Boolean GeomFill_Sweep::IsDone() const
1051{
1052 return done;
1053}
1054
1055//===============================================================
1056// Function :ErrorOnSurface
1057// Purpose :
1058//===============================================================
1059 Standard_Real GeomFill_Sweep::ErrorOnSurface() const
1060{
1061 return SError;
1062}
1063
1064//===============================================================
1065// Function ::ErrorOnRestriction
1066// Purpose :
1067//===============================================================
1068 void GeomFill_Sweep::ErrorOnRestriction(const Standard_Boolean IsFirst,
1069 Standard_Real& UError,
1070 Standard_Real& VError) const
1071{
1072 Standard_Integer ind;
1073 if (IsFirst) ind=1;
1074 else ind = myCurve2d->Length();
1075
1076 UError = CError->Value(1, ind);
1077 VError = CError->Value(2, ind);
1078}
1079
1080//===============================================================
1081// Function :ErrorOnTrace
1082// Purpose :
1083//===============================================================
1084 void GeomFill_Sweep::ErrorOnTrace(const Standard_Integer IndexOfTrace,
1085 Standard_Real& UError,
1086 Standard_Real& VError) const
1087{
1088 Standard_Integer ind = IndexOfTrace+1;
1089 if (IndexOfTrace > myLoc->TraceNumber())
1090 Standard_OutOfRange::Raise(" GeomFill_Sweep::ErrorOnTrace");
1091
1092 UError = CError->Value(1, ind);
1093 VError = CError->Value(2, ind);
1094}
1095
1096//===============================================================
1097// Function :Surface
1098// Purpose :
1099//===============================================================
1100 Handle(Geom_Surface) GeomFill_Sweep::Surface() const
1101{
1102 return mySurface;
1103}
1104
1105//===============================================================
1106// Function ::Restriction
1107// Purpose :
1108//===============================================================
1109 Handle(Geom2d_Curve) GeomFill_Sweep::Restriction(const Standard_Boolean IsFirst) const
1110{
1111 if (IsFirst)
1112 return myCurve2d->Value(1);
1113 return myCurve2d->Value(myCurve2d->Length());
1114
1115}
1116
1117//===============================================================
1118// Function :
1119// Purpose :
1120//===============================================================
1121 Standard_Integer GeomFill_Sweep::NumberOfTrace() const
1122{
1123 return myLoc->TraceNumber();
1124}
1125
1126//===============================================================
1127// Function :
1128// Purpose :
1129//===============================================================
1130 Handle(Geom2d_Curve)
1131 GeomFill_Sweep::Trace(const Standard_Integer IndexOfTrace) const
1132{
1133 Standard_Integer ind = IndexOfTrace+1;
1134 if (IndexOfTrace > myLoc->TraceNumber())
1135 Standard_OutOfRange::Raise(" GeomFill_Sweep::Trace");
1136 return myCurve2d->Value(ind);
1137}