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