Integration of OCCT 6.5.0 from SVN
[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
113//purpose : Construit s'il existe un plan de remplissage
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 {
199 // Il faut boucher les extremites
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
366 // on utilise BRepFill_CompatibleWires
367 TopTools_SequenceOfShape WorkingSections;
368 WorkingSections.Clear();
369 TopTools_DataMapOfShapeListOfShape WorkingMap;
370 WorkingMap.Clear();
371
372 // Calcul des sections de travail
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
382 // Calcul de la shape resultat
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
416 // on regarde si le premier wire est identique au dernier
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
426 // verify the orientation the solid
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;
539 // on regarde si le premier wire est ponctuel
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;
545 // on regarde si le dernier wire est ponctuel
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;
551 // on regarde si le premier wire est identique au dernier
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()) {
575 // on regarde quand meme si les vertex sont les memes.
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) ) {
581 // si le wire est ponctuel
582 anExp.Init(TopoDS::Wire(wire));
583 for(j=1; j<=nbEdges; j++) {
584 nb++;
585 shapes(nb) = anExp.Current();
586 }
587 }
588 else {
589 // sinon
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
619 // on concatene chaque section pour obtenir une surface totale que
620 // l'on va segmenter
621 Handle(Geom_BSplineSurface) TS;
622 TS = TotalSurf(shapes,nbSects,nbEdges,w1Point,w2Point,vClosed);
623
624 if(TS.IsNull()) {
625 return;
626 }
627
628 TopoDS_Shape firstEdge;
629 for (i=1; i<=nbEdges; i++) {
630
631 // segmentation de TS
632 Handle(Geom_BSplineSurface) surface;
633 surface = Handle(Geom_BSplineSurface)::DownCast(TS->Copy());
634 Standard_Real Ui1,Ui2,V0,V1;
635 Ui1 = i-1;
636 Ui2 = i;
637 V0 = surface->VKnot(surface->FirstVKnotIndex());
638 V1 = surface->VKnot(surface->LastVKnotIndex());
639 surface->Segment(Ui1,Ui2,V0,V1);
640
641 // recuperation des vertices
642 edge = TopoDS::Edge(shapes(i));
643 TopExp::Vertices(edge,v1f,v1l);
644 if (edge.Orientation() == TopAbs_REVERSED)
645 TopExp::Vertices(edge,v1l,v1f);
646 firstEdge = edge;
647
648 edge = TopoDS::Edge(shapes((nbSects-1)*nbEdges+i));
649 TopExp::Vertices(edge,v2f,v2l);
650 if (edge.Orientation() == TopAbs_REVERSED)
651 TopExp::Vertices(edge,v2l,v2f);
652
653 // make the face
654 B.MakeFace(face, surface, Precision::Confusion());
655
656 // make the wire
657 B.MakeWire(W);
658
659 // make the missing edges
660 Standard_Real f1, f2, l1, l2;
661 surface->Bounds(f1,l1,f2,l2);
662
663 // --- edge 1
664 if ( w1Point ) {
665 // copie de l'edge degeneree
666 TopoDS_Shape aLocalShape = shapes(1).EmptyCopied();
667 edge1 = TopoDS::Edge(aLocalShape);
668// edge1 = TopoDS::Edge(shapes(1).EmptyCopied());
669 edge1.Orientation(TopAbs_FORWARD);
670 }
671 else {
672 B.MakeEdge(edge1, surface->VIso(f2), Precision::Confusion());
673 }
674 v1f.Orientation(TopAbs_FORWARD);
675 B.Add(edge1, v1f);
676 v1l.Orientation(TopAbs_REVERSED);
677 B.Add(edge1, v1l);
678 B.Range(edge1, f1, l1);
679 // traitement des sections bouclantes
680 // on stocke les edges de la 1ere section
681 if (vClosed)
682 vcouture(i) = edge1;
683
684
685 // --- edge 2
686 if (vClosed)
687 edge2 = TopoDS::Edge(vcouture(i));
688 else {
689 if ( w2Point ) {
690 // copie de l'edge degeneree
691 TopoDS_Shape aLocalShape = shapes(nbSects*nbEdges).EmptyCopied();
692 edge2 = TopoDS::Edge(aLocalShape);
693// edge2 = TopoDS::Edge(shapes(nbSects*nbEdges).EmptyCopied());
694 edge2.Orientation(TopAbs_FORWARD);
695 }
696 else {
697 B.MakeEdge(edge2, surface->VIso(l2), Precision::Confusion());
698 }
699 v2f.Orientation(TopAbs_FORWARD);
700 B.Add(edge2, v2f);
701 v2l.Orientation(TopAbs_REVERSED);
702 B.Add(edge2, v2l);
703 B.Range(edge2, f1, l1);
704 }
705 edge2.Reverse();
706
707
708 // --- edge 3
709 if (i==1) {
710 B.MakeEdge(edge3, surface->UIso(f1), Precision::Confusion());
711 v1f.Orientation(TopAbs_FORWARD);
712 B.Add(edge3, v1f);
713 v2f.Orientation(TopAbs_REVERSED);
714 B.Add(edge3, v2f);
715 B.Range(edge3, f2, l2);
716 if (uClosed) {
717 couture = edge3;
718 }
719 }
720 else {
721 edge3 = edge4;
722 }
723 edge3.Reverse();
724
725 // --- edge 4
726 if ( uClosed && i==nbEdges) {
727 edge4 = couture;
728 }
729 else {
730 B.MakeEdge(edge4, surface->UIso(l1), Precision::Confusion());
731 v1l.Orientation(TopAbs_FORWARD);
732 B.Add(edge4, v1l);
733 v2l.Orientation(TopAbs_REVERSED);
734 B.Add(edge4, v2l);
735 B.Range(edge4, f2, l2);
736 }
737
738 B.Add(W,edge1);
739 B.Add(W,edge4);
740 B.Add(W,edge2);
741 B.Add(W,edge3);
742
743 // set PCurve
744 if (vClosed) {
745 B.UpdateEdge(edge1,
746 new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),
747 new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),face,
748 Precision::Confusion());
749 B.Range(edge1,face,f1,l1);
750 }
751 else {
752 B.UpdateEdge(edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),face,
753 Precision::Confusion());
754 B.Range(edge1,face,f1,l1);
755 B.UpdateEdge(edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),face,
756 Precision::Confusion());
757 B.Range(edge2,face,f1,l1);
758 }
759
760 if ( uClosed && nbEdges ==1 ) {
761 B.UpdateEdge(edge3,
762 new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),
763 new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),face,
764 Precision::Confusion());
765 B.Range(edge3,face,f2,l2);
766
767 }
768 else {
769 B.UpdateEdge(edge3,new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),face,
770 Precision::Confusion());
771 B.Range(edge3,face,f2,l2);
772 B.UpdateEdge(edge4,new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),face,
773 Precision::Confusion());
774 B.Range(edge4,face,f2,l2);
775 }
776 B.Add(face,W);
777 B.Add(shell, face);
778
779 // complete newW1 newW2
780 TopoDS_Edge edge12 = edge1;
781 TopoDS_Edge edge22 = edge2;
782 edge12.Reverse();
783 edge22.Reverse();
784 BW1.Add(newW1, edge12);
785 BW2.Add(newW2, edge22);
786
787 // history
788 myGenerated.Bind(firstEdge, face);
789 }
790
791 if (uClosed && w1Point && w2Point)
792 shell.Closed(Standard_True);
793
794 if (myIsSolid) {
795
796 if (vClosed) {
797
798 TopoDS_Solid solid;
799 BRep_Builder B;
800 B.MakeSolid(solid);
801 B.Add(solid, shell);
802
803 // verify the orientation the solid
804 BRepClass3d_SolidClassifier clas3d(solid);
805 clas3d.PerformInfinitePoint(Precision::Confusion());
806 if (clas3d.State() == TopAbs_IN) {
807 B.MakeSolid(solid);
808 TopoDS_Shape aLocalShape = shell.Reversed();
809 B.Add(solid, TopoDS::Shell(aLocalShape));
810// B.Add(solid, TopoDS::Shell(shell.Reversed()));
811 }
812 myShape = solid;
813
814 }
815
816 else {
817 myShape = MakeSolid(shell, newW1, newW2, myPres3d, myFirst, myLast);
818 }
819
820 Done();
821 }
822
823 else {
824 myShape = shell;
825 Done();
826 }
827
828 TopExp_Explorer ex(myShape,TopAbs_EDGE);
829 while (ex.More()) {
830 const TopoDS_Edge& CurE = TopoDS::Edge(ex.Current());
831 B.SameRange(CurE, Standard_False);
832 B.SameParameter(CurE, Standard_False);
833 Standard_Real tol = BRep_Tool::Tolerance(CurE);
834 BRepLib::SameParameter(CurE,tol);
835 ex.Next();
836 }
837}
838
839//=======================================================================
840//function : TotalSurf
841//purpose :
842//=======================================================================
843
844Handle(Geom_BSplineSurface) BRepOffsetAPI_ThruSections::
845 TotalSurf(const TopTools_Array1OfShape& shapes,
846 const Standard_Integer NbSects,
847 const Standard_Integer NbEdges,
848 const Standard_Boolean w1Point,
849 const Standard_Boolean w2Point,
850 const Standard_Boolean vClosed) const
851{
852 Standard_Integer i,j,jdeb=1,jfin=NbSects;
853 TopoDS_Edge edge;
854 TopLoc_Location loc;
855 Standard_Real first, last;
856 TopoDS_Vertex vf,vl;
857
858 GeomFill_SectionGenerator section;
859 Handle(Geom_BSplineSurface) surface;
860 Handle(Geom_BSplineCurve) BS, BS1;
861 Handle(Geom_TrimmedCurve) curvTrim;
862 Handle(Geom_BSplineCurve) curvBS;
863
864 if (w1Point) {
865 jdeb++;
866 edge = TopoDS::Edge(shapes(1));
867 TopExp::Vertices(edge,vl,vf);
868 TColgp_Array1OfPnt Extremities(1,2);
869 Extremities(1) = BRep_Tool::Pnt(vf);
870 Extremities(2) = BRep_Tool::Pnt(vl);
871 TColStd_Array1OfReal Bounds(1,2);
872 Bounds(1) = 0.;
873 Bounds(2) = 1.;
874 Standard_Integer Deg = 1;
875 TColStd_Array1OfInteger Mult(1,2);
876 Mult(1) = Deg+1;
877 Mult(2) = Deg+1;
878 Handle(Geom_BSplineCurve) BSPoint
879 = new Geom_BSplineCurve(Extremities,Bounds,Mult,Deg);
880 section.AddCurve(BSPoint);
881 }
882
883 if (w2Point) {
884 jfin--;
885 }
886
887 for (j=jdeb; j<=jfin; j++) {
888
889 // cas des sections bouclantes
890 if (j==jfin && vClosed) {
891 section.AddCurve(BS1);
892 }
893
894 else {
895 // read the first edge to initialise CompBS;
896 edge = TopoDS::Edge(shapes((j-1)*NbEdges+1));
897 if (BRep_Tool::Degenerated(edge)) {
898 // edge degeneree : construction d'une courbe ponctuelle
899 TopExp::Vertices(edge,vl,vf);
900 TColgp_Array1OfPnt Extremities(1,2);
901 Extremities(1) = BRep_Tool::Pnt(vf);
902 Extremities(2) = BRep_Tool::Pnt(vl);
903 Handle(Geom_Curve) curv = new Geom_BezierCurve(Extremities);
904 curvTrim = new Geom_TrimmedCurve(curv,
905 curv->FirstParameter(),
906 curv->LastParameter());
907 }
908 else {
909 // recuperation de la courbe sur l'edge
910 Handle(Geom_Curve) curv = BRep_Tool::Curve(edge, loc, first, last);
911 curvTrim = new Geom_TrimmedCurve(curv, first, last);
912 curvTrim->Transform(loc.Transformation());
913 }
914 if (edge.Orientation() == TopAbs_REVERSED) {
915 curvTrim->Reverse();
916 }
917
918 // transformation en BSpline reparametree sur [i-1,i]
919 curvBS = Handle(Geom_BSplineCurve)::DownCast(curvTrim);
920 if (curvBS.IsNull()) {
921 Handle(Geom_Curve) theCurve = curvTrim->BasisCurve();
922 if (theCurve->IsKind(STANDARD_TYPE(Geom_Conic)))
923 {
924 GeomConvert_ApproxCurve appr(curvTrim, Precision::Confusion(), GeomAbs_C1, 16, 14);
925 if (appr.HasResult())
926 curvBS = appr.Curve();
927 }
928 if (curvBS.IsNull())
929 curvBS = GeomConvert::CurveToBSplineCurve(curvTrim);
930 }
931 TColStd_Array1OfReal BSK(1,curvBS->NbKnots());
932 curvBS->Knots(BSK);
933 BSplCLib::Reparametrize(0.,1.,BSK);
934 curvBS->SetKnots(BSK);
935
936 // initialisation
937 GeomConvert_CompCurveToBSplineCurve CompBS(curvBS);
938
939 for (i=2; i<=NbEdges; i++) {
940 // read the edge
941 edge = TopoDS::Edge(shapes((j-1)*NbEdges+i));
942 if (BRep_Tool::Degenerated(edge)) {
943 // edge degeneree : construction d'une courbe ponctuelle
944 TopExp::Vertices(edge,vl,vf);
945 TColgp_Array1OfPnt Extremities(1,2);
946 Extremities(1) = BRep_Tool::Pnt(vf);
947 Extremities(2) = BRep_Tool::Pnt(vl);
948 Handle(Geom_Curve) curv = new Geom_BezierCurve(Extremities);
949 curvTrim = new Geom_TrimmedCurve(curv,
950 curv->FirstParameter(),
951 curv->LastParameter());
952 }
953 else {
954 // recuperation de la courbe sur l'edge
955 Handle(Geom_Curve) curv = BRep_Tool::Curve(edge, loc, first, last);
956 curvTrim = new Geom_TrimmedCurve(curv, first, last);
957 curvTrim->Transform(loc.Transformation());
958 }
959 if (edge.Orientation() == TopAbs_REVERSED) {
960 curvTrim->Reverse();
961 }
962
963 // transformation en BSpline reparametree sur [i-1,i]
964 curvBS = Handle(Geom_BSplineCurve)::DownCast(curvTrim);
965 if (curvBS.IsNull()) {
966 Handle(Geom_Curve) theCurve = curvTrim->BasisCurve();
967 if (theCurve->IsKind(STANDARD_TYPE(Geom_Conic)))
968 {
969 GeomConvert_ApproxCurve appr(curvTrim, Precision::Confusion(), GeomAbs_C1, 16, 14);
970 if (appr.HasResult())
971 curvBS = appr.Curve();
972 }
973 if (curvBS.IsNull())
974 curvBS = GeomConvert::CurveToBSplineCurve(curvTrim);
975 }
976 TColStd_Array1OfReal BSK(1,curvBS->NbKnots());
977 curvBS->Knots(BSK);
978 BSplCLib::Reparametrize(i-1,i,BSK);
979 curvBS->SetKnots(BSK);
980
981 // concatenation
982 CompBS.Add(curvBS,
983 Precision::Confusion(),
984 Standard_True,
985 Standard_False,
986 1);
987 }
988
989 // recuperation de la section finale
990 BS = CompBS.BSplineCurve();
991 section.AddCurve(BS);
992
993 // cas des sections bouclantes
994 if (j==jdeb && vClosed) {
995 BS1 = BS;
996 }
997
998 }
999 }
1000
1001 if (w2Point) {
1002 edge = TopoDS::Edge(shapes(NbSects*NbEdges));
1003 TopExp::Vertices(edge,vl,vf);
1004 TColgp_Array1OfPnt Extremities(1,2);
1005 Extremities(1) = BRep_Tool::Pnt(vf);
1006 Extremities(2) = BRep_Tool::Pnt(vl);
1007 TColStd_Array1OfReal Bounds(1,2);
1008 Bounds(1) = 0.;
1009 Bounds(2) = 1.;
1010 Standard_Integer Deg = 1;
1011 TColStd_Array1OfInteger Mult(1,2);
1012 Mult(1) = Deg+1;
1013 Mult(2) = Deg+1;
1014 Handle(Geom_BSplineCurve) BSPoint
1015 = new Geom_BSplineCurve(Extremities,Bounds,Mult,Deg);
1016 section.AddCurve(BSPoint);
1017 }
1018
1019 section.Perform(Precision::PConfusion());
1020 Handle(GeomFill_Line) line = new GeomFill_Line(NbSects);
1021
1022 Standard_Integer nbIt = 3;
1023 if(myPres3d <= 1.e-3) nbIt = 0;
1024
1025 Standard_Integer degmin = 2, degmax = Max(myDegMax, degmin);
1026 Standard_Boolean SpApprox = Standard_True;
1027
1028 GeomFill_AppSurf anApprox(degmin, degmax, myPres3d, myPres3d, nbIt);
1029 anApprox.SetContinuity(myContinuity);
1030
1031 if(myUseSmoothing) {
1032 anApprox.SetCriteriumWeight(myCritWeights[0], myCritWeights[1], myCritWeights[2]);
1033 anApprox.PerformSmoothing(line, section);
1034 }
1035 else {
1036 anApprox.SetParType(myParamType);
1037 anApprox.Perform(line, section, SpApprox);
1038 }
1039
1040 if(anApprox.IsDone()) {
1041 surface =
1042 new Geom_BSplineSurface(anApprox.SurfPoles(), anApprox.SurfWeights(),
1043 anApprox.SurfUKnots(), anApprox.SurfVKnots(),
1044 anApprox.SurfUMults(), anApprox.SurfVMults(),
1045 anApprox.UDegree(), anApprox.VDegree());
1046 }
1047
1048 return surface;
1049
1050}
1051
1052//=======================================================================
1053//function : FirstShape
1054//purpose :
1055//=======================================================================
1056
1057const TopoDS_Shape& BRepOffsetAPI_ThruSections::FirstShape() const
1058{
1059 return myFirst;
1060}
1061
1062//=======================================================================
1063//function : LastShape
1064//purpose :
1065//=======================================================================
1066
1067const TopoDS_Shape& BRepOffsetAPI_ThruSections::LastShape() const
1068{
1069 return myLast;
1070}
1071
1072//=======================================================================
1073//function : GeneratedFace
1074//purpose :
1075//=======================================================================
1076
1077TopoDS_Shape BRepOffsetAPI_ThruSections::GeneratedFace(const TopoDS_Shape& edge) const
1078{
1079 TopoDS_Shape bid;
1080 if (myGenerated.IsBound(edge)) {
1081 return myGenerated(edge);
1082 }
1083 else {
1084 return bid;
1085 }
1086}
1087
1088
1089//=======================================================================
1090//function : CriteriumWeight
1091//purpose : returns the Weights associed to the criterium used in
1092// the optimization.
1093//=======================================================================
1094//
1095void BRepOffsetAPI_ThruSections::CriteriumWeight(Standard_Real& W1, Standard_Real& W2, Standard_Real& W3) const
1096{
1097 W1 = myCritWeights[0];
1098 W2 = myCritWeights[1];
1099 W3 = myCritWeights[2];
1100}
1101//=======================================================================
1102//function : SetCriteriumWeight
1103//purpose :
1104//=======================================================================
1105
1106void BRepOffsetAPI_ThruSections::SetCriteriumWeight(const Standard_Real W1, const Standard_Real W2, const Standard_Real W3)
1107{
1108 if (W1 < 0 || W2 < 0 || W3 < 0 ) Standard_DomainError::Raise();
1109 myCritWeights[0] = W1;
1110 myCritWeights[1] = W2;
1111 myCritWeights[2] = W3;
1112}
1113//=======================================================================
1114//function : SetContinuity
1115//purpose :
1116//=======================================================================
1117
1118void BRepOffsetAPI_ThruSections::SetContinuity (const GeomAbs_Shape TheCont)
1119{
1120 myContinuity = TheCont;
1121}
1122
1123//=======================================================================
1124//function : Continuity
1125//purpose :
1126//=======================================================================
1127
1128GeomAbs_Shape BRepOffsetAPI_ThruSections::Continuity () const
1129{
1130 return myContinuity;
1131}
1132
1133//=======================================================================
1134//function : SetParType
1135//purpose :
1136//=======================================================================
1137
1138void BRepOffsetAPI_ThruSections::SetParType (const Approx_ParametrizationType ParType)
1139{
1140 myParamType = ParType;
1141}
1142
1143//=======================================================================
1144//function : ParType
1145//purpose :
1146//=======================================================================
1147
1148Approx_ParametrizationType BRepOffsetAPI_ThruSections::ParType () const
1149{
1150 return myParamType;
1151}
1152
1153//=======================================================================
1154//function : SetMaxDegree
1155//purpose :
1156//=======================================================================
1157
1158void BRepOffsetAPI_ThruSections:: SetMaxDegree(const Standard_Integer MaxDeg)
1159{
1160 myDegMax = MaxDeg;
1161}
1162
1163//=======================================================================
1164//function : MaxDegree
1165//purpose :
1166//=======================================================================
1167
1168Standard_Integer BRepOffsetAPI_ThruSections::MaxDegree () const
1169{
1170 return myDegMax;
1171}
1172
1173//=======================================================================
1174//function : SetSmoothing
1175//purpose :
1176//=======================================================================
1177
1178void BRepOffsetAPI_ThruSections::SetSmoothing(const Standard_Boolean UseVar)
1179{
1180 myUseSmoothing = UseVar;
1181}
1182
1183//=======================================================================
1184//function : UseSmoothing
1185//purpose :
1186//=======================================================================
1187
1188Standard_Boolean BRepOffsetAPI_ThruSections::UseSmoothing () const
1189{
1190 return myUseSmoothing;
1191}
1192
1193
1194
1195
1196