0024023: Revamp the OCCT Handle -- ambiguity
[occt.git] / src / Geom2dConvert / Geom2dConvert_CompCurveToBSplineCurve.cxx
CommitLineData
b311480e 1// Created on: 1997-04-29
2// Created by: Stagiaire Francois DUMONT
3// Copyright (c) 1997-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
b311480e 16
7fd59977 17#include <Geom2dConvert_CompCurveToBSplineCurve.ixx>
18
19#include <Geom2d_BSplineCurve.hxx>
20#include <Geom2dConvert.hxx>
21
22#include <TColStd_Array1OfReal.hxx>
23#include <TColStd_Array1OfInteger.hxx>
24
25#include <TColgp_Array1OfPnt2d.hxx>
26#include <gp_Vec2d.hxx>
27#include <gp_Pnt2d.hxx>
28#include <Precision.hxx>
29
b514beda 30//=======================================================================
31//function : constructor
32//purpose :
33//=======================================================================
34Geom2dConvert_CompCurveToBSplineCurve::Geom2dConvert_CompCurveToBSplineCurve (const Convert_ParameterisationType theParameterisation)
35: myTol (Precision::Confusion()),
36 myType (theParameterisation)
37{
38 //
39}
7fd59977 40
b514beda 41//=======================================================================
42//function : constructor
43//purpose :
44//=======================================================================
7fd59977 45Geom2dConvert_CompCurveToBSplineCurve::
46Geom2dConvert_CompCurveToBSplineCurve(const Handle(Geom2d_BoundedCurve)& BasisCurve,
47 const Convert_ParameterisationType Parameterisation) :
48 myTol(Precision::Confusion()),
49 myType(Parameterisation)
50{
51 Handle(Geom2d_BSplineCurve) Bs =
52 Handle(Geom2d_BSplineCurve)::DownCast(BasisCurve);
53 if (!Bs.IsNull()) {
54 myCurve = Handle(Geom2d_BSplineCurve)::DownCast(BasisCurve->Copy());
55 }
56 else {
57 myCurve = Geom2dConvert::CurveToBSplineCurve (BasisCurve, myType);
58 }
59}
60
61//=======================================================================
62//function : Add
b514beda 63//purpose :
7fd59977 64//=======================================================================
65
66Standard_Boolean Geom2dConvert_CompCurveToBSplineCurve::
67Add(const Handle(Geom2d_BoundedCurve)& NewCurve,
68 const Standard_Real Tolerance,
69 const Standard_Boolean After)
70{
b514beda 71 // conversion
72 Handle(Geom2d_BSplineCurve) Bs = Handle(Geom2d_BSplineCurve)::DownCast (NewCurve);
73 if (!Bs.IsNull())
74 {
75 Bs = Handle(Geom2d_BSplineCurve)::DownCast (NewCurve->Copy());
7fd59977 76 }
b514beda 77 else
78 {
7fd59977 79 Bs = Geom2dConvert::CurveToBSplineCurve (NewCurve, myType);
80 }
b514beda 81 if (myCurve.IsNull())
82 {
83 myCurve = Bs;
84 return Standard_True;
85 }
86
87 myTol = Tolerance;
7fd59977 88
89 Standard_Integer LBs = Bs->NbPoles(), LCb = myCurve->NbPoles();
90
91 // myCurve est elle fermee ?
92 if (myCurve->Pole(LCb).Distance(myCurve->Pole(1))< myTol){
93 if(After){
94 // Ajout Apres ?
95 if (myCurve->Pole(LCb).Distance(Bs->Pole(LBs)) < myTol) {Bs->Reverse();}
96 if (myCurve->Pole(LCb).Distance(Bs->Pole(1)) < myTol) {
97 Add(myCurve, Bs, Standard_True);
98 return Standard_True;
99 }
100 }
101 else{
102 // Ajout avant ?
103 if (myCurve->Pole(1).Distance(Bs->Pole(1)) < myTol) {Bs->Reverse();}
104 if (myCurve->Pole(1).Distance(Bs->Pole(LBs)) < myTol) {
105 Add(Bs, myCurve, Standard_False);
106 return Standard_True;
107 }
108 }
109 }
110 // Ajout Apres ?
111 else {
112
113 Standard_Real d1 = myCurve->Pole(LCb).Distance(Bs->Pole(1));
114 Standard_Real d2 = myCurve->Pole(LCb).Distance(Bs->Pole(LBs));
115 if (( d1 < myTol) || ( d2 < myTol)) {
116 if (d2 < d1) {Bs->Reverse();}
117 Add(myCurve, Bs, Standard_True);
118 return Standard_True;
119 }
120 // Ajout avant ?
121 else {
122 d1 = myCurve->Pole(1).Distance(Bs->Pole(1));
123 d2 = myCurve->Pole(1).Distance(Bs->Pole(LBs));
124 if ( (d1 < myTol) || (d2 < myTol)) {
125 if (d1 < d2) {Bs->Reverse();}
126 Add(Bs, myCurve, Standard_False );
127 return Standard_True;
128 }
129 }
130 }
131 return Standard_False;
132}
133
b514beda 134//=======================================================================
135//function : Add
136//purpose :
137//=======================================================================
138
7fd59977 139void Geom2dConvert_CompCurveToBSplineCurve::Add(
140 Handle(Geom2d_BSplineCurve)& FirstCurve,
141 Handle(Geom2d_BSplineCurve)& SecondCurve,
142 const Standard_Boolean After)
143{
144// Harmonisation des degres.
145 Standard_Integer Deg = Max(FirstCurve->Degree(), SecondCurve->Degree());
146 if (FirstCurve->Degree() < Deg) { FirstCurve->IncreaseDegree(Deg); }
147 if (SecondCurve->Degree() < Deg) { SecondCurve->IncreaseDegree(Deg); }
148
149// Declarationd
150 Standard_Real L1, L2, U_de_raccord;
151 Standard_Integer ii, jj;
152 Standard_Real Ratio=1, Ratio1, Ratio2, Delta1, Delta2;
153 Standard_Integer NbP1 = FirstCurve->NbPoles(), NbP2 = SecondCurve->NbPoles();
154 Standard_Integer NbK1 = FirstCurve->NbKnots(), NbK2 = SecondCurve->NbKnots();
155 TColStd_Array1OfReal Noeuds (1, NbK1+NbK2-1);
156 TColgp_Array1OfPnt2d Poles (1, NbP1+ NbP2-1);
157 TColStd_Array1OfReal Poids (1, NbP1+ NbP2-1);
158 TColStd_Array1OfInteger Mults (1, NbK1+NbK2-1);
159
160 // Ratio de reparametrisation (C1 si possible)
161 L1 = FirstCurve->DN(FirstCurve->LastParameter(), 1).Magnitude();
162 L2 = SecondCurve->DN(SecondCurve->FirstParameter(), 1). Magnitude();
163
164 if ( (L1 > Precision::Confusion()) && (L2 > Precision::Confusion()) ) {
165 Ratio = L1 / L2;
166 }
167 if ( (Ratio < Precision::Confusion()) || (Ratio > 1/Precision::Confusion()) ) {Ratio = 1;}
168
169 if (After) {
170// On ne bouge pas la premiere courbe
171 Ratio1 = 1;
172 Delta1 = 0;
173 Ratio2 = 1/Ratio;
174 Delta2 = Ratio2*SecondCurve->Knot(1) - FirstCurve->Knot(NbK1);
175 U_de_raccord = FirstCurve->LastParameter();
176 }
177 else {
178// On ne bouge pas la seconde courbe
179 Ratio1 = Ratio;
180 Delta1 = Ratio1*FirstCurve->Knot(NbK1) - SecondCurve->Knot(1);
181 Ratio2 = 1;
182 Delta2 = 0;
183 U_de_raccord = SecondCurve->FirstParameter();
184 }
185
186// Les Noeuds
187
188 for (ii=1; ii<NbK1; ii++) {
189 Noeuds(ii) = Ratio1*FirstCurve->Knot(ii) - Delta1;
190 Mults(ii) = FirstCurve->Multiplicity(ii);
191 }
192 Noeuds(NbK1) = U_de_raccord;
193 Mults(NbK1) = FirstCurve->Degree();
194 for (ii=2, jj=NbK1+1; ii<=NbK2; ii++, jj++) {
195 Noeuds(jj) = Ratio2*SecondCurve->Knot(ii) - Delta2;
196 Mults(jj) = SecondCurve->Multiplicity(ii);
197 }
198 Ratio = FirstCurve->Weight(NbP1) ;
199 Ratio /= SecondCurve->Weight(1) ;
200// Les Poles et Poids
201 for (ii=1; ii<NbP1; ii++) {
202 Poles(ii) = FirstCurve->Pole(ii);
203 Poids(ii) = FirstCurve->Weight(ii);
204 }
205 for (ii=1, jj=NbP1; ii<=NbP2; ii++, jj++) {
206 Poles(jj) = SecondCurve->Pole(ii);
207//
208// attentiion les poids ne se raccord pas forcement C0
209// d'ou Ratio
210//
211 Poids(jj) = Ratio * SecondCurve->Weight(ii);
212 }
213
214// Creation de la BSpline
215 myCurve = new (Geom2d_BSplineCurve) (Poles, Poids, Noeuds, Mults, Deg);
216
217// Reduction eventuelle de la multiplicite
218 Standard_Boolean Ok = Standard_True;
219 Standard_Integer M = Mults(NbK1);
220 while ( (M>0) && Ok) {
221 M--;
222 Ok = myCurve->RemoveKnot(NbK1, M, myTol);
223 }
224}
225
b514beda 226//=======================================================================
227//function : BSplineCurve
228//purpose :
229//=======================================================================
7fd59977 230
231Handle(Geom2d_BSplineCurve) Geom2dConvert_CompCurveToBSplineCurve::BSplineCurve() const
232{
b514beda 233 return myCurve;
234}
235
236//=======================================================================
237//function : Clear
238//purpose :
239//=======================================================================
240
241void Geom2dConvert_CompCurveToBSplineCurve::Clear()
242{
243 myCurve.Nullify();
7fd59977 244}