0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[occt.git] / src / BRepAdaptor / BRepAdaptor_CompCurve.cxx
CommitLineData
b311480e 1// Created on: 1998-08-20
2// Created by: Philippe MANGIN
3// Copyright (c) 1998-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.
7fd59977 16
c22b52d6 17#include <BRepAdaptor_CompCurve.hxx>
7fd59977 18
42cf5bc1 19#include <BRep_Tool.hxx>
7fd59977 20#include <BRepTools_WireExplorer.hxx>
42cf5bc1 21#include <GCPnts_AbscissaPoint.hxx>
22#include <Geom_BezierCurve.hxx>
23#include <Geom_BSplineCurve.hxx>
24#include <gp_Circ.hxx>
25#include <gp_Elips.hxx>
26#include <gp_Hypr.hxx>
27#include <gp_Lin.hxx>
28#include <gp_Parab.hxx>
29#include <gp_Pnt.hxx>
30#include <gp_Vec.hxx>
42cf5bc1 31#include <TopAbs_Orientation.hxx>
7fd59977 32#include <TopExp.hxx>
42cf5bc1 33#include <TopoDS_Edge.hxx>
34#include <TopoDS_Wire.hxx>
7fd59977 35
c22b52d6 36IMPLEMENT_STANDARD_RTTIEXT(BRepAdaptor_CompCurve, Adaptor3d_Curve)
37
7fd59977 38BRepAdaptor_CompCurve::BRepAdaptor_CompCurve()
cbff1e55 39: TFirst (0.0),
40 TLast (0.0),
41 PTol (0.0),
cbff1e55 42 CurIndex(-1),
43 Forward (Standard_False),
f24150b8 44 IsbyAC (Standard_False)
7fd59977 45{
46}
47
cbff1e55 48BRepAdaptor_CompCurve::BRepAdaptor_CompCurve(const TopoDS_Wire& theWire,
49 const Standard_Boolean theIsAC)
50: myWire (theWire),
51 TFirst (0.0),
52 TLast (0.0),
53 PTol (0.0),
cbff1e55 54 CurIndex(-1),
55 Forward (Standard_False),
f24150b8 56 IsbyAC (theIsAC)
7fd59977 57{
cbff1e55 58 Initialize(theWire, theIsAC);
7fd59977 59}
60
cbff1e55 61BRepAdaptor_CompCurve::BRepAdaptor_CompCurve(const TopoDS_Wire& theWire,
62 const Standard_Boolean theIsAC,
63 const Standard_Real theFirst,
64 const Standard_Real theLast,
65 const Standard_Real theTolerance)
66: myWire (theWire),
67 TFirst (theFirst),
68 TLast (theLast),
69 PTol (theTolerance),
cbff1e55 70 CurIndex(-1),
71 Forward (Standard_False),
f24150b8 72 IsbyAC (theIsAC)
7fd59977 73{
cbff1e55 74 Initialize(theWire, theIsAC, theFirst, theLast, theTolerance);
7fd59977 75}
76
872a7e3a 77//=======================================================================
78//function : ShallowCopy
79//purpose :
80//=======================================================================
81
82Handle(Adaptor3d_Curve) BRepAdaptor_CompCurve::ShallowCopy() const
83{
84 Handle(BRepAdaptor_CompCurve) aCopy = new BRepAdaptor_CompCurve();
85
86 aCopy->myWire = myWire;
87 aCopy->TFirst = TFirst;
88 aCopy->TLast = TLast;
89 aCopy->PTol = PTol;
90 aCopy->myCurves = new (BRepAdaptor_HArray1OfCurve) (1, myCurves->Size());
91 for (Standard_Integer anI = 1; anI <= myCurves->Size(); ++anI)
92 {
93 const Handle(Adaptor3d_Curve) aCurve = myCurves->Value(anI).ShallowCopy();
94 const BRepAdaptor_Curve& aBrepCurve = *(Handle(BRepAdaptor_Curve)::DownCast(aCurve));
95 aCopy->myCurves->SetValue(anI, aBrepCurve);
96 }
97 aCopy->myKnots = myKnots;
98 aCopy->CurIndex = CurIndex;
99 aCopy->Forward = Forward;
100 aCopy->IsbyAC = IsbyAC;
101
102 return aCopy;
103}
104
7fd59977 105 void BRepAdaptor_CompCurve::Initialize(const TopoDS_Wire& W,
106 const Standard_Boolean AC)
107{
108 Standard_Integer ii, NbEdge;
109 BRepTools_WireExplorer wexp;
110 TopoDS_Edge E;
111
112 myWire = W;
113 PTol = 0.0;
114 IsbyAC = AC;
115
116 for (NbEdge=0, wexp.Init(myWire);
117 wexp.More(); wexp.Next())
118 if (! BRep_Tool::Degenerated(wexp.Current())) NbEdge++;
119
120 if (NbEdge == 0) return;
121
122 CurIndex = (NbEdge+1)/2;
123 myCurves = new (BRepAdaptor_HArray1OfCurve) (1,NbEdge);
124 myKnots = new (TColStd_HArray1OfReal) (1,NbEdge+1);
125 myKnots->SetValue(1, 0.);
126
127 for (ii=0, wexp.Init(myWire);
128 wexp.More(); wexp.Next()) {
129 E = wexp.Current();
130 if (! BRep_Tool::Degenerated(E)) {
131 ii++;
132 myCurves->ChangeValue(ii).Initialize(E);
133 if (AC) {
134 myKnots->SetValue(ii+1, myKnots->Value(ii));
135 myKnots->ChangeValue(ii+1) +=
136 GCPnts_AbscissaPoint::Length(myCurves->ChangeValue(ii));
137 }
138 else myKnots->SetValue(ii+1, (Standard_Real)ii);
139 }
140 }
141
b81b237f 142 Forward = Standard_True; // Default ; The Reverse Edges are parsed.
7fd59977 143 if((NbEdge > 2) || ((NbEdge==2) && (!myWire.Closed())) ) {
144 TopAbs_Orientation Or = myCurves->Value(1).Edge().Orientation();
7fd59977 145 TopoDS_Vertex VI, VL;
96a95605 146 TopExp::CommonVertex(myCurves->Value(1).Edge(),
7fd59977 147 myCurves->Value(2).Edge(),
148 VI);
149 VL = TopExp::LastVertex(myCurves->Value(1).Edge());
0d969553 150 if (VI.IsSame(VL)) { // The direction of parsing is always preserved
7fd59977 151 if (Or == TopAbs_REVERSED)
152 Forward = Standard_False;
153 }
0d969553 154 else {// The direction of parsing is always reversed
7fd59977 155 if (Or != TopAbs_REVERSED)
156 Forward = Standard_False;
157 }
158 }
159
160 TFirst = 0;
161 TLast = myKnots->Value(myKnots->Length());
7fd59977 162}
163
164 void BRepAdaptor_CompCurve::Initialize(const TopoDS_Wire& W,
165 const Standard_Boolean AC,
166 const Standard_Real First,
167 const Standard_Real Last,
168 const Standard_Real Tol)
169{
170 Initialize(W, AC);
171 TFirst = First;
172 TLast = Last;
173 PTol = Tol;
174
0d969553 175 // Trim the extremal curves.
c22b52d6 176 Handle (BRepAdaptor_Curve) HC;
7fd59977 177 Standard_Integer i1, i2;
178 Standard_Real f=TFirst, l=TLast, d;
179 i1 = i2 = CurIndex;
180 Prepare(f, d, i1);
181 Prepare(l, d, i2);
0d969553 182 CurIndex = (i1+i2)/2; // Small optimization
7fd59977 183 if (i1==i2) {
184 if (l > f)
c22b52d6 185 HC = Handle(BRepAdaptor_Curve)::DownCast(myCurves->Value(i1).Trim(f, l, PTol));
7fd59977 186 else
c22b52d6 187 HC = Handle(BRepAdaptor_Curve)::DownCast(myCurves->Value(i1).Trim(l, f, PTol));
188 myCurves->SetValue(i1, *HC);
7fd59977 189 }
190 else {
191 const BRepAdaptor_Curve& c1 = myCurves->Value(i1);
192 const BRepAdaptor_Curve& c2 = myCurves->Value(i2);
193 Standard_Real k;
194
195 k = c1.LastParameter();
196 if (k>f)
c22b52d6 197 HC = Handle(BRepAdaptor_Curve)::DownCast(c1.Trim(f, k, PTol));
7fd59977 198 else
c22b52d6 199 HC = Handle(BRepAdaptor_Curve)::DownCast(c1.Trim(k, f, PTol));
200 myCurves->SetValue(i1, *HC);
7fd59977 201
202 k = c2.FirstParameter();
203 if (k<=l)
c22b52d6 204 HC = Handle(BRepAdaptor_Curve)::DownCast(c2.Trim(k, l, PTol));
7fd59977 205 else
c22b52d6 206 HC = Handle(BRepAdaptor_Curve)::DownCast(c2.Trim(l, k, PTol));
207 myCurves->SetValue(i2, *HC);
7fd59977 208 }
209}
210
7fd59977 211const TopoDS_Wire& BRepAdaptor_CompCurve::Wire() const
212{
213 return myWire;
214}
215
216 void BRepAdaptor_CompCurve::Edge(const Standard_Real U,
217 TopoDS_Edge& E,
218 Standard_Real& UonE) const
219{
220 Standard_Real d;
221 Standard_Integer index = CurIndex;
222 UonE = U;
223 Prepare(UonE, d, index);
224 E = myCurves->Value(index).Edge();
225}
226
227 Standard_Real BRepAdaptor_CompCurve::FirstParameter() const
228{
229 return TFirst;
230}
231
232 Standard_Real BRepAdaptor_CompCurve::LastParameter() const
233{
234 return TLast;
235}
236
237 GeomAbs_Shape BRepAdaptor_CompCurve::Continuity() const
238{
239 if ( myCurves->Length() > 1) return GeomAbs_C0;
240 return myCurves->Value(1).Continuity();
241}
242
31b1749c 243 Standard_Integer BRepAdaptor_CompCurve::NbIntervals(const GeomAbs_Shape S) const
7fd59977 244{
245 Standard_Integer NbInt, ii;
246 for (ii=1, NbInt=0; ii<=myCurves->Length(); ii++)
247 NbInt += myCurves->ChangeValue(ii).NbIntervals(S);
248
249 return NbInt;
250}
251
252 void BRepAdaptor_CompCurve::Intervals(TColStd_Array1OfReal& T,
31b1749c 253 const GeomAbs_Shape S) const
7fd59977 254{
255 Standard_Integer ii, jj, kk, n;
256 Standard_Real f, F, delta;
257
0d969553 258 // First curve (direction of parsing of the edge)
7fd59977 259 n = myCurves->ChangeValue(1).NbIntervals(S);
260 Handle(TColStd_HArray1OfReal) Ti = new (TColStd_HArray1OfReal) (1, n+1);
261 myCurves->ChangeValue(1).Intervals(Ti->ChangeArray1(), S);
262 InvPrepare(1, f, delta);
263 F = myKnots->Value(1);
264 if (delta < 0) {
0d969553 265 // invert the direction of parsing
7fd59977 266 for (kk=1,jj=Ti->Length(); jj>0; kk++, jj--)
267 T(kk) = F + (Ti->Value(jj)-f)*delta;
268 }
269 else {
270 for (kk=1; kk<=Ti->Length(); kk++)
271 T(kk) = F + (Ti->Value(kk)-f)*delta;
272 }
273
0d969553 274 // and the next
7fd59977 275 for (ii=2; ii<=myCurves->Length(); ii++) {
276 n = myCurves->ChangeValue(ii).NbIntervals(S);
277 if (n != Ti->Length()-1) Ti = new (TColStd_HArray1OfReal) (1, n+1);
278 myCurves->ChangeValue(ii).Intervals(Ti->ChangeArray1(), S);
279 InvPrepare(ii, f, delta);
280 F = myKnots->Value(ii);
281 if (delta < 0) {
0d969553 282 // invert the direction of parcing
7fd59977 283 for (jj=Ti->Length()-1; jj>0; kk++, jj--)
284 T(kk) = F + (Ti->Value(jj)-f)*delta;
285 }
286 else {
287 for (jj=2; jj<=Ti->Length(); kk++, jj++)
288 T(kk) = F + (Ti->Value(jj)-f)*delta;
289 }
290 }
291}
292
c22b52d6 293 Handle(Adaptor3d_Curve) BRepAdaptor_CompCurve::Trim(const Standard_Real First,
7fd59977 294 const Standard_Real Last,
295 const Standard_Real Tol) const
296{
297 BRepAdaptor_CompCurve C(myWire, IsbyAC, First, Last, Tol);
c22b52d6 298 Handle(BRepAdaptor_CompCurve) HC =
299 new (BRepAdaptor_CompCurve) (C);
7fd59977 300 return HC;
301}
302
303 Standard_Boolean BRepAdaptor_CompCurve::IsClosed() const
304{
305 return myWire.Closed();
306}
307
308 Standard_Boolean BRepAdaptor_CompCurve::IsPeriodic() const
309{
f24150b8 310 return Standard_False;
7fd59977 311
312}
313
314 Standard_Real BRepAdaptor_CompCurve::Period() const
315{
f24150b8 316 return (TLast - TFirst);
7fd59977 317}
318
319 gp_Pnt BRepAdaptor_CompCurve::Value(const Standard_Real U) const
320{
321 Standard_Real u = U, d;
322 Standard_Integer index = CurIndex;
323 Prepare(u, d, index);
324 return myCurves->Value(index).Value(u);
325}
326
327 void BRepAdaptor_CompCurve::D0(const Standard_Real U,
328 gp_Pnt& P) const
329{
330 Standard_Real u = U, d;
331 Standard_Integer index = CurIndex;
332 Prepare(u, d, index);
333 myCurves->Value(index).D0(u, P);
334}
335
336 void BRepAdaptor_CompCurve::D1(const Standard_Real U,
337 gp_Pnt& P,
338 gp_Vec& V) const
339{
340 Standard_Real u = U, d;
341 Standard_Integer index = CurIndex;
342 Prepare(u, d, index);
343 myCurves->Value(index).D1(u, P, V);
344 V*=d;
345}
346
347 void BRepAdaptor_CompCurve::D2(const Standard_Real U,
348 gp_Pnt& P,
349 gp_Vec& V1,
350 gp_Vec& V2) const
351{
352 Standard_Real u = U, d;
353 Standard_Integer index = CurIndex;
354 Prepare(u, d, index);
355 myCurves->Value(index).D2(u, P, V1, V2);
356 V1*=d;
357 V2 *= d*d;
358}
359
360 void BRepAdaptor_CompCurve::D3(const Standard_Real U,
361 gp_Pnt& P,gp_Vec& V1,
362 gp_Vec& V2,
363 gp_Vec& V3) const
364{
365 Standard_Real u = U, d;
366 Standard_Integer index = CurIndex;
367 Prepare(u, d, index);
368 myCurves->Value(index).D3(u, P, V1, V2, V3);
369 V1*=d;
370 V2 *= d*d;
371 V3 *= d*d*d;
372}
373
374 gp_Vec BRepAdaptor_CompCurve::DN(const Standard_Real U,
375 const Standard_Integer N) const
376{
377 Standard_Real u = U, d;
378 Standard_Integer index = CurIndex;
379 Prepare(u, d, index);
380
381 return (myCurves->Value(index).DN(u, N) * Pow(d, N));
382}
383
384 Standard_Real BRepAdaptor_CompCurve::Resolution(const Standard_Real R3d) const
385{
386 Standard_Real Res = 1.e200, r;
387 Standard_Integer ii, L = myCurves->Length();
388 for (ii=1; ii<=L; ii++) {
389 r = myCurves->Value(ii).Resolution(R3d);
390 if (r < Res) Res = r;
391 }
392 return Res;
393}
394
395 GeomAbs_CurveType BRepAdaptor_CompCurve::GetType() const
396{
0d969553 397 return GeomAbs_OtherCurve; //temporary
7fd59977 398// if ( myCurves->Length() > 1) return GeomAbs_OtherCurve;
399// return myCurves->Value(1).GetType();
400}
401
402 gp_Lin BRepAdaptor_CompCurve::Line() const
403{
404 return myCurves->Value(1).Line();
405}
406
407 gp_Circ BRepAdaptor_CompCurve::Circle() const
408{
409 return myCurves->Value(1).Circle();
410}
411
412 gp_Elips BRepAdaptor_CompCurve::Ellipse() const
413{
414 return myCurves->Value(1).Ellipse();
415}
416
417 gp_Hypr BRepAdaptor_CompCurve::Hyperbola() const
418{
419 return myCurves->Value(1).Hyperbola();
420}
421
422 gp_Parab BRepAdaptor_CompCurve::Parabola() const
423{
424 return myCurves->Value(1).Parabola();
425}
426
427 Standard_Integer BRepAdaptor_CompCurve::Degree() const
428{
429 return myCurves->Value(1).Degree();
430}
431
432 Standard_Boolean BRepAdaptor_CompCurve::IsRational() const
433{
434 return myCurves->Value(1).IsRational();
435}
436
437 Standard_Integer BRepAdaptor_CompCurve::NbPoles() const
438{
439 return myCurves->Value(1).NbPoles();
440}
441
442 Standard_Integer BRepAdaptor_CompCurve::NbKnots() const
443{
444 return myCurves->Value(1).NbKnots();
445}
446
447 Handle(Geom_BezierCurve) BRepAdaptor_CompCurve::Bezier() const
448{
449 return myCurves->Value(1).Bezier();
450}
451
452 Handle(Geom_BSplineCurve) BRepAdaptor_CompCurve::BSpline() const
453{
454 return myCurves->Value(1).BSpline();
455}
456
457//=======================================================================
458//function : Prepare
459//purpose :
0d969553
Y
460// When the parameter is close to "node" the rule is determined
461// depending on the sign of tol:
462// - negative -> Rule preceding to the node.
463// - positive -> Rule following after the node.
7fd59977 464//=======================================================================
465
466 void BRepAdaptor_CompCurve::Prepare(Standard_Real& W,
467 Standard_Real& Delta,
75259fc5 468 Standard_Integer& theCurIndex) const
7fd59977 469{
470 Standard_Real f,l, Wtest, Eps;
471 Standard_Integer ii;
472 if (W-TFirst < TLast-W) { Eps = PTol; }
473 else { Eps = -PTol;}
474
475
0d969553 476 Wtest = W+Eps; //Offset to discriminate the nodes
7fd59977 477
0d969553 478 // Find the index
7fd59977 479 Standard_Boolean Trouve = Standard_False;
75259fc5 480 if (myKnots->Value(theCurIndex) > Wtest) {
481 for (ii=theCurIndex-1; ii>0 && !Trouve; ii--)
7fd59977 482 if (myKnots->Value(ii)<= Wtest) {
75259fc5 483 theCurIndex = ii;
7fd59977 484 Trouve = Standard_True;
485 }
75259fc5 486 if (!Trouve) theCurIndex = 1; // Out of limits...
7fd59977 487 }
488
75259fc5 489 else if (myKnots->Value(theCurIndex+1) <= Wtest) {
490 for (ii=theCurIndex+1; ii<=myCurves->Length() && !Trouve; ii++)
7fd59977 491 if (myKnots->Value(ii+1)> Wtest) {
75259fc5 492 theCurIndex = ii;
7fd59977 493 Trouve = Standard_True;
494 }
75259fc5 495 if (!Trouve) theCurIndex = myCurves->Length(); // Out of limits...
7fd59977 496 }
497
0d969553 498 // Invert ?
75259fc5 499 const TopoDS_Edge& E = myCurves->Value(theCurIndex).Edge();
7fd59977 500 TopAbs_Orientation Or = E.Orientation();
501 Standard_Boolean Reverse;
502 Reverse = (Forward && (Or == TopAbs_REVERSED)) ||
503 (!Forward && (Or != TopAbs_REVERSED));
504
0d969553 505 // Calculate the local parameter
7fd59977 506 BRep_Tool::Range(E, f, l);
75259fc5 507 Delta = myKnots->Value(theCurIndex+1) - myKnots->Value(theCurIndex);
7fd59977 508 if (Delta > PTol*1.e-9) Delta = (l-f)/Delta;
509
510 if (Reverse) {
511 Delta *= -1;
75259fc5 512 W = l + (W-myKnots->Value(theCurIndex)) * Delta;
7fd59977 513 }
514 else {
75259fc5 515 W = f + (W-myKnots->Value(theCurIndex)) * Delta;
7fd59977 516 }
517}
518
519void BRepAdaptor_CompCurve::InvPrepare(const Standard_Integer index,
520 Standard_Real& First,
521 Standard_Real& Delta) const
522{
0d969553 523 // Invert?
7fd59977 524 const TopoDS_Edge& E = myCurves->Value(index).Edge();
525 TopAbs_Orientation Or = E.Orientation();
526 Standard_Boolean Reverse;
527 Reverse = (Forward && (Or == TopAbs_REVERSED)) ||
528 (!Forward && (Or != TopAbs_REVERSED));
529
0d969553
Y
530 // Calculate the parameters of reparametrisation
531 // such as : T = Ti + (t-First)*Delta
7fd59977 532 Standard_Real f, l;
533 BRep_Tool::Range(E, f, l);
534 Delta = myKnots->Value(index+1) - myKnots->Value(index);
535 if (l-f > PTol*1.e-9) Delta /= (l-f);
536
537 if (Reverse) {
538 Delta *= -1;
539 First = l;
540 }
541 else {
542 First = f;
543 }
544}