0024002: Overall code and build procedure refactoring -- automatic
[occt.git] / src / BRepFill / BRepFill_NSections.cxx
CommitLineData
b311480e 1// Created on: 1998-12-29
2// Created by: Joelle CHAUVET
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
7fd59977 17
7fd59977 18#include <BRep_Builder.hxx>
19#include <BRep_Tool.hxx>
20#include <BRepAdaptor_Curve.hxx>
42cf5bc1 21#include <BRepFill.hxx>
22#include <BRepFill_NSections.hxx>
7fd59977 23#include <BRepLib_MakeEdge.hxx>
42cf5bc1 24#include <BRepLib_MakeWire.hxx>
25#include <BRepLProp.hxx>
26#include <BRepTools_WireExplorer.hxx>
27#include <BSplCLib.hxx>
28#include <Geom_BezierCurve.hxx>
29#include <Geom_BSplineCurve.hxx>
30#include <Geom_BSplineSurface.hxx>
31#include <Geom_Conic.hxx>
7fd59977 32#include <Geom_Curve.hxx>
33#include <Geom_Line.hxx>
34#include <Geom_TrimmedCurve.hxx>
42cf5bc1 35#include <GeomConvert.hxx>
36#include <GeomConvert_ApproxCurve.hxx>
37#include <GeomConvert_CompCurveToBSplineCurve.hxx>
38#include <GeomFill_AppSurf.hxx>
7fd59977 39#include <GeomFill_EvolvedSection.hxx>
40#include <GeomFill_HArray1OfSectionLaw.hxx>
42cf5bc1 41#include <GeomFill_Line.hxx>
7fd59977 42#include <GeomFill_NSections.hxx>
7fd59977 43#include <GeomFill_SectionGenerator.hxx>
42cf5bc1 44#include <GeomFill_SectionLaw.hxx>
45#include <GeomFill_UniformSection.hxx>
46#include <Precision.hxx>
47#include <Standard_Type.hxx>
48#include <TColGeom_SequenceOfCurve.hxx>
7fd59977 49#include <TColgp_HArray1OfPnt.hxx>
7fd59977 50#include <TColStd_HArray1OfInteger.hxx>
42cf5bc1 51#include <TColStd_HArray1OfReal.hxx>
52#include <TopExp.hxx>
53#include <TopoDS.hxx>
54#include <TopoDS_Shape.hxx>
55#include <TopoDS_Vertex.hxx>
56#include <TopoDS_Wire.hxx>
7fd59977 57#include <TopTools_Array1OfShape.hxx>
58
42cf5bc1 59#include <stdio.h>
0797d9d3 60#ifdef OCCT_DEBUG
7fd59977 61static Standard_Boolean Affich = 0;
62#endif
63
64#ifdef DRAW
65#include <DrawTrSurf.hxx>
66#include <DBRep.hxx>
67#endif
68
5e5b6f81 69
70//=======================================================================
71//function : EdgeToBSpline
72//purpose : auxiliary -- get curve from edge and convert it to bspline
73// parameterized from 0 to 1
74//=======================================================================
75
76// NOTE: this code duplicates the same function in BRepOffsetAPI_ThruSections.cxx
77static Handle(Geom_BSplineCurve) EdgeToBSpline (const TopoDS_Edge& theEdge)
78{
79 Handle(Geom_BSplineCurve) aBSCurve;
80 if (BRep_Tool::Degenerated(theEdge)) {
81 // degenerated edge : construction of a point curve
82 TColStd_Array1OfReal aKnots (1,2);
83 aKnots(1) = 0.;
84 aKnots(2) = 1.;
85
86 TColStd_Array1OfInteger aMults (1,2);
87 aMults(1) = 2;
88 aMults(2) = 2;
89
90 TColgp_Array1OfPnt aPoles(1,2);
91 TopoDS_Vertex vf, vl;
92 TopExp::Vertices(theEdge,vl,vf);
93 aPoles(1) = BRep_Tool::Pnt(vf);
94 aPoles(2) = BRep_Tool::Pnt(vl);
95
96 aBSCurve = new Geom_BSplineCurve (aPoles, aKnots, aMults, 1);
97 }
98 else
99 {
100 // get the curve of the edge
101 TopLoc_Location aLoc;
102 Standard_Real aFirst, aLast;
103 Handle(Geom_Curve) aCurve = BRep_Tool::Curve (theEdge, aLoc, aFirst, aLast);
104
105 // convert its part used by edge to bspline; note that if edge curve is bspline,
106 // conversion made via trimmed curve is still needed -- it will copy it, segment
107 // as appropriate, and remove periodicity if it is periodic (deadly for approximator)
108 Handle(Geom_TrimmedCurve) aTrimCurve = new Geom_TrimmedCurve (aCurve, aFirst, aLast);
109
110 // special treatment of conic curve
111 if (aTrimCurve->BasisCurve()->IsKind(STANDARD_TYPE(Geom_Conic)))
112 {
543a9964 113 const Handle(Geom_Curve)& aCurve = aTrimCurve; // to avoid ambiguity
114 GeomConvert_ApproxCurve anAppr (aCurve, Precision::Confusion(), GeomAbs_C1, 16, 14);
5e5b6f81 115 if (anAppr.HasResult())
116 aBSCurve = anAppr.Curve();
117 }
118
119 // general case
120 if (aBSCurve.IsNull())
121 aBSCurve = GeomConvert::CurveToBSplineCurve (aTrimCurve);
122
123 // apply transformation if needed
124 if (! aLoc.IsIdentity())
125 aBSCurve->Transform (aLoc.Transformation());
126
127 // reparameterize to [0,1]
128 TColStd_Array1OfReal aKnots (1, aBSCurve->NbKnots());
129 aBSCurve->Knots (aKnots);
130 BSplCLib::Reparametrize (0., 1., aKnots);
131 aBSCurve->SetKnots (aKnots);
132 }
133
134 // reverse curve if edge is reversed
135 if (theEdge.Orientation() == TopAbs_REVERSED)
136 aBSCurve->Reverse();
137
138 return aBSCurve;
139}
140
7fd59977 141//=======================================================================
142//function : totalsurf
143//purpose :
144//=======================================================================
145
146static Handle(Geom_BSplineSurface) totalsurf(const TopTools_Array2OfShape& shapes,
147 const Standard_Integer NbSects,
148 const Standard_Integer NbEdges,
149 const TColStd_SequenceOfReal& params,
150 const Standard_Boolean w1Point,
151 const Standard_Boolean w2Point,
152 const Standard_Boolean uClosed,
153 const Standard_Boolean vClosed,
154 const Standard_Real myPres3d)
155{
156 Standard_Integer i,j,jdeb=1,jfin=NbSects;
157 TopoDS_Edge edge;
7fd59977 158 TopoDS_Vertex vf,vl;
159
160 GeomFill_SectionGenerator section;
161 Handle(Geom_BSplineSurface) surface;
162 Handle(Geom_BSplineCurve) BS, BS1;
7fd59977 163
164 if (w1Point) {
165 jdeb++;
166 edge = TopoDS::Edge(shapes.Value(1,1));
167 TopExp::Vertices(edge,vl,vf);
168 TColgp_Array1OfPnt Extremities(1,2);
169 Extremities(1) = BRep_Tool::Pnt(vf);
170 Extremities(2) = BRep_Tool::Pnt(vl);
171 TColStd_Array1OfReal Bounds(1,2);
172 Bounds(1) = 0.;
173 Bounds(2) = 1.;
7fd59977 174 TColStd_Array1OfInteger Mult(1,2);
5e5b6f81 175 Mult(1) = 2;
176 Mult(2) = 2;
7fd59977 177 Handle(Geom_BSplineCurve) BSPoint
5e5b6f81 178 = new Geom_BSplineCurve(Extremities,Bounds,Mult, 1);
7fd59977 179 section.AddCurve(BSPoint);
180 }
181
182 if (w2Point) {
183 jfin--;
184 }
185
186 for (j=jdeb; j<=jfin; j++) {
187
0d969553 188 // case of looping sections
7fd59977 189 if (j==jfin && vClosed) {
190 section.AddCurve(BS1);
191 }
192
193 else {
194 // read the first edge to initialise CompBS;
5e5b6f81 195 TopoDS_Edge aPrevEdge = TopoDS::Edge (shapes.Value(1,j));
196 Handle(Geom_BSplineCurve) curvBS = EdgeToBSpline (aPrevEdge);
7fd59977 197
0d969553 198 // initialization
7fd59977 199 GeomConvert_CompCurveToBSplineCurve CompBS(curvBS);
200
201 for (i=2; i<=NbEdges; i++) {
202 // read the edge
5e5b6f81 203 TopoDS_Edge aNextEdge = TopoDS::Edge (shapes.Value(i,j));
204 curvBS = EdgeToBSpline (aNextEdge);
7fd59977 205
206 // concatenation
207 TopoDS_Vertex ComV;
208 Standard_Real epsV;
5e5b6f81 209 Standard_Boolean Bof = TopExp::CommonVertex(aPrevEdge, aNextEdge, ComV);
7fd59977 210 if (Bof) epsV = BRep_Tool::Tolerance(ComV);
211 else epsV = Precision::Confusion();
212 Bof = CompBS.Add(curvBS, epsV, Standard_True, Standard_False, 1);
213 if (!Bof) Bof = CompBS.Add(curvBS, 200*epsV,
214 Standard_True, Standard_False, 1);
5e5b6f81 215
216 // remember previous edge
217 aPrevEdge = aNextEdge;
7fd59977 218 }
219
0d969553 220 // return the final section
7fd59977 221 BS = CompBS.BSplineCurve();
222 section.AddCurve(BS);
223
0d969553 224 // case of looping sections
7fd59977 225 if (j==jdeb && vClosed) {
226 BS1 = BS;
227 }
228
229 }
230 }
231
232 if (w2Point) {
233 edge = TopoDS::Edge(shapes.Value(NbEdges,NbSects));
234 TopExp::Vertices(edge,vl,vf);
235 TColgp_Array1OfPnt Extremities(1,2);
236 Extremities(1) = BRep_Tool::Pnt(vf);
237 Extremities(2) = BRep_Tool::Pnt(vl);
238 TColStd_Array1OfReal Bounds(1,2);
239 Bounds(1) = 0.;
240 Bounds(2) = 1.;
7fd59977 241 TColStd_Array1OfInteger Mult(1,2);
5e5b6f81 242 Mult(1) = 2;
243 Mult(2) = 2;
7fd59977 244 Handle(Geom_BSplineCurve) BSPoint
5e5b6f81 245 = new Geom_BSplineCurve(Extremities,Bounds,Mult,1);
7fd59977 246 section.AddCurve(BSPoint);
247 }
248
249 Handle(TColStd_HArray1OfReal) HPar
250 = new TColStd_HArray1OfReal(1,params.Length());
251 for (i=1; i<=params.Length(); i++) {
252 HPar->SetValue(i,params(i));
253 }
254 section.SetParam(HPar);
255 section.Perform(Precision::PConfusion());
256 Handle(GeomFill_Line) line = new GeomFill_Line(NbSects);
257 Standard_Integer nbIt = 0, degmin = 2, degmax = 6;
258 Standard_Boolean knownP = Standard_True;
259 GeomFill_AppSurf anApprox(degmin, degmax, myPres3d, myPres3d, nbIt, knownP);
260 Standard_Boolean SpApprox = Standard_True;
261 anApprox.Perform(line, section, SpApprox);
262 Standard_Boolean uperiodic = uClosed;
263 Standard_Boolean vperiodic = vClosed;
264 Standard_Integer nup = anApprox.SurfPoles().ColLength(),
265 nvp = anApprox.SurfPoles().RowLength();
266 TColStd_Array1OfInteger Umults(1,anApprox.SurfUKnots().Length());
267 Umults = anApprox.SurfUMults();
268 TColStd_Array1OfInteger Vmults(1,anApprox.SurfVKnots().Length());
269 Vmults = anApprox.SurfVMults();
270
271 if (uperiodic) {
272 Standard_Integer nbuk = anApprox.SurfUKnots().Length();
273 Umults(1) --;
274 Umults(nbuk) --;
275 nup --;
276 }
277
278 if (vperiodic) {
279 Standard_Integer nbvk = anApprox.SurfVKnots().Length();
280 Vmults(1) --;
281 Vmults(nbvk) --;
282 nvp --;
283 }
284
285 TColgp_Array2OfPnt poles (1, nup, 1, nvp);
286 TColStd_Array2OfReal weights(1, nup, 1, nvp);
287 for (j = 1; j <= nvp; j++) {
288 for (i = 1; i <= nup; i++) {
289 poles(i, j) = anApprox.SurfPoles()(i,j);
290 weights(i, j) = anApprox.SurfWeights()(i,j);
291 }
292 }
293
294 // To create non-rational surface if possible
295 Standard_Real TolEps = 1.e-13;
296 Standard_Boolean Vrational = Standard_False, Urational = Standard_False;
297 for (j = 1; j <= weights.UpperCol(); j++)
298 if (!Vrational)
299 for (i = 1; i <= weights.UpperRow()-1; i++)
300 {
301 //Standard_Real signeddelta = weights(i,j) - weights(i+1,j);
302 Standard_Real delta = Abs( weights(i,j) - weights(i+1,j) );
303// Standard_Real eps = Epsilon( Abs(weights(i,j)) );
304 if (delta > TolEps/* || delta > 3.*eps*/)
305 {
306 Vrational = Standard_True;
307 break;
308 }
309 }
310 for (i = 1; i <= weights.UpperRow(); i++)
311 if (!Urational)
312 for (j = 1; j <= weights.UpperCol()-1; j++)
313 {
314 //Standard_Real signeddelta = weights(i,j) - weights(i,j+1);
315 Standard_Real delta = Abs( weights(i,j) - weights(i,j+1) );
316// Standard_Real eps = Epsilon( Abs(weights(i,j)) );
317 if (delta > TolEps/* || delta > 3.*eps*/)
318 {
319 Urational = Standard_True;
320 break;
321 }
322 }
323 if (!Vrational && !Urational)
324 {
325 Standard_Real theWeight = weights(1,1);
326 for (i = 1; i <= weights.UpperRow(); i++)
327 for (j = 1; j <= weights.UpperCol(); j++)
328 weights(i,j) = theWeight;
329 }
330
331 surface =
332 new Geom_BSplineSurface(poles, weights,
333 anApprox.SurfUKnots(), anApprox.SurfVKnots(),
334 Umults, Vmults,
335 anApprox.UDegree(), anApprox.VDegree(),
336 uperiodic, vperiodic);
337 return surface;
338
339}
340
341
342//=======================================================================
343//function : Create
344//purpose : WSeq
345//=======================================================================
346
347BRepFill_NSections::BRepFill_NSections(const TopTools_SequenceOfShape& S,
348 const Standard_Boolean Build)
349
350{
351 myShapes = S;
352 VFirst = 0.;
353 VLast = 1.;
354 TColStd_SequenceOfReal par;
355 par.Clear();
356 for (Standard_Integer i=1;i<=S.Length();i++) {
357 par.Append(i-1);
358 }
359 myParams = par;
360 Init(par,Build);
361}
362
363//=======================================================================
364//function : Create
365//purpose : WSeq + Param
366//=======================================================================
367
368BRepFill_NSections::BRepFill_NSections(const TopTools_SequenceOfShape& S,
d7325741 369 const GeomFill_SequenceOfTrsf& Transformations,
7fd59977 370 const TColStd_SequenceOfReal & P,
371 const Standard_Real VF,
372 const Standard_Real VL,
373 const Standard_Boolean Build)
374
375{
0797d9d3 376#ifdef OCCT_DEBUG
7fd59977 377 if ( Affich) {
378#ifdef DRAW
379 Standard_Integer NBSECT = 0;
380 for (Standard_Integer i=1;i<=S.Length();i++) {
381 NBSECT++;
382 char name[256];
383 sprintf(name,"WIRE_%d",NBSECT);
384 DBRep::Set(name,TopoDS::Wire(S.Value(i)));
385 }
386#endif
387 }
388#endif
389 Standard_Boolean ok = Standard_True;
390 for (Standard_Integer iseq=1;iseq<P.Length();iseq++) {
391 ok = ok && (P.Value(iseq)<P.Value(iseq+1));
392 }
393 if (ok) {
394 myParams = P;
395 myShapes = S;
d7325741 396 myTrsfs = Transformations;
7fd59977 397 VFirst = VF;
398 VLast = VL;
399 Init(P,Build);
400 }
401}
402
403//=======================================================================
404//function : Init
0d969553 405//purpose : Create a table of GeomFill_SectionLaw
7fd59977 406//=======================================================================
407void BRepFill_NSections::Init(const TColStd_SequenceOfReal & P,
408 const Standard_Boolean Build)
409{
410 BRepTools_WireExplorer wexp;
411// Class BRep_Tool without fields and without Constructor :
412// BRep_Tool B;
413 TopoDS_Edge E;
414 Standard_Integer ii, NbEdge, jj, NbSects = P.Length();
415 Standard_Integer ideb = 1, ifin = NbSects;
416 Standard_Boolean wClosed, w1Point = Standard_True,
417 w2Point = Standard_True;
418 Standard_Real First, Last;
419 TopoDS_Wire W;
420
0d969553 421 // Check if the start and end wires are punctual
7fd59977 422 W = TopoDS::Wire(myShapes(1));
423 for (wexp.Init(W); wexp.More(); wexp.Next())
424// w1Point = w1Point && B.Degenerated(wexp.Current());
425 w1Point = w1Point && BRep_Tool::Degenerated(wexp.Current());
426 if (w1Point) ideb++;
427 W = TopoDS::Wire(myShapes(NbSects));
428 for (wexp.Init(W); wexp.More(); wexp.Next())
429// w2Point = w2Point && B.Degenerated(wexp.Current());
430 w2Point = w2Point && BRep_Tool::Degenerated(wexp.Current());
431 if (w2Point) ifin--;
432
0d969553 433 // Check if the start and end wires are identical
7fd59977 434 vclosed = myShapes(1).IsSame(myShapes(NbSects));
435
0d969553 436 // Count the number of non-degenerated edges
7fd59977 437 W = TopoDS::Wire(myShapes(ideb));
438 for (NbEdge=0, wexp.Init(W); wexp.More(); wexp.Next())
439// if (! B.Degenerated(wexp.Current())) NbEdge++;
440 if (! BRep_Tool::Degenerated(wexp.Current())) NbEdge++;
441
7fd59977 442 myEdges = new (TopTools_HArray2OfShape) (1, NbEdge, 1, NbSects);
443
0d969553 444 // Fill tables
7fd59977 445 uclosed = Standard_True;
446 for (jj=ideb;jj<=ifin;jj++){
447
448 W = TopoDS::Wire(myShapes(jj));
449
450 for (ii=1, wexp.Init(W); ii<=NbEdge ; wexp.Next(), ii++) {
451 E = wexp.Current();
452
453// if ( ! B.Degenerated(E)) {
454 if ( ! BRep_Tool::Degenerated(E)) {
455 myEdges->SetValue(ii,jj, E);
456 }
457 }
458
0d969553 459 // Is the law closed by U ?
7fd59977 460
461 wClosed = W.Closed();
462 if (!wClosed) {
0d969553 463 // if unsure about the flag, make check
7fd59977 464 TopoDS_Edge Edge1, Edge2;
465 TopoDS_Vertex V1,V2;
466 Edge1 = TopoDS::Edge (myEdges->Value(NbEdge,jj));
467 Edge2 = TopoDS::Edge (myEdges->Value(1,jj));
468
469 if ( Edge1.Orientation() == TopAbs_REVERSED) {
470 V1 = TopExp::FirstVertex(Edge1);
471 }
472 else {
473 V1 = TopExp::LastVertex(Edge1);
474 }
475 if ( Edge2.Orientation() == TopAbs_REVERSED) {
476 V2 = TopExp::LastVertex(Edge2);
477 }
478 else {
479 V2 = TopExp::FirstVertex(Edge2);
480 }
481 if (V1.IsSame(V2)) {
482 wClosed = Standard_True;
483 }
484 else {
485 BRepAdaptor_Curve Curve1(Edge1);
486 BRepAdaptor_Curve Curve2(Edge2);
487 Standard_Real U1 = BRep_Tool::Parameter(V1,Edge1);
488 Standard_Real U2 = BRep_Tool::Parameter(V2,Edge2);
489 Standard_Real Eps = BRep_Tool::Tolerance(V2) +
490 BRep_Tool::Tolerance(V1);
491
492 wClosed = Curve1.Value(U1).IsEqual(Curve2.Value(U2), Eps);
493 }
494 }
495 if (!wClosed) uclosed = Standard_False;
496 }
497
0d969553 498 // point sections at end
7fd59977 499 if (w1Point) {
500 W = TopoDS::Wire(myShapes(1));
501 wexp.Init(W);
502 E = wexp.Current();
503 for (ii=1; ii<=NbEdge ; ii++) {
504 myEdges->SetValue(ii, 1, E);
505 }
506 }
507
508 if (w2Point) {
509 W = TopoDS::Wire(myShapes(NbSects));
510 wexp.Init(W);
511 E = wexp.Current();
512 for (ii=1; ii<=NbEdge ; ii++) {
513 myEdges->SetValue(ii, NbSects, E);
514 }
515 }
516
517
518 myLaws = new (GeomFill_HArray1OfSectionLaw) (1, NbEdge);
519
520 Standard_Real tol = Precision::Confusion();
521 mySurface = totalsurf(myEdges->Array2(),myShapes.Length(),NbEdge,
522 myParams,w1Point,w2Point,uclosed,vclosed,tol);
523
0d969553
Y
524 // Increase the degree so that the position D2
525 // on GeomFill_NSections could be correct
526 // see comments in GeomFill_NSections
7fd59977 527 if (mySurface->VDegree()<2) {
528 mySurface->IncreaseDegree(mySurface->UDegree(),2);
529 }
530#ifdef DRAW
531 if ( Affich) {
532 char* name = new char[100];
533 sprintf(name,"Ref_Surf");
534 DrawTrSurf::Set(name,mySurface);
535 }
536#endif
537
0d969553 538 // Fill tables
7fd59977 539 if (Build) {
540 for (ii=1; ii<=NbEdge ; ii++) {
541 TColGeom_SequenceOfCurve NC;
542 NC.Clear();
543 for (jj=1;jj<=NbSects;jj++) {
544 E = TopoDS::Edge (myEdges->Value(ii,jj));
545 Handle(Geom_Curve) C;
546// if (B.Degenerated(E)) {
547 if (BRep_Tool::Degenerated(E)) {
548 TopoDS_Vertex vf,vl;
549 TopExp::Vertices(E,vl,vf);
550 TColgp_Array1OfPnt Extremities(1,2);
551 Extremities(1) = BRep_Tool::Pnt(vf);
552 Extremities(2) = BRep_Tool::Pnt(vl);
553 TColStd_Array1OfReal Bounds(1,2);
554 Bounds(1) = 0.;
555 Bounds(2) = 1.;
556 TColStd_Array1OfInteger Mult(1,2);
557 Mult(1) = 2;
558 Mult(2) = 2;
559 Handle(Geom_BSplineCurve) BSPoint
560 = new Geom_BSplineCurve(Extremities,Bounds,Mult,1);
561 C = BSPoint;
562 }
563 else {
564 C = BRep_Tool::Curve(E,First,Last);
565
566 if (E.Orientation() == TopAbs_REVERSED) {
567 Standard_Real aux;
568 Handle(Geom_Curve) CBis;
0d969553 569 CBis = C->Reversed(); // To avoid the spoiling of the topology
7fd59977 570 aux = C->ReversedParameter(First);
571 First = C->ReversedParameter(Last);
572 Last = aux;
573 C = CBis;
574 }
da72a17c 575 if ((ii>1) || (!BRep_Tool::IsClosed(E)) ) { // Cut C
7fd59977 576 Handle(Geom_TrimmedCurve) TC =
577 new (Geom_TrimmedCurve) (C,First, Last);
578 C = TC;
579 }
0d969553 580 // otherwise preserve the integrity of the curve
7fd59977 581 }
582 NC.Append(C);
583 }
584
585 Standard_Real Ufirst = ii-1;
586 Standard_Real Ulast = ii;
d7325741 587 myLaws->ChangeValue(ii) = new (GeomFill_NSections)(NC, myTrsfs, myParams,
7fd59977 588 Ufirst,Ulast,
589 VFirst,VLast,
590 mySurface);
591 }
592
593 }
594
595}
596
597
598//=======================================================================
599//function : IsVertex
600//purpose :
601//=======================================================================
602 Standard_Boolean BRepFill_NSections::IsVertex() const
603{
604 return Standard_False;
605}
606
607//=======================================================================
608//function : IsConstant
609//purpose :
610//=======================================================================
611 Standard_Boolean BRepFill_NSections::IsConstant() const
612{
613 return Standard_False;
614}
615
616//=======================================================================
617//function : Vertex
618//purpose :
619//=======================================================================
620 TopoDS_Vertex
621 BRepFill_NSections::Vertex(const Standard_Integer Index,
622 const Standard_Real Param) const
623{
624 BRep_Builder B;
625 TopoDS_Vertex V;
626 B.MakeVertex(V);
627 gp_Pnt P;
628
629 if (Index <= myEdges->ColLength()) {
630 Handle(Geom_BSplineCurve) Curve
631 = Handle(Geom_BSplineCurve)::DownCast(myLaws->Value(Index)->
632 BSplineSurface()->VIso(Param));
633 Standard_Real first = Curve ->FirstParameter();
634 Curve->D0(first, P);
635 B.UpdateVertex(V, P, Precision::Confusion());
636 }
637 else if (Index == myEdges->ColLength()+1) {
638 Handle(Geom_BSplineCurve) Curve
639 = Handle(Geom_BSplineCurve)::DownCast(myLaws->Value(Index-1)->
640 BSplineSurface()->VIso(Param));
641 Standard_Real last = Curve ->LastParameter();
642 Curve->D0(last, P);
643 B.UpdateVertex(V, P, Precision::Confusion());
644 }
645
646 return V;
647}
648
649
650///=======================================================================
651//function : VertexTol
0d969553 652//purpose : Evaluate the hole between 2 edges of the section
7fd59977 653//=======================================================================
654 Standard_Real BRepFill_NSections::VertexTol(const Standard_Integer Index,
655 const Standard_Real Param) const
656{
657 Standard_Real Tol = Precision::Confusion();
658 Standard_Integer I1, I2;
659 if ( (Index==0) || (Index==myEdges->ColLength()) ) {
0d969553 660 if (!uclosed) return Tol; //The least possible error
7fd59977 661 I1 = myEdges->ColLength();
662 I2 = 1;
663 }
664 else {
665 I1 = Index;
666 I2 = I1 +1;
667 }
668
669 Handle(GeomFill_SectionLaw) Loi;
670 Standard_Integer NbPoles, NbKnots, Degree;
671 Handle(TColgp_HArray1OfPnt) Poles;
672 Handle(TColStd_HArray1OfReal) Knots, Weigth;
673 Handle(TColStd_HArray1OfInteger) Mults;
674 Handle(Geom_BSplineCurve) BS;
675 gp_Pnt PFirst;
676
677 Loi = myLaws->Value(I1);
678 Loi->SectionShape( NbPoles, NbKnots, Degree);
679 Poles = new (TColgp_HArray1OfPnt) (1, NbPoles);
680 Weigth = new (TColStd_HArray1OfReal) (1, NbPoles);
681 Loi->D0(Param, Poles->ChangeArray1(), Weigth->ChangeArray1());
682 Knots = new (TColStd_HArray1OfReal) (1, NbKnots);
683 Loi->Knots(Knots->ChangeArray1());
684 Mults = new (TColStd_HArray1OfInteger) (1, NbKnots);
685 Loi->Mults(Mults->ChangeArray1());
686 BS = new (Geom_BSplineCurve) (Poles->Array1(),
687 Weigth->Array1(),
688 Knots->Array1(),
689 Mults->Array1(),
690 Degree,
691 Loi->IsUPeriodic());
692 PFirst = BS->Value( Knots->Value(Knots->Length()) );
693
694 Loi = myLaws->Value(I2);
695 Loi->SectionShape( NbPoles, NbKnots, Degree);
696 Poles = new (TColgp_HArray1OfPnt) (1, NbPoles);
697 Weigth = new (TColStd_HArray1OfReal) (1, NbPoles);
698 Loi->D0(Param, Poles->ChangeArray1(), Weigth->ChangeArray1());
699 Knots = new (TColStd_HArray1OfReal) (1, NbKnots);
700 Loi->Knots(Knots->ChangeArray1());
701 Mults = new (TColStd_HArray1OfInteger) (1, NbKnots);
702 Loi->Mults(Mults->ChangeArray1());
703 BS = new (Geom_BSplineCurve) (Poles->Array1(),
704 Weigth->Array1(),
705 Knots->Array1(),
706 Mults->Array1(),
707 Degree,
708 Loi->IsUPeriodic());
709 Tol += PFirst.Distance(BS->Value( Knots->Value(1)));
710 return Tol;
711}
712
713//=======================================================================
714//function : ConcatenedLaw
715//purpose :
716//=======================================================================
717
718 Handle(GeomFill_SectionLaw) BRepFill_NSections::ConcatenedLaw() const
719{
720 Handle(GeomFill_SectionLaw) Law;
721 if (myLaws->Length() == 1)
722 return myLaws->Value(1);
723 else {
724 Standard_Real Ufirst, Ulast, Vfirst, Vlast;
725 mySurface->Bounds(Ufirst, Ulast, Vfirst, Vlast);
726 TColGeom_SequenceOfCurve NCompo;
727 NCompo.Clear();
728 for (Standard_Integer jj=1; jj<=myShapes.Length(); jj++) {
729 NCompo.Append(mySurface->VIso(myParams(jj)));
730 }
d7325741 731 Law = new (GeomFill_NSections)(NCompo, myTrsfs, myParams,
7fd59977 732 Ufirst, Ulast,
733 Vfirst, Vlast,
734 mySurface);
735 }
736 return Law;
737}
738
739//=======================================================================
740//function : Continuity
741//purpose :
742//=======================================================================
743 GeomAbs_Shape BRepFill_NSections::Continuity(const Standard_Integer Index,
744 const Standard_Real TolAngular) const
745{
746
747 Standard_Integer jj;
748 GeomAbs_Shape cont_jj;
7fd59977 749 GeomAbs_Shape cont = GeomAbs_C0;
7fd59977 750
751 for (jj=1; jj<=myShapes.Length(); jj++) {
752
753 TopoDS_Edge Edge1, Edge2;
754 if ( (Index==0) || (Index==myEdges->ColLength()) ) {
0d969553 755 if (!uclosed) return GeomAbs_C0; //The least possible error
7fd59977 756
757 Edge1 = TopoDS::Edge (myEdges->Value(myEdges->ColLength(),jj));
758 Edge2 = TopoDS::Edge (myEdges->Value(1,jj));
759 }
760 else {
761 Edge1 = TopoDS::Edge (myEdges->Value(Index,jj));
762 Edge2 = TopoDS::Edge (myEdges->Value(Index+1,jj));
763 }
764
765 TopoDS_Vertex V1,V2;
766 if ( Edge1.Orientation() == TopAbs_REVERSED) {
767 V1 = TopExp::FirstVertex(Edge1);
768 }
769 else {
770 V1 = TopExp::LastVertex(Edge1);
771 }
772 if ( Edge2.Orientation() == TopAbs_REVERSED) {
773 V2 = TopExp::LastVertex(Edge2);
774 }
775 else {
776 V2 = TopExp::FirstVertex(Edge2);
777 }
778
779 if (BRep_Tool::Degenerated(Edge1) || BRep_Tool::Degenerated(Edge2))
780 cont_jj = GeomAbs_CN;
781 else
782 {
783 Standard_Real U1 = BRep_Tool::Parameter(V1,Edge1);
784 Standard_Real U2 = BRep_Tool::Parameter(V2,Edge2);
785 BRepAdaptor_Curve Curve1(Edge1);
786 BRepAdaptor_Curve Curve2(Edge2);
787 Standard_Real Eps = BRep_Tool::Tolerance(V2) +
788 BRep_Tool::Tolerance(V1);
789 cont_jj = BRepLProp::Continuity(Curve1,Curve2,U1,U2, Eps, TolAngular);
790 }
791
792 if (jj==1) cont = cont_jj;
793 if (cont>cont_jj) cont = cont_jj;
794
795 }
796
797 return cont;
798}
799
800//=======================================================================
801//function : D0
802//purpose :
803//=======================================================================
804 void BRepFill_NSections::D0(const Standard_Real V, TopoDS_Shape& S)
805{
806 TopoDS_Wire W;
807 BRepLib_MakeWire MW;
808 Standard_Integer ii, NbEdge = myLaws->Length();
809 for (ii=1; ii<=NbEdge ; ii++) {
810 Handle(Geom_BSplineCurve) Curve
811 = Handle(Geom_BSplineCurve)::DownCast(myLaws->Value(ii)->BSplineSurface()->VIso(V));
812 Standard_Real first = Curve ->FirstParameter(),
813 last = Curve ->LastParameter();
814 TopoDS_Edge E = BRepLib_MakeEdge(Curve,first,last);
815 MW.Add(E);
816 }
817 TopAbs_Orientation Orien = TopAbs_FORWARD;
818 TopoDS_Shape aLocalShape = MW.Wire().Oriented(Orien);
819 S = TopoDS::Wire(aLocalShape);
820// S = TopoDS::Wire(MW.Wire().Oriented(Orien));
821
822}
823