1 // Created on: 1994-06-07
2 // Created by: Bruno DUMORTIER
3 // Copyright (c) 1994-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <BRepFill_Pipe.ixx>
19 #include <Standard_ErrorHandler.hxx>
21 #include <BRep_Tool.hxx>
22 #include <BRep_Builder.hxx>
23 #include <BRepClass3d_SolidClassifier.hxx>
24 #include <BRepLib_MakeVertex.hxx>
25 #include <BRepTools_Substitution.hxx>
27 #include <GeomFill_CorrectedFrenet.hxx>
28 #include <GeomFill_Frenet.hxx>
29 #include <GeomFill_DiscreteTrihedron.hxx>
30 #include <GeomFill_CurveAndTrihedron.hxx>
32 #include <BRepFill_SectionPlacement.hxx>
33 #include <BRepFill_ShapeLaw.hxx>
34 #include <BRepFill_Edge3DLaw.hxx>
35 #include <BRepFill_Sweep.hxx>
37 #include <GeomAbs_Shape.hxx>
39 #include <TopAbs_ShapeEnum.hxx>
41 #include <TopoDS_Shell.hxx>
42 #include <TopoDS_Solid.hxx>
43 #include <TopoDS_Compound.hxx>
44 #include <TopoDS_Iterator.hxx>
45 #include <TopTools_DataMapOfShapeInteger.hxx>
46 #include <TColStd_DataMapOfIntegerInteger.hxx>
47 #include <TColStd_DataMapIteratorOfDataMapOfIntegerInteger.hxx>
49 #include <Precision.hxx>
50 #include <Standard_NotImplemented.hxx>
52 #include <Geom_TrimmedCurve.hxx>
53 #include <Geom_OffsetCurve.hxx>
54 #include <Geom_BSplineCurve.hxx>
58 static Standard_Boolean Affich = 0;
61 //=======================================================================
62 //function : BRepFill_Pipe
64 //=======================================================================
66 BRepFill_Pipe::BRepFill_Pipe()
70 myContinuity = GeomAbs_C2;
71 myMode = GeomFill_IsCorrectedFrenet;
72 myForceApproxC1 = Standard_False;
76 //=======================================================================
77 //function : BRepFill_Pipe
79 //=======================================================================
81 BRepFill_Pipe::BRepFill_Pipe(const TopoDS_Wire& Spine,
82 const TopoDS_Shape& Profile,
83 const GeomFill_Trihedron aMode,
84 const Standard_Boolean ForceApproxC1,
85 const Standard_Boolean KPart)
91 myMode = GeomFill_IsCorrectedFrenet;
92 if (aMode == GeomFill_IsFrenet ||
93 aMode == GeomFill_IsCorrectedFrenet ||
94 aMode == GeomFill_IsDiscreteTrihedron)
97 myContinuity = GeomAbs_C2;
98 if (myMode == GeomFill_IsDiscreteTrihedron)
99 myContinuity = GeomAbs_C0;
101 myForceApproxC1 = ForceApproxC1;
102 Perform(Spine, Profile, KPart);
106 //=======================================================================
109 //=======================================================================
111 void BRepFill_Pipe::Perform(const TopoDS_Wire& Spine,
112 const TopoDS_Shape& Profile,
113 const Standard_Boolean /*KPart*/)
116 mySections.Nullify();
125 BRepTools_WireExplorer wexp;
126 TopoDS_Shape TheProf;
128 Handle(GeomFill_TrihedronLaw) TLaw;
131 case GeomFill_IsFrenet:
132 TLaw = new GeomFill_Frenet();
134 case GeomFill_IsCorrectedFrenet:
135 TLaw = new GeomFill_CorrectedFrenet();
137 case GeomFill_IsDiscreteTrihedron:
138 TLaw = new GeomFill_DiscreteTrihedron();
143 Handle(GeomFill_CurveAndTrihedron) Loc =
144 new (GeomFill_CurveAndTrihedron) (TLaw);
145 myLoc = new (BRepFill_Edge3DLaw) (mySpine, Loc);
146 if (myLoc->NbLaw() == 0) {
147 return; // Degenerated case
149 myLoc->TransformInG0Law(); // Set into continuity
151 BRepFill_SectionPlacement Place(myLoc, Profile);
152 myTrsf = Place.Transformation();
154 TopLoc_Location Loc2(myTrsf), Loc1;
155 Loc1 = Profile.Location();
158 TheProf.Location(Loc2.Multiplied(Loc1));
160 // Construct First && Last Shape
161 Handle(GeomFill_LocationLaw) law;
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(),
174 fila.Multiply(myTrsf);
175 TopLoc_Location LocFirst(fila);
177 if ( ! LocFirst.IsIdentity()) {
178 myFirst.Location( LocFirst.Multiplied(myProfile.Location()) );
181 myLoc->Law(myLoc->NbLaw())->GetDomain(first, last);
182 myLoc->Law(myLoc->NbLaw())->D0(last,M, V);
183 // try { // Not good, but there are no other means to test SetValues
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(),
188 fila.Multiply(myTrsf);
189 TopLoc_Location LocLast(fila);
190 if (! myLoc->IsClosed() || LocFirst != LocLast) {
192 if ( ! LocLast.IsIdentity()) {
193 myLast.Location(LocLast.Multiplied(myProfile.Location()) );
201 DBRep::Set("theprof", TheProf);
202 DBRep::Set("thefirst", myFirst);
203 DBRep::Set("thelast" , myLast);
207 myShape = MakeShape(TheProf, myFirst, myLast);
211 //=======================================================================
214 //=======================================================================
216 const TopoDS_Shape& BRepFill_Pipe::Spine() const
221 //=======================================================================
224 //=======================================================================
226 const TopoDS_Shape& BRepFill_Pipe::Profile() const
231 //=======================================================================
234 //=======================================================================
236 const TopoDS_Shape& BRepFill_Pipe::Shape() const
242 //=======================================================================
243 //function : FirstShape
245 //=======================================================================
247 const TopoDS_Shape& BRepFill_Pipe::FirstShape() const
253 //=======================================================================
254 //function : LastShape
256 //=======================================================================
258 const TopoDS_Shape& BRepFill_Pipe::LastShape() const
264 //=======================================================================
267 //=======================================================================
269 TopoDS_Face BRepFill_Pipe::Face(const TopoDS_Edge& ESpine,
270 const TopoDS_Edge& EProfile)
274 if ( BRep_Tool::Degenerated(EProfile))
277 Standard_Integer ii, ispin = 0, iprof = 0, count = 0;
279 // *************************************************
280 // Search if EProfile is an edge of myProfile
281 // *************************************************
282 iprof = FindEdge(myProfile, EProfile, count);
284 if (!iprof) Standard_DomainError::Raise(
285 "BRepFill_Pipe::Face : Edge not in the Profile");
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;
295 if (!ispin) Standard_DomainError::Raise(
296 "BRepFill_Pipe::Edge : Edge not in the Spine");
298 theFace = TopoDS::Face(myFaces->Value(iprof, ispin));
303 //=======================================================================
306 //=======================================================================
307 TopoDS_Edge BRepFill_Pipe::Edge(const TopoDS_Edge& ESpine,
308 const TopoDS_Vertex& VProfile)
310 Standard_Integer ii, ispin = 0, iprof = 0, count = 0;;
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");
320 // *************************************************
321 // Search if ESpine is an edge of mySpine and find
322 // the index of the corresponding Filler
323 // *************************************************
325 for (ii=1; ii<=myLoc->NbLaw() && (!ispin); ii++)
326 if (ESpine.IsSame(myLoc->Edge(ii))) ispin = ii;
328 if (!ispin) Standard_DomainError::Raise(
329 "BRepFill_Pipe::Edge : Edge not in the Spine");
332 // *************************************************
333 // Generate the corresponding Shape
334 // *************************************************
336 theEdge = TopoDS::Edge(myEdges->Value(iprof, ispin));
343 //=======================================================================
346 //=======================================================================
348 TopoDS_Shape BRepFill_Pipe::Section(const TopoDS_Vertex& VSpine) const
350 TopoDS_Iterator it, itv;
352 Standard_Integer ii, ispin = 0;
354 TopoDS_Shape curSect = myProfile;
356 // *************************************************
357 // Search if ESpine is an edge of mySpine and find
358 // the index of the corresponding Filler
359 // *************************************************
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;
365 if (!ispin) Standard_DomainError::Raise(
366 "BRepFill_Pipe::Section : Vertex not in the Spine");
369 TopoDS_Compound Comp;
370 B.MakeCompound(Comp);
371 for (ii=1; ii<=mySections->ColLength(); ii++)
372 B.Add(Comp, mySections->Value(ii, ispin));
377 //=======================================================================
378 //function : PipeLine
379 //purpose : Construct a wire by sweeping of a point
380 //=======================================================================
382 TopoDS_Wire BRepFill_Pipe::PipeLine(const gp_Pnt& Point) const
389 BRepLib_MakeVertex MkV(P);
390 Handle(BRepFill_ShapeLaw) Section =
391 new (BRepFill_ShapeLaw) (MkV.Vertex());
394 BRepFill_Sweep MkSw(Section, myLoc, Standard_True);
395 MkSw.SetForceApproxC1(myForceApproxC1);
396 MkSw.Build( BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax );
397 TopoDS_Shape aLocalShape = MkSw.Shape();
398 return TopoDS::Wire(aLocalShape);
399 // return TopoDS::Wire(MkSw.Shape());
402 //=======================================================================
403 //function : MakeShape
405 //=======================================================================
407 TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S,
408 const TopoDS_Shape& FirstShape,
409 const TopoDS_Shape& LastShape)
413 Standard_Boolean explode = Standard_False;
414 TopoDS_Shape TheS, TheFirst, TheLast;
415 Standard_Integer InitialLength = 0;
417 TheFirst = FirstShape;
419 if (! myFaces.IsNull()) InitialLength = myFaces->ColLength();
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
425 // explode is True in the second case
427 // create the result empty
429 switch (S.ShapeType()) {
433 B.MakeWire(TopoDS::Wire(result));
440 B.MakeShell(TopoDS::Shell(result));
443 W.Closed(S.Closed());
445 if (!FirstShape.IsNull()) {
447 B.Add(W, FirstShape);
448 W.Closed(FirstShape.Closed());
451 if (!LastShape.IsNull()) {
454 W.Closed(LastShape.Closed());
461 B.MakeShell(TopoDS::Shell(result));
466 B.MakeShell(TopoDS::Shell(result));
467 explode = Standard_True;
468 if ( !mySpine.Closed() && !TheFirst.IsNull()) {
469 B.Add(result, TheFirst.Reversed());
476 B.MakeCompSolid(TopoDS::CompSolid(result));
477 explode = Standard_True;
482 case TopAbs_COMPSOLID :
483 Standard_DomainError::Raise("BRepFill_Pipe::SOLID or COMPSOLID");
486 case TopAbs_COMPOUND :
488 B.MakeCompound(TopoDS::Compound(result));
489 explode = Standard_True;
498 TopoDS_Iterator itFirst, itLast;
499 TopoDS_Shape first, last;
500 if (!TheFirst.IsNull()) itFirst.Initialize(TheFirst);
501 if (!TheLast.IsNull()) itLast.Initialize(TheLast);
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);
509 B.Add(result,MakeShape(it.Value(), first, last));
511 if (!TheFirst.IsNull()) itFirst.Next();
512 if (!TheLast.IsNull()) itLast.Next();
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);
521 MkSw.SetForceApproxC1(myForceApproxC1);
522 MkSw.Build( BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax );
523 result = MkSw.Shape();
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));
532 MkSw.SetForceApproxC1(myForceApproxC1);
533 MkSw.Build( BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax );
534 result = MkSw.Shape();
536 // Labeling of elements
537 if (mySections.IsNull()) {
538 myFaces = MkSw.SubShape();
539 mySections = MkSw.Sections();
540 myEdges = MkSw.InterFaces();
543 Handle(TopTools_HArray2OfShape) Aux, Somme;
544 Standard_Integer length;
545 Standard_Integer ii, jj, kk;
546 const Standard_Integer aNbFaces = myFaces->ColLength();
547 const Standard_Integer aNbEdges = myEdges->ColLength();
548 const Standard_Integer aNbSections = mySections->ColLength();
550 Aux = MkSw.SubShape();
551 length = Aux->ColLength() + myFaces->ColLength();
552 Somme = new (TopTools_HArray2OfShape) (1, length, 1,
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));
558 for (kk=1, ii=myFaces->ColLength()+1;
559 kk <=Aux->ColLength(); kk++, ii++)
560 Somme->SetValue(ii, jj, Aux->Value(kk, jj));
564 Aux = MkSw.Sections();
565 length = Aux->ColLength() + mySections->ColLength();
566 Somme = new (TopTools_HArray2OfShape) (1, length, 1,
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));
572 for (kk=1, ii=mySections->ColLength()+1;
573 kk <=Aux->ColLength(); kk++, ii++)
574 Somme->SetValue(ii, jj, Aux->Value(kk, jj));
578 Aux = MkSw.InterFaces();
579 length = Aux->ColLength() + myEdges->ColLength();
580 Somme = new (TopTools_HArray2OfShape) (1, length, 1,
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));
586 for (kk=1, ii=myEdges->ColLength()+1;
587 kk <=Aux->ColLength(); kk++, ii++)
588 Somme->SetValue(ii, jj, Aux->Value(kk, jj));
593 // Perform sharing faces
594 result = ShareFaces(result, aNbFaces, aNbEdges, aNbSections);
599 if ( TheS.ShapeType() == TopAbs_FACE ) {
600 Standard_Integer ii, jj;
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);
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));
619 result.Closed(Standard_True);
620 BS.Add(solid,TopoDS::Shell(result));
622 BRepClass3d_SolidClassifier SC(solid);
623 SC.PerformInfinitePoint(Precision::Confusion());
624 if ( SC.State() == TopAbs_IN) {
626 TopoDS_Shape aLocalShape = result.Reversed();
627 BS.Add(solid,TopoDS::Shell(aLocalShape));
628 // BS.Add(solid,TopoDS::Shell(result.Reversed()));
637 //============================================================================
638 //function : FindEdge
639 //purpose : Find the number of edge corresponding to the edge of the profile.
640 //============================================================================
642 Standard_Integer BRepFill_Pipe::FindEdge(const TopoDS_Shape& S,
643 const TopoDS_Edge& E,
644 Standard_Integer& InitialLength) const
646 Standard_Integer result = 0;
648 switch (S.ShapeType()) {
653 if (S.IsSame(E)) result = InitialLength;
659 Standard_Integer ii = InitialLength+1;
660 Handle(BRepFill_ShapeLaw) Section =
661 new (BRepFill_ShapeLaw) (TopoDS::Wire(S), Standard_False);
662 InitialLength += Section->NbLaw();
664 for (; (ii<=InitialLength) && (!result); ii++) {
665 if (E.IsSame(Section->Edge(ii)) ) result = ii;
672 case TopAbs_COMPOUND :
674 for (TopoDS_Iterator it(S); it.More() && (!result); it.Next())
675 result = FindEdge(it.Value(), E, InitialLength );
680 case TopAbs_COMPSOLID :
681 Standard_DomainError::Raise("BRepFill_Pipe::SOLID or COMPSOLID");
690 //=======================================================================
691 //function : FindVertex
692 //purpose : Find the number of edge corresponding to an edge of the profile.
693 //=======================================================================
695 Standard_Integer BRepFill_Pipe::FindVertex(const TopoDS_Shape& S,
696 const TopoDS_Vertex& V,
697 Standard_Integer& InitialLength) const
699 Standard_Integer result = 0;
701 switch (S.ShapeType()) {
705 if (S.IsSame(V)) result = InitialLength;
711 TopoDS_Vertex VF, VL;
712 TopExp::Vertices(TopoDS::Edge(S), VF, VL);
713 if (S.Orientation() == TopAbs_REVERSED) {
715 aux = VF; VF = VL; VL = aux;
717 if (VF.IsSame(V)) result = InitialLength+1;
718 else if (VL.IsSame(V)) result = InitialLength+2;
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;
730 for (; (ii<=InitialLength) && (!result); ii++) {
731 if (V.IsSame(Section->Vertex(ii, 0.)) ) result = ii;
738 case TopAbs_COMPOUND :
740 for (TopoDS_Iterator it(S); it.More() && (!result); it.Next())
741 result = FindVertex(it.Value(), V, InitialLength);
746 case TopAbs_COMPSOLID :
747 Standard_DomainError::Raise("BRepFill_Pipe::SOLID or COMPSOLID");
756 //=======================================================================
757 //function : DefineRealSegmax
758 //purpose : Defines the real number of segments
759 // required in the case of bspline spine
760 //=======================================================================
762 void BRepFill_Pipe::DefineRealSegmax()
764 Standard_Integer RealSegmax = 0;
766 TopoDS_Iterator iter(mySpine);
767 for (; iter.More(); iter.Next())
769 TopoDS_Edge E = TopoDS::Edge(iter.Value());
770 Standard_Real first, last;
771 Handle(Geom_Curve) C = BRep_Tool::Curve( E, first, last );
774 while (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve) ||
775 C->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
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();
782 if (C->DynamicType() == STANDARD_TYPE(Geom_BSplineCurve))
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())
789 Standard_Integer I1, I2;
790 BC->LocateU( first, Precision::PConfusion(), I1, I2 );
793 if (last < BC->LastParameter())
795 Standard_Integer I1, I2;
796 BC->LocateU( last, Precision::PConfusion(), I1, I2 );
797 RealNbKnots -= NbKnots-I2;
799 RealSegmax += RealNbKnots-1;
803 if (mySegmax < RealSegmax)
804 mySegmax = RealSegmax;
807 //=======================================================================
808 //function : ShareFaces
810 //=======================================================================
812 TopoDS_Shape BRepFill_Pipe::ShareFaces
813 (const TopoDS_Shape &theShape,
814 const Standard_Integer theInitialFacesLen,
815 const Standard_Integer theInitialEdgesLen,
816 const Standard_Integer theInitialSectionsLen)
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;
828 BRep_Builder aBuilder;
830 // Check the first and last J index of myFaces.
831 for (i = 1; i <= 2; i++) {
832 // Compute jj index of faces.
836 jj = myFaces->RowLength();
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);
847 for (; anExp.More(); anExp.Next()) {
848 aMapBndEdgeIndex.Bind(anExp.Current(), ii);
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);
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());
861 aMapNewOldFIndex.Bind(ii, anOldIndex);
863 // Find corresponding new and old edges indices.
865 TopExp::Vertices(TopoDS::Edge(anExp.Current()), aV[0], aV[1]);
868 // Compute jj index of edges.
869 Standard_Integer je = (i == 1 ? 1 : myEdges->RowLength());
871 for (Standard_Integer j = 0; j < 2; j++) {
872 if (aMapUsedVtx.Contains(aV[j])) {
873 // This vertex is treated.
878 Standard_Integer iEOld = -1;
879 TopoDS_Vertex aVE[2];
881 for (ie = 1; ie <= theInitialEdgesLen; ie++) {
882 const TopoDS_Shape &anEdge = myEdges->Value(ie, je);
884 TopExp::Vertices(TopoDS::Edge(anEdge), aVE[0], aVE[1]);
886 if (aV[j].IsSame(aVE[0]) || aV[j].IsSame(aVE[1])) {
894 for (ie = theInitialEdgesLen+1; ie <= myEdges->ColLength(); ie++) {
895 const TopoDS_Shape &anEdge = myEdges->Value(ie, je);
897 TopExp::Vertices(TopoDS::Edge(anEdge), aVE[0], aVE[1]);
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]);
915 if (!aMapNewOldFIndex.IsEmpty()) {
916 TColStd_DataMapIteratorOfDataMapOfIntegerInteger anIter(aMapNewOldFIndex);
917 TopTools_ListOfShape aListShape;
918 BRepTools_Substitution aSubstitute;
920 for (; anIter.More(); anIter.Next()) {
921 const Standard_Integer aNewIndex = anIter.Key();
922 const Standard_Integer anOldIndex = anIter.Value();
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);
929 if (!aSubstitute.IsCopied(aNewFace)) {
930 aListShape.Append(anOldFace.Oriented(TopAbs_REVERSED));
931 aSubstitute.Substitute(aNewFace, aListShape);
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();
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);
946 if (!aSubstitute.IsCopied(aNewEdge)) {
947 aListShape.Append(anOldEdge.Oriented(TopAbs_FORWARD));
948 aSubstitute.Substitute(aNewEdge, aListShape);
951 // Change new vertices by old ones.
952 TopoDS_Iterator aNewIt(aNewEdge);
953 TopoDS_Iterator anOldIt(anOldEdge);
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);
969 // Perform substitution.
970 aSubstitute.Build(aResult);
972 if (aSubstitute.IsCopied(aResult)) {
974 const TopTools_ListOfShape& listSh = aSubstitute.Copy(aResult);
976 aResult = listSh.First();
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
983 if (aSubstitute.IsCopied(anOldFace)) {
984 const TopTools_ListOfShape& aList = aSubstitute.Copy(anOldFace);
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);
993 // Reverse the orientation for shared face.
994 anOri = TopAbs::Reverse(anOri);
997 myFaces->SetValue(ii, jj, aCopyFace.Oriented(anOri));
999 // Check if it is necessary to update PCurves on this face.
1001 TopoDS_Face anOldF = TopoDS::Face(anOldFace);
1002 TopoDS_Face aCopyF = TopoDS::Face(aCopyFace);
1004 anOldF.Orientation(TopAbs_FORWARD);
1005 anExp.Init(anOldF, TopAbs_EDGE);
1007 for (; anExp.More(); anExp.Next()) {
1008 const TopoDS_Shape &anOldEdge = anExp.Current();
1010 if (aSubstitute.IsCopied(anOldEdge)) {
1011 const TopTools_ListOfShape& aListE =
1012 aSubstitute.Copy(anOldEdge);
1014 if(!aListE.IsEmpty()) {
1015 // This edge is copied. Check if there is a PCurve
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);
1023 if (aPCurve.IsNull()) {
1024 // There is no pcurve copy it from the old edge.
1025 TopoDS_Edge anOldE = TopoDS::Edge(anOldEdge);
1027 aPCurve = BRep_Tool::CurveOnSurface
1028 (anOldE, anOldF, aFirst, aLast);
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));
1035 aBuilder.UpdateEdge(aCopyE, aPCurve, aCopyF, aTol);
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);
1052 if (aSubstitute.IsCopied(aLocalShape)) {
1053 const TopTools_ListOfShape& aList = aSubstitute.Copy(aLocalShape);
1055 if(!aList.IsEmpty()) {
1056 const TopAbs_Orientation anOri = TopAbs_FORWARD;
1058 myEdges->SetValue(ii, jj, aList.First().Oriented(anOri));
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);
1069 if (aSubstitute.IsCopied(aLocalShape)) {
1070 const TopTools_ListOfShape& aList = aSubstitute.Copy(aLocalShape);
1072 if(!aList.IsEmpty()) {
1073 const TopAbs_Orientation anOri = TopAbs_FORWARD;
1075 mySections->SetValue(ii, jj, aList.First().Oriented(anOri));