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