0022627: Change OCCT memory management defaults
[occt.git] / src / GeomConvert / GeomConvert_CompCurveToBSplineCurve.cxx
CommitLineData
7fd59977 1// File: GeomConvert_CompCurveToBSplineCurve.cxx
2// Created: Mon Sep 23 15:03:12 1996
3// Author: Philippe MANGIN
4// <pmn@sgi29>
5// Modified: Fri Jul 10 11:23:35 1998
6// JCT : Add WithRatio,MinM
7
8
9#include <GeomConvert_CompCurveToBSplineCurve.ixx>
10
11#include <Geom_BSplineCurve.hxx>
12#include <GeomConvert.hxx>
13
14#include <TColStd_Array1OfReal.hxx>
15#include <TColStd_Array1OfInteger.hxx>
16
17#include <TColgp_Array1OfPnt.hxx>
18#include <gp_Vec.hxx>
19#include <gp_Pnt.hxx>
20#include <Precision.hxx>
21
22
23
24GeomConvert_CompCurveToBSplineCurve::
25GeomConvert_CompCurveToBSplineCurve(const Handle(Geom_BoundedCurve)& BasisCurve,
26 const Convert_ParameterisationType Parameterisation) :
27 myTol(Precision::Confusion()),
28 myType(Parameterisation)
29{
30 Handle(Geom_BSplineCurve) Bs =
31 Handle(Geom_BSplineCurve)::DownCast(BasisCurve);
32 if (!Bs.IsNull()) {
33 myCurve = Handle(Geom_BSplineCurve)::DownCast(BasisCurve->Copy());
34 }
35 else {
36 myCurve = GeomConvert::CurveToBSplineCurve (BasisCurve, myType);
37 }
38}
39
40//=======================================================================
41//function : Add
42//purpose :
43//=======================================================================
44
45Standard_Boolean GeomConvert_CompCurveToBSplineCurve::
46Add(const Handle(Geom_BoundedCurve)& NewCurve,
47 const Standard_Real Tolerance,
48 const Standard_Boolean After,
49 const Standard_Boolean WithRatio,
50 const Standard_Integer MinM)
51{
52 Standard_Boolean avant, apres;
53 myTol = Tolerance;
54 // Convertion
55 Handle(Geom_BSplineCurve) Bs =
56 Handle(Geom_BSplineCurve)::DownCast(NewCurve);
57 if (!Bs.IsNull() ) {
58 Bs = Handle(Geom_BSplineCurve)::DownCast(NewCurve->Copy());
59 }
60 else {
61 Bs = GeomConvert::CurveToBSplineCurve (NewCurve, myType);
62 }
63
64 Standard_Integer LBs = Bs->NbPoles(), LCb = myCurve->NbPoles();
65
66 avant = (( myCurve->Pole(1).Distance(Bs->Pole(1)) < myTol)||
67 ( myCurve->Pole(1).Distance(Bs->Pole(LBs))< myTol));
68 apres = (( myCurve->Pole(LCb).Distance(Bs->Pole(1)) < myTol) ||
69 ( myCurve->Pole(LCb).Distance(Bs->Pole(LBs))< myTol));
70
71 // myCurve est (sera) elle fermee ?
72 if (avant && apres) { // On leve l'ambiguite
73 if (After) avant = Standard_False;
74 else apres = Standard_False;
75 }
76
77 // Ajout Apres ?
78 if ( apres) {
79 if (myCurve->Pole(LCb).Distance(Bs->Pole(LBs)) < myTol) {Bs->Reverse();}
80 Add(myCurve, Bs, Standard_True, WithRatio, MinM);
81 return Standard_True;
82 }
83 // Ajout avant ?
84 else if (avant) {
85 if (myCurve->Pole(1).Distance(Bs->Pole(1)) < myTol) {Bs->Reverse();}
86 Add(Bs, myCurve, Standard_False, WithRatio, MinM);
87 return Standard_True;
88 }
89
90 return Standard_False;
91}
92
93void GeomConvert_CompCurveToBSplineCurve::Add(
94 Handle(Geom_BSplineCurve)& FirstCurve,
95 Handle(Geom_BSplineCurve)& SecondCurve,
96 const Standard_Boolean After,
97 const Standard_Boolean WithRatio,
98 const Standard_Integer MinM)
99{
100// Harmonisation des degres.
101 Standard_Integer Deg = Max(FirstCurve->Degree(), SecondCurve->Degree());
102 if (FirstCurve->Degree() < Deg) { FirstCurve->IncreaseDegree(Deg); }
103 if (SecondCurve->Degree() < Deg) { SecondCurve->IncreaseDegree(Deg); }
104
105// Declarationd
106 Standard_Real L1, L2, U_de_raccord;
107 Standard_Integer ii, jj;
108 Standard_Real Ratio=1, Ratio1, Ratio2, Delta1, Delta2;
109 Standard_Integer NbP1 = FirstCurve->NbPoles(), NbP2 = SecondCurve->NbPoles();
110 Standard_Integer NbK1 = FirstCurve->NbKnots(), NbK2 = SecondCurve->NbKnots();
111 TColStd_Array1OfReal Noeuds (1, NbK1+NbK2-1);
112 TColgp_Array1OfPnt Poles (1, NbP1+ NbP2-1);
113 TColStd_Array1OfReal Poids (1, NbP1+ NbP2-1);
114 TColStd_Array1OfInteger Mults (1, NbK1+NbK2-1);
115
116 // Ratio de reparametrisation (C1 si possible)
117 if (WithRatio) {
118 L1 = FirstCurve->DN(FirstCurve->LastParameter(), 1).Magnitude();
119 L2 = SecondCurve->DN(SecondCurve->FirstParameter(), 1). Magnitude();
120
121 if ( (L1 > Precision::Confusion()) && (L2 > Precision::Confusion()) ) {
122 Ratio = L1 / L2;
123 }
124 if ( (Ratio < Precision::Confusion()) || (Ratio > 1/Precision::Confusion()) ) {Ratio = 1;}
125 }
126
127 if (After) {
128// On ne bouge pas la premiere courbe
129 Ratio1 = 1;
130 Delta1 = 0;
131 Ratio2 = 1/Ratio;
132 Delta2 = Ratio2*SecondCurve->Knot(1) - FirstCurve->Knot(NbK1);
133 U_de_raccord = FirstCurve->LastParameter();
134 }
135 else {
136// On ne bouge pas la seconde courbe
137 Ratio1 = Ratio;
138 Delta1 = Ratio1*FirstCurve->Knot(NbK1) - SecondCurve->Knot(1);
139 Ratio2 = 1;
140 Delta2 = 0;
141 U_de_raccord = SecondCurve->FirstParameter();
142 }
143
144// Les Noeuds
145 Standard_Real eps;
146 for (ii=1; ii<NbK1; ii++) {
147 Noeuds(ii) = Ratio1*FirstCurve->Knot(ii) - Delta1;
148 if(ii > 1) {
149 eps = Epsilon (Abs(Noeuds(ii-1)));
150 if( eps < 5.e-10 ) eps = 5.e-10;
151 if(Noeuds(ii) - Noeuds(ii-1) <= eps) {
152 Noeuds(ii) += eps;
153 }
154 }
155 Mults(ii) = FirstCurve->Multiplicity(ii);
156 }
157 Noeuds(NbK1) = U_de_raccord;
158 eps = Epsilon (Abs(Noeuds(NbK1-1)));
159 if(Noeuds(NbK1) - Noeuds(NbK1-1) <= eps) {
160 Noeuds(NbK1) += eps;
161 }
162 Mults(NbK1) = FirstCurve->Degree();
163 for (ii=2, jj=NbK1+1; ii<=NbK2; ii++, jj++) {
164 Noeuds(jj) = Ratio2*SecondCurve->Knot(ii) - Delta2;
165 eps = Epsilon (Abs(Noeuds(jj-1)));
166 if( eps < 5.e-10 ) eps = 5.e-10;
167 if(Noeuds(jj) - Noeuds(jj-1) <= eps) {
168 Noeuds(jj) += eps;
169 }
170 Mults(jj) = SecondCurve->Multiplicity(ii);
171 }
172
173 Ratio = FirstCurve->Weight(NbP1) ;
174 Ratio /= SecondCurve->Weight(1) ;
175// Les Poles et Poids
176 for (ii=1; ii<NbP1; ii++) {
177 Poles(ii) = FirstCurve->Pole(ii);
178 Poids(ii) = FirstCurve->Weight(ii);
179 }
180 for (ii=1, jj=NbP1; ii<=NbP2; ii++, jj++) {
181 Poles(jj) = SecondCurve->Pole(ii);
182//
183// attentiion les poids ne se raccord pas forcement C0
184// d'ou Ratio
185//
186 Poids(jj) = Ratio * SecondCurve->Weight(ii);
187 }
188
189// Creation de la BSpline
190 myCurve = new (Geom_BSplineCurve) (Poles, Poids, Noeuds, Mults, Deg);
191
192// Reduction eventuelle de la multiplicite jusqu'a MinM
193 Standard_Boolean Ok = Standard_True;
194 Standard_Integer M = Mults(NbK1);
195 while ( (M>MinM) && Ok) {
196 M--;
197 Ok = myCurve->RemoveKnot(NbK1, M, myTol);
198 }
199
200
201}
202
203
204Handle(Geom_BSplineCurve) GeomConvert_CompCurveToBSplineCurve::BSplineCurve() const
205{
206 return myCurve;
207}
208
209
210
211