0023402: Issue in BRepAlgoAPI_Common - SOLID and FACE
[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,
118 const Standard_Boolean KPart)
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 }
638 return result;
639}
640
0d969553 641//============================================================================
7fd59977 642//function : FindEdge
0d969553
Y
643//purpose : Find the number of edge corresponding to the edge of the profile.
644//============================================================================
7fd59977 645
646Standard_Integer BRepFill_Pipe::FindEdge(const TopoDS_Shape& S,
647 const TopoDS_Edge& E,
648 Standard_Integer& InitialLength) const
649{
650 Standard_Integer result = 0;
651
652 switch (S.ShapeType()) {
653
654 case TopAbs_EDGE :
655 {
656 InitialLength++;
657 if (S.IsSame(E)) result = InitialLength;
658 break;
659 }
660
661 case TopAbs_WIRE :
662 {
663 Standard_Integer ii = InitialLength+1;
664 Handle(BRepFill_ShapeLaw) Section =
665 new (BRepFill_ShapeLaw) (TopoDS::Wire(S), Standard_False);
666 InitialLength += Section->NbLaw();
667
668 for (; (ii<=InitialLength) && (!result); ii++) {
669 if (E.IsSame(Section->Edge(ii)) ) result = ii;
670 }
671 break;
672 }
673
674 case TopAbs_FACE :
675 case TopAbs_SHELL :
676 case TopAbs_COMPOUND :
677 {
678 for (TopoDS_Iterator it(S); it.More() && (!result); it.Next())
679 result = FindEdge(it.Value(), E, InitialLength );
680 break;
681 }
682
683 case TopAbs_SOLID :
684 case TopAbs_COMPSOLID :
685 Standard_DomainError::Raise("BRepFill_Pipe::SOLID or COMPSOLID");
686 break;
7fd59977 687 default:
688 break;
7fd59977 689 }
690
691 return result;
692}
693
694//=======================================================================
695//function : FindVertex
0d969553 696//purpose : Find the number of edge corresponding to an edge of the profile.
7fd59977 697//=======================================================================
698
699Standard_Integer BRepFill_Pipe::FindVertex(const TopoDS_Shape& S,
700 const TopoDS_Vertex& V,
701 Standard_Integer& InitialLength) const
702{
703 Standard_Integer result = 0;
704
705 switch (S.ShapeType()) {
706 case TopAbs_VERTEX :
707 {
708 InitialLength++;
709 if (S.IsSame(V)) result = InitialLength;
710 break;
711 }
712
713 case TopAbs_EDGE :
714 {
715 TopoDS_Vertex VF, VL;
716 TopExp::Vertices(TopoDS::Edge(S), VF, VL);
717 if (S.Orientation() == TopAbs_REVERSED) {
718 TopoDS_Vertex aux;
719 aux = VF; VF = VL; VL = aux;
720 }
721 if (VF.IsSame(V)) result = InitialLength+1;
722 else if (VL.IsSame(V)) result = InitialLength+2;
723 InitialLength += 2;
724 break;
725 }
726
727 case TopAbs_WIRE :
728 {
729 Standard_Integer ii = InitialLength+1;
730 Handle(BRepFill_ShapeLaw) Section =
731 new (BRepFill_ShapeLaw) (TopoDS::Wire(S), Standard_False);
732 InitialLength += Section->NbLaw()+1;
733
734 for (; (ii<=InitialLength) && (!result); ii++) {
735 if (V.IsSame(Section->Vertex(ii, 0.)) ) result = ii;
736 }
737 break;
738 }
739
740 case TopAbs_FACE :
741 case TopAbs_SHELL :
742 case TopAbs_COMPOUND :
743 {
744 for (TopoDS_Iterator it(S); it.More() && (!result); it.Next())
745 result = FindVertex(it.Value(), V, InitialLength);
746 break;
747 }
748
749 case TopAbs_SOLID :
750 case TopAbs_COMPSOLID :
751 Standard_DomainError::Raise("BRepFill_Pipe::SOLID or COMPSOLID");
752 break;
7fd59977 753 default:
754 break;
7fd59977 755 }
756
757 return result;
758}
759
760//=======================================================================
761//function : DefineRealSegmax
762//purpose : Defines the real number of segments
763// required in the case of bspline spine
764//=======================================================================
765
766void BRepFill_Pipe::DefineRealSegmax()
767{
768 Standard_Integer RealSegmax = 0;
769
770 TopoDS_Iterator iter(mySpine);
771 for (; iter.More(); iter.Next())
772 {
773 TopoDS_Edge E = TopoDS::Edge(iter.Value());
774 Standard_Real first, last;
775 Handle(Geom_Curve) C = BRep_Tool::Curve( E, first, last );
776 if (C.IsNull())
777 continue;
778 while (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve) ||
779 C->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
780 {
781 if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve))
782 C = (*((Handle(Geom_TrimmedCurve)*)&C))->BasisCurve();
783 if (C->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
784 C = (*((Handle(Geom_OffsetCurve)*)&C))->BasisCurve();
785 }
786 if (C->DynamicType() == STANDARD_TYPE(Geom_BSplineCurve))
787 {
788 const Handle(Geom_BSplineCurve)& BC = *((Handle(Geom_BSplineCurve)*)&C);
789 Standard_Integer NbKnots = BC->NbKnots();
790 Standard_Integer RealNbKnots = NbKnots;
791 if (first > BC->FirstParameter())
792 {
793 Standard_Integer I1, I2;
794 BC->LocateU( first, Precision::PConfusion(), I1, I2 );
795 RealNbKnots -= I1-1;
796 }
797 if (last < BC->LastParameter())
798 {
799 Standard_Integer I1, I2;
800 BC->LocateU( last, Precision::PConfusion(), I1, I2 );
801 RealNbKnots -= NbKnots-I2;
802 }
803 RealSegmax += RealNbKnots-1;
804 }
805 }
806
807 if (mySegmax < RealSegmax)
808 mySegmax = RealSegmax;
809}
46e68e02 810
811//=======================================================================
812//function : ShareFaces
813//purpose :
814//=======================================================================
815
816TopoDS_Shape BRepFill_Pipe::ShareFaces
817 (const TopoDS_Shape &theShape,
818 const Standard_Integer theInitialFacesLen,
819 const Standard_Integer theInitialEdgesLen,
820 const Standard_Integer theInitialSectionsLen)
821{
822 TopoDS_Shape aResult = theShape;
823 // Check if there are shapes to be shared.
824 TopTools_DataMapOfShapeInteger aMapBndEdgeIndex;
825 TColStd_DataMapOfIntegerInteger aMapNewOldFIndex;
826 TColStd_DataMapOfIntegerInteger aMapNewOldEIndex;
827 TopTools_MapOfShape aMapUsedVtx;
828 TopExp_Explorer anExp;
829 Standard_Integer i;
830 Standard_Integer ii;
831 Standard_Integer jj;
832 BRep_Builder aBuilder;
833
834 // Check the first and last J index of myFaces.
835 for (i = 1; i <= 2; i++) {
836 // Compute jj index of faces.
837 if (i == 1) {
838 jj = 1;
839 } else {
7566ccf3 840 jj = myFaces->RowLength();
46e68e02 841
842 if (jj == 1) {
843 break;
844 }
845 }
846
847 // Fill the map of boundary edges on initial faces.
848 for (ii = 1; ii <= theInitialFacesLen; ii++) {
849 anExp.Init(myFaces->Value(ii, jj), TopAbs_EDGE);
850
851 for (; anExp.More(); anExp.Next()) {
852 if (aMapBndEdgeIndex.IsBound(anExp.Current())) {
853 // This is not boundary edge. Remove it.
854 aMapBndEdgeIndex.UnBind(anExp.Current());
855 } else {
856 // Add boundary edge.
857 aMapBndEdgeIndex.Bind(anExp.Current(), ii);
858 }
859 }
860 }
861
862 // Check if edges of newly created faces are shared with old ones.
863 for (ii = theInitialFacesLen + 1; ii <= myFaces->ColLength(); ii++) {
864 anExp.Init(myFaces->Value(ii, jj), TopAbs_EDGE);
865
866 for (; anExp.More(); anExp.Next()) {
867 if (aMapBndEdgeIndex.IsBound(anExp.Current())) {
868 // This row should be replaced.
869 Standard_Integer anOldIndex = aMapBndEdgeIndex.Find(anExp.Current());
870
871 aMapNewOldFIndex.Bind(ii, anOldIndex);
872
873 // Find corresponding new and old edges indices.
874 TopoDS_Vertex aV[2];
875 TopExp::Vertices(TopoDS::Edge(anExp.Current()), aV[0], aV[1]);
876 Standard_Integer ie;
46e68e02 877
878 // Compute jj index of edges.
7566ccf3 879 Standard_Integer je = (i == 1 ? 1 : myEdges->RowLength());
46e68e02 880
7566ccf3 881 for (Standard_Integer j = 0; j < 2; j++) {
46e68e02 882 if (aMapUsedVtx.Contains(aV[j])) {
883 // This vertex is treated.
884 continue;
885 }
886
887 // Find old index.
888 Standard_Integer iEOld = -1;
889 TopoDS_Vertex aVE[2];
890
891 for (ie = 1; ie <= theInitialEdgesLen; ie++) {
892 const TopoDS_Shape &anEdge = myEdges->Value(ie, je);
893
894 TopExp::Vertices(TopoDS::Edge(anEdge), aVE[0], aVE[1]);
895
896 if (aV[j].IsSame(aVE[0]) || aV[j].IsSame(aVE[1])) {
897 iEOld = ie;
898 break;
899 }
900 }
901
902 if (iEOld > 0) {
903 // Find new index.
904 for (ie = theInitialEdgesLen+1; ie <= myEdges->ColLength(); ie++) {
905 const TopoDS_Shape &anEdge = myEdges->Value(ie, je);
906
907 TopExp::Vertices(TopoDS::Edge(anEdge), aVE[0], aVE[1]);
908
909 if (aV[j].IsSame(aVE[0]) || aV[j].IsSame(aVE[1])) {
910 // This row should be replaced.
911 aMapNewOldEIndex.Bind(ie, iEOld);
912 aMapUsedVtx.Add(aV[j]);
913 break;
914 }
915 }
916 }
917 }
918
919 break;
920 }
921 }
922 }
923 }
924
925 if (!aMapNewOldFIndex.IsEmpty()) {
926 TColStd_DataMapIteratorOfDataMapOfIntegerInteger anIter(aMapNewOldFIndex);
927 TopTools_ListOfShape aListShape;
928 BRepTools_Substitution aSubstitute;
929
930 for (; anIter.More(); anIter.Next()) {
931 const Standard_Integer aNewIndex = anIter.Key();
932 const Standard_Integer anOldIndex = anIter.Value();
933
934 // Change new faces by old ones.
935 for (jj = 1; jj <= myFaces->RowLength(); jj++) {
936 const TopoDS_Shape &aNewFace = myFaces->Value(aNewIndex, jj);
937 const TopoDS_Shape &anOldFace = myFaces->Value(anOldIndex, jj);
938
939 if (!aSubstitute.IsCopied(aNewFace)) {
940 aListShape.Append(anOldFace.Oriented(TopAbs_REVERSED));
941 aSubstitute.Substitute(aNewFace, aListShape);
942 aListShape.Clear();
943 }
944 }
945 }
946
947 // Change new edges by old ones.
948 for (anIter.Initialize(aMapNewOldEIndex); anIter.More(); anIter.Next()) {
949 const Standard_Integer aNewIndex = anIter.Key();
950 const Standard_Integer anOldIndex = anIter.Value();
951
952 for (jj = 1; jj <= myEdges->RowLength(); jj++) {
953 const TopoDS_Shape &aNewEdge = myEdges->Value(aNewIndex, jj);
954 const TopoDS_Shape &anOldEdge = myEdges->Value(anOldIndex, jj);
955
956 if (!aSubstitute.IsCopied(aNewEdge)) {
957 aListShape.Append(anOldEdge.Oriented(TopAbs_FORWARD));
958 aSubstitute.Substitute(aNewEdge, aListShape);
959 aListShape.Clear();
960
961 // Change new vertices by old ones.
962 TopoDS_Iterator aNewIt(aNewEdge);
963 TopoDS_Iterator anOldIt(anOldEdge);
964
965 for (; aNewIt.More() && anOldIt.More();
966 aNewIt.Next(), anOldIt.Next()) {
967 if (!aNewIt.Value().IsSame(anOldIt.Value())) {
968 if (!aSubstitute.IsCopied(aNewIt.Value())) {
969 aListShape.Append(anOldIt.Value().Oriented(TopAbs_FORWARD));
970 aSubstitute.Substitute(aNewIt.Value(), aListShape);
971 aListShape.Clear();
972 }
973 }
974 }
975 }
976 }
977 }
978
979 // Perform substitution.
980 aSubstitute.Build(aResult);
981
982 if (aSubstitute.IsCopied(aResult)) {
983 // Get copied shape.
984 const TopTools_ListOfShape& listSh = aSubstitute.Copy(aResult);
985
986 aResult = listSh.First();
987
988 // Update original faces with copied ones.
989 for (ii = theInitialFacesLen + 1; ii <= myFaces->ColLength(); ii++) {
990 for (jj = 1; jj <= myFaces->RowLength(); jj++) {
991 TopoDS_Shape anOldFace = myFaces->Value(ii, jj); // Copy
992
993 if (aSubstitute.IsCopied(anOldFace)) {
994 const TopTools_ListOfShape& aList = aSubstitute.Copy(anOldFace);
995
996 if(!aList.IsEmpty()) {
997 // Store copied face.
998 const TopoDS_Shape &aCopyFace = aList.First();
999 TopAbs_Orientation anOri = anOldFace.Orientation();
1000 const Standard_Boolean isShared = aMapNewOldFIndex.IsBound(ii);
1001
1002 if (isShared) {
1003 // Reverse the orientation for shared face.
1004 anOri = TopAbs::Reverse(anOri);
1005 }
1006
1007 myFaces->SetValue(ii, jj, aCopyFace.Oriented(anOri));
1008
1009 // Check if it is necessary to update PCurves on this face.
1010 if (!isShared) {
1011 TopoDS_Face anOldF = TopoDS::Face(anOldFace);
1012 TopoDS_Face aCopyF = TopoDS::Face(aCopyFace);
1013
1014 anOldF.Orientation(TopAbs_FORWARD);
1015 anExp.Init(anOldF, TopAbs_EDGE);
1016
1017 for (; anExp.More(); anExp.Next()) {
1018 const TopoDS_Shape &anOldEdge = anExp.Current();
1019
1020 if (aSubstitute.IsCopied(anOldEdge)) {
1021 const TopTools_ListOfShape& aListE =
1022 aSubstitute.Copy(anOldEdge);
1023
1024 if(!aListE.IsEmpty()) {
1025 // This edge is copied. Check if there is a PCurve
1026 // on the face.
1027 TopoDS_Edge aCopyE = TopoDS::Edge(aListE.First());
1028 Standard_Real aFirst;
1029 Standard_Real aLast;
1030 Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface
1031 (aCopyE, aCopyF, aFirst, aLast);
1032
1033 if (aPCurve.IsNull()) {
1034 // There is no pcurve copy it from the old edge.
1035 TopoDS_Edge anOldE = TopoDS::Edge(anOldEdge);
1036
1037 aPCurve = BRep_Tool::CurveOnSurface
1038 (anOldE, anOldF, aFirst, aLast);
1039
1040 if (aPCurve.IsNull() == Standard_False) {
1041 // Update the shared edge with PCurve from new Face.
1042 Standard_Real aTol = Max(BRep_Tool::Tolerance(anOldE),
1043 BRep_Tool::Tolerance(aCopyE));
1044
1045 aBuilder.UpdateEdge(aCopyE, aPCurve, aCopyF, aTol);
1046 }
1047 }
1048 }
1049 }
1050 }
1051 }
1052 }
1053 }
1054 }
1055 }
1056
1057 // Update new edges with shared ones.
1058 for (ii = theInitialEdgesLen + 1; ii <= myEdges->ColLength(); ii++) {
1059 for (jj = 1; jj <= myEdges->RowLength(); jj++) {
1060 const TopoDS_Shape &aLocalShape = myEdges->Value(ii, jj);
1061
1062 if (aSubstitute.IsCopied(aLocalShape)) {
1063 const TopTools_ListOfShape& aList = aSubstitute.Copy(aLocalShape);
1064
1065 if(!aList.IsEmpty()) {
1066 const TopAbs_Orientation anOri = TopAbs_FORWARD;
1067
1068 myEdges->SetValue(ii, jj, aList.First().Oriented(anOri));
1069 }
1070 }
1071 }
1072 }
1073
1074 // Update new sections with shared ones.
1075 for (ii = theInitialSectionsLen+1; ii <= mySections->ColLength(); ii++) {
1076 for (jj = 1; jj <= mySections->RowLength(); jj++) {
1077 const TopoDS_Shape &aLocalShape = mySections->Value(ii, jj);
1078
1079 if (aSubstitute.IsCopied(aLocalShape)) {
1080 const TopTools_ListOfShape& aList = aSubstitute.Copy(aLocalShape);
1081
1082 if(!aList.IsEmpty()) {
1083 const TopAbs_Orientation anOri = TopAbs_FORWARD;
1084
1085 mySections->SetValue(ii, jj, aList.First().Oriented(anOri));
1086 }
1087 }
1088 }
1089 }
1090 }
1091 }
1092
1093 return aResult;
1094}