b311480e |
1 | // Created on: 1994-08-04 |
2 | // Created by: Christophe MARION |
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 | // |
d5f74e42 |
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 |
973c2be1 |
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 | |
42cf5bc1 |
17 | |
7fd59977 |
18 | #include <BRep_Builder.hxx> |
42cf5bc1 |
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> |
7fd59977 |
32 | #include <TopoDS.hxx> |
33 | #include <TopoDS_Edge.hxx> |
42cf5bc1 |
34 | #include <TopoDS_Face.hxx> |
35 | #include <TopoDS_Shape.hxx> |
7fd59977 |
36 | #include <TopoDS_Shell.hxx> |
42cf5bc1 |
37 | #include <TopoDS_Wire.hxx> |
7fd59977 |
38 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> |
42cf5bc1 |
39 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
7fd59977 |
40 | |
92efcf78 |
41 | IMPLEMENT_STANDARD_RTTIEXT(HLRTopoBRep_OutLiner,MMgt_TShared) |
42 | |
7fd59977 |
43 | //======================================================================= |
44 | //function : OutLiner |
45 | //purpose : |
46 | //======================================================================= |
7fd59977 |
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; |
6e6cd5d9 |
112 | //Standard_Boolean splitted = Standard_False; |
7fd59977 |
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 | //} |
302f96fb |
157 | myDS.AddIntL(F); |
7fd59977 |
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 | |