1 //=======================================================================
2 //file : IGESToBRep_BasicCurve
4 //:k0 abv 16.12.98: eliminating existing code
5 // 21.12.98 rln, gka S4054
6 //:k5 abv 25 Dec 98: PRO8803 1901: extending method of fixing Multi > Degree
7 // 28.12.98 dce S3767 New messaging system
9 //:l1 abv 06.01.99: USA60022.igs 243: fixing missing seam on closed surface
10 //:p6 abv 26.02.99: improve messages after call to ConvertToPeriodic
11 //#75 rln 11.03.99: using message mechanism for periodic B-Spline
12 //S4181 pdn 15.04.99 implementing of reading IGES elementary surfaces.
13 //sln 29.12.2001 OCC90 : Method checkBSplineSurfaceStatus and varification of creation of bspline surfaces were added
14 //=======================================================================
16 #include <IGESToBRep_BasicSurface.ixx>
18 #include <IGESToBRep.hxx>
19 #include <IGESToBRep_CurveAndSurface.hxx>
21 #include <IGESData_IGESEntity.hxx>
22 #include <IGESData_ToolLocation.hxx>
24 #include <IGESGeom_SplineSurface.hxx>
25 #include <IGESGeom_BSplineSurface.hxx>
27 #include <IGESConvGeom.hxx>
29 #include <Interface_Macros.hxx>
31 #include <gp_GTrsf.hxx>
32 #include <gp_Trsf.hxx>
34 #include <TColgp_Array2OfPnt.hxx>
35 #include <TColgp_HArray2OfPnt.hxx>
37 #include <TColStd_Array1OfInteger.hxx>
38 #include <TColStd_Array1OfReal.hxx>
39 #include <TColStd_Array2OfReal.hxx>
40 #include <TColStd_HArray1OfReal.hxx>
41 #include <TColStd_SequenceOfInteger.hxx>
44 #include <Standard_ErrorHandler.hxx>
45 #include <Standard_Failure.hxx>
46 #include <Precision.hxx>
49 #include <Message_Msg.hxx>
50 #include <IGESData_IGESModel.hxx>
53 #include <IGESGeom_Point.hxx>
54 #include <IGESGeom_Direction.hxx>
55 #include <Precision.hxx>
57 #include <gp_Cylinder.hxx>
58 #include <ShapeAlgo.hxx>
59 #include <ShapeAlgo_AlgoContainer.hxx>
60 #include <ShapeConstruct_Curve.hxx>
62 //=======================================================================
63 //function : CheckBSplineSurface
64 //purpose : Check coincidede knots. Check whether knots are in ascending
65 // order and difference between vaues of weights more than 1000.
66 // Send corresponding messages. The function returns Standard_False
67 // if surface can not be created, Standard_True otherwise.
68 //=======================================================================
69 static Standard_Boolean checkBSplineSurface(IGESToBRep_BasicSurface* theSurface,
70 const Handle(IGESGeom_BSplineSurface)& theBSplineSurface,
71 TColStd_Array1OfReal& SUKnots,
72 TColStd_Array1OfReal& SVKnots,
73 const TColStd_Array2OfReal& SWeights)
75 // check whether difference between vaues of weights more than 1000.
76 if(!theBSplineSurface->IsPolynomial()) {
77 Standard_Real aMinValue = SWeights.Value(SWeights.LowerRow(), SWeights.LowerCol());
78 Standard_Real aMaxValue = SWeights.Value(SWeights.LowerRow(), SWeights.LowerCol());
79 for(Standard_Integer i = SWeights.LowerRow(); i<= SWeights.UpperRow(); i++)
80 for(Standard_Integer j = SWeights.LowerCol(); j<= SWeights.UpperCol(); j++) {
81 if(SWeights.Value(i,j) < aMinValue) aMinValue = SWeights.Value(i,j);
82 if(SWeights.Value(i,j) > aMaxValue) aMaxValue = SWeights.Value(i,j);
84 if(aMaxValue - aMinValue > 1000) {
85 Message_Msg msg1374("IGES_1374"); // WARNING - Difference between weights is too big.
86 theSurface->SendWarning(theBSplineSurface, msg1374);
91 Standard_Boolean aResult = Standard_True;
93 //check whether knots are in ascending order.
94 Standard_Boolean aWrongOrder = Standard_False;
96 for (i = SUKnots.Lower(); (i < SUKnots.Upper()) && (!aWrongOrder); i++)
97 if(SUKnots.Value (i+1) < SUKnots.Value (i)) aWrongOrder = Standard_True;
98 for (i = SVKnots.Lower(); (i < SVKnots.Upper()) && (!aWrongOrder); i++)
99 if(SVKnots.Value (i+1) < SVKnots.Value (i)) aWrongOrder = Standard_True;
102 Message_Msg msg1373("IGES_1373"); // FAIL - Knots are not in ascending order
103 theSurface->SendFail(theBSplineSurface, msg1373);
104 aResult = Standard_False;
107 //Fix coincided knots
109 ShapeConstruct_Curve::FixKnots(SUKnots);
110 ShapeConstruct_Curve::FixKnots(SVKnots);
118 //=======================================================================
119 //function : IGESToBRep_BasicSurface
121 //=======================================================================
123 IGESToBRep_BasicSurface::IGESToBRep_BasicSurface()
124 :IGESToBRep_CurveAndSurface()
126 SetModeTransfer(Standard_False);
129 //=======================================================================
130 //function : IGESToBRep_BasicSurface
132 //=======================================================================
134 IGESToBRep_BasicSurface::IGESToBRep_BasicSurface
135 (const IGESToBRep_CurveAndSurface& CS)
136 :IGESToBRep_CurveAndSurface(CS)
140 //=======================================================================
141 //function : IGESToBRep_BasicSurface
143 //=======================================================================
145 IGESToBRep_BasicSurface::IGESToBRep_BasicSurface
146 (const Standard_Real eps,
147 const Standard_Real epsCoeff,
148 const Standard_Real epsGeom,
149 const Standard_Boolean mode,
150 const Standard_Boolean modeapprox,
151 const Standard_Boolean optimized)
152 :IGESToBRep_CurveAndSurface(eps, epsCoeff, epsGeom, mode, modeapprox,
158 //=============================================
159 //Function : TransferBasicSurface
160 //Purpose : Choice of the right transfer method
161 //=============================================
163 Handle(Geom_Surface) IGESToBRep_BasicSurface::TransferBasicSurface
164 (const Handle(IGESData_IGESEntity)& start)
166 Handle(Geom_Surface) resurf;
167 if (start.IsNull()) {
168 Message_Msg msg1005("IGES_1005");
169 SendFail(start, msg1005);
173 try { //:36 by abv 11.12.97: Geom_BSplineSurface raiss if some weights <0
177 if (start->IsKind(STANDARD_TYPE(IGESGeom_BSplineSurface))) {
178 DeclareAndCast(IGESGeom_BSplineSurface, st128, start);
179 resurf = TransferBSplineSurface(st128);
181 else if (start->IsKind(STANDARD_TYPE(IGESGeom_SplineSurface))) {
182 DeclareAndCast(IGESGeom_SplineSurface, st114, start);
183 resurf = TransferSplineSurface(st114);
184 } //S4181 pdn 15.04.99 implementing of reading IGES elementary surfaces.
185 else if (start->IsKind(STANDARD_TYPE(IGESSolid_PlaneSurface))) {
186 DeclareAndCast(IGESSolid_PlaneSurface, st190, start);
187 resurf = TransferPlaneSurface(st190);
189 else if (start->IsKind(STANDARD_TYPE(IGESSolid_CylindricalSurface))) {
190 DeclareAndCast(IGESSolid_CylindricalSurface, st192, start);
191 resurf = TransferRigthCylindricalSurface(st192);
193 else if (start->IsKind(STANDARD_TYPE(IGESSolid_ConicalSurface))) {
194 DeclareAndCast(IGESSolid_ConicalSurface, st194, start);
195 resurf = TransferRigthConicalSurface(st194);
197 else if (start->IsKind(STANDARD_TYPE(IGESSolid_SphericalSurface))) {
198 DeclareAndCast(IGESSolid_SphericalSurface, st196, start);
199 resurf = TransferSphericalSurface(st196);
201 else if (start->IsKind(STANDARD_TYPE(IGESSolid_ToroidalSurface))) {
202 DeclareAndCast(IGESSolid_ToroidalSurface, st198, start);
203 resurf = TransferToroidalSurface(st198);
206 // AddFail(start, "Spline or BSpline surface expected for TransferBasicSurface");
211 catch(Standard_Failure) {
213 cout << "\n** Exception in IGESToBRep_BasicSurface::TransferBasicSurface : ";
214 Standard_Failure::Caught()->Print(cout);
218 if (resurf.IsNull()) {
219 // AddFail(start,"The IGESEntity cannot be transfered");
222 resurf->Scale(gp_Pnt(0,0,0),GetUnitFactor());
228 //=======================================================================
229 //function : TransferPlaneSurface
231 //=======================================================================
233 Handle(Geom_Plane) IGESToBRep_BasicSurface::TransferPlaneSurface(const Handle(IGESSolid_PlaneSurface)& start)
235 Handle(Geom_Plane) res;
236 if (start.IsNull()) {
237 Message_Msg msg1005("IGES_1005");
238 SendFail(start, msg1005);
243 Standard_Boolean Param = start->IsParametrised();
244 Handle(IGESGeom_Point) Point = start->LocationPoint();
245 Handle(IGESGeom_Direction) Dir = start->Normal();
247 if (Point.IsNull()) {
248 Message_Msg msg174("XSTEP_174");
249 SendFail(start, msg174);
250 // Point Reading Error : Null IGESEntity
254 Message_Msg msg1280("IGES_1280");
255 SendFail(start, msg1280);
256 // Direction Reading Error : Null IGESEntity
260 gp_Pnt Pt = Point->Value();
261 gp_Dir Normale = gp_Dir(Dir->Value());
263 pln = gp_Pln(Pt,Normale);
266 Handle(IGESGeom_Direction) refdir = start->ReferenceDir();
267 gp_Dir Dirgp = gp_Dir(refdir->Value());
268 pln = gp_Pln( gp_Ax3(Pt, Normale, Dirgp));
271 return new Geom_Plane(pln);
274 //=======================================================================
275 //function : TransferRigthCylindricalSurface
277 //=======================================================================
279 Handle(Geom_CylindricalSurface) IGESToBRep_BasicSurface::TransferRigthCylindricalSurface
280 (const Handle(IGESSolid_CylindricalSurface)& start)
282 Handle(Geom_CylindricalSurface) res;
283 if (start.IsNull()) {
284 Message_Msg msg1005("IGES_1005");
285 SendFail(start, msg1005);
289 Standard_Boolean Param = start->IsParametrised();
290 Handle(IGESGeom_Point) Point = start->LocationPoint();
291 Handle(IGESGeom_Direction) Axis = start->Axis();
292 Standard_Real radius = start->Radius();
294 if (Point.IsNull()) {
295 Message_Msg msg174("XSTEP_174");
296 SendFail(start, msg174);
297 // Point Reading Error : Null IGESEntity
301 Message_Msg msg1280("IGES_1280");
302 SendFail(start, msg1280);
303 // Direction Reading Error : Null IGESEntity
306 if (radius < Precision::Confusion()) {
310 gp_Pnt Pt = Point->Value();
311 gp_Dir ax = gp_Dir(Axis->Value());
316 Handle(IGESGeom_Direction) refdir = start->ReferenceDir();
317 gp_Dir Dir = gp_Dir(refdir->Value());
319 if(vc.XYZ().Modulus() < Precision::Confusion()) {
323 ax3 = gp_Ax3(Pt,ax,Dir);
325 gp_Cylinder cyl(ax3,radius);
326 return new Geom_CylindricalSurface(cyl);
329 //=======================================================================
330 //function : TransferRigthConicalSurface
332 //=======================================================================
334 Handle(Geom_ConicalSurface) IGESToBRep_BasicSurface::TransferRigthConicalSurface
335 (const Handle(IGESSolid_ConicalSurface)& start)
337 Handle(Geom_ConicalSurface) res;
338 if (start.IsNull()) {
339 Message_Msg msg1005("IGES_1005");
340 SendFail(start, msg1005);
344 Standard_Boolean Param = start->IsParametrised();
345 Handle(IGESGeom_Point) Point = start->LocationPoint();
346 Handle(IGESGeom_Direction) Axis = start->Axis();
347 Standard_Real radius = start->Radius();
348 Standard_Real angle = start->SemiAngle()/180.*M_PI;
350 if (Point.IsNull()) {
351 Message_Msg msg174("XSTEP_174");
352 SendFail(start, msg174);
353 // Point Reading Error : Null IGESEntity
357 Message_Msg msg1280("IGES_1280");
358 SendFail(start, msg1280);
359 // Direction Reading Error : Null IGESEntity
362 if (angle < Precision::Confusion()||angle > M_PI/2.) {
368 if (radius < Precision::Confusion())
371 gp_Pnt Pt = Point->Value();
372 gp_Dir ax = gp_Dir(Axis->Value());
377 Handle(IGESGeom_Direction) refdir = start->ReferenceDir();
378 gp_Dir Dir = gp_Dir(refdir->Value());
380 if(vc.XYZ().Modulus() < Precision::Confusion()) {
384 ax3 = gp_Ax3(Pt,ax,Dir);
386 return new Geom_ConicalSurface(ax3,angle,radius);
389 //=======================================================================
390 //function : TransferSphericalSurface
392 //=======================================================================
394 Handle(Geom_SphericalSurface) IGESToBRep_BasicSurface::TransferSphericalSurface
395 (const Handle(IGESSolid_SphericalSurface)& start)
397 Handle(Geom_SphericalSurface) res;
398 if (start.IsNull()) {
399 Message_Msg msg1005("IGES_1005");
400 SendFail(start, msg1005);
404 Standard_Boolean Param = start->IsParametrised();
405 Handle(IGESGeom_Point) Point = start->Center();
406 Handle(IGESGeom_Direction) Axis = start->Axis();
407 Standard_Real radius = start->Radius();
409 if (Point.IsNull()) {
410 Message_Msg msg174("XSTEP_174");
411 SendFail(start, msg174);
412 // Point Reading Error : Null IGESEntity
416 Message_Msg msg1280("IGES_1280");
417 SendFail(start, msg1280);
418 // Direction Reading Error : Null IGESEntity
421 if (radius < Precision::Confusion()){
426 gp_Pnt Pt = Point->Value();
427 gp_Dir ax = gp_Dir(Axis->Value());
432 Handle(IGESGeom_Direction) refdir = start->ReferenceDir();
433 gp_Dir Dir = gp_Dir(refdir->Value());
435 if(vc.XYZ().Modulus() < Precision::Confusion()) {
439 ax3 = gp_Ax3(Pt,ax,Dir);
441 return new Geom_SphericalSurface(ax3,radius);
444 //=======================================================================
445 //function : TransferToroidalSurface
447 //=======================================================================
449 Handle(Geom_ToroidalSurface) IGESToBRep_BasicSurface::TransferToroidalSurface
450 (const Handle(IGESSolid_ToroidalSurface)& start)
452 Handle(Geom_ToroidalSurface) res;
453 if (start.IsNull()) {
454 Message_Msg msg1005("IGES_1005");
455 SendFail(start, msg1005);
459 Standard_Boolean Param = start->IsParametrised();
460 Handle(IGESGeom_Point) Point = start->Center();
461 Handle(IGESGeom_Direction) Axis = start->Axis();
462 Standard_Real major = start->MajorRadius();
463 Standard_Real minor = start->MinorRadius();
465 if (Point.IsNull()) {
466 Message_Msg msg174("XSTEP_174");
467 SendFail(start, msg174);
468 // Point Reading Error : Null IGESEntity
472 Message_Msg msg1280("IGES_1280");
473 SendFail(start, msg1280);
474 // Direction Reading Error : Null IGESEntity
477 if (major < Precision::Confusion()||minor < Precision::Confusion()){
482 gp_Pnt Pt = Point->Value();
483 gp_Dir ax = gp_Dir(Axis->Value());
488 Handle(IGESGeom_Direction) refdir = start->ReferenceDir();
489 gp_Dir Dir = gp_Dir(refdir->Value());
491 if(vc.XYZ().Modulus() < Precision::Confusion()) {
495 ax3 = gp_Ax3(Pt,ax,Dir);
497 return new Geom_ToroidalSurface(ax3,major,minor);
499 //==================================
500 //Function : TransferSplineSurface :
502 //==================================
504 Handle(Geom_BSplineSurface) IGESToBRep_BasicSurface::TransferSplineSurface
505 (const Handle(IGESGeom_SplineSurface)& start)
507 Handle(Geom_BSplineSurface) resconv;
508 if (start.IsNull()) {
509 Message_Msg msg1005("IGES_1005");
510 SendFail(start, msg1005);
514 Standard_Real epscoef = GetEpsCoeff();
515 Standard_Real epsgeom = GetEpsGeom();
517 Standard_Integer result = IGESConvGeom::SplineSurfaceFromIGES
518 (start, epscoef, epsgeom, resconv);
522 Message_Msg msg1305("IGES_1305");
523 SendFail (start, msg1305); // less than on segment in U or V (no result produced)
527 Message_Msg msg1190("IGES_1190");
528 SendFail (start, msg1190);
532 // AddWarning ( start, "Degree is not compatible with code boundary type , C0 is not guaranteed)");
534 // AddWarning ( start, "Degree is not compatible with code boundary type , C0 is guaranted)");
540 // Checking C2 and C1 continuity : case 1 :
541 // AddWarning ( start, "The result is not guaranteed to be C0");
542 // ===============================
544 IGESConvGeom::IncreaseSurfaceContinuity (resconv, epsgeom, GetContinuity());
548 //===================================
549 //Function : TransferBSplineSurface :
551 //===================================
553 Handle(Geom_BSplineSurface) IGESToBRep_BasicSurface::TransferBSplineSurface
554 (const Handle(IGESGeom_BSplineSurface)& start)
556 Handle(Geom_BSplineSurface) res;
557 if (start.IsNull()) {
558 Message_Msg msg1005("IGES_1005");
559 SendFail(start, msg1005);
563 Standard_Integer DegreeU = start->DegreeU();
564 Standard_Integer DegreeV = start->DegreeV();
565 if ((DegreeU <= 0) || (DegreeU > Geom_BSplineSurface::MaxDegree()) ||
566 (DegreeV <= 0) || (DegreeV > Geom_BSplineSurface::MaxDegree())) {
567 Message_Msg msg1310("IGES_1310");
568 SendFail ( start, msg1310);
569 // Improper Input BSpline Degree
573 // Filling poles array :
574 // =====================
576 Standard_Integer NbPolesU = start->NbPolesU();
577 Standard_Integer newNbPolesU = NbPolesU;
579 Message_Msg msg1195("IGES_1195");
580 SendFail(start, msg1195);
581 // Number of poles lower than 2 following U
585 Standard_Integer NbPolesV = start->NbPolesV();
586 Standard_Integer newNbPolesV = NbPolesV;
588 Message_Msg msg1195("IGES_1195");
589 SendFail(start, msg1195);
593 TColgp_Array2OfPnt Pole(1, NbPolesU, 1, NbPolesV);
594 Standard_Integer UIndex = Pole.LowerRow();
595 Standard_Integer VIndex = Pole.LowerCol();
596 Standard_Integer i, j; //szv#4:S4163:12Mar99 k unused
598 if (!GetModeTransfer() && start->HasTransf())
599 for (i=0; i <= start->UpperIndexU(); i++) {
600 for (j=0; j <= start->UpperIndexV(); j++)
601 Pole.SetValue(UIndex, VIndex++, start->TransformedPole(i,j));
603 VIndex = Pole.LowerCol();
606 for (i=0; i <= start->UpperIndexU(); i++) {
607 for (j=0; j <= start->UpperIndexV(); j++)
608 Pole.SetValue(UIndex, VIndex++, start->Pole(i,j));
610 VIndex = Pole.LowerCol();
614 // KNOTS & MULTIPLICITIES for U :
615 // ==============================
617 Standard_Integer NbUKnots = start->NbKnotsU();
618 TColStd_Array1OfReal TempUKnot(1, NbUKnots);
619 TColStd_Array1OfInteger TempUMult(1, NbUKnots);
622 UIndex = TempUKnot.Lower();
625 // If several identical IGES knots are encountered, corresponding
626 // multiplicity is increased
627 // ==============================================================
629 TempUKnot.SetValue(UIndex, start->KnotU(-DegreeU));
631 for (i = 1-DegreeU; i < NbUKnots-DegreeU; i++) {
633 Standard_Real UKnot1 = start->KnotU(i);
634 Standard_Real UKnot2 = start->KnotU(i-1);
636 if (Abs(UKnot1 - UKnot2) <= Epsilon(UKnot2))
637 TempUMult.SetValue(UIndex, TempUMult.Value(UIndex) + 1);
639 TempUKnot.SetValue(++UIndex, UKnot1);
642 // Final knots & multiplicities arraies are dimensionned so as to be fully
644 // =======================================================================
646 TColStd_Array1OfReal UKnot(1,UIndex);
647 TColStd_Array1OfInteger UMult(1,UIndex);
649 Standard_Integer SumOfUMult = 0;
651 TColStd_SequenceOfInteger SeqIndexU;
652 Standard_Integer DelIndexU;
653 Standard_Integer OldSumOfUMult = 0;
654 for (i=1 ; i <= UIndex; i++) { //:k5 abv 25 Dec 98: cycle modified
655 Standard_Integer aMult = TempUMult.Value(i);
656 Standard_Integer maxMult = ( i==1 || i == UIndex ? DegreeU + 1 : DegreeU );
657 if (aMult > maxMult) {
658 Message_Msg msg1200("IGES_1200");
661 msg1200.Arg("U");//#61 rln 05.01.99
662 SendWarning(start, msg1200); //U Multiplicity > DegreeU (or Degree+1 at end); corrected
663 for ( DelIndexU = OldSumOfUMult + 1; aMult > maxMult; DelIndexU++, aMult-- ) {
665 SeqIndexU.Append(DelIndexU);
668 OldSumOfUMult += TempUMult.Value(i);
669 UKnot.SetValue(i, TempUKnot.Value(i));
670 UMult.SetValue(i, aMult);
674 if (SumOfUMult != newNbPolesU + DegreeU + 1) {
675 Message_Msg msg1210("IGES_1210");
678 SendWarning(start, msg1210);
679 // Sum of multiplicities following U is not equal to the sum : Count of poles + DegreeU + 1
682 // KNOTS & MULTIPLICITIES for V :
683 // ==============================
685 Standard_Integer NbVKnots = start->NbKnotsV();
686 TColStd_Array1OfReal TempVKnot(1, NbVKnots);
687 TColStd_Array1OfInteger TempVMult(1, NbVKnots);
690 VIndex = TempVKnot.Lower();
693 // If several identical IGES knots are encountered, corresponding
694 // multiplicity is increased
695 // ==============================================================
697 TempVKnot.SetValue(VIndex, start->KnotV(-DegreeV));
699 for (i = 1-DegreeV; i < NbVKnots-DegreeV; i++) {
701 Standard_Real VKnot1 = start->KnotV(i);
702 Standard_Real VKnot2 = start->KnotV(i-1);
704 if (Abs(VKnot1 - VKnot2) <= Epsilon(VKnot2))
705 TempVMult.SetValue(VIndex, TempVMult.Value(VIndex) + 1);
707 TempVKnot.SetValue(++VIndex, VKnot1);
710 // Final knots & multiplicities arraies are dimensionned so as to be fully
712 // =======================================================================
714 TColStd_Array1OfReal VKnot(1,VIndex);
715 TColStd_Array1OfInteger VMult(1,VIndex);
717 Standard_Integer SumOfVMult = 0;
719 TColStd_SequenceOfInteger SeqIndexV;
720 Standard_Integer DelIndexV;
721 Standard_Integer OldSumOfVMult = 0;
722 for (i=1; i <= VIndex; i++) { //:k5 abv 25 Dec 98: cycle modified
723 Standard_Integer aMult = TempVMult.Value(i);
724 Standard_Integer maxMult = ( i==1 || i == VIndex ? DegreeV + 1 : DegreeV );
725 if (aMult > maxMult) {
726 Message_Msg msg1200("IGES_1200");//#61 rln 05.01.99
730 SendWarning(start, msg1200);
731 //V Multiplicity > DegreeV (or Degree+1 at end); corrected
732 for ( DelIndexV = OldSumOfVMult + 1; aMult > maxMult; DelIndexV++, aMult-- ) {
734 SeqIndexV.Append(DelIndexV);
737 OldSumOfVMult += TempVMult.Value(i);
738 VKnot.SetValue(i, TempVKnot.Value(i));
739 VMult.SetValue(i, aMult);
743 if (SumOfVMult != newNbPolesV + DegreeV + 1) {
744 Message_Msg msg1210("IGES_1210");
747 SendWarning(start, msg1210);
748 // Sum of multiplicities following V is not equal to the sum : Count of poles + Degree V + 1
751 // Mise a jour du tableau des poles
752 TColgp_Array2OfPnt Poles(1, newNbPolesU, 1, newNbPolesV);
753 TColStd_SequenceOfInteger PoleUInd;
754 TColStd_SequenceOfInteger PoleVInd;
755 for (i=1; i<=NbPolesU; i++) PoleUInd.Append(i);
756 for (i=1; i<=NbPolesV; i++) PoleVInd.Append(i);
757 UIndex = Poles.LowerRow();
758 VIndex = Poles.LowerCol();
760 if (( newNbPolesU < NbPolesU) || (newNbPolesV < NbPolesV)) {
761 if ( newNbPolesU < NbPolesU) {
762 Standard_Integer Offset = 0;
763 for (Standard_Integer itab = 1; itab <= SeqIndexU.Length(); itab++) {
764 DelIndexU = SeqIndexU.Value(itab) - Offset;
765 PoleUInd.Remove(DelIndexU);
769 if ( newNbPolesV < NbPolesV) {
770 Standard_Integer Offset = 0;
771 for (Standard_Integer itab = 1; itab <= SeqIndexV.Length(); itab++) {
772 DelIndexV = SeqIndexV.Value(itab) - Offset;
773 PoleVInd.Remove(DelIndexV);
777 Standard_Integer nbUseq = PoleUInd.Length();
778 Standard_Integer nbVseq = PoleVInd.Length();
779 if (( nbUseq == newNbPolesU)&&(nbVseq == newNbPolesV)) {
780 for ( i=1; i<= newNbPolesU; i++) {
781 for (j=1; j<= newNbPolesV; j++)
782 Poles.SetValue(UIndex,VIndex++ , Pole.Value(PoleUInd.Value(i),
785 VIndex = Poles.LowerCol();
789 Message_Msg msg1175("IGES_1175");
790 SendWarning(start, msg1175);
795 for ( i=1; i<= newNbPolesU; i++) {
796 for (j=1; j<= newNbPolesV; j++)
797 Poles.SetValue (UIndex, VIndex++,Pole.Value(i,j));
799 VIndex = Poles.LowerCol();
804 // Building result taking into account transformation if any :
805 // ===========================================================
807 if (!GetModeTransfer() && start->HasTransf()) {
808 gp_GTrsf GBSplTrsf(start->CompoundLocation());
810 if (IGESData_ToolLocation::ConvertLocation(GetEpsilon(),GBSplTrsf,BSplTrsf))
811 for (i=Poles.LowerRow(); i<=Poles.UpperRow(); i++)
812 for (j=Poles.LowerCol(); j<=Poles.UpperCol(); j++)
813 Poles.SetValue(i, j, Poles.Value(i,j).Transformed(BSplTrsf));
815 Message_Msg msg1035("IGES_1035");
816 SendWarning(start, msg1035);
821 // CREATION with the ARRAY of POLES WEIGHTS if any :
822 // =================================================
824 if (start->IsPolynomial())
826 //sln 29.12.2001 OCC90 : If surface can not be created do nothing
827 TColStd_Array2OfReal Weight(1, 1, 1, 1);
828 if(!checkBSplineSurface(this, start, UKnot, VKnot, Weight)) return res;
829 res = new Geom_BSplineSurface(Poles, UKnot, VKnot, UMult, VMult,
834 TColStd_Array2OfReal PoleWeight(1, NbPolesU, 1, NbPolesV);
835 Standard_Boolean polynomial = Standard_True;
836 Standard_Real WeightReference = start->Weight(0,0);
837 Standard_Integer WeightRow = PoleWeight.LowerRow();
838 Standard_Integer WeightCol = PoleWeight.LowerCol();
840 for (i=0; i <= start->UpperIndexU(); i++) {
841 for (j=0; j <= start->UpperIndexV(); j++) {
842 polynomial = (Abs(start->Weight(i,j) - WeightReference)
843 <= Epsilon(WeightReference)) && polynomial;
844 //:39 by abv 15.12.97
845 Standard_Real weight = start->Weight(i,j);
846 if ( weight < Precision::PConfusion() ) {
847 Message_Msg msg1215("IGES_1215");
848 SendFail (start, msg1215); // Some weights are not positive.
851 PoleWeight.SetValue(WeightRow, WeightCol++, weight);
852 //:39 PoleWeight.SetValue(WeightRow, WeightCol++, start->Weight(i,j));
855 WeightCol = PoleWeight.LowerCol();
858 Message_Msg msg1220("IGES_1220");
859 const Standard_CString surface ("surface");
860 msg1220.Arg(surface);
861 SendWarning(start, msg1220);
863 // Mise a jour du tableau des Weight lors de la correction de la multiplicite
864 TColStd_Array2OfReal Weight(1, newNbPolesU, 1, newNbPolesV);
865 UIndex = Weight.LowerRow();
866 VIndex = Weight.LowerCol();
867 if (( newNbPolesU < NbPolesU) || (newNbPolesV < NbPolesV)) {
868 //Standard_Integer indj = 1; //szv#4:S4163:12Mar99 unused
869 for ( i=1; i<= newNbPolesU; i++) {
870 for (j=1; j<= newNbPolesV; j++)
871 Weight.SetValue(UIndex, VIndex++ ,
872 PoleWeight.Value(PoleUInd.Value(i),PoleVInd.Value(j)));
874 VIndex = Poles.LowerCol();
878 for ( i=1; i<= newNbPolesU; i++) {
879 for (j=1; j<= newNbPolesV; j++)
880 Weight.SetValue(UIndex, VIndex++ ,PoleWeight.Value(i,j));
882 VIndex = Poles.LowerCol();
886 //sln 29.12.2001 OCC90 : If surface can not be created do nothing
887 if(!checkBSplineSurface(this, start, UKnot, VKnot, Weight)) return res;
888 res = new Geom_BSplineSurface
889 (Poles, Weight, UKnot, VKnot, UMult, VMult, DegreeU, DegreeV);
893 // Checking C2 and C1 continuity :
894 // ===============================
896 Standard_Integer icont = GetContinuity();
897 if ( icont < 1) return res;
898 //Standard_Boolean isC1 = Standard_True, isC2 = Standard_True; //szv#4:S4163:12Mar99 not needed
900 i = res->LastUKnotIndex();
901 Standard_Integer FirstIndex = res->FirstUKnotIndex();
902 while (--i >= FirstIndex+1) {
904 if(!res->RemoveUKnot(i, DegreeU-2, GetEpsGeom())) {
905 //isC2 = Standard_False; //szv#4:S4163:12Mar99 not needed
906 res->RemoveUKnot(i, DegreeU-1, GetEpsGeom()); //szv#4:S4163:12Mar99 `isC1=` not needed
909 res->RemoveUKnot(i, DegreeU-1, GetEpsGeom()); //szv#4:S4163:12Mar99 `isC1=` not needed
913 i = res->LastVKnotIndex();
914 FirstIndex = res->FirstVKnotIndex();
915 while (--i >= FirstIndex+1) {
917 if(!res->RemoveVKnot(i, DegreeV-2, GetEpsGeom())) {
918 //isC2 = Standard_False; //szv#4:S4163:12Mar99 not needed
919 res->RemoveVKnot(i, DegreeV-1, GetEpsGeom()); //szv#4:S4163:12Mar99 `isC1=` not needed
922 res->RemoveVKnot(i, DegreeV-1, GetEpsGeom()); //szv#4:S4163:12Mar99 `isC1=` not needed
926 //:h7 abv 14 Jul 98: ims010.igs 2519: closed periodic surface should be forced
927 // else some wires which can lie over the seam will be incorrect
928 //:l1 abv 6 Jan 99: USA60022 243: force periodicity on any closed surface
929 Standard_Boolean isUPeriodic = ( start->IsClosedU() && ( start->IsPeriodicU() ||
930 res->IsUClosed() ) );
931 Standard_Boolean isVPeriodic = ( start->IsClosedV() && ( start->IsPeriodicV() ||
932 res->IsVClosed() ) );
933 //:k0 abv 16 Dec 98: use ShapeCustom
934 if ( isUPeriodic || isVPeriodic ) {
935 Handle(Geom_BSplineSurface) periodicSurf =
936 Handle(Geom_BSplineSurface)::DownCast ( ShapeAlgo::AlgoContainer()->ConvertToPeriodic (res) );
937 if ( ! periodicSurf.IsNull() ) { //:p6 abv 26 Feb 99: && periodicSurf != res ) {
938 //#75 rln 11.03.99: using message mechanism
939 Message_Msg msg1221("IGES_1221");
940 SendWarning(start, msg1221);//SendWarning(start,"Surface forced to be periodic");
950 //=======================================================================
951 //function : DeletePoleRow
953 //=======================================================================
954 //szv#4:S4163:12Mar99 function never referenced
956 static void DeletePoleRow
957 (const TColgp_Array2OfPnt& Poles,
958 const Standard_Integer Index,
959 TColgp_Array2OfPnt& NewPoles)
961 Standard_Integer Offset = 0;
962 Standard_Integer ColIndex;
963 Standard_Integer RowIndex = NewPoles.LowerRow();
964 while (RowIndex <= NewPoles.UpperRow()) {
965 ColIndex = NewPoles.LowerCol();
966 if (RowIndex == Index) Offset = 1;
967 while (ColIndex <= NewPoles.UpperCol()){
968 NewPoles (RowIndex, ColIndex) = Poles (RowIndex + Offset, ColIndex);
976 //=======================================================================
977 //function : DeletePoleCol
979 //=======================================================================
980 //szv#4:S4163:12Mar99 function never referenced
982 static void DeletePoleCol
983 (const TColgp_Array2OfPnt& Poles,
984 const Standard_Integer Index,
985 TColgp_Array2OfPnt& NewPoles)
987 Standard_Integer Offset = 0;
988 Standard_Integer RowIndex;
989 Standard_Integer ColIndex = NewPoles.LowerCol();
990 while (ColIndex <= NewPoles.UpperCol()) {
991 RowIndex = NewPoles.LowerRow();
992 if (ColIndex == Index) Offset = 1;
993 while (RowIndex <= NewPoles.UpperRow()){
994 NewPoles (RowIndex, ColIndex) = Poles (RowIndex, ColIndex + Offset);