00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "PreCompiled.h"
00029
00030 #include "BRepAdaptor_CompCurve2.h"
00031 #include <BRepAdaptor_Curve.hxx>
00032 #include <BRepAdaptor_HCurve.hxx>
00033 #include <BRepAdaptor_HCompCurve.hxx>
00034 #include <BRepAdaptor_HArray1OfCurve.hxx>
00035 #include <TColStd_HArray1OfReal.hxx>
00036 #include <BRep_Tool.hxx>
00037
00038 #include <TopAbs_Orientation.hxx>
00039
00040 #include <GCPnts_AbscissaPoint.hxx>
00041 #include <ElCLib.hxx>
00042 #include <TopExp.hxx>
00043 #include <TopoDS_Vertex.hxx>
00044 #include "WireExplorer.h"
00045
00046 BRepAdaptor_CompCurve2::BRepAdaptor_CompCurve2()
00047 {
00048 }
00049
00050 BRepAdaptor_CompCurve2::BRepAdaptor_CompCurve2(const TopoDS_Wire& W,
00051 const Standard_Boolean AC)
00052 {
00053 Initialize(W, AC);
00054 }
00055
00056 BRepAdaptor_CompCurve2::BRepAdaptor_CompCurve2(const TopoDS_Wire& W,
00057 const Standard_Boolean AC,
00058 const Standard_Real First,
00059 const Standard_Real Last,
00060 const Standard_Real Tol)
00061 {
00062 Initialize(W, AC, First, Last, Tol);
00063 }
00064
00065 void BRepAdaptor_CompCurve2::Initialize(const TopoDS_Wire& W,
00066 const Standard_Boolean AC)
00067 {
00068 Standard_Integer ii, NbEdge;
00069
00070 TopoDS_Edge E;
00071
00072 myWire = W;
00073 WireExplorer wexp(myWire);
00074 PTol = 0.0;
00075 IsbyAC = AC;
00076
00077 for (NbEdge=0, wexp.Init();wexp.More(); wexp.Next())
00078 if (! BRep_Tool::Degenerated(wexp.Current())) NbEdge++;
00079
00080 if (NbEdge == 0) return;
00081
00082 CurIndex = (NbEdge+1)/2;
00083 myCurves = new BRepAdaptor_HArray1OfCurve(1,NbEdge);
00084 myKnots = new (TColStd_HArray1OfReal) (1,NbEdge+1);
00085 myKnots->SetValue(1, 0.);
00086
00087 for (ii=0, wexp.Init();wexp.More(); wexp.Next()) {
00088 E = wexp.Current();
00089 if (! BRep_Tool::Degenerated(E)) {
00090 ii++;
00091 myCurves->ChangeValue(ii).Initialize(E);
00092 if (AC) {
00093 myKnots->SetValue(ii+1, myKnots->Value(ii));
00094 myKnots->ChangeValue(ii+1) +=
00095 GCPnts_AbscissaPoint::Length(myCurves->ChangeValue(ii));
00096 }
00097 else myKnots->SetValue(ii+1, (Standard_Real)ii);
00098 }
00099 }
00100
00101 Forward = Standard_True;
00102
00103 if((NbEdge > 2) || ((NbEdge==2) && (!myWire.Closed())) ) {
00104 TopAbs_Orientation Or = myCurves->Value(1).Edge().Orientation();
00105 Standard_Boolean B;
00106 TopoDS_Vertex VI, VL;
00107 B = TopExp::CommonVertex(myCurves->Value(1).Edge(),
00108 myCurves->Value(2).Edge(),
00109 VI);
00110 VL = TopExp::LastVertex(myCurves->Value(1).Edge());
00111 if (VI.IsSame(VL)) {
00112 if (Or == TopAbs_REVERSED)
00113 Forward = Standard_False;
00114 }
00115 else {
00116 if (Or != TopAbs_REVERSED)
00117 Forward = Standard_False;
00118 }
00119 }
00120
00121 TFirst = 0;
00122 TLast = myKnots->Value(myKnots->Length());
00123 myPeriod = TLast - TFirst;
00124 if (NbEdge == 1) {
00125 Periodic = myCurves->Value(1).IsPeriodic();
00126 }
00127 else {
00128 Periodic = Standard_False;
00129 }
00130 }
00131
00132 void BRepAdaptor_CompCurve2::Initialize(const TopoDS_Wire& W,
00133 const Standard_Boolean AC,
00134 const Standard_Real First,
00135 const Standard_Real Last,
00136 const Standard_Real Tol)
00137 {
00138 Initialize(W, AC);
00139 TFirst = First;
00140 TLast = Last;
00141 PTol = Tol;
00142
00143
00144 Handle (BRepAdaptor_HCurve) HC;
00145 Standard_Integer i1, i2;
00146 Standard_Real f=TFirst, l=TLast, d;
00147 i1 = i2 = CurIndex;
00148 Prepare(f, d, i1);
00149 Prepare(l, d, i2);
00150 CurIndex = (i1+i2)/2;
00151 if (i1==i2) {
00152 if (l > f)
00153 HC = Handle(BRepAdaptor_HCurve)::DownCast(myCurves->Value(i1).Trim(f, l, PTol));
00154 else
00155 HC = Handle(BRepAdaptor_HCurve)::DownCast(myCurves->Value(i1).Trim(l, f, PTol));
00156 myCurves->SetValue(i1, HC->ChangeCurve());
00157 }
00158 else {
00159 const BRepAdaptor_Curve& c1 = myCurves->Value(i1);
00160 const BRepAdaptor_Curve& c2 = myCurves->Value(i2);
00161 Standard_Real k;
00162
00163 k = c1.LastParameter();
00164 if (k>f)
00165 HC = Handle(BRepAdaptor_HCurve)::DownCast(c1.Trim(f, k, PTol));
00166 else
00167 HC = Handle(BRepAdaptor_HCurve)::DownCast(c1.Trim(k, f, PTol));
00168 myCurves->SetValue(i1, HC->ChangeCurve());
00169
00170 k = c2.FirstParameter();
00171 if (k<=l)
00172 HC = Handle(BRepAdaptor_HCurve)::DownCast(c2.Trim(k, l, PTol));
00173 else
00174 HC = Handle(BRepAdaptor_HCurve)::DownCast(c2.Trim(l, k, PTol));
00175 myCurves->SetValue(i2, HC->ChangeCurve());
00176 }
00177 }
00178
00179
00180 void BRepAdaptor_CompCurve2::SetPeriodic(const Standard_Boolean isPeriodic)
00181 {
00182 if (myWire.Closed()) {
00183 Periodic = isPeriodic;
00184 }
00185 }
00186
00187
00188 const TopoDS_Wire& BRepAdaptor_CompCurve2::Wire() const
00189 {
00190 return myWire;
00191 }
00192
00193 void BRepAdaptor_CompCurve2::Edge(const Standard_Real U,
00194 TopoDS_Edge& E,
00195 Standard_Real& UonE) const
00196 {
00197 Standard_Real d;
00198 Standard_Integer index = CurIndex;
00199 UonE = U;
00200 Prepare(UonE, d, index);
00201 E = myCurves->Value(index).Edge();
00202 }
00203
00204 Standard_Real BRepAdaptor_CompCurve2::FirstParameter() const
00205 {
00206 return TFirst;
00207 }
00208
00209 Standard_Real BRepAdaptor_CompCurve2::LastParameter() const
00210 {
00211 return TLast;
00212 }
00213
00214 GeomAbs_Shape BRepAdaptor_CompCurve2::Continuity() const
00215 {
00216 if ( myCurves->Length() > 1) return GeomAbs_C0;
00217 return myCurves->Value(1).Continuity();
00218 }
00219
00220 Standard_Integer BRepAdaptor_CompCurve2::NbIntervals(const GeomAbs_Shape S)
00221 {
00222 Standard_Integer NbInt, ii;
00223 for (ii=1, NbInt=0; ii<=myCurves->Length(); ii++)
00224 NbInt += myCurves->ChangeValue(ii).NbIntervals(S);
00225
00226 return NbInt;
00227 }
00228
00229 void BRepAdaptor_CompCurve2::Intervals(TColStd_Array1OfReal& T,
00230 const GeomAbs_Shape S)
00231 {
00232 Standard_Integer ii, jj, kk, n;
00233 Standard_Real f, F, delta;
00234
00235
00236 n = myCurves->ChangeValue(1).NbIntervals(S);
00237 Handle(TColStd_HArray1OfReal) Ti = new (TColStd_HArray1OfReal) (1, n+1);
00238 myCurves->ChangeValue(1).Intervals(Ti->ChangeArray1(), S);
00239 InvPrepare(1, f, delta);
00240 F = myKnots->Value(1);
00241 if (delta < 0) {
00242
00243 for (kk=1,jj=Ti->Length(); jj>0; kk++, jj--)
00244 T(kk) = F + (Ti->Value(jj)-f)*delta;
00245 }
00246 else {
00247 for (kk=1; kk<=Ti->Length(); kk++)
00248 T(kk) = F + (Ti->Value(kk)-f)*delta;
00249 }
00250
00251
00252 for (ii=2; ii<=myCurves->Length(); ii++) {
00253 n = myCurves->ChangeValue(ii).NbIntervals(S);
00254 if (n != Ti->Length()-1) Ti = new (TColStd_HArray1OfReal) (1, n+1);
00255 myCurves->ChangeValue(ii).Intervals(Ti->ChangeArray1(), S);
00256 InvPrepare(ii, f, delta);
00257 F = myKnots->Value(ii);
00258 if (delta < 0) {
00259
00260 for (jj=Ti->Length()-1; jj>0; kk++, jj--)
00261 T(kk) = F + (Ti->Value(jj)-f)*delta;
00262 }
00263 else {
00264 for (jj=2; jj<=Ti->Length(); kk++, jj++)
00265 T(kk) = F + (Ti->Value(jj)-f)*delta;
00266 }
00267 }
00268 }
00269
00270
00271
00272 Standard_Boolean BRepAdaptor_CompCurve2::IsClosed() const
00273 {
00274 return myWire.Closed();
00275 }
00276
00277 Standard_Boolean BRepAdaptor_CompCurve2::IsPeriodic() const
00278 {
00279 return Periodic;
00280
00281 }
00282
00283 Standard_Real BRepAdaptor_CompCurve2::Period() const
00284 {
00285 return myPeriod;
00286 }
00287
00288 gp_Pnt BRepAdaptor_CompCurve2::Value(const Standard_Real U) const
00289 {
00290 Standard_Real u = U, d;
00291 Standard_Integer index = CurIndex;
00292 Prepare(u, d, index);
00293 return myCurves->Value(index).Value(u);
00294 }
00295
00296 void BRepAdaptor_CompCurve2::D0(const Standard_Real U,
00297 gp_Pnt& P) const
00298 {
00299 Standard_Real u = U, d;
00300 Standard_Integer index = CurIndex;
00301 Prepare(u, d, index);
00302 myCurves->Value(index).D0(u, P);
00303 }
00304
00305 void BRepAdaptor_CompCurve2::D1(const Standard_Real U,
00306 gp_Pnt& P,
00307 gp_Vec& V) const
00308 {
00309 Standard_Real u = U, d;
00310 Standard_Integer index = CurIndex;
00311 Prepare(u, d, index);
00312 myCurves->Value(index).D1(u, P, V);
00313 V*=d;
00314 }
00315
00316 void BRepAdaptor_CompCurve2::D2(const Standard_Real U,
00317 gp_Pnt& P,
00318 gp_Vec& V1,
00319 gp_Vec& V2) const
00320 {
00321 Standard_Real u = U, d;
00322 Standard_Integer index = CurIndex;
00323 Prepare(u, d, index);
00324 myCurves->Value(index).D2(u, P, V1, V2);
00325 V1*=d;
00326 V2 *= d*d;
00327 }
00328
00329 void BRepAdaptor_CompCurve2::D3(const Standard_Real U,
00330 gp_Pnt& P,gp_Vec& V1,
00331 gp_Vec& V2,
00332 gp_Vec& V3) const
00333 {
00334 Standard_Real u = U, d;
00335 Standard_Integer index = CurIndex;
00336 Prepare(u, d, index);
00337 myCurves->Value(index).D3(u, P, V1, V2, V3);
00338 V1*=d;
00339 V2 *= d*d;
00340 V3 *= d*d*d;
00341 }
00342
00343 gp_Vec BRepAdaptor_CompCurve2::DN(const Standard_Real U,
00344 const Standard_Integer N) const
00345 {
00346 Standard_Real u = U, d;
00347 Standard_Integer index = CurIndex;
00348 Prepare(u, d, index);
00349
00350 return (myCurves->Value(index).DN(u, N) * Pow(d, N));
00351 }
00352
00353 Standard_Real BRepAdaptor_CompCurve2::Resolution(const Standard_Real R3d) const
00354 {
00355 Standard_Real Res = 1.e200, r;
00356 Standard_Integer ii, L = myCurves->Length();
00357 for (ii=1; ii<=L; ii++) {
00358 r = myCurves->Value(ii).Resolution(R3d);
00359 if (r < Res) Res = r;
00360 }
00361 return Res;
00362 }
00363
00364 GeomAbs_CurveType BRepAdaptor_CompCurve2::GetType() const
00365 {
00366 return GeomAbs_OtherCurve;
00367
00368
00369 }
00370
00371 gp_Lin BRepAdaptor_CompCurve2::Line() const
00372 {
00373 return myCurves->Value(1).Line();
00374 }
00375
00376 gp_Circ BRepAdaptor_CompCurve2::Circle() const
00377 {
00378 return myCurves->Value(1).Circle();
00379 }
00380
00381 gp_Elips BRepAdaptor_CompCurve2::Ellipse() const
00382 {
00383 return myCurves->Value(1).Ellipse();
00384 }
00385
00386 gp_Hypr BRepAdaptor_CompCurve2::Hyperbola() const
00387 {
00388 return myCurves->Value(1).Hyperbola();
00389 }
00390
00391 gp_Parab BRepAdaptor_CompCurve2::Parabola() const
00392 {
00393 return myCurves->Value(1).Parabola();
00394 }
00395
00396 Standard_Integer BRepAdaptor_CompCurve2::Degree() const
00397 {
00398 return myCurves->Value(1).Degree();
00399 }
00400
00401 Standard_Boolean BRepAdaptor_CompCurve2::IsRational() const
00402 {
00403 return myCurves->Value(1).IsRational();
00404 }
00405
00406 Standard_Integer BRepAdaptor_CompCurve2::NbPoles() const
00407 {
00408 return myCurves->Value(1).NbPoles();
00409 }
00410
00411 Standard_Integer BRepAdaptor_CompCurve2::NbKnots() const
00412 {
00413 return myCurves->Value(1).NbKnots();
00414 }
00415
00416 Handle(Geom_BezierCurve) BRepAdaptor_CompCurve2::Bezier() const
00417 {
00418 return myCurves->Value(1).Bezier();
00419 }
00420
00421 Handle(Geom_BSplineCurve) BRepAdaptor_CompCurve2::BSpline() const
00422 {
00423 return myCurves->Value(1).BSpline();
00424 }
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435 void BRepAdaptor_CompCurve2::Prepare(Standard_Real& W,
00436 Standard_Real& Delta,
00437 Standard_Integer& CurIndex) const
00438 {
00439 Standard_Real f,l, Wtest, Eps;
00440 Standard_Integer ii;
00441 if (W-TFirst < TLast-W) { Eps = PTol; }
00442 else { Eps = -PTol;}
00443
00444
00445 Wtest = W+Eps;
00446 if(Periodic){
00447 Wtest = ElCLib::InPeriod(Wtest,
00448 0,
00449 myPeriod);
00450 W = Wtest-Eps;
00451 }
00452
00453
00454 Standard_Boolean Trouve = Standard_False;
00455 if (myKnots->Value(CurIndex) > Wtest) {
00456 for (ii=CurIndex-1; ii>0 && !Trouve; ii--)
00457 if (myKnots->Value(ii)<= Wtest) {
00458 CurIndex = ii;
00459 Trouve = Standard_True;
00460 }
00461 if (!Trouve) CurIndex = 1;
00462 }
00463
00464 else if (myKnots->Value(CurIndex+1) <= Wtest) {
00465 for (ii=CurIndex+1; ii<=myCurves->Length() && !Trouve; ii++)
00466 if (myKnots->Value(ii+1)> Wtest) {
00467 CurIndex = ii;
00468 Trouve = Standard_True;
00469 }
00470 if (!Trouve) CurIndex = myCurves->Length();
00471 }
00472
00473
00474 const TopoDS_Edge& E = myCurves->Value(CurIndex).Edge();
00475 TopAbs_Orientation Or = E.Orientation();
00476 Standard_Boolean Reverse;
00477 Reverse = (Forward && (Or == TopAbs_REVERSED)) ||
00478 (!Forward && (Or != TopAbs_REVERSED));
00479
00480
00481 BRep_Tool::Range(E, f, l);
00482 Delta = myKnots->Value(CurIndex+1) - myKnots->Value(CurIndex);
00483 if (Delta > PTol*1.e-9) Delta = (l-f)/Delta;
00484
00485 if (Reverse) {
00486 Delta *= -1;
00487 W = l + (W-myKnots->Value(CurIndex)) * Delta;
00488 }
00489 else {
00490 W = f + (W-myKnots->Value(CurIndex)) * Delta;
00491 }
00492 }
00493
00494 void BRepAdaptor_CompCurve2::InvPrepare(const Standard_Integer index,
00495 Standard_Real& First,
00496 Standard_Real& Delta) const
00497 {
00498
00499 const TopoDS_Edge& E = myCurves->Value(index).Edge();
00500 TopAbs_Orientation Or = E.Orientation();
00501 Standard_Boolean Reverse;
00502 Reverse = (Forward && (Or == TopAbs_REVERSED)) ||
00503 (!Forward && (Or != TopAbs_REVERSED));
00504
00505
00506
00507 Standard_Real f, l;
00508 BRep_Tool::Range(E, f, l);
00509 Delta = myKnots->Value(index+1) - myKnots->Value(index);
00510 if (l-f > PTol*1.e-9) Delta /= (l-f);
00511
00512 if (Reverse) {
00513 Delta *= -1;
00514 First = l;
00515 }
00516 else {
00517 First = f;
00518 }
00519 }