| 1 | // File: GeomFill_Profiler.cxx |
| 2 | // Created: Thu Feb 17 11:33:12 1994 |
| 3 | // Author: Bruno DUMORTIER |
| 4 | // <dub@fuegox> |
| 5 | |
| 6 | #include <GeomFill_Profiler.ixx> |
| 7 | #include <GeomConvert.hxx> |
| 8 | #include <BSplCLib.hxx> |
| 9 | #include <Geom_BSplineCurve.hxx> |
| 10 | #include <Geom_TrimmedCurve.hxx> |
| 11 | #include <Geom_Conic.hxx> |
| 12 | #include <GeomConvert_ApproxCurve.hxx> |
| 13 | |
| 14 | |
| 15 | //======================================================================= |
| 16 | //function : GeomFill_Profiler |
| 17 | //purpose : |
| 18 | //======================================================================= |
| 19 | |
| 20 | GeomFill_Profiler::GeomFill_Profiler() |
| 21 | { |
| 22 | myIsDone = Standard_False; |
| 23 | myIsPeriodic = Standard_True; |
| 24 | } |
| 25 | |
| 26 | |
| 27 | //======================================================================= |
| 28 | |
| 29 | void GeomFill_Profiler::Delete() |
| 30 | {} |
| 31 | |
| 32 | |
| 33 | //======================================================================= |
| 34 | //function : AddCurve |
| 35 | //purpose : |
| 36 | //======================================================================= |
| 37 | |
| 38 | void GeomFill_Profiler::AddCurve(const Handle(Geom_Curve)& Curve) |
| 39 | { |
| 40 | Handle(Geom_Curve) C; |
| 41 | //// modified by jgv, 19.01.05 for OCC7354 //// |
| 42 | Handle(Geom_Curve) theCurve = Curve; |
| 43 | if (theCurve->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve))) |
| 44 | theCurve = (*((Handle(Geom_TrimmedCurve)*)&theCurve))->BasisCurve(); |
| 45 | if (theCurve->IsKind(STANDARD_TYPE(Geom_Conic))) |
| 46 | { |
| 47 | GeomConvert_ApproxCurve appr(Curve, Precision::Confusion(), GeomAbs_C1, 16, 14); |
| 48 | if (appr.HasResult()) |
| 49 | C = appr.Curve(); |
| 50 | } |
| 51 | if (C.IsNull()) |
| 52 | C = GeomConvert::CurveToBSplineCurve(Curve); |
| 53 | /* |
| 54 | if ( Curve->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) { |
| 55 | C = Handle(Geom_Curve)::DownCast(Curve->Copy()); |
| 56 | } |
| 57 | else { |
| 58 | C = GeomConvert::CurveToBSplineCurve(Curve,Convert_QuasiAngular); |
| 59 | } |
| 60 | */ |
| 61 | /////////////////////////////////////////////// |
| 62 | |
| 63 | mySequence.Append( C); |
| 64 | |
| 65 | if ( myIsPeriodic && !C->IsPeriodic()) |
| 66 | myIsPeriodic = Standard_False; |
| 67 | } |
| 68 | |
| 69 | |
| 70 | //======================================================================= |
| 71 | //function : Perform |
| 72 | //purpose : |
| 73 | //======================================================================= |
| 74 | |
| 75 | void GeomFill_Profiler::Perform(const Standard_Real PTol) |
| 76 | { |
| 77 | Standard_Integer i; |
| 78 | // Standard_Integer myDegree = 0, myNbPoles = 0; |
| 79 | Standard_Integer myDegree = 0; |
| 80 | Handle(Geom_BSplineCurve) C; |
| 81 | Standard_Real U1, U2, UFirst=0, ULast=0; |
| 82 | Standard_Real EcartMax = 0.; |
| 83 | |
| 84 | for ( i = 1; i <= mySequence.Length(); i++) { |
| 85 | C = Handle(Geom_BSplineCurve)::DownCast(mySequence(i)); |
| 86 | |
| 87 | // si non periodique, il faut deperiodiser toutes les courbes |
| 88 | // on les segmente ensuite pour assurer K(1) et K(n) de multiplicite |
| 89 | // degre + 1 |
| 90 | |
| 91 | U2 = C->Knot(C->LastUKnotIndex()); |
| 92 | U1 = C->Knot(C->FirstUKnotIndex()); |
| 93 | |
| 94 | if ( !myIsPeriodic && C->IsPeriodic()) { |
| 95 | C->SetNotPeriodic(); |
| 96 | C->Segment( U1, U2); |
| 97 | } |
| 98 | |
| 99 | // evaluate the max degree |
| 100 | myDegree = Max( myDegree, C->Degree()); |
| 101 | |
| 102 | // Calcul de Max ( Ufin - Udeb) sur l ensemble des courbes. |
| 103 | if ( ( U2 - U1) > EcartMax) { |
| 104 | EcartMax = U2 - U1; |
| 105 | UFirst = U1; |
| 106 | ULast = U2; |
| 107 | } |
| 108 | } |
| 109 | |
| 110 | // increase the degree of the curves to my degree |
| 111 | // reparametrize them in the range U1, U2. |
| 112 | for ( i = 1; i <= mySequence.Length(); i++) { |
| 113 | C = Handle(Geom_BSplineCurve)::DownCast(mySequence(i)); |
| 114 | |
| 115 | C->IncreaseDegree( myDegree); |
| 116 | |
| 117 | TColStd_Array1OfReal Knots(1,C->NbKnots()); |
| 118 | C->Knots(Knots); |
| 119 | BSplCLib::Reparametrize(UFirst,ULast,Knots); |
| 120 | C->SetKnots(Knots); |
| 121 | } |
| 122 | |
| 123 | // inserting in the first curve the knot-vector of all the others. |
| 124 | C = Handle(Geom_BSplineCurve)::DownCast(mySequence(1)); |
| 125 | |
| 126 | for ( i = 2; i <= mySequence.Length(); i++) { |
| 127 | Handle(Geom_BSplineCurve) Ci = |
| 128 | Handle(Geom_BSplineCurve)::DownCast(mySequence(i)); |
| 129 | TColStd_Array1OfReal Ki(1,Ci->NbKnots()); |
| 130 | Ci->Knots(Ki); |
| 131 | TColStd_Array1OfInteger Mi(1,Ci->NbKnots()); |
| 132 | Ci->Multiplicities(Mi); |
| 133 | |
| 134 | C->InsertKnots( Ki, Mi, PTol, Standard_False); |
| 135 | } |
| 136 | |
| 137 | TColStd_Array1OfReal NewKnots(1,C->NbKnots()); |
| 138 | C->Knots(NewKnots); |
| 139 | TColStd_Array1OfInteger NewMults(1,C->NbKnots()); |
| 140 | C->Multiplicities(NewMults); |
| 141 | for ( i = 2; i <= mySequence.Length(); i++) { |
| 142 | Handle(Geom_BSplineCurve) Ci = |
| 143 | Handle(Geom_BSplineCurve)::DownCast(mySequence(i)); |
| 144 | Ci->InsertKnots(NewKnots, NewMults, PTol, Standard_False); |
| 145 | } |
| 146 | |
| 147 | // essai : tentative mise des poids sur chaque section a une moyenne 1 |
| 148 | for ( i = 1; i <= mySequence.Length(); i++) { |
| 149 | Handle(Geom_BSplineCurve) Ci = |
| 150 | Handle(Geom_BSplineCurve)::DownCast(mySequence(i)); |
| 151 | if ( Ci->IsRational() ) { |
| 152 | Standard_Integer np = Ci->NbPoles(); |
| 153 | Standard_Real sigma = 0.; |
| 154 | Standard_Integer j; |
| 155 | for ( j = 1; j <= np; j++) { |
| 156 | sigma += Ci->Weight(j); |
| 157 | } |
| 158 | sigma /= np; |
| 159 | for ( j= 1; j<= np; j++) { |
| 160 | Ci->SetWeight(j,Ci->Weight(j) / sigma); |
| 161 | } |
| 162 | } |
| 163 | } |
| 164 | // fin de l essai |
| 165 | |
| 166 | myIsDone = Standard_True; |
| 167 | } |
| 168 | |
| 169 | |
| 170 | //======================================================================= |
| 171 | //function : Degree |
| 172 | //purpose : |
| 173 | //======================================================================= |
| 174 | |
| 175 | Standard_Integer GeomFill_Profiler::Degree() const |
| 176 | { |
| 177 | if ( !myIsDone) |
| 178 | StdFail_NotDone::Raise("GeomFill_Profiler::Degree"); |
| 179 | |
| 180 | Handle(Geom_BSplineCurve) C = |
| 181 | Handle(Geom_BSplineCurve)::DownCast(mySequence(1)); |
| 182 | return C->Degree(); |
| 183 | } |
| 184 | |
| 185 | |
| 186 | //======================================================================= |
| 187 | //function : NbPoles |
| 188 | //purpose : |
| 189 | //======================================================================= |
| 190 | |
| 191 | Standard_Integer GeomFill_Profiler::NbPoles() const |
| 192 | { |
| 193 | if ( !myIsDone) |
| 194 | StdFail_NotDone::Raise("GeomFill_Profiler::Degree"); |
| 195 | |
| 196 | Handle(Geom_BSplineCurve) C = |
| 197 | Handle(Geom_BSplineCurve)::DownCast(mySequence(1)); |
| 198 | return C->NbPoles(); |
| 199 | } |
| 200 | |
| 201 | |
| 202 | //======================================================================= |
| 203 | //function : Poles |
| 204 | //purpose : |
| 205 | //======================================================================= |
| 206 | |
| 207 | void GeomFill_Profiler::Poles(const Standard_Integer Index, |
| 208 | TColgp_Array1OfPnt& Poles) const |
| 209 | { |
| 210 | if ( !myIsDone) |
| 211 | StdFail_NotDone::Raise("GeomFill_Profiler::Degree"); |
| 212 | |
| 213 | Standard_DomainError_Raise_if( Poles.Length() != NbPoles(), |
| 214 | "GeomFill_Profiler::Poles"); |
| 215 | Standard_DomainError_Raise_if( Index < 1 || Index > mySequence.Length(), |
| 216 | "GeomFill_Profiler::Poles"); |
| 217 | |
| 218 | Handle(Geom_BSplineCurve) C = |
| 219 | Handle(Geom_BSplineCurve)::DownCast(mySequence(Index)); |
| 220 | |
| 221 | C->Poles(Poles); |
| 222 | } |
| 223 | |
| 224 | |
| 225 | //======================================================================= |
| 226 | //function : Weights |
| 227 | //purpose : |
| 228 | //======================================================================= |
| 229 | |
| 230 | void GeomFill_Profiler::Weights(const Standard_Integer Index, |
| 231 | TColStd_Array1OfReal& Weights) const |
| 232 | { |
| 233 | if ( !myIsDone) |
| 234 | StdFail_NotDone::Raise("GeomFill_Profiler::Degree"); |
| 235 | |
| 236 | Standard_DomainError_Raise_if( Weights.Length() != NbPoles(), |
| 237 | "GeomFill_Profiler::Weights"); |
| 238 | Standard_DomainError_Raise_if( Index < 1 || Index > mySequence.Length(), |
| 239 | "GeomFill_Profiler::Weights"); |
| 240 | |
| 241 | Handle(Geom_BSplineCurve) C = |
| 242 | Handle(Geom_BSplineCurve)::DownCast(mySequence(Index)); |
| 243 | |
| 244 | C->Weights(Weights); |
| 245 | } |
| 246 | |
| 247 | |
| 248 | //======================================================================= |
| 249 | //function : NbKnots |
| 250 | //purpose : |
| 251 | //======================================================================= |
| 252 | |
| 253 | Standard_Integer GeomFill_Profiler::NbKnots() const |
| 254 | { |
| 255 | if ( !myIsDone) |
| 256 | StdFail_NotDone::Raise("GeomFill_Profiler::Degree"); |
| 257 | |
| 258 | Handle(Geom_BSplineCurve) C = |
| 259 | Handle(Geom_BSplineCurve)::DownCast(mySequence(1)); |
| 260 | |
| 261 | return C->NbKnots(); |
| 262 | } |
| 263 | |
| 264 | |
| 265 | //======================================================================= |
| 266 | //function : KnotsAndMults |
| 267 | //purpose : |
| 268 | //======================================================================= |
| 269 | |
| 270 | void GeomFill_Profiler::KnotsAndMults(TColStd_Array1OfReal& Knots, |
| 271 | TColStd_Array1OfInteger& Mults ) const |
| 272 | { |
| 273 | if ( !myIsDone) |
| 274 | StdFail_NotDone::Raise("GeomFill_Profiler::Degree"); |
| 275 | |
| 276 | #ifndef No_Exception |
| 277 | Standard_Integer n = NbKnots(); |
| 278 | #endif |
| 279 | Standard_DomainError_Raise_if( Knots.Length() != n || Mults.Length() != n, |
| 280 | "GeomFill_Profiler::KnotsAndMults"); |
| 281 | |
| 282 | Handle(Geom_BSplineCurve) C = |
| 283 | Handle(Geom_BSplineCurve)::DownCast(mySequence(1)); |
| 284 | |
| 285 | C->Knots(Knots); |
| 286 | C->Multiplicities(Mults); |
| 287 | } |
| 288 | |
| 289 | |