Loading files
3d097a032This file is pinned to the selected release. Download the original to open it in your design tool.
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
//=======================================================================
// modified:
//: k0 abv 16.12.98: eliminating existing code
// 21.12.98 rln, gka S4054
//: k5 abv 25 Dec 98: PRO8803 1901: extending method of fixing Multi > Degree
// 28.12.98 dce S3767 New messaging system
// #61 rln 05.01.99
//: l1 abv 06.01.99: USA60022.igs 243: fixing missing seam on closed surface
//: p6 abv 26.02.99: improve messages after call to ConvertToPeriodic
// #75 rln 11.03.99: using message mechanism for periodic B-Spline
// S4181 pdn 15.04.99 implementing of reading IGES elementary surfaces.
// sln 29.12.2001 OCC90 : Method checkBSplineSurfaceStatus and verification of creation of bspline
// surfaces were added
//=======================================================================
#include <Geom_BSplineSurface.hxx>
#include <Geom_ConicalSurface.hxx>
#include <Geom_CylindricalSurface.hxx>
#include <Geom_Plane.hxx>
#include <Geom_SphericalSurface.hxx>
#include <Geom_Surface.hxx>
#include <Geom_ToroidalSurface.hxx>
#include <gp_Ax3.hxx>
#include <gp_Cylinder.hxx>
#include <gp_GTrsf.hxx>
#include <gp_Pln.hxx>
#include <gp_Trsf.hxx>
#include <IGESConvGeom.hxx>
#include <IGESData_ToolLocation.hxx>
#include <IGESGeom_BSplineSurface.hxx>
#include <IGESGeom_Direction.hxx>
#include <IGESGeom_Point.hxx>
#include <IGESGeom_SplineSurface.hxx>
#include <IGESSolid_ConicalSurface.hxx>
#include <IGESSolid_CylindricalSurface.hxx>
#include <IGESSolid_PlaneSurface.hxx>
#include <IGESSolid_SphericalSurface.hxx>
#include <IGESSolid_ToroidalSurface.hxx>
#include <IGESToBRep_BasicSurface.hxx>
#include <IGESToBRep_CurveAndSurface.hxx>
#include <MoniTool_Macros.hxx>
#include <Message_Msg.hxx>
#include <Precision.hxx>
#include <ShapeAlgo.hxx>
#include <ShapeAlgo_AlgoContainer.hxx>
#include <ShapeConstruct_Curve.hxx>
#include <Standard_ErrorHandler.hxx>
#include <Standard_Failure.hxx>
#include <gp_Pnt.hxx>
#include <NCollection_Array2.hxx>
#include <Standard_Integer.hxx>
#include <NCollection_Array1.hxx>
#include <NCollection_Sequence.hxx>
//: 36
// S3767
// S4181
//=======================================================================
// function : CheckBSplineSurface
// purpose : Check coincidede knots. Check whether knots are in ascending
// order and difference between values of weights more than 1000.
// Send corresponding messages. The function returns false
// if surface can not be created, true otherwise.
//=======================================================================
static bool checkBSplineSurface(IGESToBRep_BasicSurface* theSurface,
const occ::handle<IGESGeom_BSplineSurface>& theBSplineSurface,
NCollection_Array1<double>& SUKnots,
NCollection_Array1<double>& SVKnots,
const NCollection_Array2<double>& SWeights)
{
// check whether difference between values of weights more than 1000.
if (!theBSplineSurface->IsPolynomial())
{
double aMinValue = SWeights.Value(SWeights.LowerRow(), SWeights.LowerCol());
double aMaxValue = SWeights.Value(SWeights.LowerRow(), SWeights.LowerCol());
for (int i = SWeights.LowerRow(); i <= SWeights.UpperRow(); i++)
{
for (int j = SWeights.LowerCol(); j <= SWeights.UpperCol(); j++)
{
if (SWeights.Value(i, j) < aMinValue)
{
aMinValue = SWeights.Value(i, j);
}
if (SWeights.Value(i, j) > aMaxValue)
{
aMaxValue = SWeights.Value(i, j);
}
if (aMaxValue - aMinValue > 1000)
{
Message_Msg msg1374("IGES_1374"); // WARNING - Difference between weights is too big.
theSurface->SendWarning(theBSplineSurface, msg1374);
}
}
}
}
bool aResult = true;
// check whether knots are in ascending order.
bool aWrongOrder = false;
int i;
for (i = SUKnots.Lower(); (i < SUKnots.Upper()) && (!aWrongOrder); i++)
{
if (SUKnots.Value(i + 1) < SUKnots.Value(i))
{
aWrongOrder = true;
}
}
for (i = SVKnots.Lower(); (i < SVKnots.Upper()) && (!aWrongOrder); i++)
{
if (SVKnots.Value(i + 1) < SVKnots.Value(i))
{
aWrongOrder = true;
}
}
if (aWrongOrder)
{
Message_Msg msg1373("IGES_1373"); // FAIL - Knots are not in ascending order
theSurface->SendFail(theBSplineSurface, msg1373);
aResult = false;
}
// Fix coincided knots
if (aResult)
{
ShapeConstruct_Curve::FixKnots(SUKnots);
ShapeConstruct_Curve::FixKnots(SVKnots);
}
return aResult;
}
//=================================================================================================
IGESToBRep_BasicSurface::IGESToBRep_BasicSurface()
{
SetModeTransfer(false);
}
//=================================================================================================
IGESToBRep_BasicSurface::IGESToBRep_BasicSurface(const IGESToBRep_CurveAndSurface& CS)
: IGESToBRep_CurveAndSurface(CS)
{
}
//=================================================================================================
IGESToBRep_BasicSurface::IGESToBRep_BasicSurface(const double eps,
const double epsCoeff,
const double epsGeom,
const bool mode,
const bool modeapprox,
const bool optimized)
: IGESToBRep_CurveAndSurface(eps, epsCoeff, epsGeom, mode, modeapprox, optimized)
{
}
//=============================================
// Function : TransferBasicSurface
// Purpose : Choice of the right transfer method
//=============================================
occ::handle<Geom_Surface> IGESToBRep_BasicSurface::TransferBasicSurface(
const occ::handle<IGESData_IGESEntity>& start)
{
occ::handle<Geom_Surface> resurf;
if (start.IsNull())
{
Message_Msg msg1005("IGES_1005");
SendFail(start, msg1005);
return resurf;
}
try
{ //: 36 by abv 11.12.97: Geom_BSplineSurface raiss if some weights <0
OCC_CATCH_SIGNALS
// S4054
if (start->IsKind(STANDARD_TYPE(IGESGeom_BSplineSurface)))
{
DeclareAndCast(IGESGeom_BSplineSurface, st128, start);
resurf = TransferBSplineSurface(st128);
}
else if (start->IsKind(STANDARD_TYPE(IGESGeom_SplineSurface)))
{
DeclareAndCast(IGESGeom_SplineSurface, st114, start);
resurf = TransferSplineSurface(st114);
} // S4181 pdn 15.04.99 implementing of reading IGES elementary surfaces.
else if (start->IsKind(STANDARD_TYPE(IGESSolid_PlaneSurface)))
{
DeclareAndCast(IGESSolid_PlaneSurface, st190, start);
resurf = TransferPlaneSurface(st190);
}
else if (start->IsKind(STANDARD_TYPE(IGESSolid_CylindricalSurface)))
{
DeclareAndCast(IGESSolid_CylindricalSurface, st192, start);
resurf = TransferRigthCylindricalSurface(st192);
}
else if (start->IsKind(STANDARD_TYPE(IGESSolid_ConicalSurface)))
{
DeclareAndCast(IGESSolid_ConicalSurface, st194, start);
resurf = TransferRigthConicalSurface(st194);
}
else if (start->IsKind(STANDARD_TYPE(IGESSolid_SphericalSurface)))
{
DeclareAndCast(IGESSolid_SphericalSurface, st196, start);
resurf = TransferSphericalSurface(st196);
}
else if (start->IsKind(STANDARD_TYPE(IGESSolid_ToroidalSurface)))
{
DeclareAndCast(IGESSolid_ToroidalSurface, st198, start);
resurf = TransferToroidalSurface(st198);
}
else
{
// AddFail(start, "Spline or BSpline surface expected for TransferBasicSurface");
return resurf;
}
} //: 36
catch (Standard_Failure const& anException)
{
#ifdef OCCT_DEBUG
std::cout << "\n** Exception in IGESToBRep_BasicSurface::TransferBasicSurface : ";
anException.Print(std::cout);
#endif
(void)anException;
}
if (resurf.IsNull())
{
// AddFail(start,"The IGESEntity cannot be transferred");
}
else
{
resurf->Scale(gp_Pnt(0, 0, 0), GetUnitFactor());
}
return resurf;
}
//=================================================================================================
occ::handle<Geom_Plane> IGESToBRep_BasicSurface::TransferPlaneSurface(
const occ::handle<IGESSolid_PlaneSurface>& start)
{
occ::handle<Geom_Plane> res;
if (start.IsNull())
{
Message_Msg msg1005("IGES_1005");
SendFail(start, msg1005);
return res;
}
gp_Pln pln;
bool Param = start->IsParametrised();
occ::handle<IGESGeom_Point> Point = start->LocationPoint();
occ::handle<IGESGeom_Direction> Dir = start->Normal();
if (Point.IsNull())
{
Message_Msg msg174("XSTEP_174");
SendFail(start, msg174);
// Point Reading Error : Null IGESEntity
return res;
}
if (Dir.IsNull())
{
Message_Msg msg1280("IGES_1280");
SendFail(start, msg1280);
// Direction Reading Error : Null IGESEntity
return res;
}
gp_Pnt Pt = Point->Value();
gp_Dir Normale = gp_Dir(Dir->Value());
if (!Param)
{
pln = gp_Pln(Pt, Normale);
}
else
{
occ::handle<IGESGeom_Direction> refdir = start->ReferenceDir();
gp_Dir Dirgp = gp_Dir(refdir->Value());
pln = gp_Pln(gp_Ax3(Pt, Normale, Dirgp));
}
return new Geom_Plane(pln);
}
//=================================================================================================
occ::handle<Geom_CylindricalSurface> IGESToBRep_BasicSurface::TransferRigthCylindricalSurface(
const occ::handle<IGESSolid_CylindricalSurface>& start)
{
occ::handle<Geom_CylindricalSurface> res;
if (start.IsNull())
{
Message_Msg msg1005("IGES_1005");
SendFail(start, msg1005);
return res;
}
bool Param = start->IsParametrised();
occ::handle<IGESGeom_Point> Point = start->LocationPoint();
occ::handle<IGESGeom_Direction> Axis = start->Axis();
double radius = start->Radius();
if (Point.IsNull())
{
Message_Msg msg174("XSTEP_174");
SendFail(start, msg174);
// Point Reading Error : Null IGESEntity
return res;
}
if (Axis.IsNull())
{
Message_Msg msg1280("IGES_1280");
SendFail(start, msg1280);
// Direction Reading Error : Null IGESEntity
return res;
}
if (radius < Precision::Confusion())
{
return res;
}
gp_Pnt Pt = Point->Value();
gp_Dir ax = gp_Dir(Axis->Value());
gp_Ax3 ax3;
if (!Param)
{
ax3 = gp_Ax3(Pt, ax);
}
else
{
occ::handle<IGESGeom_Direction> refdir = start->ReferenceDir();
gp_Dir Dir = gp_Dir(refdir->Value());
gp_Dir vc = Dir ^ ax;
if (vc.XYZ().Modulus() < Precision::Confusion())
{
return res;
}
ax3 = gp_Ax3(Pt, ax, Dir);
}
gp_Cylinder cyl(ax3, radius);
return new Geom_CylindricalSurface(cyl);
}
//=================================================================================================
occ::handle<Geom_ConicalSurface> IGESToBRep_BasicSurface::TransferRigthConicalSurface(
const occ::handle<IGESSolid_ConicalSurface>& start)
{
occ::handle<Geom_ConicalSurface> res;
if (start.IsNull())
{
Message_Msg msg1005("IGES_1005");
SendFail(start, msg1005);
return res;
}
bool Param = start->IsParametrised();
occ::handle<IGESGeom_Point> Point = start->LocationPoint();
occ::handle<IGESGeom_Direction> Axis = start->Axis();
double radius = start->Radius();
double angle = start->SemiAngle() / 180. * M_PI;
if (Point.IsNull())
{
Message_Msg msg174("XSTEP_174");
SendFail(start, msg174);
// Point Reading Error : Null IGESEntity
return res;
}
if (Axis.IsNull())
{
Message_Msg msg1280("IGES_1280");
SendFail(start, msg1280);
// Direction Reading Error : Null IGESEntity
return res;
}
if (angle < Precision::Confusion() || angle > M_PI / 2.)
{
return res;
}
if (radius < 0)
{
return res;
}
if (radius < Precision::Confusion())
{
radius = 0.;
}
gp_Pnt Pt = Point->Value();
gp_Dir ax = gp_Dir(Axis->Value());
gp_Ax3 ax3;
if (!Param)
{
ax3 = gp_Ax3(Pt, ax);
}
else
{
occ::handle<IGESGeom_Direction> refdir = start->ReferenceDir();
gp_Dir Dir = gp_Dir(refdir->Value());
gp_Dir vc = Dir ^ ax;
if (vc.XYZ().Modulus() < Precision::Confusion())
{
return res;
}
ax3 = gp_Ax3(Pt, ax, Dir);
}
return new Geom_ConicalSurface(ax3, angle, radius);
}
//=================================================================================================
occ::handle<Geom_SphericalSurface> IGESToBRep_BasicSurface::TransferSphericalSurface(
const occ::handle<IGESSolid_SphericalSurface>& start)
{
occ::handle<Geom_SphericalSurface> res;
if (start.IsNull())
{
Message_Msg msg1005("IGES_1005");
SendFail(start, msg1005);
return res;
}
bool Param = start->IsParametrised();
occ::handle<IGESGeom_Point> Point = start->Center();
occ::handle<IGESGeom_Direction> Axis = start->Axis();
double radius = start->Radius();
if (Point.IsNull())
{
Message_Msg msg174("XSTEP_174");
SendFail(start, msg174);
// Point Reading Error : Null IGESEntity
return res;
}
if (Axis.IsNull())
{
Message_Msg msg1280("IGES_1280");
SendFail(start, msg1280);
// Direction Reading Error : Null IGESEntity
return res;
}
if (radius < Precision::Confusion())
{
return res;
}
gp_Pnt Pt = Point->Value();
gp_Dir ax = gp_Dir(Axis->Value());
gp_Ax3 ax3;
if (!Param)
{
ax3 = gp_Ax3(Pt, ax);
}
else
{
occ::handle<IGESGeom_Direction> refdir = start->ReferenceDir();
gp_Dir Dir = gp_Dir(refdir->Value());
gp_Dir vc = Dir ^ ax;
if (vc.XYZ().Modulus() < Precision::Confusion())
{
return res;
}
ax3 = gp_Ax3(Pt, ax, Dir);
}
return new Geom_SphericalSurface(ax3, radius);
}
//=================================================================================================
occ::handle<Geom_ToroidalSurface> IGESToBRep_BasicSurface::TransferToroidalSurface(
const occ::handle<IGESSolid_ToroidalSurface>& start)
{
occ::handle<Geom_ToroidalSurface> res;
if (start.IsNull())
{
Message_Msg msg1005("IGES_1005");
SendFail(start, msg1005);
return res;
}
bool Param = start->IsParametrised();
occ::handle<IGESGeom_Point> Point = start->Center();
occ::handle<IGESGeom_Direction> Axis = start->Axis();
double major = start->MajorRadius();
double minor = start->MinorRadius();
if (Point.IsNull())
{
Message_Msg msg174("XSTEP_174");
SendFail(start, msg174);
// Point Reading Error : Null IGESEntity
return res;
}
if (Axis.IsNull())
{
Message_Msg msg1280("IGES_1280");
SendFail(start, msg1280);
// Direction Reading Error : Null IGESEntity
return res;
}
if (major < Precision::Confusion() || minor < Precision::Confusion())
{
return res;
}
gp_Pnt Pt = Point->Value();
gp_Dir ax = gp_Dir(Axis->Value());
gp_Ax3 ax3;
if (!Param)
{
ax3 = gp_Ax3(Pt, ax);
}
else
{
occ::handle<IGESGeom_Direction> refdir = start->ReferenceDir();
gp_Dir Dir = gp_Dir(refdir->Value());
gp_Dir vc = Dir ^ ax;
if (vc.XYZ().Modulus() < Precision::Confusion())
{
return res;
}
ax3 = gp_Ax3(Pt, ax, Dir);
}
return new Geom_ToroidalSurface(ax3, major, minor);
}
//=================================================================================================
occ::handle<Geom_BSplineSurface> IGESToBRep_BasicSurface::TransferSplineSurface(
const occ::handle<IGESGeom_SplineSurface>& start)
{
occ::handle<Geom_BSplineSurface> resconv;
if (start.IsNull())
{
Message_Msg msg1005("IGES_1005");
SendFail(start, msg1005);
return resconv;
}
double epscoef = GetEpsCoeff();
double epsgeom = GetEpsGeom();
int result = IGESConvGeom::SplineSurfaceFromIGES(start, epscoef, epsgeom, resconv);
switch (result)
{
case 5: {
Message_Msg msg1305("IGES_1305");
SendFail(start, msg1305); // less than on segment in U or V (no result produced)
return resconv;
}
case 4: {
Message_Msg msg1190("IGES_1190");
SendFail(start, msg1190);
return resconv;
}
// case 3 :
// AddWarning ( start, "Degree is not compatible with code boundary type , C0 is not
// guaranteed)");
// case 2 :
// AddWarning ( start, "Degree is not compatible with code boundary type , C0 is
// guaranteed)");
default:
break;
}
// Checking C2 and C1 continuity : case 1 :
// AddWarning ( start, "The result is not guaranteed to be C0");
// ===============================
IGESConvGeom::IncreaseSurfaceContinuity(resconv, epsgeom, GetContinuity());
return resconv;
}
//=================================================================================================
occ::handle<Geom_BSplineSurface> IGESToBRep_BasicSurface::TransferBSplineSurface(
const occ::handle<IGESGeom_BSplineSurface>& start)
{
occ::handle<Geom_BSplineSurface> res;
if (start.IsNull())
{
Message_Msg msg1005("IGES_1005");
SendFail(start, msg1005);
return res;
}
int DegreeU = start->DegreeU();
int DegreeV = start->DegreeV();
if ((DegreeU <= 0) || (DegreeU > Geom_BSplineSurface::MaxDegree()) || (DegreeV <= 0)
|| (DegreeV > Geom_BSplineSurface::MaxDegree()))
{
Message_Msg msg1310("IGES_1310");
SendFail(start, msg1310);
// Improper Input BSpline Degree
return res;
}
// Filling poles array :
// =====================
int NbPolesU = start->NbPolesU();
int newNbPolesU = NbPolesU;
if (NbPolesU < 2)
{
Message_Msg msg1195("IGES_1195");
SendFail(start, msg1195);
// Number of poles lower than 2 following U
return res;
}
int NbPolesV = start->NbPolesV();
int newNbPolesV = NbPolesV;
if (NbPolesV < 2)
{
Message_Msg msg1195("IGES_1195");
SendFail(start, msg1195);
return res;
}
NCollection_Array2<gp_Pnt> Pole(1, NbPolesU, 1, NbPolesV);
int UIndex = Pole.LowerRow();
int VIndex = Pole.LowerCol();
int i, j; // szv#4:S4163:12Mar99 k unused
if (!GetModeTransfer() && start->HasTransf())
{
for (i = 0; i <= start->UpperIndexU(); i++)
{
for (j = 0; j <= start->UpperIndexV(); j++)
{
Pole.SetValue(UIndex, VIndex++, start->TransformedPole(i, j));
}
UIndex++;
VIndex = Pole.LowerCol();
}
}
else
{
for (i = 0; i <= start->UpperIndexU(); i++)
{
for (j = 0; j <= start->UpperIndexV(); j++)
{
Pole.SetValue(UIndex, VIndex++, start->Pole(i, j));
}
UIndex++;
VIndex = Pole.LowerCol();
}
}
// KNOTS & MULTIPLICITIES for U :
// ==============================
int NbUKnots = start->NbKnotsU();
NCollection_Array1<double> TempUKnot(1, NbUKnots);
NCollection_Array1<int> TempUMult(1, NbUKnots);
TempUMult.Init(1);
UIndex = TempUKnot.Lower();
// If several identical IGES knots are encountered, corresponding
// multiplicity is increased
// ==============================================================
TempUKnot.SetValue(UIndex, start->KnotU(-DegreeU));
for (i = 1 - DegreeU; i < NbUKnots - DegreeU; i++)
{
double UKnot1 = start->KnotU(i);
double UKnot2 = start->KnotU(i - 1);
if (std::abs(UKnot1 - UKnot2) <= Epsilon(UKnot2))
{
TempUMult.SetValue(UIndex, TempUMult.Value(UIndex) + 1);
}
else
{
TempUKnot.SetValue(++UIndex, UKnot1);
}
}
// Final knots & multiplicities arrays are dimensioned so as to be fully
// filled :
// =======================================================================
NCollection_Array1<double> UKnot(1, UIndex);
NCollection_Array1<int> UMult(1, UIndex);
int SumOfUMult = 0;
NCollection_Sequence<int> SeqIndexU;
int DelIndexU;
int OldSumOfUMult = 0;
for (i = 1; i <= UIndex; i++)
{ //: k5 abv 25 Dec 98: cycle modified
int aMult = TempUMult.Value(i);
int maxMult = (i == 1 || i == UIndex ? DegreeU + 1 : DegreeU);
if (aMult > maxMult)
{
Message_Msg msg1200("IGES_1200");
msg1200.Arg("U");
msg1200.Arg("U");
msg1200.Arg("U"); // #61 rln 05.01.99
SendWarning(start, msg1200); // U Multiplicity > DegreeU (or Degree+1 at end); corrected
for (DelIndexU = OldSumOfUMult + 1; aMult > maxMult; DelIndexU++, aMult--)
{
newNbPolesU--;
SeqIndexU.Append(DelIndexU);
}
}
OldSumOfUMult += TempUMult.Value(i);
UKnot.SetValue(i, TempUKnot.Value(i));
UMult.SetValue(i, aMult);
SumOfUMult += aMult;
}
if (SumOfUMult != newNbPolesU + DegreeU + 1)
{
Message_Msg msg1210("IGES_1210");
msg1210.Arg("U");
msg1210.Arg("U");
SendWarning(start, msg1210);
// Sum of multiplicities following U is not equal to the sum : Count of poles + DegreeU + 1
}
// KNOTS & MULTIPLICITIES for V :
// ==============================
int NbVKnots = start->NbKnotsV();
NCollection_Array1<double> TempVKnot(1, NbVKnots);
NCollection_Array1<int> TempVMult(1, NbVKnots);
TempVMult.Init(1);
VIndex = TempVKnot.Lower();
// If several identical IGES knots are encountered, corresponding
// multiplicity is increased
// ==============================================================
TempVKnot.SetValue(VIndex, start->KnotV(-DegreeV));
for (i = 1 - DegreeV; i < NbVKnots - DegreeV; i++)
{
double VKnot1 = start->KnotV(i);
double VKnot2 = start->KnotV(i - 1);
if (std::abs(VKnot1 - VKnot2) <= Epsilon(VKnot2))
{
TempVMult.SetValue(VIndex, TempVMult.Value(VIndex) + 1);
}
else
{
TempVKnot.SetValue(++VIndex, VKnot1);
}
}
// Final knots & multiplicities arrays are dimensioned so as to be fully
// filled :
// =======================================================================
NCollection_Array1<double> VKnot(1, VIndex);
NCollection_Array1<int> VMult(1, VIndex);
int SumOfVMult = 0;
NCollection_Sequence<int> SeqIndexV;
int DelIndexV;
int OldSumOfVMult = 0;
for (i = 1; i <= VIndex; i++)
{ //: k5 abv 25 Dec 98: cycle modified
int aMult = TempVMult.Value(i);
int maxMult = (i == 1 || i == VIndex ? DegreeV + 1 : DegreeV);
if (aMult > maxMult)
{
Message_Msg msg1200("IGES_1200"); // #61 rln 05.01.99
msg1200.Arg("V");
msg1200.Arg("V");
msg1200.Arg("V");
SendWarning(start, msg1200);
// V Multiplicity > DegreeV (or Degree+1 at end); corrected
for (DelIndexV = OldSumOfVMult + 1; aMult > maxMult; DelIndexV++, aMult--)
{
newNbPolesV--;
SeqIndexV.Append(DelIndexV);
}
}
OldSumOfVMult += TempVMult.Value(i);
VKnot.SetValue(i, TempVKnot.Value(i));
VMult.SetValue(i, aMult);
SumOfVMult += aMult;
}
if (SumOfVMult != newNbPolesV + DegreeV + 1)
{
Message_Msg msg1210("IGES_1210");
msg1210.Arg("V");
msg1210.Arg("V");
SendWarning(start, msg1210);
// Sum of multiplicities following V is not equal to the sum : Count of poles + Degree V + 1
}
// Update of the poles array
NCollection_Array2<gp_Pnt> Poles(1, newNbPolesU, 1, newNbPolesV);
NCollection_Sequence<int> PoleUInd;
NCollection_Sequence<int> PoleVInd;
for (i = 1; i <= NbPolesU; i++)
{
PoleUInd.Append(i);
}
for (i = 1; i <= NbPolesV; i++)
{
PoleVInd.Append(i);
}
UIndex = Poles.LowerRow();
VIndex = Poles.LowerCol();
if ((newNbPolesU < NbPolesU) || (newNbPolesV < NbPolesV))
{
if (newNbPolesU < NbPolesU)
{
int Offset = 0;
for (int itab = 1; itab <= SeqIndexU.Length(); itab++)
{
DelIndexU = SeqIndexU.Value(itab) - Offset;
PoleUInd.Remove(DelIndexU);
Offset++;
}
}
if (newNbPolesV < NbPolesV)
{
int Offset = 0;
for (int itab = 1; itab <= SeqIndexV.Length(); itab++)
{
DelIndexV = SeqIndexV.Value(itab) - Offset;
PoleVInd.Remove(DelIndexV);
Offset++;
}
}
int nbUseq = PoleUInd.Length();
int nbVseq = PoleVInd.Length();
if ((nbUseq == newNbPolesU) && (nbVseq == newNbPolesV))
{
for (i = 1; i <= newNbPolesU; i++)
{
for (j = 1; j <= newNbPolesV; j++)
{
Poles.SetValue(UIndex, VIndex++, Pole.Value(PoleUInd.Value(i), PoleVInd.Value(j)));
}
UIndex++;
VIndex = Poles.LowerCol();
}
}
else
{
Message_Msg msg1175("IGES_1175");
SendWarning(start, msg1175);
}
}
else
{
for (i = 1; i <= newNbPolesU; i++)
{
for (j = 1; j <= newNbPolesV; j++)
{
Poles.SetValue(UIndex, VIndex++, Pole.Value(i, j));
}
UIndex++;
VIndex = Poles.LowerCol();
}
}
// Building result taking into account transformation if any :
// ===========================================================
if (!GetModeTransfer() && start->HasTransf())
{
gp_GTrsf GBSplTrsf(start->CompoundLocation());
gp_Trsf BSplTrsf;
if (IGESData_ToolLocation::ConvertLocation(GetEpsilon(), GBSplTrsf, BSplTrsf))
{
for (i = Poles.LowerRow(); i <= Poles.UpperRow(); i++)
{
for (j = Poles.LowerCol(); j <= Poles.UpperCol(); j++)
{
Poles.SetValue(i, j, Poles.Value(i, j).Transformed(BSplTrsf));
}
}
}
else
{
Message_Msg msg1035("IGES_1035");
SendWarning(start, msg1035);
}
}
// CREATION with the ARRAY of POLES WEIGHTS if any :
// =================================================
if (start->IsPolynomial())
{
// sln 29.12.2001 OCC90 : If surface can not be created do nothing
NCollection_Array2<double> Weight(1, 1, 1, 1);
if (!checkBSplineSurface(this, start, UKnot, VKnot, Weight))
{
return res;
}
res = new Geom_BSplineSurface(Poles, UKnot, VKnot, UMult, VMult, DegreeU, DegreeV);
}
else
{
NCollection_Array2<double> PoleWeight(1, NbPolesU, 1, NbPolesV);
bool polynomial = true;
double WeightReference = start->Weight(0, 0);
int WeightRow = PoleWeight.LowerRow();
int WeightCol = PoleWeight.LowerCol();
for (i = 0; i <= start->UpperIndexU(); i++)
{
for (j = 0; j <= start->UpperIndexV(); j++)
{
polynomial = (std::abs(start->Weight(i, j) - WeightReference) <= Epsilon(WeightReference))
&& polynomial;
//: 39 by abv 15.12.97
double weight = start->Weight(i, j);
if (weight < Precision::PConfusion())
{
Message_Msg msg1215("IGES_1215");
SendFail(start, msg1215); // Some weights are not positive.
return res;
}
PoleWeight.SetValue(WeightRow, WeightCol++, weight);
//: 39 PoleWeight.SetValue(WeightRow, WeightCol++, start->Weight(i,j));
}
WeightRow++;
WeightCol = PoleWeight.LowerCol();
}
if (polynomial)
{
Message_Msg msg1220("IGES_1220");
const char* const surface("surface");
msg1220.Arg(surface);
SendWarning(start, msg1220);
}
// Update of the Weight array during multiplicity correction
NCollection_Array2<double> Weight(1, newNbPolesU, 1, newNbPolesV);
UIndex = Weight.LowerRow();
VIndex = Weight.LowerCol();
if ((newNbPolesU < NbPolesU) || (newNbPolesV < NbPolesV))
{
// int indj = 1; //szv#4:S4163:12Mar99 unused
for (i = 1; i <= newNbPolesU; i++)
{
for (j = 1; j <= newNbPolesV; j++)
{
Weight.SetValue(UIndex, VIndex++, PoleWeight.Value(PoleUInd.Value(i), PoleVInd.Value(j)));
}
UIndex++;
VIndex = Poles.LowerCol();
}
}
else
{
for (i = 1; i <= newNbPolesU; i++)
{
for (j = 1; j <= newNbPolesV; j++)
{
Weight.SetValue(UIndex, VIndex++, PoleWeight.Value(i, j));
}
UIndex++;
VIndex = Poles.LowerCol();
}
}
// sln 29.12.2001 OCC90 : If surface can not be created do nothing
if (!checkBSplineSurface(this, start, UKnot, VKnot, Weight))
{
return res;
}
res = new Geom_BSplineSurface(Poles, Weight, UKnot, VKnot, UMult, VMult, DegreeU, DegreeV);
}
// Checking C2 and C1 continuity :
// ===============================
int icont = GetContinuity();
// bool isC1 = true, isC2 = true; //szv#4:S4163:12Mar99 not needed
i = res->LastUKnotIndex();
int FirstIndex = res->FirstUKnotIndex();
while (--i >= FirstIndex + 1)
{
if (icont >= 2)
{
if (!res->RemoveUKnot(i, DegreeU - 2, GetEpsGeom()))
{
// isC2 = false; //szv#4:S4163:12Mar99 not needed
res->RemoveUKnot(i, DegreeU - 1, GetEpsGeom()); // szv#4:S4163:12Mar99 `isC1=` not needed
}
else
{
res->RemoveUKnot(i, DegreeU - 1, GetEpsGeom()); // szv#4:S4163:12Mar99 `isC1=` not needed
}
}
}
i = res->LastVKnotIndex();
FirstIndex = res->FirstVKnotIndex();
while (--i >= FirstIndex + 1)
{
if (icont >= 2)
{
if (!res->RemoveVKnot(i, DegreeV - 2, GetEpsGeom()))
{
// isC2 = false; //szv#4:S4163:12Mar99 not needed
res->RemoveVKnot(i, DegreeV - 1, GetEpsGeom()); // szv#4:S4163:12Mar99 `isC1=` not needed
}
else
{
res->RemoveVKnot(i, DegreeV - 1, GetEpsGeom()); // szv#4:S4163:12Mar99 `isC1=` not needed
}
}
}
//: h7 abv 14 Jul 98: ims010.igs 2519: closed periodic surface should be forced
// else some wires which can lie over the seam will be incorrect
//: l1 abv 6 Jan 99: USA60022 243: force periodicity on any closed surface
bool isUPeriodic = (start->IsClosedU() && (start->IsPeriodicU() || res->IsUClosed()));
bool isVPeriodic = (start->IsClosedV() && (start->IsPeriodicV() || res->IsVClosed()));
//: k0 abv 16 Dec 98: use ShapeCustom
if (isUPeriodic || isVPeriodic)
{
occ::handle<Geom_BSplineSurface> periodicSurf =
occ::down_cast<Geom_BSplineSurface>(ShapeAlgo::AlgoContainer()->ConvertToPeriodic(res));
if (!periodicSurf.IsNull())
{ //: p6 abv 26 Feb 99: && periodicSurf != res ) {
// #75 rln 11.03.99: using message mechanism
Message_Msg msg1221("IGES_1221");
SendWarning(start, msg1221); // SendWarning(start,"Surface forced to be periodic");
res = periodicSurf;
}
}
return res;
}
//=================================================================================================
// szv#4:S4163:12Mar99 function never referenced
/*
static void DeletePoleRow
(const NCollection_Array2<gp_Pnt>& Poles,
const int Index,
NCollection_Array2<gp_Pnt>& NewPoles)
{
int Offset = 0;
int ColIndex;
int RowIndex = NewPoles.LowerRow();
while (RowIndex <= NewPoles.UpperRow()) {
ColIndex = NewPoles.LowerCol();
if (RowIndex == Index) Offset = 1;
while (ColIndex <= NewPoles.UpperCol()){
NewPoles (RowIndex, ColIndex) = Poles (RowIndex + Offset, ColIndex);
ColIndex++;
}
RowIndex++;
}
}
*/
//=================================================================================================
// szv#4:S4163:12Mar99 function never referenced
/*
static void DeletePoleCol
(const NCollection_Array2<gp_Pnt>& Poles,
const int Index,
NCollection_Array2<gp_Pnt>& NewPoles)
{
int Offset = 0;
int RowIndex;
int ColIndex = NewPoles.LowerCol();
while (ColIndex <= NewPoles.UpperCol()) {
RowIndex = NewPoles.LowerRow();
if (ColIndex == Index) Offset = 1;
while (RowIndex <= NewPoles.UpperRow()){
NewPoles (RowIndex, ColIndex) = Poles (RowIndex, ColIndex + Offset);
RowIndex++;
}
ColIndex++;
}
}
*/