81dd364b34100ae897b635cefee0e47d8d5c8208
[occt.git] / src / BRepMAT2d / BRepMAT2d_Explorer.cxx
1 // Created on: 1994-10-04
2 // Created by: Yves FRICAUD
3 // Copyright (c) 1994-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
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);
84   TopoDS_Face          aNewF = BRepBuilderAPI_MakeFace(aSurf, Precision::Confusion());
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