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