// Copyright (c) 1995-1999 Matra Datavision // 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 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. // lpa, le 11/09/91 // Approximation d un ensemble de points contraints (MultiLine) avec une // solution approchee (MultiCurve). L algorithme utilise est l algorithme // d Uzawa du package mathematique. #define No_Standard_RangeError #define No_Standard_OutOfRange #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include AppParCurves_ResolConstraint:: AppParCurves_ResolConstraint(const MultiLine& SSP, AppParCurves_MultiCurve& SCurv, const Standard_Integer FirstPoint, const Standard_Integer LastPoint, const Handle(AppParCurves_HArray1OfConstraintCouple)& TheConstraints, const math_Matrix& Bern, const math_Matrix& DerivativeBern, const Standard_Real Tolerance): Cont(1, NbConstraints(SSP, FirstPoint, LastPoint, TheConstraints), 1, NbColumns(SSP, SCurv.NbPoles()-1), 0.0), DeCont(1, NbConstraints(SSP, FirstPoint, LastPoint, TheConstraints), 1, NbColumns(SSP, SCurv.NbPoles()-1), 0.0), Secont(1, NbConstraints(SSP, FirstPoint, LastPoint, TheConstraints), 0.0), CTCinv(1, NbConstraints(SSP, FirstPoint, LastPoint, TheConstraints), 1, NbConstraints(SSP, FirstPoint, LastPoint, TheConstraints)), Vardua(1, NbConstraints(SSP, FirstPoint, LastPoint, TheConstraints)), IPas(1, LastPoint-FirstPoint+1), ITan(1, LastPoint-FirstPoint+1), ICurv(1, LastPoint-FirstPoint+1) { Standard_Integer i, j, k, NbCu= SCurv.NbCurves(); Standard_Integer Npt; Standard_Integer Inc3, IncSec, IncCol, IP = 0, CCol; Standard_Integer myindex, Def = SCurv.NbPoles()-1; Standard_Integer nb3d, nb2d, Npol= Def+1, Npol2 = 2*Npol; Standard_Real T1 = 0., T2 = 0., T3, Tmax, Daij; Standard_Boolean Ok; gp_Vec V; gp_Vec2d V2d; gp_Pnt Poi; gp_Pnt2d Poi2d; AppParCurves_ConstraintCouple mycouple; AppParCurves_Constraint FC = AppParCurves_NoConstraint, LC = AppParCurves_NoConstraint, Cons; // Boucle de calcul du nombre de points de passage afin de dimensionner // les matrices. IncPass = 0; IncTan = 0; IncCurv = 0; for (i = TheConstraints->Lower(); i <= TheConstraints->Upper(); i++) { mycouple = TheConstraints->Value(i); myindex = mycouple.Index(); Cons = mycouple.Constraint(); if (myindex == FirstPoint) FC = Cons; if (myindex == LastPoint) LC = Cons; if (Cons >= 1) { IncPass++; // IncPass = nbre de points de passage. IPas(IncPass) = myindex; } if (Cons >= 2) { IncTan++; // IncTan= nbre de points de tangence. ITan(IncTan) = myindex; } if (Cons == 3) { IncCurv++; // IncCurv = nbre de pts de courbure. ICurv(IncCurv) = myindex; } } if (IncPass == 0) { Done = Standard_True; return; } nb3d = ToolLine::NbP3d(SSP); nb2d = ToolLine::NbP2d(SSP); Standard_Integer mynb3d=nb3d, mynb2d=nb2d; if (nb3d == 0) mynb3d = 1; if (nb2d == 0) mynb2d = 1; CCol = nb3d* 3 + nb2d* 2; // Declaration et initialisation des matrices et vecteurs de contraintes: math_Matrix ContInit(1, IncPass, 1, Npol); math_Vector Start(1, CCol*Npol); TColStd_Array2OfInteger Ibont(1, NbCu, 1, IncTan); // Remplissage de Cont pour les points de passage: // ================================================= for (i =1; i <= IncPass; i++) { // Cette partie ne depend que de Bernstein Npt = IPas(i); for (j = 1; j <= Npol; j++) { ContInit(i, j) = Bern(Npt, j); } } for (i = 1; i <= CCol; i++) { Cont.Set(IncPass*(i-1)+1, IncPass*i, Npol*(i-1)+1, Npol*i, ContInit); } // recuperation des vecteurs de depart pour Uzawa. Ce vecteur represente les // poles de SCurv. // Remplissage de secont et resolution. TColgp_Array1OfVec tabV(1, mynb3d); TColgp_Array1OfVec2d tabV2d(1, mynb2d); TColgp_Array1OfPnt tabP(1, mynb3d); TColgp_Array1OfPnt2d tabP2d(1, mynb2d); Inc3 = CCol*IncPass +1; IncCol = 0; IncSec = 0; for (k = 1; k <= NbCu; k++) { if (k <= nb3d) { for (i = 1; i <= IncTan; i++) { Npt = ITan(i); // choix du maximum de tangence pour exprimer la colinearite: ToolLine::Tangency(SSP, Npt, tabV); V = tabV(k); V.Coord(T1, T2, T3); Tmax = Abs(T1); Ibont(k, i) = 1; if (Abs(T2) > Tmax) { Tmax = Abs(T2); Ibont(k, i) = 2; } if (Abs(T3) > Tmax) { Tmax = Abs(T3); Ibont(k, i) = 3; } if (Ibont(k, i) == 3) { for (j = 1; j <= Npol; j++) { Daij = DerivativeBern(Npt, j); Cont(Inc3, j+ Npol + IncCol) = Daij*T3/Tmax; Cont(Inc3, j + Npol2 + IncCol) = -Daij *T2/Tmax; Cont(Inc3+1, j+ IncCol) = Daij* T3/Tmax; Cont(Inc3+1, j+ Npol2 + IncCol) = -Daij*T1/Tmax; } } else if (Ibont(k, i) == 1) { for (j = 1; j <= Npol; j++) { Daij = DerivativeBern(Npt, j); Cont(Inc3, j + IncCol) = Daij*T3/Tmax; Cont(Inc3, j + Npol2 + IncCol) = -Daij *T1/Tmax; Cont(Inc3+1, j+ IncCol) = Daij* T2/Tmax; Cont(Inc3+1, j+ Npol +IncCol) = -Daij*T1/Tmax; } } else if (Ibont(k, i) == 2) { for (j = 1; j <= Def+1; j++) { Daij = DerivativeBern(Npt, j); Cont(Inc3, j+ Npol + IncCol) = Daij*T3/Tmax; Cont(Inc3, j + Npol2 + IncCol) = -Daij *T2/Tmax; Cont(Inc3+1, j+ IncCol) = Daij* T2/Tmax; Cont(Inc3+1, j+ Npol + IncCol) = -Daij*T1/Tmax; } } Inc3 = Inc3 + 2; } // Remplissage du second membre: for (i = 1; i <= IncPass; i++) { ToolLine::Value(SSP, IPas(i), tabP); Poi = tabP(k); Secont(i + IncSec) = Poi.X(); Secont(i + IncPass + IncSec) = Poi.Y(); Secont(i + 2*IncPass + IncSec) = Poi.Z(); } IncSec = IncSec + 3*IncPass; // Vecteur de depart: for (j =1; j <= Npol; j++) { Poi = SCurv.Value(j).Point(k); Start(j + IncCol) = Poi.X(); Start(j+ Npol + IncCol) = Poi.Y(); Start(j + Npol2 + IncCol) = Poi.Z(); } IncCol = IncCol + 3*Npol; } else { for (i = 1; i <= IncTan; i++) { Npt = ITan(i); ToolLine::Tangency(SSP, Npt, tabV2d); V2d = tabV2d(k-nb3d); T1 = V2d.X(); T2 = V2d.Y(); Tmax = Abs(T1); Ibont(k, i) = 1; if (Abs(T2) > Tmax) { Tmax = Abs(T2); Ibont(k, i) = 2; } for (j = 1; j <= Npol; j++) { Daij = DerivativeBern(Npt, j); Cont(Inc3, j + IncCol) = Daij*T2; Cont(Inc3, j + Npol + IncCol) = -Daij*T1; } Inc3 = Inc3 +1; } // Remplissage du second membre: for (i = 1; i <= IncPass; i++) { ToolLine::Value(SSP, IPas(i), tabP2d); Poi2d = tabP2d(i-nb3d); Secont(i + IncSec) = Poi2d.X(); Secont(i + IncPass + IncSec) = Poi2d.Y(); } IncSec = IncSec + 2*IncPass; // Remplissage du vecteur de depart: for (j = 1; j <= Npol; j++) { Poi2d = SCurv.Value(j).Point2d(k); Start(j + IncCol) = Poi2d.X(); Start(j + Npol + IncCol) = Poi2d.Y(); } IncCol = IncCol + Npol2; } } // Equations exprimant le meme rapport de tangence sur chaque courbe: // On prend les coordonnees les plus significatives. --Inc3; for (i = 1; i <= IncTan; ++i) { IncCol = 0; Npt = ITan(i); for (k = 1; k <= NbCu-1; ++k) { ++Inc3; // Initialize first relation variable (T1) Standard_Integer addIndex_1 = 0, aVal = Ibont(k, i); switch (aVal) { case 1: //T1 ~ T1x { if (k <= nb3d) { Ok = ToolLine::Tangency(SSP, Npt, tabV); V = tabV(k); T1 = V.X(); IP = 3 * Npol; } else { Ok = ToolLine::Tangency(SSP, Npt, tabV2d); V2d = tabV2d(k-nb3d); T1 = V2d.X(); IP = 2 * Npol; } addIndex_1 = 0; break; } case 2: //T1 ~ T1y { if (k <= nb3d) { Ok = ToolLine::Tangency(SSP, Npt, tabV); V = tabV(k); IP = 3 * Npol; } else { Ok = ToolLine::Tangency(SSP, Npt, tabV2d); V2d = tabV2d(k-nb3d); T1 = V2d.Y(); IP = 2 * Npol; } addIndex_1 = Npol; break; } case 3: //T1 ~ T1z { Ok = ToolLine::Tangency(SSP, Npt, tabV); V = tabV(k); T1 = V.Z(); IP = 3 * Npol; addIndex_1 = 2 * Npol; break; } } // Initialize second relation variable (T2) Standard_Integer addIndex_2 = 0, aNextVal = Ibont(k + 1, i); switch (aNextVal) { case 1: //T2 ~ T2x { if ((k+1) <= nb3d) { Ok = ToolLine::Tangency(SSP, Npt, tabV); V = tabV(k+1); T2 = V.X(); } else { Ok = ToolLine::Tangency(SSP, Npt, tabV2d); V2d = tabV2d(k+1-nb3d); T2 = V2d.X(); } addIndex_2 = 0; break; } case 2: //T2 ~ T2y { if ((k+1) <= nb3d) { Ok = ToolLine::Tangency(SSP, Npt, tabV); V = tabV(k+1); T2 = V.Y(); } else { Ok = ToolLine::Tangency(SSP, Npt, tabV2d); V2d = tabV2d(k+1-nb3d); T2 = V2d.Y(); } addIndex_2 = Npol; break; } case 3: //T2 ~ T2z { Ok = ToolLine::Tangency(SSP, Npt, tabV); V = tabV(k+1); T2 = V.Z(); addIndex_2 = 2 * Npol; break; } } // Relations between T1 and T2: for (j = 1; j <= Npol; j++) { Daij = DerivativeBern(Npt, j); Cont(Inc3, j + IncCol + addIndex_1) = Daij*T2; Cont(Inc3, j + IP + IncCol + addIndex_2) = -Daij*T1; } IncCol += IP; } } // Equations concernant la courbure: /* Inc3 = Inc3 +1; IncCol = 0; for (k = 1; k <= NbCu; k++) { for (i = 1; i <= IncCurv; i++) { Npt = ICurv(i); AppDef_MultiPointConstraint MP = SSP.Value(Npt); DDA = SecondDerivativeBern(Parameters(Npt)); if (SSP.Value(1).Dimension(k) == 3) { C1 = MP.Curv(k).X(); C2 = MP.Curv(k).Y(); C3 = MP.Curv(k).Z(); for (j = 1; j <= Npol; j++) { Daij = DerivativeBern(Npt, j); D2Aij = DDA(j); Cont(Inc3, j + IncCol) = D2Aij; Cont(Inc3, j + Npol2 + IncCol) = -C2*Daij; Cont(Inc3, j + Npol + IncCol) = C3*Daij; Cont(Inc3+1, j + Npol + IncCol) = D2Aij; Cont(Inc3+1, j +IncCol) = -C3*Daij; Cont(Inc3+1, j + Npol2 + IncCol) = C1*Daij; Cont(Inc3+2, j + Npol2+IncCol) = D2Aij; Cont(Inc3+2, j + Npol+IncCol) = -C1*Daij; Cont(Inc3+2, j + IncCol) = C2*Daij; } Inc3 = Inc3 + 3; } else { // Dimension 2: C1 = MP.Curv2d(k).X(); C2 = MP.Curv2d(k).Y(); for (j = 1; j <= Npol; j++) { Daij = DerivativeBern(Npt, j); D2Aij = DDA(j); Cont(Inc3, j + IncCol) = D2Aij*C1; Cont(Inc3+1, j + Npol + IncCol) = D2Aij*C2; } Inc3 = Inc3 + 2; } } } */ // Resolution par Uzawa: math_Uzawa UzaResol(Cont, Secont, Start, Tolerance); if (!(UzaResol.IsDone())) { Done = Standard_False; return; } CTCinv = UzaResol.InverseCont(); UzaResol.Duale(Vardua); for (i = 1; i <= CTCinv.RowNumber(); i++) { for (j = i; j <= CTCinv.RowNumber(); j++) { CTCinv(i, j) = CTCinv(j, i); } } Done = Standard_True; math_Vector VecPoles (1, CCol*Npol); VecPoles = UzaResol.Value(); Standard_Integer polinit = 1, polfin=Npol; if (FC >= 1) polinit = 2; if (LC >= 1) polfin = Npol-1; for (i = polinit; i <= polfin; i++) { IncCol = 0; AppParCurves_MultiPoint MPol(nb3d, nb2d); for (k = 1; k <= NbCu; k++) { if (k <= nb3d) { gp_Pnt Pol(VecPoles(IncCol + i), VecPoles(IncCol + Npol +i), VecPoles(IncCol + 2*Npol + i)); MPol.SetPoint(k, Pol); IncCol = IncCol + 3*Npol; } else { gp_Pnt2d Pol2d(VecPoles(IncCol + i), VecPoles(IncCol + Npol + i)); MPol.SetPoint2d(k, Pol2d); IncCol = IncCol + 2*Npol; } } SCurv.SetValue(i, MPol); } } Standard_Boolean AppParCurves_ResolConstraint::IsDone () const { return Done; } Standard_Integer AppParCurves_ResolConstraint:: NbConstraints(const MultiLine& SSP, const Standard_Integer, const Standard_Integer, const Handle(AppParCurves_HArray1OfConstraintCouple)& TheConstraints) const { // Boucle de calcul du nombre de points de passage afin de dimensionner // les matrices. Standard_Integer aIncPass, aIncTan, aIncCurv, aCCol; Standard_Integer i; AppParCurves_Constraint Cons; aIncPass = 0; aIncTan = 0; aIncCurv = 0; for (i = TheConstraints->Lower(); i <= TheConstraints->Upper(); i++) { Cons = (TheConstraints->Value(i)).Constraint(); if (Cons >= 1) { aIncPass++; // IncPass = nbre de points de passage. } if (Cons >= 2) { aIncTan++; // IncTan= nbre de points de tangence. } if (Cons == 3) { aIncCurv++; // IncCurv = nbre de pts de courbure. } } Standard_Integer nb3d = ToolLine::NbP3d(SSP); Standard_Integer nb2d = ToolLine::NbP2d(SSP); aCCol = nb3d* 3 + nb2d* 2; return aCCol*aIncPass + aIncTan*(aCCol-1) + 3*aIncCurv; } Standard_Integer AppParCurves_ResolConstraint::NbColumns(const MultiLine& SSP, const Standard_Integer Deg) const { Standard_Integer nb3d = ToolLine::NbP3d(SSP); Standard_Integer nb2d = ToolLine::NbP2d(SSP); Standard_Integer CCol = nb3d* 3 + nb2d* 2; return CCol*(Deg+1); } const math_Matrix& AppParCurves_ResolConstraint::ConstraintMatrix() const { return Cont; } const math_Matrix& AppParCurves_ResolConstraint::InverseMatrix() const { return CTCinv; } const math_Vector& AppParCurves_ResolConstraint::Duale() const { return Vardua; } const math_Matrix& AppParCurves_ResolConstraint:: ConstraintDerivative(const MultiLine& SSP, const math_Vector& Parameters, const Standard_Integer Deg, const math_Matrix& DA) { Standard_Integer i, j, k, nb2d, nb3d, CCol, Inc3, IncCol, Npt; Standard_Integer Npol, Npol2, NbCu =ToolLine::NbP3d(SSP)+ToolLine::NbP2d(SSP); Standard_Integer IP; Standard_Real Daij; Npol = Deg+1; Npol2 = 2*Npol; Standard_Boolean Ok; TColStd_Array2OfInteger Ibont(1, NbCu, 1, IncTan); math_Matrix DeCInit(1, IncPass, 1, Npol); math_Vector DDA(1, Npol); gp_Vec V; gp_Vec2d V2d; Standard_Real T1, T2, T3, Tmax, DDaij; // Standard_Integer FirstP = IPas(1); nb3d = ToolLine::NbP3d(SSP); nb2d = ToolLine::NbP2d(SSP); Standard_Integer mynb3d = nb3d, mynb2d = nb2d; if (nb3d == 0) mynb3d = 1; if (nb2d == 0) mynb2d = 1; CCol = nb3d* 3 + nb2d* 2; TColgp_Array1OfVec tabV(1, mynb3d); TColgp_Array1OfVec2d tabV2d(1, mynb2d); TColgp_Array1OfPnt tabP(1, mynb3d); TColgp_Array1OfPnt2d tabP2d(1, mynb2d); for (i = 1; i <= DeCont.RowNumber(); i++) for (j = 1; j <= DeCont.ColNumber(); j++) DeCont(i, j) = 0.0; // Remplissage de DK pour les points de passages: for (i =1; i <= IncPass; i++) { Npt = IPas(i); for (j = 1; j <= Npol; j++) DeCInit(i, j) = DA(Npt, j); } for (i = 1; i <= CCol; i++) { DeCont.Set(IncPass*(i-1)+1, IncPass*i, Npol*(i-1)+1, Npol*i, DeCInit); } // Pour les points de tangence: Inc3 = CCol*IncPass +1; IncCol = 0; for (k = 1; k <= NbCu; k++) { if (k <= nb3d) { for (i = 1; i <= IncTan; i++) { Npt = ITan(i); // MultiPoint MPoint = ToolLine::Value(SSP, Npt); // choix du maximum de tangence pour exprimer la colinearite: Ok = ToolLine::Tangency(SSP, Npt, tabV); V = tabV(k); V.Coord(T1, T2, T3); Tmax = Abs(T1); Ibont(k, i) = 1; if (Abs(T2) > Tmax) { Tmax = Abs(T2); Ibont(k, i) = 2; } if (Abs(T3) > Tmax) { Tmax = Abs(T3); Ibont(k, i) = 3; } AppParCurves::SecondDerivativeBernstein(Parameters(Npt), DDA); if (Ibont(k, i) == 3) { for (j = 1; j <= Npol; j++) { DDaij = DDA(j); DeCont(Inc3, j+ Npol + IncCol) = DDaij*T3/Tmax; DeCont(Inc3, j + Npol2 + IncCol) = -DDaij *T2/Tmax; DeCont(Inc3+1, j+ IncCol) = DDaij* T3/Tmax; DeCont(Inc3+1, j+ Npol2 + IncCol) = -DDaij*T1/Tmax; } } else if (Ibont(k, i) == 1) { for (j = 1; j <= Npol; j++) { DDaij = DDA(j); DeCont(Inc3, j + IncCol) = DDaij*T3/Tmax; DeCont(Inc3, j + Npol2 + IncCol) = -DDaij *T1/Tmax; DeCont(Inc3+1, j+ IncCol) = DDaij* T2/Tmax; DeCont(Inc3+1, j+ Npol +IncCol) = -DDaij*T1/Tmax; } } else if (Ibont(k, i) == 2) { for (j = 1; j <= Npol; j++) { DDaij = DDA(j); DeCont(Inc3, j+ Npol + IncCol) = DDaij*T3/Tmax; DeCont(Inc3, j + Npol2 + IncCol) = -DDaij *T2/Tmax; DeCont(Inc3+1, j+ IncCol) = DDaij* T2/Tmax; DeCont(Inc3+1, j+ Npol + IncCol) = -DDaij*T1/Tmax; } } Inc3 = Inc3 + 2; } IncCol = IncCol + 3*Npol; } else { for (i = 1; i <= IncTan; i++) { Npt = ITan(i); AppParCurves::SecondDerivativeBernstein(Parameters(Npt), DDA); Ok = ToolLine::Tangency(SSP, Npt, tabV2d); V2d = tabV2d(k); V2d.Coord(T1, T2); Tmax = Abs(T1); Ibont(k, i) = 1; if (Abs(T2) > Tmax) { Tmax = Abs(T2); Ibont(k, i) = 2; } for (j = 1; j <= Npol; j++) { DDaij = DDA(j); DeCont(Inc3, j + IncCol) = DDaij*T2; DeCont(Inc3, j + Npol + IncCol) = -DDaij*T1; } Inc3 = Inc3 +1; } } } // Equations exprimant le meme rapport de tangence sur chaque courbe: // On prend les coordonnees les plus significatives. Inc3 = Inc3 -1; for (i =1; i <= IncTan; i++) { IncCol = 0; Npt = ITan(i); AppParCurves::SecondDerivativeBernstein(Parameters(Npt), DDA); // MultiPoint MP = ToolLine::Value(SSP, Npt); for (k = 1; k <= NbCu-1; k++) { Inc3 = Inc3 + 1; if (Ibont(k, i) == 1) { if (k <= nb3d) { Ok = ToolLine::Tangency(SSP, Npt, tabV); V = tabV(k); T1 = V.X(); IP = 3*Npol; } else { Ok = ToolLine::Tangency(SSP, Npt, tabV2d); V2d = tabV2d(k); T1 = V2d.X(); IP = 2*Npol; } if (Ibont(k+1, i) == 1) { // Relations entre T1x et T2x: if ((k+1) <= nb3d) { Ok = ToolLine::Tangency(SSP, Npt, tabV); V = tabV(k+1); T2 = V.X(); } else { Ok = ToolLine::Tangency(SSP, Npt, tabV2d); V2d = tabV2d(k+1); T2 = V2d.X(); } for (j = 1; j <= Npol; j++) { Daij = DDA(j); Cont(Inc3, j + IncCol) = Daij*T2; Cont(Inc3, j + IP + IncCol) = -Daij*T1; } IncCol = IncCol + IP; } else if (Ibont(k+1, i) == 2) { // Relations entre T1x et T2y: if ((k+1) <= nb3d) { Ok = ToolLine::Tangency(SSP, Npt, tabV); V = tabV(k+1); T2 = V.Y(); } else { Ok = ToolLine::Tangency(SSP, Npt, tabV2d); V2d = tabV2d(k+1); T2 = V2d.Y(); } for (j = 1; j <= Npol; j++) { Daij = DDA(j); Cont(Inc3, j + IncCol) = Daij*T2; Cont(Inc3, j + IP + Npol + IncCol) = -Daij*T1; } IncCol = IncCol + IP; } else if (Ibont(k+1,i) == 3) { // Relations entre T1x et T2z: ToolLine::Tangency(SSP, Npt, tabV); V = tabV(k+1); T2 = V.Z(); for (j = 1; j <= Npol; j++) { Daij = DDA(j); Cont(Inc3, j + IncCol) = Daij*T2; Cont(Inc3, j + IP + 2*Npol + IncCol) = -Daij*T1; } IncCol = IncCol + IP; } } else if (Ibont(k,i) == 2) { if (k <= nb3d) { Ok = ToolLine::Tangency(SSP, Npt, tabV); V = tabV(k); T1 = V.Y(); IP = 3*Npol; } else { Ok = ToolLine::Tangency(SSP, Npt, tabV2d); V2d = tabV2d(k); T1 = V2d.Y(); IP = 2*Npol; } if (Ibont(k+1, i) == 1) { // Relations entre T1y et T2x: if ((k+1) <= nb3d) { Ok = ToolLine::Tangency(SSP, Npt, tabV); V = tabV(k+1); T2 = V.X(); } else { Ok = ToolLine::Tangency(SSP, Npt, tabV2d); V2d = tabV2d(k+1); T2 = V2d.X(); } for (j = 1; j <= Npol; j++) { Daij = DDA( j); Cont(Inc3, j + Npol + IncCol) = Daij*T2; Cont(Inc3, j + IP + IncCol) = -Daij*T1; } IncCol = IncCol + IP; } else if (Ibont(k+1, i) == 2) { // Relations entre T1y et T2y: if ((k+1) <= nb3d) { Ok = ToolLine::Tangency(SSP, Npt, tabV); V = tabV(k+1); T2 = V.Y(); } else { Ok = ToolLine::Tangency(SSP, Npt, tabV2d); V2d = tabV2d(k+1); T2 = V2d.Y(); } for (j = 1; j <= Npol; j++) { Daij = DDA(j); Cont(Inc3, j + Npol + IncCol) = Daij*T2; Cont(Inc3, j + IP + Npol + IncCol) = -Daij*T1; } IncCol = IncCol + IP; } else if (Ibont(k+1,i)== 3) { // Relations entre T1y et T2z: ToolLine::Tangency(SSP, Npt, tabV); V = tabV(k+1); T2 = V.Z(); for (j = 1; j <= Npol; j++) { Daij = DDA(j); Cont(Inc3, j + Npol +IncCol) = Daij*T2; Cont(Inc3, j + IP + 2*Npol + IncCol) = -Daij*T1; } IncCol = IncCol + IP; } } else { Ok = ToolLine::Tangency(SSP, Npt, tabV); V = tabV(k); T1 = V.Z(); IP = 3*Npol; if (Ibont(k+1, i) == 1) { // Relations entre T1z et T2x: if ((k+1) <= nb3d) { Ok = ToolLine::Tangency(SSP, Npt, tabV); V = tabV(k+1); T2 = V.X(); } else { Ok = ToolLine::Tangency(SSP, Npt, tabV2d); V2d = tabV2d(k+1); T2 = V2d.X(); } for (j = 1; j <= Npol; j++) { Daij = DDA(j); Cont(Inc3, j + 2*Npol +IncCol) = Daij*T2; Cont(Inc3, j + IP + IncCol) = -Daij*T1; } IncCol = IncCol + IP; } else if (Ibont(k+1, i) == 2) { // Relations entre T1z et T2y: if ((k+1) <= nb3d) { Ok = ToolLine::Tangency(SSP, Npt, tabV); V = tabV(k+1); T2 = V.Y(); } else { Ok = ToolLine::Tangency(SSP, Npt, tabV2d); V2d = tabV2d(k+1); T2 = V2d.Y(); } for (j = 1; j <= Npol; j++) { Daij = DDA(j); Cont(Inc3, j + 2*Npol +IncCol) = Daij*T2; Cont(Inc3, j + IP + Npol + IncCol) = -Daij*T1; } IncCol = IncCol + IP; } else if (Ibont(k+1,i)==3) { // Relations entre T1z et T2z: ToolLine::Tangency(SSP, Npt, tabV); V = tabV(k+1); T2 = V.Z(); for (j = 1; j <= Npol; j++) { Daij = DDA(j); Cont(Inc3, j + 2*Npol + IncCol) = Daij*T2; Cont(Inc3, j + IP + 2*Npol + IncCol) = -Daij*T1; } IncCol = IncCol + IP; } } } } return DeCont; }