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