1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
14 //=======================================================================
16 //:k0 abv 16.12.98: eliminating existing code
17 // 21.12.98 rln, gka S4054
18 //:k5 abv 25 Dec 98: PRO8803 1901: extending method of fixing Multi > Degree
19 // 28.12.98 dce S3767 New messaging system
21 //:l1 abv 06.01.99: USA60022.igs 243: fixing missing seam on closed surface
22 //:p6 abv 26.02.99: improve messages after call to ConvertToPeriodic
23 //#75 rln 11.03.99: using message mechanism for periodic B-Spline
24 //S4181 pdn 15.04.99 implementing of reading IGES elementary surfaces.
25 //sln 29.12.2001 OCC90 : Method checkBSplineSurfaceStatus and varification of creation of bspline surfaces were added
26 //=======================================================================
28 #include <Geom_BSplineSurface.hxx>
29 #include <Geom_ConicalSurface.hxx>
30 #include <Geom_CylindricalSurface.hxx>
31 #include <Geom_Plane.hxx>
32 #include <Geom_SphericalSurface.hxx>
33 #include <Geom_Surface.hxx>
34 #include <Geom_ToroidalSurface.hxx>
36 #include <gp_Cylinder.hxx>
37 #include <gp_GTrsf.hxx>
39 #include <gp_Trsf.hxx>
40 #include <IGESConvGeom.hxx>
41 #include <IGESData_IGESEntity.hxx>
42 #include <IGESData_IGESModel.hxx>
43 #include <IGESData_ToolLocation.hxx>
44 #include <IGESGeom_BSplineSurface.hxx>
45 #include <IGESGeom_Direction.hxx>
46 #include <IGESGeom_Point.hxx>
47 #include <IGESGeom_SplineSurface.hxx>
48 #include <IGESSolid_ConicalSurface.hxx>
49 #include <IGESSolid_CylindricalSurface.hxx>
50 #include <IGESSolid_PlaneSurface.hxx>
51 #include <IGESSolid_SphericalSurface.hxx>
52 #include <IGESSolid_ToroidalSurface.hxx>
53 #include <IGESToBRep.hxx>
54 #include <IGESToBRep_BasicSurface.hxx>
55 #include <IGESToBRep_CurveAndSurface.hxx>
56 #include <Interface_Macros.hxx>
57 #include <Message_Msg.hxx>
58 #include <Precision.hxx>
59 #include <ShapeAlgo.hxx>
60 #include <ShapeAlgo_AlgoContainer.hxx>
61 #include <ShapeConstruct_Curve.hxx>
62 #include <Standard_ErrorHandler.hxx>
63 #include <Standard_Failure.hxx>
64 #include <TColgp_Array2OfPnt.hxx>
65 #include <TColgp_HArray2OfPnt.hxx>
66 #include <TColStd_Array1OfInteger.hxx>
67 #include <TColStd_Array1OfReal.hxx>
68 #include <TColStd_Array2OfReal.hxx>
69 #include <TColStd_HArray1OfReal.hxx>
70 #include <TColStd_SequenceOfInteger.hxx>
75 //=======================================================================
76 //function : CheckBSplineSurface
77 //purpose : Check coincidede knots. Check whether knots are in ascending
78 // order and difference between vaues of weights more than 1000.
79 // Send corresponding messages. The function returns Standard_False
80 // if surface can not be created, Standard_True otherwise.
81 //=======================================================================
82 static Standard_Boolean checkBSplineSurface(IGESToBRep_BasicSurface* theSurface,
83 const Handle(IGESGeom_BSplineSurface)& theBSplineSurface,
84 TColStd_Array1OfReal& SUKnots,
85 TColStd_Array1OfReal& SVKnots,
86 const TColStd_Array2OfReal& SWeights)
88 // check whether difference between vaues of weights more than 1000.
89 if(!theBSplineSurface->IsPolynomial()) {
90 Standard_Real aMinValue = SWeights.Value(SWeights.LowerRow(), SWeights.LowerCol());
91 Standard_Real aMaxValue = SWeights.Value(SWeights.LowerRow(), SWeights.LowerCol());
92 for(Standard_Integer i = SWeights.LowerRow(); i<= SWeights.UpperRow(); i++)
93 for(Standard_Integer j = SWeights.LowerCol(); j<= SWeights.UpperCol(); j++) {
94 if(SWeights.Value(i,j) < aMinValue) aMinValue = SWeights.Value(i,j);
95 if(SWeights.Value(i,j) > aMaxValue) aMaxValue = SWeights.Value(i,j);
97 if(aMaxValue - aMinValue > 1000) {
98 Message_Msg msg1374("IGES_1374"); // WARNING - Difference between weights is too big.
99 theSurface->SendWarning(theBSplineSurface, msg1374);
104 Standard_Boolean aResult = Standard_True;
106 //check whether knots are in ascending order.
107 Standard_Boolean aWrongOrder = Standard_False;
109 for (i = SUKnots.Lower(); (i < SUKnots.Upper()) && (!aWrongOrder); i++)
110 if(SUKnots.Value (i+1) < SUKnots.Value (i)) aWrongOrder = Standard_True;
111 for (i = SVKnots.Lower(); (i < SVKnots.Upper()) && (!aWrongOrder); i++)
112 if(SVKnots.Value (i+1) < SVKnots.Value (i)) aWrongOrder = Standard_True;
115 Message_Msg msg1373("IGES_1373"); // FAIL - Knots are not in ascending order
116 theSurface->SendFail(theBSplineSurface, msg1373);
117 aResult = Standard_False;
120 //Fix coincided knots
122 ShapeConstruct_Curve::FixKnots(SUKnots);
123 ShapeConstruct_Curve::FixKnots(SVKnots);
131 //=======================================================================
132 //function : IGESToBRep_BasicSurface
134 //=======================================================================
136 IGESToBRep_BasicSurface::IGESToBRep_BasicSurface()
137 :IGESToBRep_CurveAndSurface()
139 SetModeTransfer(Standard_False);
142 //=======================================================================
143 //function : IGESToBRep_BasicSurface
145 //=======================================================================
147 IGESToBRep_BasicSurface::IGESToBRep_BasicSurface
148 (const IGESToBRep_CurveAndSurface& CS)
149 :IGESToBRep_CurveAndSurface(CS)
153 //=======================================================================
154 //function : IGESToBRep_BasicSurface
156 //=======================================================================
158 IGESToBRep_BasicSurface::IGESToBRep_BasicSurface
159 (const Standard_Real eps,
160 const Standard_Real epsCoeff,
161 const Standard_Real epsGeom,
162 const Standard_Boolean mode,
163 const Standard_Boolean modeapprox,
164 const Standard_Boolean optimized)
165 :IGESToBRep_CurveAndSurface(eps, epsCoeff, epsGeom, mode, modeapprox,
171 //=============================================
172 //Function : TransferBasicSurface
173 //Purpose : Choice of the right transfer method
174 //=============================================
176 Handle(Geom_Surface) IGESToBRep_BasicSurface::TransferBasicSurface
177 (const Handle(IGESData_IGESEntity)& start)
179 Handle(Geom_Surface) resurf;
180 if (start.IsNull()) {
181 Message_Msg msg1005("IGES_1005");
182 SendFail(start, msg1005);
186 try { //:36 by abv 11.12.97: Geom_BSplineSurface raiss if some weights <0
190 if (start->IsKind(STANDARD_TYPE(IGESGeom_BSplineSurface))) {
191 DeclareAndCast(IGESGeom_BSplineSurface, st128, start);
192 resurf = TransferBSplineSurface(st128);
194 else if (start->IsKind(STANDARD_TYPE(IGESGeom_SplineSurface))) {
195 DeclareAndCast(IGESGeom_SplineSurface, st114, start);
196 resurf = TransferSplineSurface(st114);
197 } //S4181 pdn 15.04.99 implementing of reading IGES elementary surfaces.
198 else if (start->IsKind(STANDARD_TYPE(IGESSolid_PlaneSurface))) {
199 DeclareAndCast(IGESSolid_PlaneSurface, st190, start);
200 resurf = TransferPlaneSurface(st190);
202 else if (start->IsKind(STANDARD_TYPE(IGESSolid_CylindricalSurface))) {
203 DeclareAndCast(IGESSolid_CylindricalSurface, st192, start);
204 resurf = TransferRigthCylindricalSurface(st192);
206 else if (start->IsKind(STANDARD_TYPE(IGESSolid_ConicalSurface))) {
207 DeclareAndCast(IGESSolid_ConicalSurface, st194, start);
208 resurf = TransferRigthConicalSurface(st194);
210 else if (start->IsKind(STANDARD_TYPE(IGESSolid_SphericalSurface))) {
211 DeclareAndCast(IGESSolid_SphericalSurface, st196, start);
212 resurf = TransferSphericalSurface(st196);
214 else if (start->IsKind(STANDARD_TYPE(IGESSolid_ToroidalSurface))) {
215 DeclareAndCast(IGESSolid_ToroidalSurface, st198, start);
216 resurf = TransferToroidalSurface(st198);
219 // AddFail(start, "Spline or BSpline surface expected for TransferBasicSurface");
224 catch(Standard_Failure const& anException) {
226 std::cout << "\n** Exception in IGESToBRep_BasicSurface::TransferBasicSurface : ";
227 anException.Print(std::cout);
232 if (resurf.IsNull()) {
233 // AddFail(start,"The IGESEntity cannot be transferred");
236 resurf->Scale(gp_Pnt(0,0,0),GetUnitFactor());
242 //=======================================================================
243 //function : TransferPlaneSurface
245 //=======================================================================
247 Handle(Geom_Plane) IGESToBRep_BasicSurface::TransferPlaneSurface(const Handle(IGESSolid_PlaneSurface)& start)
249 Handle(Geom_Plane) res;
250 if (start.IsNull()) {
251 Message_Msg msg1005("IGES_1005");
252 SendFail(start, msg1005);
257 Standard_Boolean Param = start->IsParametrised();
258 Handle(IGESGeom_Point) Point = start->LocationPoint();
259 Handle(IGESGeom_Direction) Dir = start->Normal();
261 if (Point.IsNull()) {
262 Message_Msg msg174("XSTEP_174");
263 SendFail(start, msg174);
264 // Point Reading Error : Null IGESEntity
268 Message_Msg msg1280("IGES_1280");
269 SendFail(start, msg1280);
270 // Direction Reading Error : Null IGESEntity
274 gp_Pnt Pt = Point->Value();
275 gp_Dir Normale = gp_Dir(Dir->Value());
277 pln = gp_Pln(Pt,Normale);
280 Handle(IGESGeom_Direction) refdir = start->ReferenceDir();
281 gp_Dir Dirgp = gp_Dir(refdir->Value());
282 pln = gp_Pln( gp_Ax3(Pt, Normale, Dirgp));
285 return new Geom_Plane(pln);
288 //=======================================================================
289 //function : TransferRigthCylindricalSurface
291 //=======================================================================
293 Handle(Geom_CylindricalSurface) IGESToBRep_BasicSurface::TransferRigthCylindricalSurface
294 (const Handle(IGESSolid_CylindricalSurface)& start)
296 Handle(Geom_CylindricalSurface) res;
297 if (start.IsNull()) {
298 Message_Msg msg1005("IGES_1005");
299 SendFail(start, msg1005);
303 Standard_Boolean Param = start->IsParametrised();
304 Handle(IGESGeom_Point) Point = start->LocationPoint();
305 Handle(IGESGeom_Direction) Axis = start->Axis();
306 Standard_Real radius = start->Radius();
308 if (Point.IsNull()) {
309 Message_Msg msg174("XSTEP_174");
310 SendFail(start, msg174);
311 // Point Reading Error : Null IGESEntity
315 Message_Msg msg1280("IGES_1280");
316 SendFail(start, msg1280);
317 // Direction Reading Error : Null IGESEntity
320 if (radius < Precision::Confusion()) {
324 gp_Pnt Pt = Point->Value();
325 gp_Dir ax = gp_Dir(Axis->Value());
330 Handle(IGESGeom_Direction) refdir = start->ReferenceDir();
331 gp_Dir Dir = gp_Dir(refdir->Value());
333 if(vc.XYZ().Modulus() < Precision::Confusion()) {
337 ax3 = gp_Ax3(Pt,ax,Dir);
339 gp_Cylinder cyl(ax3,radius);
340 return new Geom_CylindricalSurface(cyl);
343 //=======================================================================
344 //function : TransferRigthConicalSurface
346 //=======================================================================
348 Handle(Geom_ConicalSurface) IGESToBRep_BasicSurface::TransferRigthConicalSurface
349 (const Handle(IGESSolid_ConicalSurface)& start)
351 Handle(Geom_ConicalSurface) res;
352 if (start.IsNull()) {
353 Message_Msg msg1005("IGES_1005");
354 SendFail(start, msg1005);
358 Standard_Boolean Param = start->IsParametrised();
359 Handle(IGESGeom_Point) Point = start->LocationPoint();
360 Handle(IGESGeom_Direction) Axis = start->Axis();
361 Standard_Real radius = start->Radius();
362 Standard_Real angle = start->SemiAngle()/180.*M_PI;
364 if (Point.IsNull()) {
365 Message_Msg msg174("XSTEP_174");
366 SendFail(start, msg174);
367 // Point Reading Error : Null IGESEntity
371 Message_Msg msg1280("IGES_1280");
372 SendFail(start, msg1280);
373 // Direction Reading Error : Null IGESEntity
376 if (angle < Precision::Confusion()||angle > M_PI/2.) {
382 if (radius < Precision::Confusion())
385 gp_Pnt Pt = Point->Value();
386 gp_Dir ax = gp_Dir(Axis->Value());
391 Handle(IGESGeom_Direction) refdir = start->ReferenceDir();
392 gp_Dir Dir = gp_Dir(refdir->Value());
394 if(vc.XYZ().Modulus() < Precision::Confusion()) {
398 ax3 = gp_Ax3(Pt,ax,Dir);
400 return new Geom_ConicalSurface(ax3,angle,radius);
403 //=======================================================================
404 //function : TransferSphericalSurface
406 //=======================================================================
408 Handle(Geom_SphericalSurface) IGESToBRep_BasicSurface::TransferSphericalSurface
409 (const Handle(IGESSolid_SphericalSurface)& start)
411 Handle(Geom_SphericalSurface) res;
412 if (start.IsNull()) {
413 Message_Msg msg1005("IGES_1005");
414 SendFail(start, msg1005);
418 Standard_Boolean Param = start->IsParametrised();
419 Handle(IGESGeom_Point) Point = start->Center();
420 Handle(IGESGeom_Direction) Axis = start->Axis();
421 Standard_Real radius = start->Radius();
423 if (Point.IsNull()) {
424 Message_Msg msg174("XSTEP_174");
425 SendFail(start, msg174);
426 // Point Reading Error : Null IGESEntity
430 Message_Msg msg1280("IGES_1280");
431 SendFail(start, msg1280);
432 // Direction Reading Error : Null IGESEntity
435 if (radius < Precision::Confusion()){
440 gp_Pnt Pt = Point->Value();
441 gp_Dir ax = gp_Dir(Axis->Value());
446 Handle(IGESGeom_Direction) refdir = start->ReferenceDir();
447 gp_Dir Dir = gp_Dir(refdir->Value());
449 if(vc.XYZ().Modulus() < Precision::Confusion()) {
453 ax3 = gp_Ax3(Pt,ax,Dir);
455 return new Geom_SphericalSurface(ax3,radius);
458 //=======================================================================
459 //function : TransferToroidalSurface
461 //=======================================================================
463 Handle(Geom_ToroidalSurface) IGESToBRep_BasicSurface::TransferToroidalSurface
464 (const Handle(IGESSolid_ToroidalSurface)& start)
466 Handle(Geom_ToroidalSurface) res;
467 if (start.IsNull()) {
468 Message_Msg msg1005("IGES_1005");
469 SendFail(start, msg1005);
473 Standard_Boolean Param = start->IsParametrised();
474 Handle(IGESGeom_Point) Point = start->Center();
475 Handle(IGESGeom_Direction) Axis = start->Axis();
476 Standard_Real major = start->MajorRadius();
477 Standard_Real minor = start->MinorRadius();
479 if (Point.IsNull()) {
480 Message_Msg msg174("XSTEP_174");
481 SendFail(start, msg174);
482 // Point Reading Error : Null IGESEntity
486 Message_Msg msg1280("IGES_1280");
487 SendFail(start, msg1280);
488 // Direction Reading Error : Null IGESEntity
491 if (major < Precision::Confusion()||minor < Precision::Confusion()){
496 gp_Pnt Pt = Point->Value();
497 gp_Dir ax = gp_Dir(Axis->Value());
502 Handle(IGESGeom_Direction) refdir = start->ReferenceDir();
503 gp_Dir Dir = gp_Dir(refdir->Value());
505 if(vc.XYZ().Modulus() < Precision::Confusion()) {
509 ax3 = gp_Ax3(Pt,ax,Dir);
511 return new Geom_ToroidalSurface(ax3,major,minor);
513 //==================================
514 //Function : TransferSplineSurface :
516 //==================================
518 Handle(Geom_BSplineSurface) IGESToBRep_BasicSurface::TransferSplineSurface
519 (const Handle(IGESGeom_SplineSurface)& start)
521 Handle(Geom_BSplineSurface) resconv;
522 if (start.IsNull()) {
523 Message_Msg msg1005("IGES_1005");
524 SendFail(start, msg1005);
528 Standard_Real epscoef = GetEpsCoeff();
529 Standard_Real epsgeom = GetEpsGeom();
531 Standard_Integer result = IGESConvGeom::SplineSurfaceFromIGES
532 (start, epscoef, epsgeom, resconv);
536 Message_Msg msg1305("IGES_1305");
537 SendFail (start, msg1305); // less than on segment in U or V (no result produced)
541 Message_Msg msg1190("IGES_1190");
542 SendFail (start, msg1190);
546 // AddWarning ( start, "Degree is not compatible with code boundary type , C0 is not guaranteed)");
548 // AddWarning ( start, "Degree is not compatible with code boundary type , C0 is guaranted)");
554 // Checking C2 and C1 continuity : case 1 :
555 // AddWarning ( start, "The result is not guaranteed to be C0");
556 // ===============================
558 IGESConvGeom::IncreaseSurfaceContinuity (resconv, epsgeom, GetContinuity());
562 //===================================
563 //Function : TransferBSplineSurface :
565 //===================================
567 Handle(Geom_BSplineSurface) IGESToBRep_BasicSurface::TransferBSplineSurface
568 (const Handle(IGESGeom_BSplineSurface)& start)
570 Handle(Geom_BSplineSurface) res;
571 if (start.IsNull()) {
572 Message_Msg msg1005("IGES_1005");
573 SendFail(start, msg1005);
577 Standard_Integer DegreeU = start->DegreeU();
578 Standard_Integer DegreeV = start->DegreeV();
579 if ((DegreeU <= 0) || (DegreeU > Geom_BSplineSurface::MaxDegree()) ||
580 (DegreeV <= 0) || (DegreeV > Geom_BSplineSurface::MaxDegree())) {
581 Message_Msg msg1310("IGES_1310");
582 SendFail ( start, msg1310);
583 // Improper Input BSpline Degree
587 // Filling poles array :
588 // =====================
590 Standard_Integer NbPolesU = start->NbPolesU();
591 Standard_Integer newNbPolesU = NbPolesU;
593 Message_Msg msg1195("IGES_1195");
594 SendFail(start, msg1195);
595 // Number of poles lower than 2 following U
599 Standard_Integer NbPolesV = start->NbPolesV();
600 Standard_Integer newNbPolesV = NbPolesV;
602 Message_Msg msg1195("IGES_1195");
603 SendFail(start, msg1195);
607 TColgp_Array2OfPnt Pole(1, NbPolesU, 1, NbPolesV);
608 Standard_Integer UIndex = Pole.LowerRow();
609 Standard_Integer VIndex = Pole.LowerCol();
610 Standard_Integer i, j; //szv#4:S4163:12Mar99 k unused
612 if (!GetModeTransfer() && start->HasTransf())
613 for (i=0; i <= start->UpperIndexU(); i++) {
614 for (j=0; j <= start->UpperIndexV(); j++)
615 Pole.SetValue(UIndex, VIndex++, start->TransformedPole(i,j));
617 VIndex = Pole.LowerCol();
620 for (i=0; i <= start->UpperIndexU(); i++) {
621 for (j=0; j <= start->UpperIndexV(); j++)
622 Pole.SetValue(UIndex, VIndex++, start->Pole(i,j));
624 VIndex = Pole.LowerCol();
628 // KNOTS & MULTIPLICITIES for U :
629 // ==============================
631 Standard_Integer NbUKnots = start->NbKnotsU();
632 TColStd_Array1OfReal TempUKnot(1, NbUKnots);
633 TColStd_Array1OfInteger TempUMult(1, NbUKnots);
636 UIndex = TempUKnot.Lower();
639 // If several identical IGES knots are encountered, corresponding
640 // multiplicity is increased
641 // ==============================================================
643 TempUKnot.SetValue(UIndex, start->KnotU(-DegreeU));
645 for (i = 1-DegreeU; i < NbUKnots-DegreeU; i++) {
647 Standard_Real UKnot1 = start->KnotU(i);
648 Standard_Real UKnot2 = start->KnotU(i-1);
650 if (Abs(UKnot1 - UKnot2) <= Epsilon(UKnot2))
651 TempUMult.SetValue(UIndex, TempUMult.Value(UIndex) + 1);
653 TempUKnot.SetValue(++UIndex, UKnot1);
656 // Final knots & multiplicities arraies are dimensionned so as to be fully
658 // =======================================================================
660 TColStd_Array1OfReal UKnot(1,UIndex);
661 TColStd_Array1OfInteger UMult(1,UIndex);
663 Standard_Integer SumOfUMult = 0;
665 TColStd_SequenceOfInteger SeqIndexU;
666 Standard_Integer DelIndexU;
667 Standard_Integer OldSumOfUMult = 0;
668 for (i=1 ; i <= UIndex; i++) { //:k5 abv 25 Dec 98: cycle modified
669 Standard_Integer aMult = TempUMult.Value(i);
670 Standard_Integer maxMult = ( i==1 || i == UIndex ? DegreeU + 1 : DegreeU );
671 if (aMult > maxMult) {
672 Message_Msg msg1200("IGES_1200");
675 msg1200.Arg("U");//#61 rln 05.01.99
676 SendWarning(start, msg1200); //U Multiplicity > DegreeU (or Degree+1 at end); corrected
677 for ( DelIndexU = OldSumOfUMult + 1; aMult > maxMult; DelIndexU++, aMult-- ) {
679 SeqIndexU.Append(DelIndexU);
682 OldSumOfUMult += TempUMult.Value(i);
683 UKnot.SetValue(i, TempUKnot.Value(i));
684 UMult.SetValue(i, aMult);
688 if (SumOfUMult != newNbPolesU + DegreeU + 1) {
689 Message_Msg msg1210("IGES_1210");
692 SendWarning(start, msg1210);
693 // Sum of multiplicities following U is not equal to the sum : Count of poles + DegreeU + 1
696 // KNOTS & MULTIPLICITIES for V :
697 // ==============================
699 Standard_Integer NbVKnots = start->NbKnotsV();
700 TColStd_Array1OfReal TempVKnot(1, NbVKnots);
701 TColStd_Array1OfInteger TempVMult(1, NbVKnots);
704 VIndex = TempVKnot.Lower();
707 // If several identical IGES knots are encountered, corresponding
708 // multiplicity is increased
709 // ==============================================================
711 TempVKnot.SetValue(VIndex, start->KnotV(-DegreeV));
713 for (i = 1-DegreeV; i < NbVKnots-DegreeV; i++) {
715 Standard_Real VKnot1 = start->KnotV(i);
716 Standard_Real VKnot2 = start->KnotV(i-1);
718 if (Abs(VKnot1 - VKnot2) <= Epsilon(VKnot2))
719 TempVMult.SetValue(VIndex, TempVMult.Value(VIndex) + 1);
721 TempVKnot.SetValue(++VIndex, VKnot1);
724 // Final knots & multiplicities arraies are dimensionned so as to be fully
726 // =======================================================================
728 TColStd_Array1OfReal VKnot(1,VIndex);
729 TColStd_Array1OfInteger VMult(1,VIndex);
731 Standard_Integer SumOfVMult = 0;
733 TColStd_SequenceOfInteger SeqIndexV;
734 Standard_Integer DelIndexV;
735 Standard_Integer OldSumOfVMult = 0;
736 for (i=1; i <= VIndex; i++) { //:k5 abv 25 Dec 98: cycle modified
737 Standard_Integer aMult = TempVMult.Value(i);
738 Standard_Integer maxMult = ( i==1 || i == VIndex ? DegreeV + 1 : DegreeV );
739 if (aMult > maxMult) {
740 Message_Msg msg1200("IGES_1200");//#61 rln 05.01.99
744 SendWarning(start, msg1200);
745 //V Multiplicity > DegreeV (or Degree+1 at end); corrected
746 for ( DelIndexV = OldSumOfVMult + 1; aMult > maxMult; DelIndexV++, aMult-- ) {
748 SeqIndexV.Append(DelIndexV);
751 OldSumOfVMult += TempVMult.Value(i);
752 VKnot.SetValue(i, TempVKnot.Value(i));
753 VMult.SetValue(i, aMult);
757 if (SumOfVMult != newNbPolesV + DegreeV + 1) {
758 Message_Msg msg1210("IGES_1210");
761 SendWarning(start, msg1210);
762 // Sum of multiplicities following V is not equal to the sum : Count of poles + Degree V + 1
765 // Mise a jour du tableau des poles
766 TColgp_Array2OfPnt Poles(1, newNbPolesU, 1, newNbPolesV);
767 TColStd_SequenceOfInteger PoleUInd;
768 TColStd_SequenceOfInteger PoleVInd;
769 for (i=1; i<=NbPolesU; i++) PoleUInd.Append(i);
770 for (i=1; i<=NbPolesV; i++) PoleVInd.Append(i);
771 UIndex = Poles.LowerRow();
772 VIndex = Poles.LowerCol();
774 if (( newNbPolesU < NbPolesU) || (newNbPolesV < NbPolesV)) {
775 if ( newNbPolesU < NbPolesU) {
776 Standard_Integer Offset = 0;
777 for (Standard_Integer itab = 1; itab <= SeqIndexU.Length(); itab++) {
778 DelIndexU = SeqIndexU.Value(itab) - Offset;
779 PoleUInd.Remove(DelIndexU);
783 if ( newNbPolesV < NbPolesV) {
784 Standard_Integer Offset = 0;
785 for (Standard_Integer itab = 1; itab <= SeqIndexV.Length(); itab++) {
786 DelIndexV = SeqIndexV.Value(itab) - Offset;
787 PoleVInd.Remove(DelIndexV);
791 Standard_Integer nbUseq = PoleUInd.Length();
792 Standard_Integer nbVseq = PoleVInd.Length();
793 if (( nbUseq == newNbPolesU)&&(nbVseq == newNbPolesV)) {
794 for ( i=1; i<= newNbPolesU; i++) {
795 for (j=1; j<= newNbPolesV; j++)
796 Poles.SetValue(UIndex,VIndex++ , Pole.Value(PoleUInd.Value(i),
799 VIndex = Poles.LowerCol();
803 Message_Msg msg1175("IGES_1175");
804 SendWarning(start, msg1175);
809 for ( i=1; i<= newNbPolesU; i++) {
810 for (j=1; j<= newNbPolesV; j++)
811 Poles.SetValue (UIndex, VIndex++,Pole.Value(i,j));
813 VIndex = Poles.LowerCol();
818 // Building result taking into account transformation if any :
819 // ===========================================================
821 if (!GetModeTransfer() && start->HasTransf()) {
822 gp_GTrsf GBSplTrsf(start->CompoundLocation());
824 if (IGESData_ToolLocation::ConvertLocation(GetEpsilon(),GBSplTrsf,BSplTrsf))
825 for (i=Poles.LowerRow(); i<=Poles.UpperRow(); i++)
826 for (j=Poles.LowerCol(); j<=Poles.UpperCol(); j++)
827 Poles.SetValue(i, j, Poles.Value(i,j).Transformed(BSplTrsf));
829 Message_Msg msg1035("IGES_1035");
830 SendWarning(start, msg1035);
835 // CREATION with the ARRAY of POLES WEIGHTS if any :
836 // =================================================
838 if (start->IsPolynomial())
840 //sln 29.12.2001 OCC90 : If surface can not be created do nothing
841 TColStd_Array2OfReal Weight(1, 1, 1, 1);
842 if(!checkBSplineSurface(this, start, UKnot, VKnot, Weight)) return res;
843 res = new Geom_BSplineSurface(Poles, UKnot, VKnot, UMult, VMult,
848 TColStd_Array2OfReal PoleWeight(1, NbPolesU, 1, NbPolesV);
849 Standard_Boolean polynomial = Standard_True;
850 Standard_Real WeightReference = start->Weight(0,0);
851 Standard_Integer WeightRow = PoleWeight.LowerRow();
852 Standard_Integer WeightCol = PoleWeight.LowerCol();
854 for (i=0; i <= start->UpperIndexU(); i++) {
855 for (j=0; j <= start->UpperIndexV(); j++) {
856 polynomial = (Abs(start->Weight(i,j) - WeightReference)
857 <= Epsilon(WeightReference)) && polynomial;
858 //:39 by abv 15.12.97
859 Standard_Real weight = start->Weight(i,j);
860 if ( weight < Precision::PConfusion() ) {
861 Message_Msg msg1215("IGES_1215");
862 SendFail (start, msg1215); // Some weights are not positive.
865 PoleWeight.SetValue(WeightRow, WeightCol++, weight);
866 //:39 PoleWeight.SetValue(WeightRow, WeightCol++, start->Weight(i,j));
869 WeightCol = PoleWeight.LowerCol();
872 Message_Msg msg1220("IGES_1220");
873 const Standard_CString surface ("surface");
874 msg1220.Arg(surface);
875 SendWarning(start, msg1220);
877 // Mise a jour du tableau des Weight lors de la correction de la multiplicite
878 TColStd_Array2OfReal Weight(1, newNbPolesU, 1, newNbPolesV);
879 UIndex = Weight.LowerRow();
880 VIndex = Weight.LowerCol();
881 if (( newNbPolesU < NbPolesU) || (newNbPolesV < NbPolesV)) {
882 //Standard_Integer indj = 1; //szv#4:S4163:12Mar99 unused
883 for ( i=1; i<= newNbPolesU; i++) {
884 for (j=1; j<= newNbPolesV; j++)
885 Weight.SetValue(UIndex, VIndex++ ,
886 PoleWeight.Value(PoleUInd.Value(i),PoleVInd.Value(j)));
888 VIndex = Poles.LowerCol();
892 for ( i=1; i<= newNbPolesU; i++) {
893 for (j=1; j<= newNbPolesV; j++)
894 Weight.SetValue(UIndex, VIndex++ ,PoleWeight.Value(i,j));
896 VIndex = Poles.LowerCol();
900 //sln 29.12.2001 OCC90 : If surface can not be created do nothing
901 if(!checkBSplineSurface(this, start, UKnot, VKnot, Weight)) return res;
902 res = new Geom_BSplineSurface
903 (Poles, Weight, UKnot, VKnot, UMult, VMult, DegreeU, DegreeV);
907 // Checking C2 and C1 continuity :
908 // ===============================
910 Standard_Integer icont = GetContinuity();
911 //Standard_Boolean isC1 = Standard_True, isC2 = Standard_True; //szv#4:S4163:12Mar99 not needed
913 i = res->LastUKnotIndex();
914 Standard_Integer FirstIndex = res->FirstUKnotIndex();
915 while (--i >= FirstIndex+1) {
917 if(!res->RemoveUKnot(i, DegreeU-2, GetEpsGeom())) {
918 //isC2 = Standard_False; //szv#4:S4163:12Mar99 not needed
919 res->RemoveUKnot(i, DegreeU-1, GetEpsGeom()); //szv#4:S4163:12Mar99 `isC1=` not needed
922 res->RemoveUKnot(i, DegreeU-1, GetEpsGeom()); //szv#4:S4163:12Mar99 `isC1=` not needed
926 i = res->LastVKnotIndex();
927 FirstIndex = res->FirstVKnotIndex();
928 while (--i >= FirstIndex+1) {
930 if(!res->RemoveVKnot(i, DegreeV-2, GetEpsGeom())) {
931 //isC2 = Standard_False; //szv#4:S4163:12Mar99 not needed
932 res->RemoveVKnot(i, DegreeV-1, GetEpsGeom()); //szv#4:S4163:12Mar99 `isC1=` not needed
935 res->RemoveVKnot(i, DegreeV-1, GetEpsGeom()); //szv#4:S4163:12Mar99 `isC1=` not needed
939 //:h7 abv 14 Jul 98: ims010.igs 2519: closed periodic surface should be forced
940 // else some wires which can lie over the seam will be incorrect
941 //:l1 abv 6 Jan 99: USA60022 243: force periodicity on any closed surface
942 Standard_Boolean isUPeriodic = ( start->IsClosedU() && ( start->IsPeriodicU() ||
943 res->IsUClosed() ) );
944 Standard_Boolean isVPeriodic = ( start->IsClosedV() && ( start->IsPeriodicV() ||
945 res->IsVClosed() ) );
946 //:k0 abv 16 Dec 98: use ShapeCustom
947 if ( isUPeriodic || isVPeriodic ) {
948 Handle(Geom_BSplineSurface) periodicSurf =
949 Handle(Geom_BSplineSurface)::DownCast ( ShapeAlgo::AlgoContainer()->ConvertToPeriodic (res) );
950 if ( ! periodicSurf.IsNull() ) { //:p6 abv 26 Feb 99: && periodicSurf != res ) {
951 //#75 rln 11.03.99: using message mechanism
952 Message_Msg msg1221("IGES_1221");
953 SendWarning(start, msg1221);//SendWarning(start,"Surface forced to be periodic");
963 //=======================================================================
964 //function : DeletePoleRow
966 //=======================================================================
967 //szv#4:S4163:12Mar99 function never referenced
969 static void DeletePoleRow
970 (const TColgp_Array2OfPnt& Poles,
971 const Standard_Integer Index,
972 TColgp_Array2OfPnt& NewPoles)
974 Standard_Integer Offset = 0;
975 Standard_Integer ColIndex;
976 Standard_Integer RowIndex = NewPoles.LowerRow();
977 while (RowIndex <= NewPoles.UpperRow()) {
978 ColIndex = NewPoles.LowerCol();
979 if (RowIndex == Index) Offset = 1;
980 while (ColIndex <= NewPoles.UpperCol()){
981 NewPoles (RowIndex, ColIndex) = Poles (RowIndex + Offset, ColIndex);
989 //=======================================================================
990 //function : DeletePoleCol
992 //=======================================================================
993 //szv#4:S4163:12Mar99 function never referenced
995 static void DeletePoleCol
996 (const TColgp_Array2OfPnt& Poles,
997 const Standard_Integer Index,
998 TColgp_Array2OfPnt& NewPoles)
1000 Standard_Integer Offset = 0;
1001 Standard_Integer RowIndex;
1002 Standard_Integer ColIndex = NewPoles.LowerCol();
1003 while (ColIndex <= NewPoles.UpperCol()) {
1004 RowIndex = NewPoles.LowerRow();
1005 if (ColIndex == Index) Offset = 1;
1006 while (RowIndex <= NewPoles.UpperRow()){
1007 NewPoles (RowIndex, ColIndex) = Poles (RowIndex, ColIndex + Offset);