0024400: Wrong result obtained by Section
[occt.git] / src / BRepFill / BRepFill_Pipe.cxx
CommitLineData
b311480e 1// Created on: 1994-06-07
2// Created by: Bruno DUMORTIER
3// Copyright (c) 1994-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
22#include <BRepFill_Pipe.ixx>
23
24#include <Standard_ErrorHandler.hxx>
25
26#include <BRep_Tool.hxx>
27#include <BRep_Builder.hxx>
28#include <BRepClass3d_SolidClassifier.hxx>
29#include <BRepLib_MakeVertex.hxx>
46e68e02 30#include <BRepTools_Substitution.hxx>
7fd59977 31
32#include <GeomFill_CorrectedFrenet.hxx>
a31abc03 33#include <GeomFill_Frenet.hxx>
34#include <GeomFill_DiscreteTrihedron.hxx>
7fd59977 35#include <GeomFill_CurveAndTrihedron.hxx>
36
37#include <BRepFill_SectionPlacement.hxx>
38#include <BRepFill_ShapeLaw.hxx>
39#include <BRepFill_Edge3DLaw.hxx>
40#include <BRepFill_Sweep.hxx>
41
42#include <GeomAbs_Shape.hxx>
43#include <TopExp.hxx>
44#include <TopAbs_ShapeEnum.hxx>
45#include <TopoDS.hxx>
46#include <TopoDS_Shell.hxx>
47#include <TopoDS_Solid.hxx>
48#include <TopoDS_Compound.hxx>
49#include <TopoDS_Iterator.hxx>
46e68e02 50#include <TopTools_DataMapOfShapeInteger.hxx>
51#include <TColStd_DataMapOfIntegerInteger.hxx>
52#include <TColStd_DataMapIteratorOfDataMapOfIntegerInteger.hxx>
7fd59977 53
54#include <Precision.hxx>
55#include <Standard_NotImplemented.hxx>
56
57#include <Geom_TrimmedCurve.hxx>
58#include <Geom_OffsetCurve.hxx>
59#include <Geom_BSplineCurve.hxx>
60
61#ifdef DRAW
62#include <DBRep.hxx>
63static Standard_Boolean Affich = 0;
64#endif
65
66//=======================================================================
67//function : BRepFill_Pipe
68//purpose :
69//=======================================================================
70
71BRepFill_Pipe::BRepFill_Pipe()
72{
471ce736 73 myDegmax = 11;
7fd59977 74 mySegmax = 100;
471ce736 75 myContinuity = GeomAbs_C2;
a31abc03 76 myMode = GeomFill_IsCorrectedFrenet;
77 myForceApproxC1 = Standard_False;
7fd59977 78}
79
80
81//=======================================================================
82//function : BRepFill_Pipe
83//purpose :
84//=======================================================================
85
86BRepFill_Pipe::BRepFill_Pipe(const TopoDS_Wire& Spine,
87 const TopoDS_Shape& Profile,
471ce736 88 const GeomFill_Trihedron aMode,
89 const Standard_Boolean ForceApproxC1,
7fd59977 90 const Standard_Boolean KPart)
471ce736 91
7fd59977 92{
471ce736 93 myDegmax = 11;
7fd59977 94 mySegmax = 100;
471ce736 95
a31abc03 96 myMode = GeomFill_IsCorrectedFrenet;
a31abc03 97 if (aMode == GeomFill_IsFrenet ||
98 aMode == GeomFill_IsCorrectedFrenet ||
99 aMode == GeomFill_IsDiscreteTrihedron)
100 myMode = aMode;
a31abc03 101
471ce736 102 myContinuity = GeomAbs_C2;
103 if (myMode == GeomFill_IsDiscreteTrihedron)
104 myContinuity = GeomAbs_C0;
105
a31abc03 106 myForceApproxC1 = ForceApproxC1;
471ce736 107 Perform(Spine, Profile, KPart);
a31abc03 108}
7fd59977 109
110
111//=======================================================================
112//function : Perform
113//purpose :
114//=======================================================================
115
116void BRepFill_Pipe::Perform(const TopoDS_Wire& Spine,
117 const TopoDS_Shape& Profile,
35e08fe8 118 const Standard_Boolean /*KPart*/)
7fd59977 119
120{
121 mySections.Nullify();
122 myFaces.Nullify();
123 myEdges.Nullify();
124
125 mySpine = Spine;
126 myProfile = Profile;
127
128 DefineRealSegmax();
129
130 BRepTools_WireExplorer wexp;
131 TopoDS_Shape TheProf;
132
a31abc03 133 Handle(GeomFill_TrihedronLaw) TLaw;
134 switch (myMode)
135 {
136 case GeomFill_IsFrenet:
137 TLaw = new GeomFill_Frenet();
138 break;
139 case GeomFill_IsCorrectedFrenet:
140 TLaw = new GeomFill_CorrectedFrenet();
141 break;
142 case GeomFill_IsDiscreteTrihedron:
143 TLaw = new GeomFill_DiscreteTrihedron();
144 break;
145 }
7fd59977 146 Handle(GeomFill_CurveAndTrihedron) Loc =
147 new (GeomFill_CurveAndTrihedron) (TLaw);
148 myLoc = new (BRepFill_Edge3DLaw) (mySpine, Loc);
149 if (myLoc->NbLaw() == 0) {
0d969553 150 return; // Degenerated case
7fd59977 151 }
0d969553 152 myLoc->TransformInG0Law(); // Set into continuity
7fd59977 153
154 BRepFill_SectionPlacement Place(myLoc, Profile);
155 myTrsf = Place.Transformation();
156
157 TopLoc_Location Loc2(myTrsf), Loc1;
158 Loc1 = Profile.Location();
159 TopoDS_Shape aux;
160 TheProf = myProfile;
161 TheProf.Location(Loc2.Multiplied(Loc1));
162
0d969553 163 // Construct First && Last Shape
7fd59977 164 Handle(GeomFill_LocationLaw) law;
165
166 gp_Mat M;
167 gp_Vec V;
168 gp_Trsf fila;
169 Standard_Real first, last;
170 myLoc->Law(1)->GetDomain(first, last);
171 myLoc->Law(1)->D0(first, M, V);
172 fila.SetValues(M(1,1), M(1,2), M(1,3), V.X(),
173 M(2,1), M(2,2), M(2,3), V.Y(),
174 M(3,1), M(3,2), M(3,3), V.Z(),
175 1.e-12, 1.e-14);
176
177 fila.Multiply(myTrsf);
178 TopLoc_Location LocFirst(fila);
179 myFirst = myProfile;
180 if ( ! LocFirst.IsIdentity()) {
181 myFirst.Location( LocFirst.Multiplied(myProfile.Location()) );
182 }
183
184 myLoc->Law(myLoc->NbLaw())->GetDomain(first, last);
185 myLoc->Law(myLoc->NbLaw())->D0(last,M, V);
0d969553 186// try { // Not good, but there are no other means to test SetValues
7fd59977 187 fila.SetValues(M(1,1), M(1,2), M(1,3), V.X(),
188 M(2,1), M(2,2), M(2,3), V.Y(),
189 M(3,1), M(3,2), M(3,3), V.Z(),
190 1.e-12, 1.e-14);
191 fila.Multiply(myTrsf);
192 TopLoc_Location LocLast(fila);
193 if (! myLoc->IsClosed() || LocFirst != LocLast) {
194 myLast = myProfile;
195 if ( ! LocLast.IsIdentity()) {
196 myLast.Location(LocLast.Multiplied(myProfile.Location()) );
197 }
198 }
199 else {
200 myLast = myFirst;
201 }
202#if DRAW
203 if (Affich) {
204 DBRep::Set("theprof", TheProf);
205 DBRep::Set("thefirst", myFirst);
206 DBRep::Set("thelast" , myLast);
207 }
208#endif
209
210 myShape = MakeShape(TheProf, myFirst, myLast);
211}
212
213
214//=======================================================================
215//function : Spine
216//purpose :
217//=======================================================================
218
219const TopoDS_Shape& BRepFill_Pipe::Spine() const
220{
221 return mySpine;
222}
223
224//=======================================================================
225//function : Profile
226//purpose :
227//=======================================================================
228
229const TopoDS_Shape& BRepFill_Pipe::Profile() const
230{
231 return myProfile;
232}
233
234//=======================================================================
235//function : Shape
236//purpose :
237//=======================================================================
238
239const TopoDS_Shape& BRepFill_Pipe::Shape() const
240{
241 return myShape;
242}
243
244
245//=======================================================================
246//function : FirstShape
247//purpose :
248//=======================================================================
249
250const TopoDS_Shape& BRepFill_Pipe::FirstShape() const
251{
252 return myFirst;
253}
254
255
256//=======================================================================
257//function : LastShape
258//purpose :
259//=======================================================================
260
261const TopoDS_Shape& BRepFill_Pipe::LastShape() const
262{
263 return myLast;
264}
265
266
267//=======================================================================
268//function : Face
269//purpose :
270//=======================================================================
271
272TopoDS_Face BRepFill_Pipe::Face(const TopoDS_Edge& ESpine,
273 const TopoDS_Edge& EProfile)
274{
275 TopoDS_Face theFace;
276
277 if ( BRep_Tool::Degenerated(EProfile))
278 return theFace;
279
280 Standard_Integer ii, ispin = 0, iprof = 0, count = 0;
281
282 // *************************************************
283 // Search if EProfile is an edge of myProfile
284 // *************************************************
285 iprof = FindEdge(myProfile, EProfile, count);
286
287 if (!iprof) Standard_DomainError::Raise(
288 "BRepFill_Pipe::Face : Edge not in the Profile");
289
290
291 // *************************************************
292 // Search if ESpine is an edge of mySpine and find
293 // the index of the corresponding Filler
294 // *************************************************
295 for (ii=1; ii<=myLoc->NbLaw() && (!ispin); ii++)
296 if (ESpine.IsSame(myLoc->Edge(ii))) ispin = ii;
297
298 if (!ispin) Standard_DomainError::Raise(
299 "BRepFill_Pipe::Edge : Edge not in the Spine");
300
301 theFace = TopoDS::Face(myFaces->Value(iprof, ispin));
302 return theFace;
303
304}
305
306//=======================================================================
307//function : Edge
308//purpose :
309//=======================================================================
310TopoDS_Edge BRepFill_Pipe::Edge(const TopoDS_Edge& ESpine,
311 const TopoDS_Vertex& VProfile)
312{
313 Standard_Integer ii, ispin = 0, iprof = 0, count = 0;;
314
315 // *************************************************
316 // Search if VProfile is a Vertex of myProfile
317 // *************************************************
318 iprof = FindVertex(myProfile, VProfile, count);
319 if (!iprof) Standard_DomainError::Raise(
320 "BRepFill_Pipe::Edge : Vertex not in the Profile");
321
322
323 // *************************************************
324 // Search if ESpine is an edge of mySpine and find
325 // the index of the corresponding Filler
326 // *************************************************
327
328 for (ii=1; ii<=myLoc->NbLaw() && (!ispin); ii++)
329 if (ESpine.IsSame(myLoc->Edge(ii))) ispin = ii;
330
331 if (!ispin) Standard_DomainError::Raise(
332 "BRepFill_Pipe::Edge : Edge not in the Spine");
333
334
335 // *************************************************
336 // Generate the corresponding Shape
337 // *************************************************
338 TopoDS_Edge theEdge;
339 theEdge = TopoDS::Edge(myEdges->Value(iprof, ispin));
340
341 return theEdge;
342
343}
344
345
346//=======================================================================
347//function : Section
348//purpose :
349//=======================================================================
350
351TopoDS_Shape BRepFill_Pipe::Section(const TopoDS_Vertex& VSpine) const
352{
353 TopoDS_Iterator it, itv;
354
355 Standard_Integer ii, ispin = 0;
356
357 TopoDS_Shape curSect = myProfile;
358
359 // *************************************************
360 // Search if ESpine is an edge of mySpine and find
361 // the index of the corresponding Filler
362 // *************************************************
363
364 // iterate on all the edges of mySpine
365 for (ii=1; ii<=myLoc->NbLaw()+1 && (!ispin); ii++)
366 if (VSpine.IsSame(myLoc->Vertex(ii))) ispin = ii;
367
368 if (!ispin) Standard_DomainError::Raise(
369 "BRepFill_Pipe::Section : Vertex not in the Spine");
370
371 BRep_Builder B;
372 TopoDS_Compound Comp;
373 B.MakeCompound(Comp);
374 for (ii=1; ii<=mySections->ColLength(); ii++)
375 B.Add(Comp, mySections->Value(ii, ispin));
376
377 return Comp;
378}
379
380//=======================================================================
381//function : PipeLine
0d969553 382//purpose : Construct a wire by sweeping of a point
7fd59977 383//=======================================================================
384
385TopoDS_Wire BRepFill_Pipe::PipeLine(const gp_Pnt& Point) const
386{
0d969553 387 // Postioning
7fd59977 388 gp_Pnt P;
389 P = Point;
390 P.Transform(myTrsf);
391
392 BRepLib_MakeVertex MkV(P);
393 Handle(BRepFill_ShapeLaw) Section =
394 new (BRepFill_ShapeLaw) (MkV.Vertex());
395
0d969553 396 // Sweeping
7fd59977 397 BRepFill_Sweep MkSw(Section, myLoc, Standard_True);
a31abc03 398 MkSw.SetForceApproxC1(myForceApproxC1);
471ce736 399 MkSw.Build( BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax );
7fd59977 400 TopoDS_Shape aLocalShape = MkSw.Shape();
401 return TopoDS::Wire(aLocalShape);
402// return TopoDS::Wire(MkSw.Shape());
403}
404
405//=======================================================================
406//function : MakeShape
407//purpose :
408//=======================================================================
409
410TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S,
411 const TopoDS_Shape& FirstShape,
412 const TopoDS_Shape& LastShape)
413{
414 TopoDS_Shape result;
415 BRep_Builder B;
416 Standard_Boolean explode = Standard_False;
417 TopoDS_Shape TheS, TheFirst, TheLast;
418 Standard_Integer InitialLength = 0;
419 TheS = S;
420 TheFirst = FirstShape;
421 TheLast = LastShape;
422 if (! myFaces.IsNull()) InitialLength = myFaces->ColLength();
423
424 // there are two kinds of generation
425 // 1. generate with S from each Filler (Vertex, Edge)
426 // 2. call MakeShape recursively on the subshapes of S
427 //
428 // explode is True in the second case
429
430 // create the result empty
431
432 switch (S.ShapeType()) {
433
434 case TopAbs_VERTEX :
435 {
436 B.MakeWire(TopoDS::Wire(result));
437 break;
438 }
439
440 case TopAbs_EDGE :
441 {
442 TopoDS_Wire W;
443 B.MakeShell(TopoDS::Shell(result));
444 B.MakeWire(W);
445 B.Add(W, S);
446 W.Closed(S.Closed());
447 TheS = W;
448 if (!FirstShape.IsNull()) {
449 B.MakeWire(W);
450 B.Add(W, FirstShape);
451 W.Closed(FirstShape.Closed());
452 TheFirst = W;
453 }
454 if (!LastShape.IsNull()) {
455 B.MakeWire(W);
456 B.Add(W, LastShape);
457 W.Closed(LastShape.Closed());
458 TheLast = W;
459 }
460 break;
461 }
462
463 case TopAbs_WIRE :
464 B.MakeShell(TopoDS::Shell(result));
465 break;
466
467 case TopAbs_FACE :
468 {
469 B.MakeShell(TopoDS::Shell(result));
470 explode = Standard_True;
471 if ( !mySpine.Closed() && !TheFirst.IsNull()) {
472 B.Add(result, TheFirst.Reversed());
473 }
474 break;
475 }
476
477 case TopAbs_SHELL :
478 {
479 B.MakeCompSolid(TopoDS::CompSolid(result));
480 explode = Standard_True;
481 break;
482 }
483
484 case TopAbs_SOLID :
485 case TopAbs_COMPSOLID :
486 Standard_DomainError::Raise("BRepFill_Pipe::SOLID or COMPSOLID");
487 break;
488
489 case TopAbs_COMPOUND :
490 {
491 B.MakeCompound(TopoDS::Compound(result));
492 explode = Standard_True;
493 break;
494 }
7fd59977 495 default:
496 break;
7fd59977 497 }
498
499 if (explode) {
500 // add the subshapes
501 TopoDS_Iterator itFirst, itLast;
502 TopoDS_Shape first, last;
503 if (!TheFirst.IsNull()) itFirst.Initialize(TheFirst);
504 if (!TheLast.IsNull()) itLast.Initialize(TheLast);
505
506 for (TopoDS_Iterator it(S); it.More(); it.Next()) {
507 if (!TheFirst.IsNull()) first = itFirst.Value();
508 if (!TheLast.IsNull()) last = itLast.Value();
509 if (TheS.ShapeType() == TopAbs_FACE )
510 MakeShape(it.Value(), first, last);
511 else
512 B.Add(result,MakeShape(it.Value(), first, last));
513
514 if (!TheFirst.IsNull()) itFirst.Next();
515 if (!TheLast.IsNull()) itLast.Next();
516 }
517 }
518
519 else {
520 if (TheS.ShapeType() == TopAbs_VERTEX ) {
521 Handle(BRepFill_ShapeLaw) Section =
522 new (BRepFill_ShapeLaw) (TopoDS::Vertex(TheS));
523 BRepFill_Sweep MkSw(Section, myLoc, Standard_True);
a31abc03 524 MkSw.SetForceApproxC1(myForceApproxC1);
471ce736 525 MkSw.Build( BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax );
7fd59977 526 result = MkSw.Shape();
527 }
528
529 if (TheS.ShapeType() == TopAbs_WIRE ) {
530 Handle(BRepFill_ShapeLaw) Section =
531 new (BRepFill_ShapeLaw) (TopoDS::Wire(TheS));
532 BRepFill_Sweep MkSw(Section, myLoc, Standard_True);
533 MkSw.SetBounds(TopoDS::Wire(TheFirst),
534 TopoDS::Wire(TheLast));
a31abc03 535 MkSw.SetForceApproxC1(myForceApproxC1);
471ce736 536 MkSw.Build( BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax );
7fd59977 537 result = MkSw.Shape();
538
0d969553 539 // Labeling of elements
7fd59977 540 if (mySections.IsNull()) {
541 myFaces = MkSw.SubShape();
542 mySections = MkSw.Sections();
543 myEdges = MkSw.InterFaces();
544 }
545 else {
546 Handle(TopTools_HArray2OfShape) Aux, Somme;
547 Standard_Integer length;
548 Standard_Integer ii, jj, kk;
46e68e02 549 const Standard_Integer aNbFaces = myFaces->ColLength();
550 const Standard_Integer aNbEdges = myEdges->ColLength();
551 const Standard_Integer aNbSections = mySections->ColLength();
7fd59977 552
553 Aux = MkSw.SubShape();
554 length = Aux->ColLength() + myFaces->ColLength();
555 Somme = new (TopTools_HArray2OfShape) (1, length, 1,
556 Aux->RowLength());
557 for (jj=1; jj<=myFaces->RowLength(); jj++) {
558 for (ii=1; ii<=myFaces->ColLength(); ii++)
559 Somme->SetValue(ii, jj, myFaces->Value(ii, jj));
560
561 for (kk=1, ii=myFaces->ColLength()+1;
562 kk <=Aux->ColLength(); kk++, ii++)
563 Somme->SetValue(ii, jj, Aux->Value(kk, jj));
564 }
565 myFaces = Somme;
7fd59977 566
567 Aux = MkSw.Sections();
568 length = Aux->ColLength() + mySections->ColLength();
569 Somme = new (TopTools_HArray2OfShape) (1, length, 1,
570 Aux->RowLength());
571 for (jj=1; jj<=mySections->RowLength(); jj++) {
572 for (ii=1; ii<=mySections->ColLength(); ii++)
573 Somme->SetValue(ii, jj, mySections->Value(ii, jj));
574
575 for (kk=1, ii=mySections->ColLength()+1;
576 kk <=Aux->ColLength(); kk++, ii++)
577 Somme->SetValue(ii, jj, Aux->Value(kk, jj));
578 }
579 mySections = Somme;
580
581 Aux = MkSw.InterFaces();
582 length = Aux->ColLength() + myEdges->ColLength();
583 Somme = new (TopTools_HArray2OfShape) (1, length, 1,
584 Aux->RowLength());
585 for (jj=1; jj<=myEdges->RowLength(); jj++) {
586 for (ii=1; ii<=myEdges->ColLength(); ii++)
587 Somme->SetValue(ii, jj, myEdges->Value(ii, jj));
588
589 for (kk=1, ii=myEdges->ColLength()+1;
590 kk <=Aux->ColLength(); kk++, ii++)
591 Somme->SetValue(ii, jj, Aux->Value(kk, jj));
592 }
46e68e02 593
594 myEdges = Somme;
595
596 // Perform sharing faces
597 result = ShareFaces(result, aNbFaces, aNbEdges, aNbSections);
7fd59977 598 }
599 }
600 }
601
602 if ( TheS.ShapeType() == TopAbs_FACE ) {
603 Standard_Integer ii, jj;
604 TopoDS_Face F;
605 for (ii=InitialLength+1; ii<=myFaces->ColLength(); ii++) {
606 for (jj=1; jj<=myFaces->RowLength(); jj++) {
607 F = TopoDS::Face(myFaces->Value(ii, jj));
608 if (!F.IsNull()) B.Add(result, F);
609 }
610 }
611
612 if ( !mySpine.Closed()) {
613 // if Spine is not closed
614 // add the last face of the solid
615 B.Add(result, TopoDS::Face(TheLast));
616 }
617
618 TopoDS_Solid solid;
619 BRep_Builder BS;
620 BS.MakeSolid(solid);
621
622 result.Closed(Standard_True);
623 BS.Add(solid,TopoDS::Shell(result));
624
625 BRepClass3d_SolidClassifier SC(solid);
626 SC.PerformInfinitePoint(Precision::Confusion());
627 if ( SC.State() == TopAbs_IN) {
628 BS.MakeSolid(solid);
629 TopoDS_Shape aLocalShape = result.Reversed();
630 BS.Add(solid,TopoDS::Shell(aLocalShape));
631// BS.Add(solid,TopoDS::Shell(result.Reversed()));
632 }
633 return solid;
634 }
635 else {
636 return result;
637 }
7fd59977 638}
639
0d969553 640//============================================================================
7fd59977 641//function : FindEdge
0d969553
Y
642//purpose : Find the number of edge corresponding to the edge of the profile.
643//============================================================================
7fd59977 644
645Standard_Integer BRepFill_Pipe::FindEdge(const TopoDS_Shape& S,
646 const TopoDS_Edge& E,
647 Standard_Integer& InitialLength) const
648{
649 Standard_Integer result = 0;
650
651 switch (S.ShapeType()) {
652
653 case TopAbs_EDGE :
654 {
655 InitialLength++;
656 if (S.IsSame(E)) result = InitialLength;
657 break;
658 }
659
660 case TopAbs_WIRE :
661 {
662 Standard_Integer ii = InitialLength+1;
663 Handle(BRepFill_ShapeLaw) Section =
664 new (BRepFill_ShapeLaw) (TopoDS::Wire(S), Standard_False);
665 InitialLength += Section->NbLaw();
666
667 for (; (ii<=InitialLength) && (!result); ii++) {
668 if (E.IsSame(Section->Edge(ii)) ) result = ii;
669 }
670 break;
671 }
672
673 case TopAbs_FACE :
674 case TopAbs_SHELL :
675 case TopAbs_COMPOUND :
676 {
677 for (TopoDS_Iterator it(S); it.More() && (!result); it.Next())
678 result = FindEdge(it.Value(), E, InitialLength );
679 break;
680 }
681
682 case TopAbs_SOLID :
683 case TopAbs_COMPSOLID :
684 Standard_DomainError::Raise("BRepFill_Pipe::SOLID or COMPSOLID");
685 break;
7fd59977 686 default:
687 break;
7fd59977 688 }
689
690 return result;
691}
692
693//=======================================================================
694//function : FindVertex
0d969553 695//purpose : Find the number of edge corresponding to an edge of the profile.
7fd59977 696//=======================================================================
697
698Standard_Integer BRepFill_Pipe::FindVertex(const TopoDS_Shape& S,
699 const TopoDS_Vertex& V,
700 Standard_Integer& InitialLength) const
701{
702 Standard_Integer result = 0;
703
704 switch (S.ShapeType()) {
705 case TopAbs_VERTEX :
706 {
707 InitialLength++;
708 if (S.IsSame(V)) result = InitialLength;
709 break;
710 }
711
712 case TopAbs_EDGE :
713 {
714 TopoDS_Vertex VF, VL;
715 TopExp::Vertices(TopoDS::Edge(S), VF, VL);
716 if (S.Orientation() == TopAbs_REVERSED) {
717 TopoDS_Vertex aux;
718 aux = VF; VF = VL; VL = aux;
719 }
720 if (VF.IsSame(V)) result = InitialLength+1;
721 else if (VL.IsSame(V)) result = InitialLength+2;
722 InitialLength += 2;
723 break;
724 }
725
726 case TopAbs_WIRE :
727 {
728 Standard_Integer ii = InitialLength+1;
729 Handle(BRepFill_ShapeLaw) Section =
730 new (BRepFill_ShapeLaw) (TopoDS::Wire(S), Standard_False);
731 InitialLength += Section->NbLaw()+1;
732
733 for (; (ii<=InitialLength) && (!result); ii++) {
734 if (V.IsSame(Section->Vertex(ii, 0.)) ) result = ii;
735 }
736 break;
737 }
738
739 case TopAbs_FACE :
740 case TopAbs_SHELL :
741 case TopAbs_COMPOUND :
742 {
743 for (TopoDS_Iterator it(S); it.More() && (!result); it.Next())
744 result = FindVertex(it.Value(), V, InitialLength);
745 break;
746 }
747
748 case TopAbs_SOLID :
749 case TopAbs_COMPSOLID :
750 Standard_DomainError::Raise("BRepFill_Pipe::SOLID or COMPSOLID");
751 break;
7fd59977 752 default:
753 break;
7fd59977 754 }
755
756 return result;
757}
758
759//=======================================================================
760//function : DefineRealSegmax
761//purpose : Defines the real number of segments
762// required in the case of bspline spine
763//=======================================================================
764
765void BRepFill_Pipe::DefineRealSegmax()
766{
767 Standard_Integer RealSegmax = 0;
768
769 TopoDS_Iterator iter(mySpine);
770 for (; iter.More(); iter.Next())
771 {
772 TopoDS_Edge E = TopoDS::Edge(iter.Value());
773 Standard_Real first, last;
774 Handle(Geom_Curve) C = BRep_Tool::Curve( E, first, last );
775 if (C.IsNull())
776 continue;
777 while (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve) ||
778 C->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
779 {
780 if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve))
781 C = (*((Handle(Geom_TrimmedCurve)*)&C))->BasisCurve();
782 if (C->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
783 C = (*((Handle(Geom_OffsetCurve)*)&C))->BasisCurve();
784 }
785 if (C->DynamicType() == STANDARD_TYPE(Geom_BSplineCurve))
786 {
787 const Handle(Geom_BSplineCurve)& BC = *((Handle(Geom_BSplineCurve)*)&C);
788 Standard_Integer NbKnots = BC->NbKnots();
789 Standard_Integer RealNbKnots = NbKnots;
790 if (first > BC->FirstParameter())
791 {
792 Standard_Integer I1, I2;
793 BC->LocateU( first, Precision::PConfusion(), I1, I2 );
794 RealNbKnots -= I1-1;
795 }
796 if (last < BC->LastParameter())
797 {
798 Standard_Integer I1, I2;
799 BC->LocateU( last, Precision::PConfusion(), I1, I2 );
800 RealNbKnots -= NbKnots-I2;
801 }
802 RealSegmax += RealNbKnots-1;
803 }
804 }
805
806 if (mySegmax < RealSegmax)
807 mySegmax = RealSegmax;
808}
46e68e02 809
810//=======================================================================
811//function : ShareFaces
812//purpose :
813//=======================================================================
814
815TopoDS_Shape BRepFill_Pipe::ShareFaces
816 (const TopoDS_Shape &theShape,
817 const Standard_Integer theInitialFacesLen,
818 const Standard_Integer theInitialEdgesLen,
819 const Standard_Integer theInitialSectionsLen)
820{
821 TopoDS_Shape aResult = theShape;
822 // Check if there are shapes to be shared.
823 TopTools_DataMapOfShapeInteger aMapBndEdgeIndex;
824 TColStd_DataMapOfIntegerInteger aMapNewOldFIndex;
825 TColStd_DataMapOfIntegerInteger aMapNewOldEIndex;
826 TopTools_MapOfShape aMapUsedVtx;
827 TopExp_Explorer anExp;
828 Standard_Integer i;
829 Standard_Integer ii;
830 Standard_Integer jj;
831 BRep_Builder aBuilder;
832
833 // Check the first and last J index of myFaces.
834 for (i = 1; i <= 2; i++) {
835 // Compute jj index of faces.
836 if (i == 1) {
837 jj = 1;
838 } else {
7566ccf3 839 jj = myFaces->RowLength();
46e68e02 840
841 if (jj == 1) {
842 break;
843 }
844 }
845
846 // Fill the map of boundary edges on initial faces.
847 for (ii = 1; ii <= theInitialFacesLen; ii++) {
848 anExp.Init(myFaces->Value(ii, jj), TopAbs_EDGE);
849
850 for (; anExp.More(); anExp.Next()) {
cf3327f4 851 aMapBndEdgeIndex.Bind(anExp.Current(), ii);
46e68e02 852 }
853 }
854
855 // Check if edges of newly created faces are shared with old ones.
856 for (ii = theInitialFacesLen + 1; ii <= myFaces->ColLength(); ii++) {
857 anExp.Init(myFaces->Value(ii, jj), TopAbs_EDGE);
858
859 for (; anExp.More(); anExp.Next()) {
860 if (aMapBndEdgeIndex.IsBound(anExp.Current())) {
861 // This row should be replaced.
862 Standard_Integer anOldIndex = aMapBndEdgeIndex.Find(anExp.Current());
863
864 aMapNewOldFIndex.Bind(ii, anOldIndex);
865
866 // Find corresponding new and old edges indices.
867 TopoDS_Vertex aV[2];
868 TopExp::Vertices(TopoDS::Edge(anExp.Current()), aV[0], aV[1]);
869 Standard_Integer ie;
46e68e02 870
871 // Compute jj index of edges.
7566ccf3 872 Standard_Integer je = (i == 1 ? 1 : myEdges->RowLength());
46e68e02 873
7566ccf3 874 for (Standard_Integer j = 0; j < 2; j++) {
46e68e02 875 if (aMapUsedVtx.Contains(aV[j])) {
876 // This vertex is treated.
877 continue;
878 }
879
880 // Find old index.
881 Standard_Integer iEOld = -1;
882 TopoDS_Vertex aVE[2];
883
884 for (ie = 1; ie <= theInitialEdgesLen; ie++) {
885 const TopoDS_Shape &anEdge = myEdges->Value(ie, je);
886
887 TopExp::Vertices(TopoDS::Edge(anEdge), aVE[0], aVE[1]);
888
889 if (aV[j].IsSame(aVE[0]) || aV[j].IsSame(aVE[1])) {
890 iEOld = ie;
891 break;
892 }
893 }
894
895 if (iEOld > 0) {
896 // Find new index.
897 for (ie = theInitialEdgesLen+1; ie <= myEdges->ColLength(); ie++) {
898 const TopoDS_Shape &anEdge = myEdges->Value(ie, je);
899
900 TopExp::Vertices(TopoDS::Edge(anEdge), aVE[0], aVE[1]);
901
902 if (aV[j].IsSame(aVE[0]) || aV[j].IsSame(aVE[1])) {
903 // This row should be replaced.
904 aMapNewOldEIndex.Bind(ie, iEOld);
905 aMapUsedVtx.Add(aV[j]);
906 break;
907 }
908 }
909 }
910 }
911
912 break;
913 }
914 }
915 }
916 }
917
918 if (!aMapNewOldFIndex.IsEmpty()) {
919 TColStd_DataMapIteratorOfDataMapOfIntegerInteger anIter(aMapNewOldFIndex);
920 TopTools_ListOfShape aListShape;
921 BRepTools_Substitution aSubstitute;
922
923 for (; anIter.More(); anIter.Next()) {
924 const Standard_Integer aNewIndex = anIter.Key();
925 const Standard_Integer anOldIndex = anIter.Value();
926
927 // Change new faces by old ones.
928 for (jj = 1; jj <= myFaces->RowLength(); jj++) {
929 const TopoDS_Shape &aNewFace = myFaces->Value(aNewIndex, jj);
930 const TopoDS_Shape &anOldFace = myFaces->Value(anOldIndex, jj);
931
932 if (!aSubstitute.IsCopied(aNewFace)) {
933 aListShape.Append(anOldFace.Oriented(TopAbs_REVERSED));
934 aSubstitute.Substitute(aNewFace, aListShape);
935 aListShape.Clear();
936 }
937 }
938 }
939
940 // Change new edges by old ones.
941 for (anIter.Initialize(aMapNewOldEIndex); anIter.More(); anIter.Next()) {
942 const Standard_Integer aNewIndex = anIter.Key();
943 const Standard_Integer anOldIndex = anIter.Value();
944
945 for (jj = 1; jj <= myEdges->RowLength(); jj++) {
946 const TopoDS_Shape &aNewEdge = myEdges->Value(aNewIndex, jj);
947 const TopoDS_Shape &anOldEdge = myEdges->Value(anOldIndex, jj);
948
949 if (!aSubstitute.IsCopied(aNewEdge)) {
950 aListShape.Append(anOldEdge.Oriented(TopAbs_FORWARD));
951 aSubstitute.Substitute(aNewEdge, aListShape);
952 aListShape.Clear();
953
954 // Change new vertices by old ones.
955 TopoDS_Iterator aNewIt(aNewEdge);
956 TopoDS_Iterator anOldIt(anOldEdge);
957
958 for (; aNewIt.More() && anOldIt.More();
959 aNewIt.Next(), anOldIt.Next()) {
960 if (!aNewIt.Value().IsSame(anOldIt.Value())) {
961 if (!aSubstitute.IsCopied(aNewIt.Value())) {
962 aListShape.Append(anOldIt.Value().Oriented(TopAbs_FORWARD));
963 aSubstitute.Substitute(aNewIt.Value(), aListShape);
964 aListShape.Clear();
965 }
966 }
967 }
968 }
969 }
970 }
971
972 // Perform substitution.
973 aSubstitute.Build(aResult);
974
975 if (aSubstitute.IsCopied(aResult)) {
976 // Get copied shape.
977 const TopTools_ListOfShape& listSh = aSubstitute.Copy(aResult);
978
979 aResult = listSh.First();
980
981 // Update original faces with copied ones.
982 for (ii = theInitialFacesLen + 1; ii <= myFaces->ColLength(); ii++) {
983 for (jj = 1; jj <= myFaces->RowLength(); jj++) {
984 TopoDS_Shape anOldFace = myFaces->Value(ii, jj); // Copy
985
986 if (aSubstitute.IsCopied(anOldFace)) {
987 const TopTools_ListOfShape& aList = aSubstitute.Copy(anOldFace);
988
989 if(!aList.IsEmpty()) {
990 // Store copied face.
991 const TopoDS_Shape &aCopyFace = aList.First();
992 TopAbs_Orientation anOri = anOldFace.Orientation();
993 const Standard_Boolean isShared = aMapNewOldFIndex.IsBound(ii);
994
995 if (isShared) {
996 // Reverse the orientation for shared face.
997 anOri = TopAbs::Reverse(anOri);
998 }
999
1000 myFaces->SetValue(ii, jj, aCopyFace.Oriented(anOri));
1001
1002 // Check if it is necessary to update PCurves on this face.
1003 if (!isShared) {
1004 TopoDS_Face anOldF = TopoDS::Face(anOldFace);
1005 TopoDS_Face aCopyF = TopoDS::Face(aCopyFace);
1006
1007 anOldF.Orientation(TopAbs_FORWARD);
1008 anExp.Init(anOldF, TopAbs_EDGE);
1009
1010 for (; anExp.More(); anExp.Next()) {
1011 const TopoDS_Shape &anOldEdge = anExp.Current();
1012
1013 if (aSubstitute.IsCopied(anOldEdge)) {
1014 const TopTools_ListOfShape& aListE =
1015 aSubstitute.Copy(anOldEdge);
1016
1017 if(!aListE.IsEmpty()) {
1018 // This edge is copied. Check if there is a PCurve
1019 // on the face.
1020 TopoDS_Edge aCopyE = TopoDS::Edge(aListE.First());
1021 Standard_Real aFirst;
1022 Standard_Real aLast;
1023 Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface
1024 (aCopyE, aCopyF, aFirst, aLast);
1025
1026 if (aPCurve.IsNull()) {
1027 // There is no pcurve copy it from the old edge.
1028 TopoDS_Edge anOldE = TopoDS::Edge(anOldEdge);
1029
1030 aPCurve = BRep_Tool::CurveOnSurface
1031 (anOldE, anOldF, aFirst, aLast);
1032
1033 if (aPCurve.IsNull() == Standard_False) {
1034 // Update the shared edge with PCurve from new Face.
1035 Standard_Real aTol = Max(BRep_Tool::Tolerance(anOldE),
1036 BRep_Tool::Tolerance(aCopyE));
1037
1038 aBuilder.UpdateEdge(aCopyE, aPCurve, aCopyF, aTol);
1039 }
1040 }
1041 }
1042 }
1043 }
1044 }
1045 }
1046 }
1047 }
1048 }
1049
1050 // Update new edges with shared ones.
1051 for (ii = theInitialEdgesLen + 1; ii <= myEdges->ColLength(); ii++) {
1052 for (jj = 1; jj <= myEdges->RowLength(); jj++) {
1053 const TopoDS_Shape &aLocalShape = myEdges->Value(ii, jj);
1054
1055 if (aSubstitute.IsCopied(aLocalShape)) {
1056 const TopTools_ListOfShape& aList = aSubstitute.Copy(aLocalShape);
1057
1058 if(!aList.IsEmpty()) {
1059 const TopAbs_Orientation anOri = TopAbs_FORWARD;
1060
1061 myEdges->SetValue(ii, jj, aList.First().Oriented(anOri));
1062 }
1063 }
1064 }
1065 }
1066
1067 // Update new sections with shared ones.
1068 for (ii = theInitialSectionsLen+1; ii <= mySections->ColLength(); ii++) {
1069 for (jj = 1; jj <= mySections->RowLength(); jj++) {
1070 const TopoDS_Shape &aLocalShape = mySections->Value(ii, jj);
1071
1072 if (aSubstitute.IsCopied(aLocalShape)) {
1073 const TopTools_ListOfShape& aList = aSubstitute.Copy(aLocalShape);
1074
1075 if(!aList.IsEmpty()) {
1076 const TopAbs_Orientation anOri = TopAbs_FORWARD;
1077
1078 mySections->SetValue(ii, jj, aList.First().Oriented(anOri));
1079 }
1080 }
1081 }
1082 }
1083 }
1084 }
1085
1086 return aResult;
1087}