0022312: Translation of french commentaries in OCCT files
[occt.git] / src / BRepOffsetAPI / BRepOffsetAPI_ThruSections.cxx
CommitLineData
7fd59977 1// File: BRepOffsetAPI_ThruSections.cxx
2// Created: Tue Jul 18 16:18:09 1995
3// Author: Jing Cheng MEI
4// <mei@junon>
5// Modified: Mon Jan 12 10:50:10 1998
6// Author: Joelle CHAUVET
7// <jct@sgi64>
8// gestion automatique de l'origine et de l'orientation
9// avec la methode ArrangeWires
10// Modified: Mon Jan 19 10:11:56 1998
11// Author: Joelle CHAUVET
12// <jct@sgi64>
13// traitement des cas particuliers cylindre, cone, plan
14// (methodes DetectKPart et CreateKPart)
15// Modified: Mon Feb 23 09:28:46 1998
16// Author: Joelle CHAUVET
17// <jct@sgi64>
18// traitement des sections avec nombre d'elements different
19// + quelques ameliorations pour les cas particuliers
20// + cas de la derniere section ponctuelle
21// Modified: Mon Apr 6 15:47:44 1998
22// Author: Joelle CHAUVET
23// <jct@sgi64>
24// traitement des cas particuliers deplace dans BRepFill
25// Modified: Thu Apr 30 15:24:17 1998
26// Author: Joelle CHAUVET
27// <jct@sgi64>
28// separation sections fermees / sections ouvertes + debug
29// Modified: Fri Jul 10 11:23:35 1998
30// Author: Joelle CHAUVET
31// <jct@sgi64>
32// surface de CreateSmoothed par concatenation,approximation
33// et segmentation (PRO13924, CTS21295)
34// Modified: Tue Jul 21 16:48:35 1998
35// Author: Joelle CHAUVET
36// <jct@sgi64>
37// pb de ratio (BUC60281)
38// Modified: Thu Jul 23 11:38:36 1998
39// Author: Joelle CHAUVET
40// <jct@sgi64>
41// sections bouclantes
42// Modified: Fri Aug 28 10:13:44 1998
43// Author: Joelle CHAUVET
44// <jct@sgi64>
45// traitement des sections ponctuelles
46// dans l'historique (cf. loft06 et loft09)
47// et dans le cas des solides
48// Modified: Tue Nov 3 10:06:15 1998
49// Author: Joelle CHAUVET
50// <jct@sgi64>
51// utilisation de BRepFill_CompatibleWires
52
53
54#include <BRepOffsetAPI_ThruSections.ixx>
55
56#include <Precision.hxx>
57#include <Standard_DomainError.hxx>
58
59#include <gp_Pnt.hxx>
60#include <gp_Pnt2d.hxx>
61#include <gp_Dir2d.hxx>
62#include <TColgp_Array1OfPnt.hxx>
63
64#include <GeomAbs_Shape.hxx>
65#include <Geom_Curve.hxx>
66#include <Geom_BSplineSurface.hxx>
67#include <Geom_TrimmedCurve.hxx>
68#include <Geom_BezierCurve.hxx>
69#include <Geom_Conic.hxx>
70#include <Geom2d_Line.hxx>
71#include <GeomFill_Line.hxx>
72#include <GeomFill_AppSurf.hxx>
73#include <GeomFill_SectionGenerator.hxx>
74#include <GeomConvert_CompCurveToBSplineCurve.hxx>
75#include <GeomConvert.hxx>
76#include <GeomConvert_ApproxCurve.hxx>
77#include <Geom_BSplineCurve.hxx>
78#include <BSplCLib.hxx>
79
80#include <TopAbs.hxx>
81#include <TopoDS.hxx>
82#include <TopoDS_Solid.hxx>
83#include <TopoDS_Face.hxx>
84#include <TopoDS_Edge.hxx>
85#include <TopoDS_Vertex.hxx>
86#include <TopoDS_Wire.hxx>
87#include <TopLoc_Location.hxx>
88#include <TopTools_Array1OfShape.hxx>
89#include <TopTools_ListIteratorOfListOfShape.hxx>
90#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
91#include <TopExp.hxx>
92#include <TopoDS_Iterator.hxx>
93
94
95#include <BRep_Builder.hxx>
96#include <BRep_Tool.hxx>
97#include <BRepTools_WireExplorer.hxx>
98
99#include <BRepLib.hxx>
100#include <BRepClass3d_SolidClassifier.hxx>
101
102#include <BRepFill_Generator.hxx>
103#include <BRepFill_CompatibleWires.hxx>
104
105#include <BRepBuilderAPI_MakeFace.hxx>
106#include <BRepBuilderAPI_FindPlane.hxx>
107
108
109
110
111//=======================================================================
112//function : PerformPlan
0d969553 113//purpose : Construct a plane of filling if exists
7fd59977 114//=======================================================================
115
116static Standard_Boolean PerformPlan(const TopoDS_Wire& W,
117 const Standard_Real presPln,
118 TopoDS_Face& theFace)
119{
120 Standard_Boolean isDegen = Standard_True;
121 TopoDS_Iterator iter(W);
122 for (; iter.More(); iter.Next())
123 {
124 const TopoDS_Edge& anEdge = TopoDS::Edge(iter.Value());
125 if (!BRep_Tool::Degenerated(anEdge))
126 isDegen = Standard_False;
127 }
128 if (isDegen)
129 return Standard_True;
130
131 Standard_Boolean Ok = Standard_False;
132 if (!W.IsNull()) {
133 BRepBuilderAPI_FindPlane Searcher( W, presPln );
134 if (Searcher.Found())
135 {
136 theFace = BRepBuilderAPI_MakeFace(Searcher.Plane(), W);
137 Ok = Standard_True;
138 }
139 else // try to find another surface
140 {
141 BRepBuilderAPI_MakeFace MF( W );
142 if (MF.IsDone())
143 {
144 theFace = MF.Face();
145 Ok = Standard_True;
146 }
147 }
148 }
149
150 return Ok;
151}
152
153//=============================================================================
154//function : IsSameOriented
155//purpose : Checks whether aFace is oriented to the same side as aShell or not
156//=============================================================================
157
158static Standard_Boolean IsSameOriented(const TopoDS_Shape& aFace,
159 const TopoDS_Shape& aShell)
160{
161 TopExp_Explorer Explo(aFace, TopAbs_EDGE);
162 TopoDS_Shape anEdge = Explo.Current();
163 TopAbs_Orientation Or1 = anEdge.Orientation();
164
165 TopTools_IndexedDataMapOfShapeListOfShape EFmap;
166 TopExp::MapShapesAndAncestors( aShell, TopAbs_EDGE, TopAbs_FACE, EFmap );
167
168 const TopoDS_Shape& AdjacentFace = EFmap.FindFromKey(anEdge).First();
169 TopoDS_Shape theEdge;
170 for (Explo.Init(AdjacentFace, TopAbs_EDGE); Explo.More(); Explo.Next())
171 {
172 theEdge = Explo.Current();
173 if (theEdge.IsSame(anEdge))
174 break;
175 }
176
177 TopAbs_Orientation Or2 = theEdge.Orientation();
178 if (Or1 == Or2)
179 return Standard_False;
180 return Standard_True;
181}
182
183//=======================================================================
184//function : MakeSolid
185//purpose :
186//=======================================================================
187
188static TopoDS_Solid MakeSolid(TopoDS_Shell& shell, const TopoDS_Wire& wire1,
189 const TopoDS_Wire& wire2, const Standard_Real presPln,
190 TopoDS_Face& face1, TopoDS_Face& face2)
191{
192 if (shell.IsNull())
193 StdFail_NotDone::Raise("Thrusections is not build");
194 Standard_Boolean B = shell.Closed();
195 BRep_Builder BB;
196
197 if (!B)
198 {
0d969553 199 // It is necessary to close the extremities
7fd59977 200 B = PerformPlan(wire1, presPln, face1);
201 if (B) {
202 B = PerformPlan(wire2, presPln, face2);
203 if (B) {
204 if (!face1.IsNull() && !IsSameOriented( face1, shell ))
205 face1.Reverse();
206 if (!face2.IsNull() && !IsSameOriented( face2, shell ))
207 face2.Reverse();
208
209 if (!face1.IsNull())
210 BB.Add(shell, face1);
211 if (!face2.IsNull())
212 BB.Add(shell, face2);
213
214 shell.Closed(Standard_True);
215 }
216 }
217 }
218
219 TopoDS_Solid solid;
220 BB.MakeSolid(solid);
221 BB.Add(solid, shell);
222
223 // verify the orientation the solid
224 BRepClass3d_SolidClassifier clas3d(solid);
225 clas3d.PerformInfinitePoint(Precision::Confusion());
226 if (clas3d.State() == TopAbs_IN) {
227 BB.MakeSolid(solid);
228 TopoDS_Shape aLocalShape = shell.Reversed();
229 BB.Add(solid, TopoDS::Shell(aLocalShape));
230// B.Add(solid, TopoDS::Shell(newShell.Reversed()));
231 }
232
233 solid.Closed(Standard_True);
234 return solid;
235}
236
237
238//=======================================================================
239//function : BRepOffsetAPI_ThruSections
240//purpose :
241//=======================================================================
242
243BRepOffsetAPI_ThruSections::BRepOffsetAPI_ThruSections(const Standard_Boolean isSolid, const Standard_Boolean ruled,
244 const Standard_Real pres3d):
245 myIsSolid(isSolid), myIsRuled(ruled), myPres3d(pres3d)
246{
247 myWCheck = Standard_True;
248//----------------------------
249 myParamType = Approx_ChordLength;
250 myDegMax = 8;
251 myContinuity = GeomAbs_C2;
252 myCritWeights[0] = .4;
253 myCritWeights[1] = .2;
254 myCritWeights[2] = .4;
255 myUseSmoothing = Standard_False;
256}
257
258
259//=======================================================================
260//function : Init
261//purpose :
262//=======================================================================
263
264void BRepOffsetAPI_ThruSections::Init(const Standard_Boolean isSolid, const Standard_Boolean ruled,
265 const Standard_Real pres3d)
266{
267 myIsSolid = isSolid;
268 myIsRuled = ruled;
269 myPres3d = pres3d;
270 myWCheck = Standard_True;
271//----------------------------
272 myParamType = Approx_ChordLength;
273 myDegMax = 6;
274 myContinuity = GeomAbs_C2;
275 myCritWeights[0] = .4;
276 myCritWeights[1] = .2;
277 myCritWeights[2] = .4;
278 myUseSmoothing = Standard_False;
279
280}
281
282
283//=======================================================================
284//function : AddWire
285//purpose :
286//=======================================================================
287
288void BRepOffsetAPI_ThruSections::AddWire(const TopoDS_Wire& wire)
289{
290 myWires.Append(wire);
291}
292
293//=======================================================================
294//function : AddVertex
295//purpose :
296//=======================================================================
297
298void BRepOffsetAPI_ThruSections::AddVertex(const TopoDS_Vertex& aVertex)
299{
300 BRep_Builder BB;
301
302 TopoDS_Edge DegEdge;
303 BB.MakeEdge( DegEdge );
304 BB.Add( DegEdge, aVertex.Oriented(TopAbs_FORWARD) );
305 BB.Add( DegEdge, aVertex.Oriented(TopAbs_REVERSED) );
306 BB.Degenerated( DegEdge, Standard_True );
307 DegEdge.Closed( Standard_True );
308
309 TopoDS_Wire DegWire;
310 BB.MakeWire( DegWire );
311 BB.Add( DegWire, DegEdge );
312 DegWire.Closed( Standard_True );
313
314 myWires.Append( DegWire );
315}
316
317//=======================================================================
318//function : CheckCompatibility
319//purpose :
320//=======================================================================
321
322void BRepOffsetAPI_ThruSections::CheckCompatibility(const Standard_Boolean check)
323{
324 myWCheck = check;
325}
326
327
328//=======================================================================
329//function : Build
330//purpose :
331//=======================================================================
332
333void BRepOffsetAPI_ThruSections::Build()
334{
335 //Check set of section for right configuration of punctual sections
336 Standard_Integer i;
337 TopExp_Explorer explo;
338 for (i = 2; i <= myWires.Length()-1; i++)
339 {
340 Standard_Boolean wdeg = Standard_True;
341 for (explo.Init(myWires(i), TopAbs_EDGE); explo.More(); explo.Next())
342 {
343 const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current());
344 wdeg = wdeg && (BRep_Tool::Degenerated(anEdge));
345 }
346 if (wdeg)
347 Standard_Failure::Raise("Wrong usage of punctual sections");
348 }
349 if (myWires.Length() <= 2)
350 {
351 Standard_Boolean wdeg = Standard_True;
352 for (i = 1; i <= myWires.Length(); i++)
353 for (explo.Init(myWires(i), TopAbs_EDGE); explo.More(); explo.Next())
354 {
355 const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current());
356 wdeg = wdeg && (BRep_Tool::Degenerated(anEdge));
357 }
358 if (wdeg)
359 Standard_Failure::Raise("Wrong usage of punctual sections");
360 }
361
362 if (myWCheck) {
363 // compute origin and orientation on wires to avoid twisted results
364 // and update wires to have same number of edges
365
0d969553 366 // use BRepFill_CompatibleWires
7fd59977 367 TopTools_SequenceOfShape WorkingSections;
368 WorkingSections.Clear();
369 TopTools_DataMapOfShapeListOfShape WorkingMap;
370 WorkingMap.Clear();
371
0d969553 372 // Calculate the working sections
7fd59977 373 BRepFill_CompatibleWires Georges(myWires);
374 Georges.Perform();
375 if (Georges.IsDone()) {
376 WorkingSections = Georges.Shape();
377 WorkingMap = Georges.Generated();
378 }
379 myWires = WorkingSections;
380 }
381
0d969553 382 // Calculate the resulting shape
7fd59977 383 if (myWires.Length() == 2 || myIsRuled) {
384 // create a ruled shell
385 CreateRuled();
386 }
387 else {
388 // create a smoothed shell
389 CreateSmoothed();
390 }
391 // Encode the Regularities
392 BRepLib::EncodeRegularity(myShape);
393
394}
395
396
397//=======================================================================
398//function : CreateRuled
399//purpose :
400//=======================================================================
401
402void BRepOffsetAPI_ThruSections::CreateRuled()
403{
404 Standard_Integer nbSects = myWires.Length();
405 BRepFill_Generator aGene;
406// for (Standard_Integer i=1; i<=nbSects; i++) {
407 Standard_Integer i;
408 for (i=1; i<=nbSects; i++) {
409 aGene.AddWire(TopoDS::Wire(myWires(i)));
410 }
411 aGene.Perform();
412 TopoDS_Shell shell = aGene.Shell();
413
414 if (myIsSolid) {
415
0d969553 416 // check if the first wire is the same as the last
7fd59977 417 Standard_Boolean vClosed = (myWires(1).IsSame(myWires(nbSects))) ;
418
419 if (vClosed) {
420
421 TopoDS_Solid solid;
422 BRep_Builder B;
423 B.MakeSolid(solid);
424 B.Add(solid, shell);
425
0d969553 426 // verify the orientation of the solid
7fd59977 427 BRepClass3d_SolidClassifier clas3d(solid);
428 clas3d.PerformInfinitePoint(Precision::Confusion());
429 if (clas3d.State() == TopAbs_IN) {
430 B.MakeSolid(solid);
431 TopoDS_Shape aLocalShape = shell.Reversed();
432 B.Add(solid, TopoDS::Shell(aLocalShape));
433// B.Add(solid, TopoDS::Shell(shell.Reversed()));
434 }
435 myShape = solid;
436
437 }
438
439 else {
440
441 TopoDS_Wire wire1 = TopoDS::Wire(myWires.First());
442 TopoDS_Wire wire2 = TopoDS::Wire(myWires.Last());
443 myShape = MakeSolid(shell, wire1, wire2, myPres3d, myFirst, myLast);
444
445 }
446
447 Done();
448 }
449
450 else {
451 myShape = shell;
452 Done();
453 }
454
455 // history
456 BRepTools_WireExplorer anExp1, anExp2;
457 TopTools_IndexedDataMapOfShapeListOfShape M;
458 TopExp::MapShapesAndAncestors(shell, TopAbs_EDGE, TopAbs_FACE, M);
459 TopTools_ListIteratorOfListOfShape it;
460
461 TopTools_IndexedDataMapOfShapeListOfShape MV;
462 TopExp::MapShapesAndAncestors(shell, TopAbs_VERTEX, TopAbs_FACE, MV);
463
464 for (i=1; i<=nbSects-1; i++) {
465
466 const TopoDS_Wire& wire1 = TopoDS::Wire(myWires(i));
467 const TopoDS_Wire& wire2 = TopoDS::Wire(myWires(i+1));
468
469 anExp1.Init(wire1);
470 anExp2.Init(wire2);
471
472 Standard_Boolean tantque = anExp1.More() && anExp2.More();
473
474 while (tantque) {
475
476 const TopoDS_Shape& edge1 = anExp1.Current();
477 const TopoDS_Shape& edge2 = anExp2.Current();
478 Standard_Boolean degen1 = BRep_Tool::Degenerated(anExp1.Current());
479 Standard_Boolean degen2 = BRep_Tool::Degenerated(anExp2.Current());
480
481 TopTools_MapOfShape MapFaces;
482 if (degen2){
483 TopoDS_Vertex Vdegen = TopExp::FirstVertex(TopoDS::Edge(edge2));
484 for (it.Initialize(MV.FindFromKey(Vdegen)); it.More(); it.Next()) {
485 MapFaces.Add(it.Value());
486 }
487 }
488 else {
489 for (it.Initialize(M.FindFromKey(edge2)); it.More(); it.Next()) {
490 MapFaces.Add(it.Value());
491 }
492 }
493
494 if (degen1) {
495 TopoDS_Vertex Vdegen = TopExp::FirstVertex(TopoDS::Edge(edge1));
496 for (it.Initialize(MV.FindFromKey(Vdegen)); it.More(); it.Next()) {
497 const TopoDS_Shape& Face = it.Value();
498 if (MapFaces.Contains(Face)) {
499 myGenerated.Bind(edge1, Face);
500 break;
501 }
502 }
503 }
504 else {
505 for (it.Initialize(M.FindFromKey(edge1)); it.More(); it.Next()) {
506 const TopoDS_Shape& Face = it.Value();
507 if (MapFaces.Contains(Face)) {
508 myGenerated.Bind(edge1, Face);
509 break;
510 }
511 }
512 }
513
514 if (!degen1) anExp1.Next();
515 if (!degen2) anExp2.Next();
516
517 tantque = anExp1.More() && anExp2.More();
518 if (degen1) tantque = anExp2.More();
519 if (degen2) tantque = anExp1.More();
520
521 }
522
523 }
524
525}
526
527//=======================================================================
528//function : CreateSmoothed
529//purpose :
530//=======================================================================
531
532void BRepOffsetAPI_ThruSections::CreateSmoothed()
533{
534 // initialisation
535 Standard_Integer nbSects = myWires.Length();
536 BRepTools_WireExplorer anExp;
537
538 Standard_Boolean w1Point = Standard_True;
0d969553 539 // check if the first wire is punctual
7fd59977 540 for(anExp.Init(TopoDS::Wire(myWires(1))); anExp.More(); anExp.Next()) {
541 w1Point = w1Point && (BRep_Tool::Degenerated(anExp.Current()));
542 }
543
544 Standard_Boolean w2Point = Standard_True;
0d969553 545 // check if the last wire is punctual
7fd59977 546 for(anExp.Init(TopoDS::Wire(myWires(nbSects))); anExp.More(); anExp.Next()) {
547 w2Point = w2Point && (BRep_Tool::Degenerated(anExp.Current()));
548 }
549
550 Standard_Boolean vClosed = Standard_False;
0d969553 551 // check if the first wire is the same as last
7fd59977 552 if (myWires(1).IsSame(myWires(myWires.Length()))) vClosed = Standard_True;
553
554 // find the dimension
555 Standard_Integer nbEdges=0;
556 if (!w1Point) {
557 for(anExp.Init(TopoDS::Wire(myWires(1))); anExp.More(); anExp.Next()) {
558 nbEdges++;
559 }
560 }
561 else {
562 for(anExp.Init(TopoDS::Wire(myWires(2))); anExp.More(); anExp.Next()) {
563 nbEdges++;
564 }
565 }
566
567 // recover the shapes
568 Standard_Boolean uClosed = Standard_True;
569 TopTools_Array1OfShape shapes(1, nbSects*nbEdges);
570 Standard_Integer nb=0, i, j;
571
572 for (i=1; i<=nbSects; i++) {
573 const TopoDS_Wire& wire = TopoDS::Wire(myWires(i));
574 if (!wire.Closed()) {
0d969553 575 // check if the vertices are the same
7fd59977 576 TopoDS_Vertex V1, V2;
577 TopExp::Vertices(wire,V1,V2);
578 if ( !V1.IsSame(V2)) uClosed = Standard_False;
579 }
580 if ( (i==1 && w1Point) || (i==nbSects && w2Point) ) {
0d969553 581 // if the wire is punctual
7fd59977 582 anExp.Init(TopoDS::Wire(wire));
583 for(j=1; j<=nbEdges; j++) {
584 nb++;
585 shapes(nb) = anExp.Current();
586 }
587 }
588 else {
0d969553 589 // otherwise
7fd59977 590 for(anExp.Init(TopoDS::Wire(wire)); anExp.More(); anExp.Next()) {
591 nb++;
592 shapes(nb) = anExp.Current();
593 }
594 }
595 }
596
597 // create the new surface
598 TopoDS_Shell shell;
599 TopoDS_Face face;
600 TopoDS_Wire W;
601 TopoDS_Edge edge, edge1, edge2, edge3, edge4, couture;
602 TopTools_Array1OfShape vcouture(1, nbEdges);
603
604 BRep_Builder B;
605 B.MakeShell(shell);
606
607 TopoDS_Wire newW1, newW2;
608 BRep_Builder BW1, BW2;
609 BW1.MakeWire(newW1);
610 BW2.MakeWire(newW2);
611
612 TopLoc_Location loc;
613 TopoDS_Vertex v1f,v1l,v2f,v2l;
614
615 GeomFill_SectionGenerator section;
616 Standard_Integer nbPnts = 21;
617 TColgp_Array2OfPnt points(1, nbPnts, 1, nbSects);
618
0d969553 619 // concatenate each section to get a total surface that will be segmented
7fd59977 620 Handle(Geom_BSplineSurface) TS;
621 TS = TotalSurf(shapes,nbSects,nbEdges,w1Point,w2Point,vClosed);
622
623 if(TS.IsNull()) {
624 return;
625 }
626
627 TopoDS_Shape firstEdge;
628 for (i=1; i<=nbEdges; i++) {
629
0d969553 630 // segmentation of TS
7fd59977 631 Handle(Geom_BSplineSurface) surface;
632 surface = Handle(Geom_BSplineSurface)::DownCast(TS->Copy());
633 Standard_Real Ui1,Ui2,V0,V1;
634 Ui1 = i-1;
635 Ui2 = i;
636 V0 = surface->VKnot(surface->FirstVKnotIndex());
637 V1 = surface->VKnot(surface->LastVKnotIndex());
638 surface->Segment(Ui1,Ui2,V0,V1);
639
0d969553 640 // return vertices
7fd59977 641 edge = TopoDS::Edge(shapes(i));
642 TopExp::Vertices(edge,v1f,v1l);
643 if (edge.Orientation() == TopAbs_REVERSED)
644 TopExp::Vertices(edge,v1l,v1f);
645 firstEdge = edge;
646
647 edge = TopoDS::Edge(shapes((nbSects-1)*nbEdges+i));
648 TopExp::Vertices(edge,v2f,v2l);
649 if (edge.Orientation() == TopAbs_REVERSED)
650 TopExp::Vertices(edge,v2l,v2f);
651
652 // make the face
653 B.MakeFace(face, surface, Precision::Confusion());
654
655 // make the wire
656 B.MakeWire(W);
657
658 // make the missing edges
659 Standard_Real f1, f2, l1, l2;
660 surface->Bounds(f1,l1,f2,l2);
661
662 // --- edge 1
663 if ( w1Point ) {
0d969553 664 // copy the degenerated edge
7fd59977 665 TopoDS_Shape aLocalShape = shapes(1).EmptyCopied();
666 edge1 = TopoDS::Edge(aLocalShape);
667// edge1 = TopoDS::Edge(shapes(1).EmptyCopied());
668 edge1.Orientation(TopAbs_FORWARD);
669 }
670 else {
671 B.MakeEdge(edge1, surface->VIso(f2), Precision::Confusion());
672 }
673 v1f.Orientation(TopAbs_FORWARD);
674 B.Add(edge1, v1f);
675 v1l.Orientation(TopAbs_REVERSED);
676 B.Add(edge1, v1l);
677 B.Range(edge1, f1, l1);
0d969553
Y
678 // processing of looping sections
679 // store edges of the 1st section
7fd59977 680 if (vClosed)
681 vcouture(i) = edge1;
682
683
684 // --- edge 2
685 if (vClosed)
686 edge2 = TopoDS::Edge(vcouture(i));
687 else {
688 if ( w2Point ) {
0d969553 689 // copy of the degenerated edge
7fd59977 690 TopoDS_Shape aLocalShape = shapes(nbSects*nbEdges).EmptyCopied();
691 edge2 = TopoDS::Edge(aLocalShape);
692// edge2 = TopoDS::Edge(shapes(nbSects*nbEdges).EmptyCopied());
693 edge2.Orientation(TopAbs_FORWARD);
694 }
695 else {
696 B.MakeEdge(edge2, surface->VIso(l2), Precision::Confusion());
697 }
698 v2f.Orientation(TopAbs_FORWARD);
699 B.Add(edge2, v2f);
700 v2l.Orientation(TopAbs_REVERSED);
701 B.Add(edge2, v2l);
702 B.Range(edge2, f1, l1);
703 }
704 edge2.Reverse();
705
706
707 // --- edge 3
708 if (i==1) {
709 B.MakeEdge(edge3, surface->UIso(f1), Precision::Confusion());
710 v1f.Orientation(TopAbs_FORWARD);
711 B.Add(edge3, v1f);
712 v2f.Orientation(TopAbs_REVERSED);
713 B.Add(edge3, v2f);
714 B.Range(edge3, f2, l2);
715 if (uClosed) {
716 couture = edge3;
717 }
718 }
719 else {
720 edge3 = edge4;
721 }
722 edge3.Reverse();
723
724 // --- edge 4
725 if ( uClosed && i==nbEdges) {
726 edge4 = couture;
727 }
728 else {
729 B.MakeEdge(edge4, surface->UIso(l1), Precision::Confusion());
730 v1l.Orientation(TopAbs_FORWARD);
731 B.Add(edge4, v1l);
732 v2l.Orientation(TopAbs_REVERSED);
733 B.Add(edge4, v2l);
734 B.Range(edge4, f2, l2);
735 }
736
737 B.Add(W,edge1);
738 B.Add(W,edge4);
739 B.Add(W,edge2);
740 B.Add(W,edge3);
741
742 // set PCurve
743 if (vClosed) {
744 B.UpdateEdge(edge1,
745 new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),
746 new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),face,
747 Precision::Confusion());
748 B.Range(edge1,face,f1,l1);
749 }
750 else {
751 B.UpdateEdge(edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),face,
752 Precision::Confusion());
753 B.Range(edge1,face,f1,l1);
754 B.UpdateEdge(edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),face,
755 Precision::Confusion());
756 B.Range(edge2,face,f1,l1);
757 }
758
759 if ( uClosed && nbEdges ==1 ) {
760 B.UpdateEdge(edge3,
761 new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),
762 new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),face,
763 Precision::Confusion());
764 B.Range(edge3,face,f2,l2);
765
766 }
767 else {
768 B.UpdateEdge(edge3,new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),face,
769 Precision::Confusion());
770 B.Range(edge3,face,f2,l2);
771 B.UpdateEdge(edge4,new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),face,
772 Precision::Confusion());
773 B.Range(edge4,face,f2,l2);
774 }
775 B.Add(face,W);
776 B.Add(shell, face);
777
778 // complete newW1 newW2
779 TopoDS_Edge edge12 = edge1;
780 TopoDS_Edge edge22 = edge2;
781 edge12.Reverse();
782 edge22.Reverse();
783 BW1.Add(newW1, edge12);
784 BW2.Add(newW2, edge22);
785
786 // history
787 myGenerated.Bind(firstEdge, face);
788 }
789
790 if (uClosed && w1Point && w2Point)
791 shell.Closed(Standard_True);
792
793 if (myIsSolid) {
794
795 if (vClosed) {
796
797 TopoDS_Solid solid;
798 BRep_Builder B;
799 B.MakeSolid(solid);
800 B.Add(solid, shell);
801
802 // verify the orientation the solid
803 BRepClass3d_SolidClassifier clas3d(solid);
804 clas3d.PerformInfinitePoint(Precision::Confusion());
805 if (clas3d.State() == TopAbs_IN) {
806 B.MakeSolid(solid);
807 TopoDS_Shape aLocalShape = shell.Reversed();
808 B.Add(solid, TopoDS::Shell(aLocalShape));
809// B.Add(solid, TopoDS::Shell(shell.Reversed()));
810 }
811 myShape = solid;
812
813 }
814
815 else {
816 myShape = MakeSolid(shell, newW1, newW2, myPres3d, myFirst, myLast);
817 }
818
819 Done();
820 }
821
822 else {
823 myShape = shell;
824 Done();
825 }
826
827 TopExp_Explorer ex(myShape,TopAbs_EDGE);
828 while (ex.More()) {
829 const TopoDS_Edge& CurE = TopoDS::Edge(ex.Current());
830 B.SameRange(CurE, Standard_False);
831 B.SameParameter(CurE, Standard_False);
832 Standard_Real tol = BRep_Tool::Tolerance(CurE);
833 BRepLib::SameParameter(CurE,tol);
834 ex.Next();
835 }
836}
837
838//=======================================================================
839//function : TotalSurf
840//purpose :
841//=======================================================================
842
843Handle(Geom_BSplineSurface) BRepOffsetAPI_ThruSections::
844 TotalSurf(const TopTools_Array1OfShape& shapes,
845 const Standard_Integer NbSects,
846 const Standard_Integer NbEdges,
847 const Standard_Boolean w1Point,
848 const Standard_Boolean w2Point,
849 const Standard_Boolean vClosed) const
850{
851 Standard_Integer i,j,jdeb=1,jfin=NbSects;
852 TopoDS_Edge edge;
853 TopLoc_Location loc;
854 Standard_Real first, last;
855 TopoDS_Vertex vf,vl;
856
857 GeomFill_SectionGenerator section;
858 Handle(Geom_BSplineSurface) surface;
859 Handle(Geom_BSplineCurve) BS, BS1;
860 Handle(Geom_TrimmedCurve) curvTrim;
861 Handle(Geom_BSplineCurve) curvBS;
862
863 if (w1Point) {
864 jdeb++;
865 edge = TopoDS::Edge(shapes(1));
866 TopExp::Vertices(edge,vl,vf);
867 TColgp_Array1OfPnt Extremities(1,2);
868 Extremities(1) = BRep_Tool::Pnt(vf);
869 Extremities(2) = BRep_Tool::Pnt(vl);
870 TColStd_Array1OfReal Bounds(1,2);
871 Bounds(1) = 0.;
872 Bounds(2) = 1.;
873 Standard_Integer Deg = 1;
874 TColStd_Array1OfInteger Mult(1,2);
875 Mult(1) = Deg+1;
876 Mult(2) = Deg+1;
877 Handle(Geom_BSplineCurve) BSPoint
878 = new Geom_BSplineCurve(Extremities,Bounds,Mult,Deg);
879 section.AddCurve(BSPoint);
880 }
881
882 if (w2Point) {
883 jfin--;
884 }
885
886 for (j=jdeb; j<=jfin; j++) {
887
0d969553 888 // case of looping sections
7fd59977 889 if (j==jfin && vClosed) {
890 section.AddCurve(BS1);
891 }
892
893 else {
894 // read the first edge to initialise CompBS;
895 edge = TopoDS::Edge(shapes((j-1)*NbEdges+1));
896 if (BRep_Tool::Degenerated(edge)) {
0d969553 897 // degenerated edge : construction of a punctual curve
7fd59977 898 TopExp::Vertices(edge,vl,vf);
899 TColgp_Array1OfPnt Extremities(1,2);
900 Extremities(1) = BRep_Tool::Pnt(vf);
901 Extremities(2) = BRep_Tool::Pnt(vl);
902 Handle(Geom_Curve) curv = new Geom_BezierCurve(Extremities);
903 curvTrim = new Geom_TrimmedCurve(curv,
904 curv->FirstParameter(),
905 curv->LastParameter());
906 }
907 else {
0d969553 908 // recover the curve on the edge
7fd59977 909 Handle(Geom_Curve) curv = BRep_Tool::Curve(edge, loc, first, last);
910 curvTrim = new Geom_TrimmedCurve(curv, first, last);
911 curvTrim->Transform(loc.Transformation());
912 }
913 if (edge.Orientation() == TopAbs_REVERSED) {
914 curvTrim->Reverse();
915 }
916
0d969553 917 // transformation into BSpline reparameterized on [i-1,i]
7fd59977 918 curvBS = Handle(Geom_BSplineCurve)::DownCast(curvTrim);
919 if (curvBS.IsNull()) {
920 Handle(Geom_Curve) theCurve = curvTrim->BasisCurve();
921 if (theCurve->IsKind(STANDARD_TYPE(Geom_Conic)))
922 {
923 GeomConvert_ApproxCurve appr(curvTrim, Precision::Confusion(), GeomAbs_C1, 16, 14);
924 if (appr.HasResult())
925 curvBS = appr.Curve();
926 }
927 if (curvBS.IsNull())
928 curvBS = GeomConvert::CurveToBSplineCurve(curvTrim);
929 }
930 TColStd_Array1OfReal BSK(1,curvBS->NbKnots());
931 curvBS->Knots(BSK);
932 BSplCLib::Reparametrize(0.,1.,BSK);
933 curvBS->SetKnots(BSK);
934
0d969553 935 // initialization
7fd59977 936 GeomConvert_CompCurveToBSplineCurve CompBS(curvBS);
937
938 for (i=2; i<=NbEdges; i++) {
939 // read the edge
940 edge = TopoDS::Edge(shapes((j-1)*NbEdges+i));
941 if (BRep_Tool::Degenerated(edge)) {
0d969553 942 // degenerated edge : construction of a punctual curve
7fd59977 943 TopExp::Vertices(edge,vl,vf);
944 TColgp_Array1OfPnt Extremities(1,2);
945 Extremities(1) = BRep_Tool::Pnt(vf);
946 Extremities(2) = BRep_Tool::Pnt(vl);
947 Handle(Geom_Curve) curv = new Geom_BezierCurve(Extremities);
948 curvTrim = new Geom_TrimmedCurve(curv,
949 curv->FirstParameter(),
950 curv->LastParameter());
951 }
952 else {
0d969553 953 // return the curve on the edge
7fd59977 954 Handle(Geom_Curve) curv = BRep_Tool::Curve(edge, loc, first, last);
955 curvTrim = new Geom_TrimmedCurve(curv, first, last);
956 curvTrim->Transform(loc.Transformation());
957 }
958 if (edge.Orientation() == TopAbs_REVERSED) {
959 curvTrim->Reverse();
960 }
961
0d969553 962 // transformation into BSpline reparameterized on [i-1,i]
7fd59977 963 curvBS = Handle(Geom_BSplineCurve)::DownCast(curvTrim);
964 if (curvBS.IsNull()) {
965 Handle(Geom_Curve) theCurve = curvTrim->BasisCurve();
966 if (theCurve->IsKind(STANDARD_TYPE(Geom_Conic)))
967 {
968 GeomConvert_ApproxCurve appr(curvTrim, Precision::Confusion(), GeomAbs_C1, 16, 14);
969 if (appr.HasResult())
970 curvBS = appr.Curve();
971 }
972 if (curvBS.IsNull())
973 curvBS = GeomConvert::CurveToBSplineCurve(curvTrim);
974 }
975 TColStd_Array1OfReal BSK(1,curvBS->NbKnots());
976 curvBS->Knots(BSK);
977 BSplCLib::Reparametrize(i-1,i,BSK);
978 curvBS->SetKnots(BSK);
979
980 // concatenation
981 CompBS.Add(curvBS,
982 Precision::Confusion(),
983 Standard_True,
984 Standard_False,
985 1);
986 }
987
0d969553 988 // return the final section
7fd59977 989 BS = CompBS.BSplineCurve();
990 section.AddCurve(BS);
991
0d969553 992 // case of looping sections
7fd59977 993 if (j==jdeb && vClosed) {
994 BS1 = BS;
995 }
996
997 }
998 }
999
1000 if (w2Point) {
1001 edge = TopoDS::Edge(shapes(NbSects*NbEdges));
1002 TopExp::Vertices(edge,vl,vf);
1003 TColgp_Array1OfPnt Extremities(1,2);
1004 Extremities(1) = BRep_Tool::Pnt(vf);
1005 Extremities(2) = BRep_Tool::Pnt(vl);
1006 TColStd_Array1OfReal Bounds(1,2);
1007 Bounds(1) = 0.;
1008 Bounds(2) = 1.;
1009 Standard_Integer Deg = 1;
1010 TColStd_Array1OfInteger Mult(1,2);
1011 Mult(1) = Deg+1;
1012 Mult(2) = Deg+1;
1013 Handle(Geom_BSplineCurve) BSPoint
1014 = new Geom_BSplineCurve(Extremities,Bounds,Mult,Deg);
1015 section.AddCurve(BSPoint);
1016 }
1017
1018 section.Perform(Precision::PConfusion());
1019 Handle(GeomFill_Line) line = new GeomFill_Line(NbSects);
1020
1021 Standard_Integer nbIt = 3;
1022 if(myPres3d <= 1.e-3) nbIt = 0;
1023
1024 Standard_Integer degmin = 2, degmax = Max(myDegMax, degmin);
1025 Standard_Boolean SpApprox = Standard_True;
1026
1027 GeomFill_AppSurf anApprox(degmin, degmax, myPres3d, myPres3d, nbIt);
1028 anApprox.SetContinuity(myContinuity);
1029
1030 if(myUseSmoothing) {
1031 anApprox.SetCriteriumWeight(myCritWeights[0], myCritWeights[1], myCritWeights[2]);
1032 anApprox.PerformSmoothing(line, section);
1033 }
1034 else {
1035 anApprox.SetParType(myParamType);
1036 anApprox.Perform(line, section, SpApprox);
1037 }
1038
1039 if(anApprox.IsDone()) {
1040 surface =
1041 new Geom_BSplineSurface(anApprox.SurfPoles(), anApprox.SurfWeights(),
1042 anApprox.SurfUKnots(), anApprox.SurfVKnots(),
1043 anApprox.SurfUMults(), anApprox.SurfVMults(),
1044 anApprox.UDegree(), anApprox.VDegree());
1045 }
1046
1047 return surface;
1048
1049}
1050
1051//=======================================================================
1052//function : FirstShape
1053//purpose :
1054//=======================================================================
1055
1056const TopoDS_Shape& BRepOffsetAPI_ThruSections::FirstShape() const
1057{
1058 return myFirst;
1059}
1060
1061//=======================================================================
1062//function : LastShape
1063//purpose :
1064//=======================================================================
1065
1066const TopoDS_Shape& BRepOffsetAPI_ThruSections::LastShape() const
1067{
1068 return myLast;
1069}
1070
1071//=======================================================================
1072//function : GeneratedFace
1073//purpose :
1074//=======================================================================
1075
1076TopoDS_Shape BRepOffsetAPI_ThruSections::GeneratedFace(const TopoDS_Shape& edge) const
1077{
1078 TopoDS_Shape bid;
1079 if (myGenerated.IsBound(edge)) {
1080 return myGenerated(edge);
1081 }
1082 else {
1083 return bid;
1084 }
1085}
1086
1087
1088//=======================================================================
1089//function : CriteriumWeight
0d969553 1090//purpose : returns the Weights associated to the criterium used in
7fd59977 1091// the optimization.
1092//=======================================================================
1093//
1094void BRepOffsetAPI_ThruSections::CriteriumWeight(Standard_Real& W1, Standard_Real& W2, Standard_Real& W3) const
1095{
1096 W1 = myCritWeights[0];
1097 W2 = myCritWeights[1];
1098 W3 = myCritWeights[2];
1099}
1100//=======================================================================
1101//function : SetCriteriumWeight
1102//purpose :
1103//=======================================================================
1104
1105void BRepOffsetAPI_ThruSections::SetCriteriumWeight(const Standard_Real W1, const Standard_Real W2, const Standard_Real W3)
1106{
1107 if (W1 < 0 || W2 < 0 || W3 < 0 ) Standard_DomainError::Raise();
1108 myCritWeights[0] = W1;
1109 myCritWeights[1] = W2;
1110 myCritWeights[2] = W3;
1111}
1112//=======================================================================
1113//function : SetContinuity
1114//purpose :
1115//=======================================================================
1116
1117void BRepOffsetAPI_ThruSections::SetContinuity (const GeomAbs_Shape TheCont)
1118{
1119 myContinuity = TheCont;
1120}
1121
1122//=======================================================================
1123//function : Continuity
1124//purpose :
1125//=======================================================================
1126
1127GeomAbs_Shape BRepOffsetAPI_ThruSections::Continuity () const
1128{
1129 return myContinuity;
1130}
1131
1132//=======================================================================
1133//function : SetParType
1134//purpose :
1135//=======================================================================
1136
1137void BRepOffsetAPI_ThruSections::SetParType (const Approx_ParametrizationType ParType)
1138{
1139 myParamType = ParType;
1140}
1141
1142//=======================================================================
1143//function : ParType
1144//purpose :
1145//=======================================================================
1146
1147Approx_ParametrizationType BRepOffsetAPI_ThruSections::ParType () const
1148{
1149 return myParamType;
1150}
1151
1152//=======================================================================
1153//function : SetMaxDegree
1154//purpose :
1155//=======================================================================
1156
1157void BRepOffsetAPI_ThruSections:: SetMaxDegree(const Standard_Integer MaxDeg)
1158{
1159 myDegMax = MaxDeg;
1160}
1161
1162//=======================================================================
1163//function : MaxDegree
1164//purpose :
1165//=======================================================================
1166
1167Standard_Integer BRepOffsetAPI_ThruSections::MaxDegree () const
1168{
1169 return myDegMax;
1170}
1171
1172//=======================================================================
1173//function : SetSmoothing
1174//purpose :
1175//=======================================================================
1176
1177void BRepOffsetAPI_ThruSections::SetSmoothing(const Standard_Boolean UseVar)
1178{
1179 myUseSmoothing = UseVar;
1180}
1181
1182//=======================================================================
1183//function : UseSmoothing
1184//purpose :
1185//=======================================================================
1186
1187Standard_Boolean BRepOffsetAPI_ThruSections::UseSmoothing () const
1188{
1189 return myUseSmoothing;
1190}
1191
1192
1193
1194
1195