b311480e |
1 | // Created on: 1994-10-04 |
2 | // Created by: Yves FRICAUD |
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 | // |
973c2be1 |
8 | // This library is free software; you can redistribute it and / or modify it |
9 | // under the terms of the GNU Lesser General Public version 2.1 as published |
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 | |
17 | #include <BRepMAT2d_Explorer.ixx> |
18 | #include <MAT2d_SequenceOfSequenceOfCurve.hxx> |
19 | #include <TColGeom2d_SequenceOfCurve.hxx> |
20 | #include <TopoDS_Wire.hxx> |
21 | #include <BRepTools_WireExplorer.hxx> |
22 | #include <TopLoc_Location.hxx> |
23 | #include <Geom_Curve.hxx> |
24 | #include <Geom_TrimmedCurve.hxx> |
25 | #include <Geom2d_TrimmedCurve.hxx> |
26 | #include <GeomAPI.hxx> |
27 | #include <BRep_Tool.hxx> |
28 | #include <gp.hxx> |
29 | #include <gp_Pln.hxx> |
30 | #include <TopExp_Explorer.hxx> |
31 | #include <TopAbs.hxx> |
32 | #include <TopoDS.hxx> |
33 | |
34 | #include <Precision.hxx> |
35 | #include <Geom2d_BSplineCurve.hxx> |
36 | #include <Geom2dConvert.hxx> |
37 | #include <BRepBuilderAPI_MakeFace.hxx> |
38 | #include <TopExp.hxx> |
39 | #include <BRep_Builder.hxx> |
40 | #include <BRepLib.hxx> |
41 | #include <TopTools_IndexedDataMapOfShapeShape.hxx> |
42 | |
43 | // Modified by Sergey KHROMOV - Thu Dec 5 10:38:14 2002 Begin |
44 | static TopoDS_Edge MakeEdge(const Handle(Geom2d_Curve) &theCurve, |
45 | const TopoDS_Face &theFace, |
46 | const TopoDS_Vertex &theVFirst, |
47 | const TopoDS_Vertex &theVLast); |
48 | // Modified by Sergey KHROMOV - Thu Dec 5 10:38:16 2002 End |
49 | |
50 | //======================================================================= |
51 | //function : BRepMAT2d_Explorer |
52 | //purpose : |
53 | //======================================================================= |
54 | |
55 | BRepMAT2d_Explorer::BRepMAT2d_Explorer() |
56 | { |
57 | Clear(); |
58 | } |
59 | |
60 | //======================================================================= |
61 | //function : BRepMAT2d_Explorer |
62 | //purpose : |
63 | //======================================================================= |
64 | |
65 | BRepMAT2d_Explorer::BRepMAT2d_Explorer(const TopoDS_Face& aFace) |
66 | { |
67 | Perform (aFace); |
68 | } |
69 | |
70 | //======================================================================= |
71 | //function : Perform |
72 | //purpose : |
73 | //======================================================================= |
74 | |
75 | void BRepMAT2d_Explorer::Perform(const TopoDS_Face& aFace) |
76 | { |
77 | Clear(); |
78 | myShape = aFace; |
79 | TopoDS_Face F = TopoDS::Face(aFace); |
80 | F.Orientation(TopAbs_FORWARD); |
81 | TopExp_Explorer Exp (F,TopAbs_WIRE); |
82 | // Modified by Sergey KHROMOV - Tue Nov 26 16:10:37 2002 Begin |
83 | Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F); |
1c72dff6 |
84 | TopoDS_Face aNewF = BRepBuilderAPI_MakeFace(aSurf, Precision::Confusion()); |
7fd59977 |
85 | |
86 | while (Exp.More()) { |
87 | Add (TopoDS::Wire (Exp.Current()),F, aNewF); |
88 | Exp.Next(); |
89 | } |
90 | |
91 | BRepLib::BuildCurves3d(aNewF); |
92 | |
93 | myModifShapes.Add(aFace, aNewF); |
94 | // CheckConnection(); |
95 | // Modified by Sergey KHROMOV - Tue Nov 26 16:10:38 2002 End |
96 | } |
97 | |
98 | //======================================================================= |
99 | //function : Add |
100 | //purpose : |
101 | //======================================================================= |
102 | |
103 | void BRepMAT2d_Explorer::Add(const TopoDS_Wire& Spine, |
104 | const TopoDS_Face& aFace, |
105 | TopoDS_Face& aNewFace) |
106 | { |
107 | // Modified by Sergey KHROMOV - Tue Nov 26 14:25:46 2002 Begin |
108 | // This method is totally rewroted to include check |
109 | // of connection and creation of a new spine. |
110 | NewContour(); |
111 | myIsClosed(currentContour) = (Spine.Closed()) ? Standard_True : Standard_False; |
112 | |
113 | // Modified by skv - Wed Jun 23 12:23:01 2004 Integration Begin |
114 | // Taking into account side of bisecting loci construction. |
115 | // TopoDS_Wire aWFwd = TopoDS::Wire(Spine.Oriented(TopAbs_FORWARD)); |
116 | // BRepTools_WireExplorer anExp(aWFwd, aFace); |
117 | BRepTools_WireExplorer anExp(Spine, aFace); |
118 | // Modified by skv - Wed Jun 23 12:23:02 2004 Integration End |
119 | TopTools_IndexedDataMapOfShapeShape anOldNewE; |
120 | |
121 | if (!anExp.More()) |
122 | return; |
123 | |
124 | TopoDS_Edge aFirstEdge = anExp.Current(); |
125 | Standard_Real UFirst,ULast, aD; |
126 | Handle(Geom2d_BSplineCurve) BCurve; |
127 | Handle(Geom2d_Curve) C2d; |
128 | Handle(Geom2d_TrimmedCurve) CT2d; |
129 | Handle(Geom2d_TrimmedCurve) aFirstCurve; |
130 | gp_Pnt2d aPFirst; |
131 | gp_Pnt2d aPLast; |
132 | gp_Pnt2d aPCurFirst; |
133 | // Modified by skv - Mon Jul 11 19:00:25 2005 Integration Begin |
134 | // Set the confusion tolerance in accordance with the further algo |
135 | // Standard_Real aTolConf = Precision::Confusion(); |
136 | Standard_Real aTolConf = 1.e-8; |
137 | // Modified by skv - Mon Jul 11 19:00:25 2005 Integration End |
138 | Standard_Boolean isModif = Standard_False; |
139 | |
140 | // Treatment of the first edge of a wire. |
141 | anOldNewE.Add(aFirstEdge, aFirstEdge); |
142 | C2d = BRep_Tool::CurveOnSurface (aFirstEdge, aFace, UFirst, ULast); |
143 | CT2d = new Geom2d_TrimmedCurve(C2d,UFirst,ULast); |
144 | |
145 | if (aFirstEdge.Orientation() == TopAbs_REVERSED) |
146 | CT2d->Reverse(); |
147 | |
148 | aPFirst = CT2d->Value(CT2d->FirstParameter()); |
149 | aPLast = CT2d->Value(CT2d->LastParameter()); |
150 | |
151 | Add(CT2d); |
152 | aFirstCurve = CT2d; |
153 | anExp.Next(); |
154 | |
155 | // Treatment of the next edges: |
156 | for (; anExp.More(); anExp.Next()) { |
157 | TopoDS_Edge anEdge = anExp.Current(); |
158 | |
159 | anOldNewE.Add(anEdge, anEdge); |
160 | C2d = BRep_Tool::CurveOnSurface (anEdge, aFace, UFirst, ULast); |
161 | CT2d = new Geom2d_TrimmedCurve(C2d,UFirst,ULast); |
162 | |
163 | if (anEdge.Orientation() == TopAbs_REVERSED) |
164 | CT2d->Reverse(); |
165 | |
166 | aPCurFirst = CT2d->Value(CT2d->FirstParameter()); |
167 | // |
168 | aD=aPLast.Distance(aPCurFirst); |
169 | if (aD > aTolConf) { |
170 | // There are two ways how to fill holes: |
171 | // First, to create a line between these two points. |
172 | // Second, create a BSpline curve and to add the last point of the previous |
173 | // curve as the first pole of the current one. Second method which |
174 | // is worse was performed before and leaved here. Otherwise too much |
175 | // code should be rewritten. |
176 | isModif = Standard_True; |
177 | // |
178 | //modified by NIZNHY-PKV Tue Aug 7 09:14:03 2007f |
179 | //BCurve = Geom2dConvert::CurveToBSplineCurve(CT2d); |
180 | BCurve=Geom2dConvert::CurveToBSplineCurve(CT2d, Convert_QuasiAngular); |
181 | //modified by NIZNHY-PKV Tue Aug 7 09:14:07 2007t |
182 | |
183 | BCurve->SetPole(1, aPLast); |
184 | CT2d = new Geom2d_TrimmedCurve(BCurve, BCurve->FirstParameter(), |
185 | BCurve->LastParameter()); |
186 | |
187 | // Creation of new edge. |
188 | TopoDS_Edge aNewEdge; |
189 | TopoDS_Vertex aVf = TopExp::FirstVertex(anEdge); |
190 | TopoDS_Vertex aVl = TopExp::LastVertex(anEdge); |
191 | |
192 | if (anEdge.Orientation() == TopAbs_FORWARD) |
193 | aNewEdge = MakeEdge(CT2d, aNewFace, aVf, aVl); |
194 | else |
195 | aNewEdge = MakeEdge(CT2d->Reversed(), aNewFace, aVf, aVl); |
196 | |
197 | aNewEdge.Orientation(anEdge.Orientation()); |
198 | |
199 | anOldNewE.ChangeFromKey(anEdge) = aNewEdge; |
200 | } |
201 | |
202 | aPLast = CT2d->Value(CT2d->LastParameter()); |
203 | Add(CT2d); |
204 | } |
205 | |
206 | // Check of the distance between the first and the last point of wire |
207 | // if the wire is closed. |
208 | if (myIsClosed(currentContour) && aPLast.Distance(aPFirst) > aTolConf) { |
209 | isModif = Standard_True; |
210 | |
211 | |
212 | //modified by NIZNHY-PKV Tue Aug 7 09:20:08 2007f |
213 | //Handle(Geom2d_BSplineCurve) |
214 | //BCurve = Geom2dConvert::CurveToBSplineCurve(aFirstCurve); |
215 | BCurve = Geom2dConvert::CurveToBSplineCurve(aFirstCurve, Convert_QuasiAngular); |
216 | //modified by NIZNHY-PKV Tue Aug 7 09:20:11 2007t |
217 | |
218 | BCurve->SetPole(1, aPLast); |
219 | aFirstCurve = new Geom2d_TrimmedCurve(BCurve, BCurve->FirstParameter(), |
220 | BCurve->LastParameter()); |
221 | theCurves.ChangeValue(currentContour).ChangeValue(1) = aFirstCurve; |
222 | |
223 | // Creation of new first edge. |
224 | TopoDS_Edge aNewEdge; |
225 | TopoDS_Vertex aVf = TopExp::FirstVertex(aFirstEdge); |
226 | TopoDS_Vertex aVl = TopExp::LastVertex(aFirstEdge); |
227 | |
228 | if (aFirstEdge.Orientation() == TopAbs_FORWARD) |
229 | aNewEdge = MakeEdge(aFirstCurve, aNewFace, aVf, aVl); |
230 | else |
231 | aNewEdge = MakeEdge(aFirstCurve->Reversed(), aNewFace, aVf, aVl); |
232 | |
233 | aNewEdge.Orientation(aFirstEdge.Orientation()); |
234 | anOldNewE.ChangeFromKey(aFirstEdge) = aNewEdge; |
235 | } |
236 | |
237 | TopoDS_Wire aNewWire; |
238 | BRep_Builder aBuilder; |
239 | |
240 | if (isModif) { |
241 | Standard_Integer i; |
242 | Standard_Integer aNbEdges = anOldNewE.Extent(); |
243 | |
244 | aBuilder.MakeWire(aNewWire); |
245 | |
246 | for (i = 1; i <= aNbEdges; i++) { |
247 | const TopoDS_Shape &aKey = anOldNewE.FindKey(i); |
248 | const TopoDS_Shape &aNewEdge = anOldNewE.FindFromIndex(i); |
249 | |
250 | aBuilder.Add(aNewWire, aNewEdge); |
251 | myModifShapes.Add(aKey, aNewEdge); |
252 | } |
253 | |
254 | if (myIsClosed(currentContour)) |
255 | aNewWire.Closed(Standard_True); |
256 | |
257 | // Modified by skv - Fri Nov 12 17:22:12 2004 Integration Begin |
258 | // The orientation of wire is already taken into account. |
259 | // aNewWire.Orientation(Spine.Orientation()); |
260 | // Modified by skv - Fri Nov 12 17:22:12 2004 Integration End |
261 | myModifShapes.Add(Spine, aNewWire); |
262 | } else |
263 | aNewWire = Spine; |
264 | |
265 | aBuilder.Add(aNewFace, aNewWire); |
266 | // Modified by Sergey KHROMOV - Tue Nov 26 14:25:53 2002 End |
267 | } |
268 | |
269 | //======================================================================= |
270 | //function : CheckConnection |
271 | //purpose : |
272 | //======================================================================= |
273 | |
274 | // Modified by Sergey KHROMOV - Tue Nov 26 17:21:44 2002 Begin |
275 | // void BRepMAT2d_Explorer::CheckConnection() |
276 | // { |
277 | // for (Standard_Integer i = 1; i <= theCurves.Length(); i++) |
278 | // for (Standard_Integer j = 2; j <= theCurves(i).Length(); j++) |
279 | // { |
280 | // gp_Pnt2d P1 = theCurves(i)(j-1)->Value( theCurves(i)(j-1)->LastParameter() ); |
281 | // gp_Pnt2d P2 = theCurves(i)(j)->Value( theCurves(i)(j)->FirstParameter() ); |
282 | // if (P1.Distance( P2 ) > Precision::Confusion()) |
283 | // { |
284 | // Handle( Geom2d_BSplineCurve ) BCurve; |
285 | // if (theCurves(i)(j)->DynamicType() != STANDARD_TYPE(Geom2d_BSplineCurve)) |
286 | // BCurve = Geom2dConvert::CurveToBSplineCurve( theCurves(i)(j) ); |
287 | // else |
288 | // BCurve = Handle( Geom2d_BSplineCurve )::DownCast( theCurves(i)(j) ); |
289 | // BCurve->SetPole( 1, P1 ); |
290 | // theCurves(i)(j) = new Geom2d_TrimmedCurve( BCurve, BCurve->FirstParameter(), BCurve->LastParameter() ); |
291 | // } |
292 | // } |
293 | // } |
294 | // Modified by Sergey KHROMOV - Tue Nov 26 17:21:29 2002 End |
295 | |
296 | //======================================================================= |
297 | //function : Clear |
298 | //purpose : |
299 | //======================================================================= |
300 | |
301 | void BRepMAT2d_Explorer::Clear() |
302 | { |
303 | theCurves.Clear() ; |
304 | currentContour = 0; |
305 | // Modified by Sergey KHROMOV - Wed Mar 6 16:07:55 2002 Begin |
306 | myIsClosed.Clear(); |
307 | myModifShapes.Clear(); |
308 | // Modified by Sergey KHROMOV - Wed Mar 6 16:07:55 2002 End |
309 | } |
310 | |
311 | |
312 | //======================================================================= |
313 | //function : NewContour |
314 | //purpose : |
315 | //======================================================================= |
316 | |
317 | void BRepMAT2d_Explorer::NewContour() |
318 | { |
319 | TColGeom2d_SequenceOfCurve Contour; |
320 | theCurves.Append(Contour); |
321 | // Modified by Sergey KHROMOV - Wed Mar 6 16:12:05 2002 Begin |
322 | myIsClosed.Append(Standard_False); |
323 | // Modified by Sergey KHROMOV - Wed Mar 6 16:12:05 2002 End |
324 | currentContour ++ ; |
325 | } |
326 | |
327 | |
328 | //======================================================================= |
329 | //function : Add |
330 | //purpose : |
331 | //======================================================================= |
332 | |
333 | void BRepMAT2d_Explorer::Add(const Handle(Geom2d_Curve)& aCurve) |
334 | { |
335 | theCurves.ChangeValue(currentContour).Append(aCurve); |
336 | } |
337 | |
338 | //======================================================================= |
339 | //function : NumberOfContours |
340 | //purpose : |
341 | //======================================================================= |
342 | |
343 | Standard_Integer BRepMAT2d_Explorer::NumberOfContours() const |
344 | { |
345 | return theCurves.Length() ; |
346 | } |
347 | |
348 | |
349 | //======================================================================= |
350 | //function : NumberOfCurves |
351 | //purpose : |
352 | //======================================================================= |
353 | |
354 | Standard_Integer BRepMAT2d_Explorer::NumberOfCurves |
355 | (const Standard_Integer IndexContour) |
356 | const |
357 | { |
358 | return theCurves.Value(IndexContour).Length(); |
359 | } |
360 | |
361 | |
362 | //======================================================================= |
363 | //function : Init |
364 | //purpose : |
365 | //======================================================================= |
366 | |
367 | void BRepMAT2d_Explorer::Init(const Standard_Integer IndexContour) |
368 | { |
369 | currentContour = IndexContour; |
370 | current = 1; |
371 | } |
372 | |
373 | |
374 | //======================================================================= |
375 | //function : More |
376 | //purpose : |
377 | //======================================================================= |
378 | |
379 | Standard_Boolean BRepMAT2d_Explorer::More() const |
380 | { |
381 | return (current <= NumberOfCurves(currentContour)); |
382 | } |
383 | |
384 | |
385 | //======================================================================= |
386 | //function : Next |
387 | //purpose : |
388 | //======================================================================= |
389 | |
390 | void BRepMAT2d_Explorer::Next() |
391 | { |
392 | current++; |
393 | } |
394 | |
395 | |
396 | //======================================================================= |
397 | //function : Value |
398 | //purpose : |
399 | //======================================================================= |
400 | |
401 | Handle(Geom2d_Curve) BRepMAT2d_Explorer::Value() const |
402 | { |
403 | return theCurves.Value(currentContour).Value(current); |
404 | } |
405 | |
406 | //======================================================================= |
407 | //function : Shape |
408 | //purpose : |
409 | //======================================================================= |
410 | |
411 | TopoDS_Shape BRepMAT2d_Explorer::Shape() const |
412 | { |
413 | return myShape; |
414 | } |
415 | |
416 | |
417 | //======================================================================= |
418 | //function : Contour |
419 | //purpose : |
420 | //======================================================================= |
421 | |
422 | const TColGeom2d_SequenceOfCurve& BRepMAT2d_Explorer::Contour |
423 | (const Standard_Integer IC) |
424 | const |
425 | { |
426 | return theCurves.Value(IC); |
427 | } |
428 | |
429 | |
430 | // Modified by Sergey KHROMOV - Wed Mar 6 17:40:07 2002 Begin |
431 | //======================================================================= |
432 | //function : IsModified |
433 | //purpose : |
434 | //======================================================================= |
435 | |
436 | Standard_Boolean BRepMAT2d_Explorer::IsModified |
437 | (const TopoDS_Shape &aShape) const |
438 | { |
439 | if (myModifShapes.Contains(aShape)) { |
440 | const TopoDS_Shape &aNewShape = myModifShapes.FindFromKey(aShape); |
441 | const Standard_Boolean isSame = aNewShape.IsSame(aShape); |
442 | |
443 | return !isSame; |
444 | } |
445 | |
446 | return Standard_False; |
447 | } |
448 | |
449 | //======================================================================= |
450 | //function : ModifiedShape |
451 | //purpose : |
452 | //======================================================================= |
453 | |
454 | TopoDS_Shape BRepMAT2d_Explorer::ModifiedShape |
455 | (const TopoDS_Shape &aShape) const |
456 | { |
457 | if (myModifShapes.Contains(aShape)) { |
458 | const TopoDS_Shape &aNewShape = myModifShapes.FindFromKey(aShape); |
459 | |
460 | return aNewShape; |
461 | } |
462 | |
463 | return aShape; |
464 | } |
465 | |
466 | //======================================================================= |
467 | //function : GetIsClosed |
468 | //purpose : |
469 | //======================================================================= |
470 | |
471 | const TColStd_SequenceOfBoolean &BRepMAT2d_Explorer::GetIsClosed() const |
472 | { |
473 | return myIsClosed; |
474 | } |
475 | |
476 | //======================================================================= |
477 | //function : MakeEdge |
478 | //purpose : Creation of an edge by 2d curve, face and two vertices. |
479 | //======================================================================= |
480 | |
481 | TopoDS_Edge MakeEdge(const Handle(Geom2d_Curve) &theCurve, |
482 | const TopoDS_Face &theFace, |
483 | const TopoDS_Vertex &theVFirst, |
484 | const TopoDS_Vertex &theVLast) |
485 | { |
486 | TopoDS_Edge aNewEdge; |
487 | BRep_Builder aBuilder; |
488 | Standard_Real aTol = Precision::Confusion(); |
489 | Standard_Real aFPar = theCurve->FirstParameter(); |
490 | Standard_Real aLPar = theCurve->LastParameter(); |
491 | |
492 | aBuilder.MakeEdge(aNewEdge); |
493 | aBuilder.UpdateEdge(aNewEdge, theCurve, theFace, aTol); |
494 | aBuilder.Add(aNewEdge, theVFirst.Oriented(TopAbs_FORWARD)); |
495 | aBuilder.Add(aNewEdge, theVLast.Oriented(TopAbs_REVERSED)); |
496 | aBuilder.Range(aNewEdge, aFPar, aLPar); |
497 | |
498 | return aNewEdge; |
499 | } |
500 | // Modified by Sergey KHROMOV - Wed Mar 6 17:40:14 2002 End |