0024211: Definition of Basic Runtime Check parameter causes regression in debug mode
[occt.git] / src / Geom2dConvert / Geom2dConvert_CompCurveToBSplineCurve.cxx
... / ...
CommitLineData
1// Created on: 1997-04-29
2// Created by: Stagiaire Francois DUMONT
3// Copyright (c) 1997-1999 Matra Datavision
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
21
22
23#include <Geom2dConvert_CompCurveToBSplineCurve.ixx>
24
25#include <Geom2d_BSplineCurve.hxx>
26#include <Geom2dConvert.hxx>
27
28#include <TColStd_Array1OfReal.hxx>
29#include <TColStd_Array1OfInteger.hxx>
30
31#include <TColgp_Array1OfPnt2d.hxx>
32#include <gp_Vec2d.hxx>
33#include <gp_Pnt2d.hxx>
34#include <Precision.hxx>
35
36
37Geom2dConvert_CompCurveToBSplineCurve::
38Geom2dConvert_CompCurveToBSplineCurve(const Handle(Geom2d_BoundedCurve)& BasisCurve,
39 const Convert_ParameterisationType Parameterisation) :
40 myTol(Precision::Confusion()),
41 myType(Parameterisation)
42{
43 Handle(Geom2d_BSplineCurve) Bs =
44 Handle(Geom2d_BSplineCurve)::DownCast(BasisCurve);
45 if (!Bs.IsNull()) {
46 myCurve = Handle(Geom2d_BSplineCurve)::DownCast(BasisCurve->Copy());
47 }
48 else {
49 myCurve = Geom2dConvert::CurveToBSplineCurve (BasisCurve, myType);
50 }
51}
52
53//=======================================================================
54//function : Add
55//purpose :
56//=======================================================================
57
58Standard_Boolean Geom2dConvert_CompCurveToBSplineCurve::
59Add(const Handle(Geom2d_BoundedCurve)& NewCurve,
60 const Standard_Real Tolerance,
61 const Standard_Boolean After)
62{
63 myTol = Tolerance;
64// Convertion
65 Handle(Geom2d_BSplineCurve) Bs =
66 Handle(Geom2d_BSplineCurve)::DownCast(NewCurve);
67 if (!Bs.IsNull() ) {
68 Bs = Handle(Geom2d_BSplineCurve)::DownCast(NewCurve->Copy());
69 }
70 else {
71 Bs = Geom2dConvert::CurveToBSplineCurve (NewCurve, myType);
72 }
73
74 Standard_Integer LBs = Bs->NbPoles(), LCb = myCurve->NbPoles();
75
76 // myCurve est elle fermee ?
77 if (myCurve->Pole(LCb).Distance(myCurve->Pole(1))< myTol){
78 if(After){
79 // Ajout Apres ?
80 if (myCurve->Pole(LCb).Distance(Bs->Pole(LBs)) < myTol) {Bs->Reverse();}
81 if (myCurve->Pole(LCb).Distance(Bs->Pole(1)) < myTol) {
82 Add(myCurve, Bs, Standard_True);
83 return Standard_True;
84 }
85 }
86 else{
87 // Ajout avant ?
88 if (myCurve->Pole(1).Distance(Bs->Pole(1)) < myTol) {Bs->Reverse();}
89 if (myCurve->Pole(1).Distance(Bs->Pole(LBs)) < myTol) {
90 Add(Bs, myCurve, Standard_False);
91 return Standard_True;
92 }
93 }
94 }
95 // Ajout Apres ?
96 else {
97
98 Standard_Real d1 = myCurve->Pole(LCb).Distance(Bs->Pole(1));
99 Standard_Real d2 = myCurve->Pole(LCb).Distance(Bs->Pole(LBs));
100 if (( d1 < myTol) || ( d2 < myTol)) {
101 if (d2 < d1) {Bs->Reverse();}
102 Add(myCurve, Bs, Standard_True);
103 return Standard_True;
104 }
105 // Ajout avant ?
106 else {
107 d1 = myCurve->Pole(1).Distance(Bs->Pole(1));
108 d2 = myCurve->Pole(1).Distance(Bs->Pole(LBs));
109 if ( (d1 < myTol) || (d2 < myTol)) {
110 if (d1 < d2) {Bs->Reverse();}
111 Add(Bs, myCurve, Standard_False );
112 return Standard_True;
113 }
114 }
115 }
116 return Standard_False;
117}
118
119void Geom2dConvert_CompCurveToBSplineCurve::Add(
120 Handle(Geom2d_BSplineCurve)& FirstCurve,
121 Handle(Geom2d_BSplineCurve)& SecondCurve,
122 const Standard_Boolean After)
123{
124// Harmonisation des degres.
125 Standard_Integer Deg = Max(FirstCurve->Degree(), SecondCurve->Degree());
126 if (FirstCurve->Degree() < Deg) { FirstCurve->IncreaseDegree(Deg); }
127 if (SecondCurve->Degree() < Deg) { SecondCurve->IncreaseDegree(Deg); }
128
129// Declarationd
130 Standard_Real L1, L2, U_de_raccord;
131 Standard_Integer ii, jj;
132 Standard_Real Ratio=1, Ratio1, Ratio2, Delta1, Delta2;
133 Standard_Integer NbP1 = FirstCurve->NbPoles(), NbP2 = SecondCurve->NbPoles();
134 Standard_Integer NbK1 = FirstCurve->NbKnots(), NbK2 = SecondCurve->NbKnots();
135 TColStd_Array1OfReal Noeuds (1, NbK1+NbK2-1);
136 TColgp_Array1OfPnt2d Poles (1, NbP1+ NbP2-1);
137 TColStd_Array1OfReal Poids (1, NbP1+ NbP2-1);
138 TColStd_Array1OfInteger Mults (1, NbK1+NbK2-1);
139
140 // Ratio de reparametrisation (C1 si possible)
141 L1 = FirstCurve->DN(FirstCurve->LastParameter(), 1).Magnitude();
142 L2 = SecondCurve->DN(SecondCurve->FirstParameter(), 1). Magnitude();
143
144 if ( (L1 > Precision::Confusion()) && (L2 > Precision::Confusion()) ) {
145 Ratio = L1 / L2;
146 }
147 if ( (Ratio < Precision::Confusion()) || (Ratio > 1/Precision::Confusion()) ) {Ratio = 1;}
148
149 if (After) {
150// On ne bouge pas la premiere courbe
151 Ratio1 = 1;
152 Delta1 = 0;
153 Ratio2 = 1/Ratio;
154 Delta2 = Ratio2*SecondCurve->Knot(1) - FirstCurve->Knot(NbK1);
155 U_de_raccord = FirstCurve->LastParameter();
156 }
157 else {
158// On ne bouge pas la seconde courbe
159 Ratio1 = Ratio;
160 Delta1 = Ratio1*FirstCurve->Knot(NbK1) - SecondCurve->Knot(1);
161 Ratio2 = 1;
162 Delta2 = 0;
163 U_de_raccord = SecondCurve->FirstParameter();
164 }
165
166// Les Noeuds
167
168 for (ii=1; ii<NbK1; ii++) {
169 Noeuds(ii) = Ratio1*FirstCurve->Knot(ii) - Delta1;
170 Mults(ii) = FirstCurve->Multiplicity(ii);
171 }
172 Noeuds(NbK1) = U_de_raccord;
173 Mults(NbK1) = FirstCurve->Degree();
174 for (ii=2, jj=NbK1+1; ii<=NbK2; ii++, jj++) {
175 Noeuds(jj) = Ratio2*SecondCurve->Knot(ii) - Delta2;
176 Mults(jj) = SecondCurve->Multiplicity(ii);
177 }
178 Ratio = FirstCurve->Weight(NbP1) ;
179 Ratio /= SecondCurve->Weight(1) ;
180// Les Poles et Poids
181 for (ii=1; ii<NbP1; ii++) {
182 Poles(ii) = FirstCurve->Pole(ii);
183 Poids(ii) = FirstCurve->Weight(ii);
184 }
185 for (ii=1, jj=NbP1; ii<=NbP2; ii++, jj++) {
186 Poles(jj) = SecondCurve->Pole(ii);
187//
188// attentiion les poids ne se raccord pas forcement C0
189// d'ou Ratio
190//
191 Poids(jj) = Ratio * SecondCurve->Weight(ii);
192 }
193
194// Creation de la BSpline
195 myCurve = new (Geom2d_BSplineCurve) (Poles, Poids, Noeuds, Mults, Deg);
196
197// Reduction eventuelle de la multiplicite
198 Standard_Boolean Ok = Standard_True;
199 Standard_Integer M = Mults(NbK1);
200 while ( (M>0) && Ok) {
201 M--;
202 Ok = myCurve->RemoveKnot(NbK1, M, myTol);
203 }
204}
205
206
207Handle(Geom2d_BSplineCurve) Geom2dConvert_CompCurveToBSplineCurve::BSplineCurve() const
208{
209 return myCurve;
210}