Commit | Line | Data |
---|---|---|
7fd59977 | 1 | // File: BRepAlgo_FaceRestrictor.cxx |
2 | // Created: Fri Sep 1 14:28:42 1995 | |
3 | // Author: Yves FRICAUD | |
4 | // <yfr@nonox> | |
5 | ||
6 | #include <BRepAlgo_FaceRestrictor.ixx> | |
7 | ||
8 | #include <BRepTopAdaptor_FClass2d.hxx> | |
9 | #include <TopoDS.hxx> | |
10 | #include <TopoDS_Vertex.hxx> | |
11 | #include <TopoDS_Edge.hxx> | |
12 | #include <TopExp_Explorer.hxx> | |
13 | #include <TopExp.hxx> | |
14 | #include <TopOpeBRepBuild_WireToFace.hxx> | |
15 | #include <TopTools_ListIteratorOfListOfShape.hxx> | |
16 | #include <Geom_Surface.hxx> | |
17 | #include <Geom2d_Curve.hxx> | |
18 | #include <Geom_Curve.hxx> | |
19 | #include <Geom_TrimmedCurve.hxx> | |
20 | #include <BRep_Builder.hxx> | |
21 | #include <BRep_Tool.hxx> | |
22 | #include <GeomProjLib.hxx> | |
23 | #include <gp_Pnt2d.hxx> | |
24 | ||
25 | #include <Precision.hxx> | |
26 | ||
27 | //======================================================================= | |
28 | //function : BRepAlgo_FaceRestrictor | |
29 | //purpose : | |
30 | //======================================================================= | |
31 | ||
32 | BRepAlgo_FaceRestrictor::BRepAlgo_FaceRestrictor() | |
33 | {} | |
34 | ||
35 | //======================================================================= | |
36 | //function : | |
37 | //purpose : | |
38 | //======================================================================= | |
39 | ||
40 | void BRepAlgo_FaceRestrictor::Init(const TopoDS_Face& F, | |
41 | const Standard_Boolean Proj, | |
42 | const Standard_Boolean CorrectionOrientation) | |
43 | { | |
44 | myFace = F; modeProj = Proj; myCorrection = CorrectionOrientation; | |
45 | } | |
46 | ||
47 | ||
48 | //======================================================================= | |
49 | //function : Add | |
50 | //purpose : | |
51 | //======================================================================= | |
52 | ||
53 | void BRepAlgo_FaceRestrictor::Add(TopoDS_Wire& W) | |
54 | { | |
55 | wires.Append(W); | |
56 | } | |
57 | ||
58 | ||
59 | //======================================================================= | |
60 | //function : Clear | |
61 | //purpose : | |
62 | //======================================================================= | |
63 | ||
64 | void BRepAlgo_FaceRestrictor::Clear() | |
65 | { | |
66 | wires.Clear(); | |
67 | faces.Clear(); | |
68 | } | |
69 | ||
70 | //======================================================================= | |
71 | //function : ChangePcurve | |
72 | //purpose : | |
73 | //======================================================================= | |
74 | ||
75 | static Standard_Boolean ChangePCurve (TopoDS_Edge& E, | |
76 | const Handle(Geom_Surface)& S, | |
77 | TopLoc_Location& L) | |
78 | { | |
79 | BRep_Builder BB; | |
80 | Handle(Geom_Surface) SE; | |
81 | Handle(Geom2d_Curve) C2; | |
82 | TopLoc_Location LE; | |
83 | Standard_Real f,l; | |
84 | ||
85 | BRep_Tool::CurveOnSurface (E,C2,SE,LE,f,l,1); | |
86 | if (!C2.IsNull()) | |
87 | BB.UpdateEdge(E,C2,S,L,Precision::Confusion()); | |
88 | return (C2.IsNull()); | |
89 | } | |
90 | ||
91 | //======================================================================= | |
92 | //function : ProjCurve3d | |
93 | //purpose : | |
94 | //======================================================================= | |
95 | ||
96 | static void ProjCurve3d (TopoDS_Edge& E, | |
97 | const Handle(Geom_Surface)& S, | |
98 | TopLoc_Location& L) | |
99 | { | |
100 | BRep_Builder BB; | |
101 | TopLoc_Location LE; | |
102 | Standard_Real f,l; | |
103 | Handle(Geom_Curve) C = BRep_Tool::Curve(E,LE,f,l); | |
104 | Handle(Geom_TrimmedCurve) CT = new Geom_TrimmedCurve(C,f,l); | |
105 | ||
106 | TopLoc_Location LL = L.Inverted().Multiplied(LE); | |
107 | CT->Transform(LL.Transformation()); | |
108 | ||
109 | Handle(Geom2d_Curve) C2 = GeomProjLib::Curve2d (CT,S); | |
110 | BB.UpdateEdge(E,C2,S,L,Precision::Confusion()); | |
111 | } | |
112 | ||
113 | //======================================================================= | |
114 | //function : Perform | |
115 | //purpose : | |
116 | //======================================================================= | |
117 | ||
118 | void BRepAlgo_FaceRestrictor::Perform() | |
119 | { | |
120 | ||
121 | if (myCorrection) { | |
122 | PerformWithCorrection(); | |
123 | return; | |
124 | } | |
125 | ||
126 | myDone = Standard_False; | |
127 | TopTools_ListIteratorOfListOfShape it(wires); | |
128 | ||
129 | //-------------------------------------------------------------------- | |
0d969553 | 130 | // return geometry of the reference face. |
7fd59977 | 131 | //-------------------------------------------------------------------- |
132 | TopLoc_Location L; | |
133 | const Handle(Geom_Surface)& S = BRep_Tool::Surface(myFace,L); | |
134 | ||
135 | //----------------------------------------------------------------------- | |
0d969553 Y |
136 | // test if edges are on S. otherwise add S to the first pcurve. |
137 | // or projection of the edge on F. | |
7fd59977 | 138 | //---------------------------------------------------------------------- |
139 | TopExp_Explorer Exp; | |
140 | // BRep_Builder BB; | |
141 | Standard_Real f,l; | |
142 | ||
143 | TopOpeBRepBuild_WireToFace WTF; | |
144 | ||
145 | for ( ; it.More(); it.Next()) { | |
0d969553 | 146 | // update the surface on edges. |
7fd59977 | 147 | const TopoDS_Wire& W = TopoDS::Wire(it.Value()); |
148 | ||
149 | for (Exp.Init(W,TopAbs_EDGE); Exp.More(); Exp.Next()) { | |
150 | ||
151 | TopoDS_Edge E = TopoDS::Edge(Exp.Current()); | |
152 | Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E,S,L,f,l); | |
153 | ||
154 | if (C2.IsNull()) { | |
0d969553 | 155 | // no pcurve on the reference surface. |
7fd59977 | 156 | if (modeProj) { |
0d969553 | 157 | // Projection of the 3D curve on surface. |
7fd59977 | 158 | ProjCurve3d ( E, S, L); |
159 | } | |
160 | else { | |
0d969553 | 161 | // return the first pcurve glued on <S> |
7fd59977 | 162 | Standard_Boolean YaPCurve = ChangePCurve (E, S, L); |
163 | if (!YaPCurve) { | |
164 | ProjCurve3d (E, S, L); | |
165 | } | |
166 | ||
167 | } | |
168 | } | |
169 | } | |
170 | WTF.AddWire(W); | |
171 | } | |
172 | ||
173 | WTF.MakeFaces(myFace,faces); | |
174 | ||
175 | myDone = Standard_True; | |
176 | } | |
177 | ||
178 | ||
179 | //======================================================================= | |
180 | //function : IsDone | |
181 | //purpose : | |
182 | //======================================================================= | |
183 | ||
184 | Standard_Boolean BRepAlgo_FaceRestrictor::IsDone() const | |
185 | { | |
186 | return myDone; | |
187 | } | |
188 | ||
189 | ||
190 | //======================================================================= | |
191 | //function : More | |
192 | //purpose : | |
193 | //======================================================================= | |
194 | ||
195 | Standard_Boolean BRepAlgo_FaceRestrictor::More() const | |
196 | { | |
197 | return (!faces.IsEmpty()); | |
198 | } | |
199 | ||
200 | ||
201 | //======================================================================= | |
202 | //function : Next | |
203 | //purpose : | |
204 | //======================================================================= | |
205 | ||
206 | void BRepAlgo_FaceRestrictor::Next() | |
207 | { | |
208 | faces.RemoveFirst(); | |
209 | } | |
210 | ||
211 | ||
212 | //======================================================================= | |
213 | //function : Current | |
214 | //purpose : | |
215 | //======================================================================= | |
216 | ||
217 | TopoDS_Face BRepAlgo_FaceRestrictor::Current() const | |
218 | { | |
219 | return (TopoDS::Face(faces.First())); | |
220 | } | |
221 | ||
222 | //======================================================================= | |
223 | //function : Standard_Boolean | |
224 | //purpose : | |
225 | //======================================================================= | |
226 | ||
227 | static Standard_Boolean IsClosed (const TopoDS_Wire& W) | |
228 | ||
229 | { | |
230 | if (W.Closed()) return 1; | |
231 | TopoDS_Vertex V1,V2; | |
232 | TopExp::Vertices (W, V1,V2); | |
233 | return (V1.IsSame(V2)); | |
234 | } | |
235 | ||
236 | ||
237 | //======================================================================= | |
238 | //function : IsInside | |
239 | //purpose : | |
240 | //======================================================================= | |
241 | ||
242 | static Standard_Boolean IsInside(const TopoDS_Wire& wir, | |
243 | const TopoDS_Face& F, | |
244 | BRepTopAdaptor_FClass2d& /*FClass2d*/) | |
245 | { | |
246 | ||
247 | //Standard_Real U,V; | |
248 | TopExp_Explorer exp; | |
249 | for (exp.Init(wir,TopAbs_EDGE); | |
250 | exp.More(); | |
251 | exp.Next()) { | |
252 | const TopoDS_Edge& edg = TopoDS::Edge(exp.Current()); | |
253 | Standard_Real f,l; | |
254 | Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(edg,F,f,l); | |
255 | Standard_Real prm; | |
256 | ||
257 | if (!Precision::IsNegativeInfinite(f) && | |
258 | !Precision::IsPositiveInfinite(l)) { | |
259 | prm = (f+l)/2.; | |
260 | } | |
261 | else { | |
262 | if (Precision::IsNegativeInfinite(f) && | |
263 | Precision::IsPositiveInfinite(l)){ | |
264 | prm = 0.; | |
265 | } | |
266 | else if (Precision::IsNegativeInfinite(f)) { | |
267 | prm = l-1.; | |
268 | } | |
269 | else { | |
270 | prm = f+1.; | |
271 | } | |
272 | } | |
273 | ||
274 | gp_Pnt2d pt2d(C2d->Value(prm)); | |
275 | BRepTopAdaptor_FClass2d FClass2d(F,Precision::PConfusion()); | |
276 | TopAbs_State st2=FClass2d.Perform(pt2d,Standard_False); | |
277 | return(st2 == TopAbs_IN); | |
278 | } | |
279 | return Standard_False; | |
280 | } | |
281 | //======================================================================= | |
282 | //function : Store | |
283 | //purpose : | |
284 | //======================================================================= | |
285 | ||
286 | static void Store (const TopoDS_Wire& W2, | |
287 | const TopoDS_Wire& W1, | |
288 | TopTools_DataMapOfShapeListOfShape& keyIsIn, | |
289 | TopTools_DataMapOfShapeListOfShape& keyContains) | |
290 | { | |
291 | if (!keyIsIn.IsBound(W2)) { | |
292 | TopTools_ListOfShape empty; | |
293 | keyIsIn.Bind(W2,empty); | |
294 | } | |
295 | keyIsIn(W2).Append(W1); | |
296 | if (!keyContains.IsBound(W1)) { | |
297 | TopTools_ListOfShape empty; | |
298 | keyContains.Bind(W1,empty); | |
299 | } | |
300 | keyContains(W1).Append(W2); | |
301 | } | |
302 | //======================================================================= | |
303 | //function : BuildFaceIn | |
304 | //purpose : | |
305 | //======================================================================= | |
306 | ||
307 | static void BuildFaceIn( TopoDS_Face& F, | |
308 | const TopoDS_Wire& W, | |
309 | TopTools_DataMapOfShapeListOfShape& KeyContains, | |
310 | TopTools_DataMapOfShapeListOfShape& KeyIsIn, | |
311 | TopAbs_Orientation Orientation, | |
312 | TopTools_ListOfShape& Faces) | |
313 | { | |
314 | BRep_Builder B; | |
315 | ||
316 | if (!KeyContains.IsBound(W) || KeyContains(W).IsEmpty()) return; | |
317 | ||
0d969553 | 318 | // Removal of W in KeyIsIn. |
7fd59977 | 319 | // for (TopTools_ListIteratorOfListOfShape it(KeyContains(W)); it.More(); it.Next()) { |
320 | ||
321 | TopTools_ListIteratorOfListOfShape it; | |
322 | for (it.Initialize(KeyContains(W)); it.More(); it.Next()) { | |
323 | const TopoDS_Wire& WI = TopoDS::Wire(it.Value()); | |
324 | TopTools_ListOfShape& L2 = KeyIsIn(WI); | |
325 | TopTools_ListIteratorOfListOfShape it2; | |
326 | for (it2.Initialize(L2); it2.More(); it2.Next()) { | |
327 | if (it2.Value().IsSame(W)) { | |
328 | L2.Remove(it2); | |
329 | break; | |
330 | } | |
331 | } | |
332 | } | |
333 | ||
334 | TopTools_ListOfShape WireExt; | |
335 | ||
336 | for (it.Initialize(KeyContains(W)); it.More(); it.Next()) { | |
337 | const TopoDS_Wire& WI = TopoDS::Wire(it.Value()); | |
338 | TopTools_ListOfShape& L2 = KeyIsIn(WI); | |
339 | ||
340 | if (L2.IsEmpty()) { | |
341 | WireExt.Append(WI); | |
342 | } | |
343 | } | |
344 | ||
345 | for (it.Initialize(WireExt); it.More(); it.Next()) { | |
346 | const TopoDS_Wire& WI = TopoDS::Wire(it.Value()); | |
347 | TopTools_ListOfShape& L2 = KeyIsIn(WI); | |
348 | if (L2.IsEmpty()) { | |
349 | if (Orientation == TopAbs_FORWARD) { | |
350 | TopoDS_Wire NWI(WI); | |
351 | NWI.Reverse(); | |
352 | // TopoDS_Wire NWI = TopoDS::Wire(WI.Reversed()); | |
353 | B.Add(F,NWI); | |
354 | BuildFaceIn (F,WI,KeyContains, KeyIsIn,TopAbs_REVERSED,Faces); | |
355 | } | |
356 | else { | |
357 | TopoDS_Shape aLocalShape = Faces.First().EmptyCopied(); | |
358 | TopoDS_Face NF = TopoDS::Face(aLocalShape); | |
359 | // TopoDS_Face NF = TopoDS::Face(Faces.First().EmptyCopied());; | |
360 | B.Add (NF,WI); | |
361 | Faces.Append (NF); | |
362 | BuildFaceIn (NF, WI, KeyContains, KeyIsIn, TopAbs_FORWARD,Faces); | |
363 | } | |
364 | } | |
365 | } | |
366 | } | |
367 | ||
368 | //======================================================================= | |
369 | //function : Perform | |
370 | //purpose : | |
371 | //======================================================================= | |
372 | ||
373 | void BRepAlgo_FaceRestrictor::PerformWithCorrection() | |
374 | { | |
375 | BRep_Builder B; | |
376 | ||
377 | myDone = Standard_False; | |
378 | TopTools_ListIteratorOfListOfShape it(wires); | |
379 | //--------------------------------------------------------- | |
0d969553 | 380 | // Reorientation of all closed wires to the left. |
7fd59977 | 381 | //--------------------------------------------------------- |
382 | for (; it.More(); it.Next()) { | |
383 | TopoDS_Wire& W = TopoDS::Wire(it.Value()); | |
384 | TopoDS_Shape aLocalShape = myFace.EmptyCopied(); | |
385 | TopoDS_Face NF = TopoDS::Face(aLocalShape); | |
386 | // TopoDS_Face NF = TopoDS::Face(myFace.EmptyCopied()); | |
387 | NF.Orientation(TopAbs_FORWARD); | |
388 | B.Add(NF,W); | |
389 | ||
390 | if (IsClosed(W)) { | |
391 | BRepTopAdaptor_FClass2d FClass2d(NF,Precision::PConfusion()); | |
392 | if(FClass2d.PerformInfinitePoint() != TopAbs_OUT) { | |
393 | W.Reverse(); | |
394 | } | |
395 | } | |
396 | } | |
397 | //--------------------------------------------------------- | |
0d969553 | 398 | // Classification of wires ones compared to the others. |
7fd59977 | 399 | //--------------------------------------------------------- |
400 | Standard_Integer j,i = 1; | |
401 | ||
402 | for (it.Initialize(wires) ; it.More(); it.Next()) { | |
403 | TopoDS_Wire& W1 = TopoDS::Wire(it.Value()); | |
404 | TopTools_ListIteratorOfListOfShape it2(wires); | |
405 | j = 1; | |
406 | ||
407 | if (IsClosed(W1)) { | |
408 | TopoDS_Shape aLocalShape = myFace.EmptyCopied(); | |
409 | TopoDS_Face NF = TopoDS::Face(aLocalShape); | |
410 | // TopoDS_Face NF = TopoDS::Face(myFace.EmptyCopied()); | |
411 | NF.Orientation(TopAbs_FORWARD); | |
412 | B.Add(NF,W1); | |
413 | ||
414 | BRepTopAdaptor_FClass2d FClass2d(NF,Precision::PConfusion()); | |
415 | while (it2.More()) { | |
416 | const TopoDS_Wire& W2 = TopoDS::Wire(it2.Value()); | |
417 | if (!W1.IsSame(W2) && IsInside (W2,NF,FClass2d)) { | |
418 | Store (W2,W1,keyIsIn,keyContains); | |
419 | } | |
420 | it2.Next(); | |
421 | j++; | |
422 | } | |
423 | } | |
424 | i++; | |
425 | } | |
426 | TopTools_ListOfShape WireExt; | |
427 | ||
428 | for (it.Initialize(wires) ; it.More(); it.Next()) { | |
429 | const TopoDS_Wire& W = TopoDS::Wire(it.Value()); | |
430 | if (!keyIsIn.IsBound(W) || keyIsIn(W).IsEmpty()) { | |
431 | WireExt.Append(W); | |
432 | } | |
433 | } | |
434 | ||
435 | for (it.Initialize(WireExt) ; it.More(); it.Next()) { | |
436 | const TopoDS_Wire& W = TopoDS::Wire(it.Value()); | |
437 | if (!keyIsIn.IsBound(W) || keyIsIn(W).IsEmpty()) { | |
438 | TopoDS_Shape aLocalShape = myFace.EmptyCopied(); | |
439 | TopoDS_Face NewFace = TopoDS::Face(aLocalShape); | |
440 | // TopoDS_Face NewFace = TopoDS::Face(myFace.EmptyCopied()); | |
441 | NewFace.Orientation(TopAbs_FORWARD); | |
442 | B.Add (NewFace,W); | |
443 | faces.Append(NewFace); | |
444 | //-------------------------------------------- | |
0d969553 | 445 | // Construction of a face by exterior wire. |
7fd59977 | 446 | //-------------------------------------------- |
447 | BuildFaceIn(NewFace,W, keyContains, keyIsIn, TopAbs_FORWARD, faces); | |
448 | } | |
449 | } | |
450 | myDone = Standard_True; | |
451 | } | |
452 | ||
453 | ||
454 | ||
455 | ||
456 | ||
457 | ||
458 | ||
459 | ||
460 | ||
461 |