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