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