Integration of OCCT 6.5.0 from SVN
[occt.git] / src / BRepTools / BRepTools_Substitution.cxx
1 // File:        BRepTools_Substitution.cxx
2 // Created:     Tue Mar 28 09:54:41 1995
3 // Author:      Yves FRICAUD
4 //              <yfr@stylox>
5
6
7 #include <BRepTools_Substitution.ixx>
8 #include <TopoDS.hxx>
9 #include <TopoDS_Iterator.hxx>
10 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
11 #include <TopTools_ListIteratorOfListOfShape.hxx>
12 #include <BRep_Builder.hxx>
13 #include <Standard_ConstructionError.hxx>
14 #include <BRep_Tool.hxx>
15  
16 //=======================================================================
17 //function : BRepTools_Substitution
18 //purpose  : 
19 //=======================================================================
20
21 BRepTools_Substitution::BRepTools_Substitution()
22 {}
23
24 //=======================================================================
25 //function : Clear
26 //purpose  : 
27 //=======================================================================
28
29 void BRepTools_Substitution::Clear()
30 {
31   myMap.Clear();
32 }
33
34 //=======================================================================
35 //function : Substitute
36 //purpose  : 
37 //=======================================================================
38
39 void BRepTools_Substitution::Substitute(const TopoDS_Shape&         OS, 
40                                         const TopTools_ListOfShape& NS)
41 {
42   Standard_ConstructionError_Raise_if 
43     (IsCopied(OS),"BRepTools_CutClue::Substitute");
44   myMap.Bind(OS,NS);
45 }
46
47
48 //=======================================================================
49 //function : Build
50 //purpose  : 
51 //=======================================================================
52
53 void BRepTools_Substitution::Build(const TopoDS_Shape& S)
54 {
55   if (IsCopied(S)) return;
56
57   BRep_Builder     B;
58   TopoDS_Iterator  iteS (S.Oriented(TopAbs_FORWARD));
59   Standard_Boolean IsModified  = Standard_False;
60   Standard_Boolean HasSubShape = Standard_False;
61
62   //------------------------------------------
63   // look S is modified and build subshapes.
64   //------------------------------------------
65   for (; iteS.More(); iteS.Next()) {
66     const TopoDS_Shape& SS = iteS.Value();
67     Build (SS);
68     if (IsCopied(SS)) {
69       IsModified = Standard_True;
70     }
71   }
72
73   TopoDS_Shape NewS = S.Oriented(TopAbs_FORWARD);
74   if (IsModified) {
75     //----------------------------------------
76     // Rebuild S.
77     //------------------------------------------
78     NewS.EmptyCopy();
79
80     if (NewS.ShapeType() == TopAbs_EDGE) {
81       Standard_Real f,l;
82       BRep_Tool::Range(TopoDS::Edge(S),f,l);
83       B.Range(TopoDS::Edge(NewS),f,l);
84     }
85     
86     iteS.Initialize(S.Oriented(TopAbs_FORWARD));
87     //------------------------------------------
88     // Add the copy of subshapes of S to NewS.
89     //------------------------------------------
90     for ( ;iteS.More(); iteS.Next()) {
91       TopAbs_Orientation          OS = iteS.Value().Orientation();
92       TopTools_ListOfShape L;
93       L  = myMap(iteS.Value());
94       TopTools_ListIteratorOfListOfShape iteL(L);
95
96       for ( ; iteL.More(); iteL.Next()){
97         const TopoDS_Shape NSS = iteL.Value();
98         //------------------------------------------
99         // Rebuild NSS and add its copy to NewS.
100         //------------------------------------------
101         Build(NSS);      
102
103         const TopTools_ListOfShape&  NL = myMap(NSS);
104         TopAbs_Orientation NewOr = TopAbs::Compose(OS,NSS.Orientation());               
105         TopTools_ListIteratorOfListOfShape iteNL(NL);
106
107         for ( ; iteNL.More(); iteNL.Next()){
108           B.Add (NewS,iteNL.Value().Oriented(NewOr));
109           HasSubShape = Standard_True;
110         }
111       }
112     }
113     if (!HasSubShape) {
114       if (NewS.ShapeType() == TopAbs_WIRE  || NewS.ShapeType() == TopAbs_SHELL ||
115           NewS.ShapeType() == TopAbs_SOLID || NewS.ShapeType() == TopAbs_COMPOUND)
116         //----------------------------------------------------------------
117         // Wire,Solid,Shell,Compound mut have subshape else they disapear
118         //---------------------------------------------------------------       
119         NewS.Nullify();
120     }
121   }
122   TopTools_ListOfShape L;
123   //-------------------------------------------------------
124   // NewS has the same orientation than S in its ancestors
125   // so NewS is bound with orientation FORWARD.
126   //-------------------------------------------------------
127   if (!NewS.IsNull()) L.Append(NewS.Oriented(TopAbs_FORWARD));
128   Substitute(S, L);
129 }
130
131
132 //=======================================================================
133 //function : IsCopied
134 //purpose  : 
135 //=======================================================================
136
137 Standard_Boolean BRepTools_Substitution::IsCopied(const TopoDS_Shape& S) const 
138 {
139   if (myMap.IsBound(S)) {
140     if (myMap (S).IsEmpty()) return Standard_True;
141     else
142       return !S.IsSame(myMap(S).First());
143   }
144   else
145     return Standard_False;
146 }
147
148
149 //=======================================================================
150 //function : Copy
151 //purpose  : 
152 //=======================================================================
153
154 const TopTools_ListOfShape& BRepTools_Substitution::Copy (const TopoDS_Shape& S) 
155      const 
156 {
157   Standard_NoSuchObject_Raise_if(!IsCopied(S),"BRepTools_Substitution::Copy");
158   return myMap(S);
159 }
160