0029915: Porting to VC 2017 : Regressions in Modeling Algorithms on VC 2017
[occt.git] / src / HLRTopoBRep / HLRTopoBRep_OutLiner.cxx
1 // Created on: 1994-08-04
2 // Created by: Christophe MARION
3 // Copyright (c) 1994-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License 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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <BRep_Builder.hxx>
19 #include <BRepAdaptor_Curve.hxx>
20 #include <Contap_Contour.hxx>
21 #include <Extrema_ExtPC.hxx>
22 #include <gp_Dir.hxx>
23 #include <gp_Pnt.hxx>
24 #include <gp_Vec.hxx>
25 #include <HLRAlgo_Projector.hxx>
26 #include <HLRTopoBRep_Data.hxx>
27 #include <HLRTopoBRep_DSFiller.hxx>
28 #include <HLRTopoBRep_OutLiner.hxx>
29 #include <Standard_Type.hxx>
30 #include <TopExp.hxx>
31 #include <TopExp_Explorer.hxx>
32 #include <TopoDS.hxx>
33 #include <TopoDS_Edge.hxx>
34 #include <TopoDS_Face.hxx>
35 #include <TopoDS_Shape.hxx>
36 #include <TopoDS_Shell.hxx>
37 #include <TopoDS_Wire.hxx>
38 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
39 #include <TopTools_ListIteratorOfListOfShape.hxx>
40
41 IMPLEMENT_STANDARD_RTTIEXT(HLRTopoBRep_OutLiner,Standard_Transient)
42
43 //=======================================================================
44 //function : OutLiner
45 //purpose  : 
46 //=======================================================================
47 HLRTopoBRep_OutLiner::HLRTopoBRep_OutLiner ()
48 {}
49
50 //=======================================================================
51 //function : OutLiner
52 //purpose  : 
53 //=======================================================================
54
55 HLRTopoBRep_OutLiner::HLRTopoBRep_OutLiner(const TopoDS_Shape& OriS) :
56   myOriginalShape(OriS)
57 {}
58
59 //=======================================================================
60 //function : OutLiner
61 //purpose  : 
62 //=======================================================================
63
64 HLRTopoBRep_OutLiner::HLRTopoBRep_OutLiner(const TopoDS_Shape& OriS,
65                                            const TopoDS_Shape& OutS) :
66   myOriginalShape(OriS),
67   myOutLinedShape(OutS)
68 {}
69
70 //=======================================================================
71 //function : Fill
72 //purpose  : 
73 //=======================================================================
74
75 void HLRTopoBRep_OutLiner::Fill(const HLRAlgo_Projector& P,
76                                 BRepTopAdaptor_MapOfShapeTool& MST,
77                                 const Standard_Integer nbIso)
78 {
79   if (!myOriginalShape.IsNull()) {
80     if (myOutLinedShape.IsNull()) {
81       gp_Vec Vecz (0., 0., 1.);
82       gp_Trsf Tr (P.Transformation ());
83       Tr.Invert ();
84       Vecz.Transform (Tr);
85       Contap_Contour FO;
86       if (P.Perspective ()) {
87         gp_Pnt Eye;
88         Eye.SetXYZ (P.Focus ()*Vecz.XYZ ());
89         FO.Init(Eye);
90       }
91       else {
92         gp_Dir DirZ(Vecz);
93         FO.Init(DirZ);
94       }
95       HLRTopoBRep_DSFiller::Insert(myOriginalShape,FO,myDS,MST,nbIso);
96       BuildShape(MST);
97     }
98   }
99 }
100
101 //=======================================================================
102 // Function : ProcessFace
103 // Purpose  : Build a Face using myDS and add the new face to a shell
104 //=======================================================================
105
106 void HLRTopoBRep_OutLiner::ProcessFace(const TopoDS_Face& F,
107                                        TopoDS_Shape& S,
108                                        BRepTopAdaptor_MapOfShapeTool& MST)
109 {
110   BRep_Builder B;
111   TopExp_Explorer exE, exW;
112   //Standard_Boolean splitted = Standard_False;
113
114   TopTools_IndexedDataMapOfShapeListOfShape aVEMap;
115   TopExp::MapShapesAndAncestors(F, TopAbs_VERTEX, TopAbs_EDGE, aVEMap);
116
117   TopoDS_Shape NF;// = F;
118   //NF.Free(Standard_True);
119
120   //for (exE.Init(F,TopAbs_EDGE); exE.More(); exE.Next()) {
121     //if (myDS.EdgeHasSplE(TopoDS::Edge(exE.Current()))) {
122       //splitted = Standard_True;
123       //break;
124     //}
125   //}
126
127   //if (splitted) { // the face contains a splitted edge :
128                   // Make a copy with the new Edges
129     NF = F.EmptyCopied ();
130     
131     
132     for (exW.Init(F,TopAbs_WIRE); exW.More(); exW.Next()) {
133       TopoDS_Wire W;
134       B.MakeWire(W);
135       
136       for (exE.Init(exW.Current(),TopAbs_EDGE); exE.More(); exE.Next()) {
137         TopoDS_Edge E = TopoDS::Edge(exE.Current());
138         if (myDS.EdgeHasSplE(E)) {
139           
140           TopTools_ListIteratorOfListOfShape itS;
141           for (itS.Initialize(myDS.EdgeSplE(E));
142                itS.More();
143                itS.Next()) {
144             TopoDS_Edge newE = TopoDS::Edge(itS.Value());
145             newE.Orientation(E.Orientation());
146             myDS.AddOldS(newE,E);
147             B.Add(W,newE);
148           }
149         }
150         else {
151           B.Add(W,E);
152         }
153       }
154       B.Add(NF,W); // add the new wire in the new face.
155     }
156   //}
157   myDS.AddIntL(F);
158   TopTools_ListOfShape& OutL = myDS.AddOutL(F);
159
160   if (myDS.FaceHasIntL(F)) { // get the InternalOutLines on face F
161     TopoDS_Wire W;
162     
163     TopTools_ListIteratorOfListOfShape itE;
164     for(itE.Initialize(myDS.FaceIntL(F));
165         itE.More();
166         itE.Next()) {
167       TopoDS_Edge E = TopoDS::Edge(itE.Value());
168       E.Orientation(TopAbs_INTERNAL);
169       //Check, if outline edge coincides real edge
170
171       BRepAdaptor_Curve C(E);
172       Standard_Real par = 0.34*C.FirstParameter() + 0.66*C.LastParameter();
173       gp_Pnt P = C.Value(par);
174       TopoDS_Vertex V1, V2, aV1, aV2;
175       TopExp::Vertices(E, V1, V2);
176
177       Standard_Boolean SameEdge = Standard_False;
178       if(!V1.IsNull() && aVEMap.Contains(V1)) {
179         const TopTools_ListOfShape& aEList = aVEMap.FindFromKey(V1);
180         TopTools_ListIteratorOfListOfShape it(aEList);
181         for(; it.More(); it.Next()) {
182           const TopoDS_Edge& aE = TopoDS::Edge(it.Value());
183           TopExp::Vertices(aE, aV1, aV2);
184
185           if((V1.IsSame(aV1) && V2.IsSame(aV2)) || (V1.IsSame(aV2) && V2.IsSame(aV1))) {
186             BRepAdaptor_Curve aC(aE);
187             if((C.GetType() == GeomAbs_Line) &&
188                (aC.GetType() == GeomAbs_Line)) {
189               SameEdge = Standard_True;
190               break;
191             }
192             else {
193               //Try to project one point
194               Extrema_ExtPC anExt(P, aC);
195               if(anExt.IsDone()) {
196                 Standard_Integer aNe = anExt.NbExt();
197                 if(aNe > 0) {
198                   Standard_Real dist = RealLast();
199                   Standard_Integer ec;
200                   for(ec = 1; ec <= aNe; ++ec) {
201 //                  dist = Min(dist, anExt.Value(ec));
202                     dist = Min(dist, anExt.SquareDistance(ec));
203                   }
204
205 //                if(dist <= 1.e-7) {
206                   if(dist <= 1.e-14) {
207                     SameEdge = Standard_True;
208                     break;
209                   }
210                 }
211               }
212             }
213           }
214         }
215       }
216
217       if(SameEdge) {
218         OutL.Append(E);
219         continue;
220       }
221               
222       if (myDS.EdgeHasSplE(E)) { 
223         
224         TopTools_ListIteratorOfListOfShape itS;
225         for (itS.Initialize(myDS.EdgeSplE(E));
226              itS.More();
227              itS.Next()) {
228           TopoDS_Shape newE = itS.Value();
229           newE.Orientation(TopAbs_INTERNAL);
230           if (W.IsNull()) B.MakeWire(W);
231           myDS.AddOldS(newE,F);
232           B.Add(W,newE);
233         }
234       }
235       else {
236         if (W.IsNull()) B.MakeWire(W);
237         myDS.AddOldS(E,F);
238         B.Add(W,E);
239       }
240     }
241     if (!W.IsNull()) B.Add(NF,W); // add the new wire in the new face.
242   }
243   
244   if (myDS.FaceHasIsoL(F)) { // get the IsoLines on face F
245     TopoDS_Wire W;
246     
247     TopTools_ListIteratorOfListOfShape itE;
248     for(itE.Initialize(myDS.FaceIsoL(F));
249         itE.More();
250         itE.Next()) {
251       TopoDS_Edge E = TopoDS::Edge(itE.Value());
252       E.Orientation(TopAbs_INTERNAL);
253       if (myDS.EdgeHasSplE(E)) { // normaly IsoLines are never splitted.
254         
255         TopTools_ListIteratorOfListOfShape itS;
256         for (itS.Initialize(myDS.EdgeSplE(E));
257              itS.More();
258              itS.Next()) {
259           TopoDS_Shape newE = itS.Value();
260           newE.Orientation(TopAbs_INTERNAL);
261           if (W.IsNull()) B.MakeWire(W);
262           myDS.AddOldS(newE,F);
263           B.Add(W,newE);
264         }
265       }
266       else {
267         if (W.IsNull()) B.MakeWire(W);
268         myDS.AddOldS(E,F);
269         B.Add(W,E);
270       }
271     }
272     if (!W.IsNull()) B.Add(NF,W); // add the new wire in the new face.
273   }
274   myDS.AddOldS(NF,F);
275   MST.Bind(NF, MST.ChangeFind(F));
276   //
277   B.Add(S,NF); // add the face in the shell.
278 }
279
280 //=======================================================================
281 //function : BuildShape
282 //purpose  : Build the OutLinedShape
283 //=======================================================================
284
285 void HLRTopoBRep_OutLiner::BuildShape (BRepTopAdaptor_MapOfShapeTool& MST)
286 {
287   TopExp_Explorer exshell, exface, exedge;
288   BRep_Builder B;
289   B.MakeCompound(TopoDS::Compound(myOutLinedShape));
290   TopTools_MapOfShape ShapeMap;
291
292   for (exshell.Init (myOriginalShape, TopAbs_SHELL);
293        exshell.More (); 
294        exshell.Next ()) {             // faces in a shell (open or close)
295     TopoDS_Shell theShell;
296     B.MakeShell(theShell);
297     theShell.Closed(exshell.Current().Closed ());
298
299     for (exface.Init(exshell.Current(), TopAbs_FACE);
300          exface.More(); 
301          exface.Next()) {
302       if (ShapeMap.Add(exface.Current()))
303         ProcessFace(TopoDS::Face(exface.Current()),theShell,MST);
304     }
305     B.Add(myOutLinedShape,theShell);
306   }
307   
308   for (exface.Init(myOriginalShape, TopAbs_FACE, TopAbs_SHELL);
309        exface.More(); 
310        exface.Next()) {                           // faces not in a shell
311     if (ShapeMap.Add(exface.Current()))
312       ProcessFace (TopoDS::Face(exface.Current()),myOutLinedShape,MST);
313   }
314   
315   for (exedge.Init(myOriginalShape, TopAbs_EDGE, TopAbs_FACE);
316        exedge.More();
317        exedge.Next())                              // edges not in a face
318     B.Add(myOutLinedShape,exedge.Current());
319 }
320