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