summaryrefslogtreecommitdiff
path: root/src/BRepMAT2d/BRepMAT2d_Explorer.cxx
blob: 3872f7a52ae0f1d7b5f4ce3a113d1c09a0401896 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
// File:	BRepMAT2d_Explorer.cxx
// Created:	Tue Oct  4 09:25:21 1994
// Author:	Yves FRICAUD
//		<dub@fuegox>


#include <BRepMAT2d_Explorer.ixx>
#include <MAT2d_SequenceOfSequenceOfCurve.hxx>
#include <TColGeom2d_SequenceOfCurve.hxx>
#include <TopoDS_Wire.hxx>
#include <BRepTools_WireExplorer.hxx>
#include <TopLoc_Location.hxx>
#include <Geom_Curve.hxx>
#include <Geom_TrimmedCurve.hxx>  
#include <Geom2d_TrimmedCurve.hxx>
#include <GeomAPI.hxx>
#include <BRep_Tool.hxx>
#include <gp.hxx>
#include <gp_Pln.hxx>
#include <TopExp_Explorer.hxx>
#include <TopAbs.hxx>
#include <TopoDS.hxx>

#include <Precision.hxx>
#include <Geom2d_BSplineCurve.hxx>
#include <Geom2dConvert.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <TopExp.hxx>
#include <BRep_Builder.hxx>
#include <BRepLib.hxx>
#include <TopTools_IndexedDataMapOfShapeShape.hxx>

//  Modified by Sergey KHROMOV - Thu Dec  5 10:38:14 2002 Begin
static TopoDS_Edge MakeEdge(const Handle(Geom2d_Curve) &theCurve,
			    const TopoDS_Face          &theFace,
			    const TopoDS_Vertex        &theVFirst,
			    const TopoDS_Vertex        &theVLast);
//  Modified by Sergey KHROMOV - Thu Dec  5 10:38:16 2002 End

//=======================================================================
//function : BRepMAT2d_Explorer
//purpose  : 
//=======================================================================

BRepMAT2d_Explorer::BRepMAT2d_Explorer()
{
  Clear();
}

//=======================================================================
//function : BRepMAT2d_Explorer
//purpose  : 
//=======================================================================

BRepMAT2d_Explorer::BRepMAT2d_Explorer(const TopoDS_Face& aFace)
{
  Perform (aFace);
}

//=======================================================================
//function : Perform
//purpose  : 
//=======================================================================

void BRepMAT2d_Explorer::Perform(const TopoDS_Face& aFace)
{
  Clear();
  myShape        = aFace;
  TopoDS_Face  F = TopoDS::Face(aFace);
  F.Orientation(TopAbs_FORWARD);
  TopExp_Explorer Exp (F,TopAbs_WIRE);
//  Modified by Sergey KHROMOV - Tue Nov 26 16:10:37 2002 Begin
  Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F);
  TopoDS_Face          aNewF = (TopoDS_Face) BRepBuilderAPI_MakeFace(aSurf, Precision::Confusion());

  while (Exp.More()) {
    Add (TopoDS::Wire (Exp.Current()),F, aNewF);
    Exp.Next();
  }

  BRepLib::BuildCurves3d(aNewF);

  myModifShapes.Add(aFace, aNewF);
//   CheckConnection();
//  Modified by Sergey KHROMOV - Tue Nov 26 16:10:38 2002 End
}

//=======================================================================
//function : Add
//purpose  : 
//=======================================================================

void BRepMAT2d_Explorer::Add(const TopoDS_Wire& Spine,
			     const TopoDS_Face& aFace,
			           TopoDS_Face& aNewFace)
{  
//  Modified by Sergey KHROMOV - Tue Nov 26 14:25:46 2002 Begin
// This method is totally rewroted to include check
// of connection and creation of a new spine.
  NewContour();
  myIsClosed(currentContour) = (Spine.Closed()) ? Standard_True : Standard_False;

//  Modified by skv - Wed Jun 23 12:23:01 2004 Integration Begin
//  Taking into account side of bisecting loci construction.
//   TopoDS_Wire                         aWFwd = TopoDS::Wire(Spine.Oriented(TopAbs_FORWARD));
//   BRepTools_WireExplorer              anExp(aWFwd, aFace);
  BRepTools_WireExplorer              anExp(Spine, aFace);
//  Modified by skv - Wed Jun 23 12:23:02 2004 Integration End
  TopTools_IndexedDataMapOfShapeShape anOldNewE;

  if (!anExp.More())
    return;

  TopoDS_Edge                 aFirstEdge = anExp.Current();
  Standard_Real               UFirst,ULast, aD;
  Handle(Geom2d_BSplineCurve) BCurve;
  Handle(Geom2d_Curve)        C2d;
  Handle(Geom2d_TrimmedCurve) CT2d;
  Handle(Geom2d_TrimmedCurve) aFirstCurve;
  gp_Pnt2d                    aPFirst;
  gp_Pnt2d                    aPLast;
  gp_Pnt2d                    aPCurFirst;
//  Modified by skv - Mon Jul 11 19:00:25 2005 Integration Begin
//  Set the confusion tolerance in accordance with the further algo
//   Standard_Real               aTolConf   = Precision::Confusion();
  Standard_Real               aTolConf   = 1.e-8;
//  Modified by skv - Mon Jul 11 19:00:25 2005 Integration End
  Standard_Boolean            isModif    = Standard_False;

// Treatment of the first edge of a wire.
  anOldNewE.Add(aFirstEdge, aFirstEdge);
  C2d  = BRep_Tool::CurveOnSurface (aFirstEdge, aFace, UFirst, ULast);
  CT2d = new Geom2d_TrimmedCurve(C2d,UFirst,ULast);

  if (aFirstEdge.Orientation() == TopAbs_REVERSED)
    CT2d->Reverse();

  aPFirst = CT2d->Value(CT2d->FirstParameter());
  aPLast  = CT2d->Value(CT2d->LastParameter());

  Add(CT2d);
  aFirstCurve = CT2d;
  anExp.Next();

// Treatment of the next edges:
  for (; anExp.More(); anExp.Next()) {
    TopoDS_Edge  anEdge = anExp.Current();

    anOldNewE.Add(anEdge, anEdge);
    C2d  = BRep_Tool::CurveOnSurface (anEdge, aFace, UFirst, ULast);
    CT2d = new Geom2d_TrimmedCurve(C2d,UFirst,ULast);

    if (anEdge.Orientation() == TopAbs_REVERSED)
      CT2d->Reverse();

    aPCurFirst = CT2d->Value(CT2d->FirstParameter());
    //
    aD=aPLast.Distance(aPCurFirst);
    if (aD > aTolConf) {
      // There are two ways how to fill holes:
      //     First,  to create a line between these two points.
      //     Second, create a BSpline curve and to add the last point of the previous
      //             curve as the first pole of the current one. Second method which
      //             is worse was performed before and leaved here. Otherwise too much
      //             code should be rewritten.
      isModif = Standard_True;
      //
      //modified by NIZNHY-PKV Tue Aug  7 09:14:03 2007f
      //BCurve = Geom2dConvert::CurveToBSplineCurve(CT2d);
      BCurve=Geom2dConvert::CurveToBSplineCurve(CT2d, Convert_QuasiAngular);
      //modified by NIZNHY-PKV Tue Aug  7 09:14:07 2007t
      
      BCurve->SetPole(1, aPLast);
      CT2d = new Geom2d_TrimmedCurve(BCurve, BCurve->FirstParameter(),
				             BCurve->LastParameter());

      // Creation of new edge.
      TopoDS_Edge aNewEdge;
      TopoDS_Vertex aVf = TopExp::FirstVertex(anEdge);
      TopoDS_Vertex aVl = TopExp::LastVertex(anEdge);

      if (anEdge.Orientation() == TopAbs_FORWARD)
	aNewEdge = MakeEdge(CT2d, aNewFace, aVf, aVl);
      else 
	aNewEdge = MakeEdge(CT2d->Reversed(), aNewFace, aVf, aVl);

      aNewEdge.Orientation(anEdge.Orientation());

      anOldNewE.ChangeFromKey(anEdge) = aNewEdge;
    }

    aPLast = CT2d->Value(CT2d->LastParameter());
    Add(CT2d);
  }

  // Check of the distance between the first and the last point of wire
  // if the wire is closed.
    if (myIsClosed(currentContour) && aPLast.Distance(aPFirst) > aTolConf) {
      isModif = Standard_True;

      
      //modified by NIZNHY-PKV Tue Aug  7 09:20:08 2007f
      //Handle(Geom2d_BSplineCurve)
      //BCurve = Geom2dConvert::CurveToBSplineCurve(aFirstCurve);
      BCurve = Geom2dConvert::CurveToBSplineCurve(aFirstCurve, Convert_QuasiAngular);
      //modified by NIZNHY-PKV Tue Aug  7 09:20:11 2007t

      BCurve->SetPole(1, aPLast);
      aFirstCurve = new Geom2d_TrimmedCurve(BCurve, BCurve->FirstParameter(),
				                    BCurve->LastParameter());
      theCurves.ChangeValue(currentContour).ChangeValue(1) = aFirstCurve;

      // Creation of new first edge.
      TopoDS_Edge aNewEdge;
      TopoDS_Vertex aVf = TopExp::FirstVertex(aFirstEdge);
      TopoDS_Vertex aVl = TopExp::LastVertex(aFirstEdge);

      if (aFirstEdge.Orientation() == TopAbs_FORWARD)
	aNewEdge = MakeEdge(aFirstCurve, aNewFace, aVf, aVl);
      else 
	aNewEdge = MakeEdge(aFirstCurve->Reversed(), aNewFace, aVf, aVl);

      aNewEdge.Orientation(aFirstEdge.Orientation());
      anOldNewE.ChangeFromKey(aFirstEdge) = aNewEdge;
    }

  TopoDS_Wire  aNewWire;
  BRep_Builder aBuilder;

  if (isModif) {
    Standard_Integer i;
    Standard_Integer aNbEdges = anOldNewE.Extent();

    aBuilder.MakeWire(aNewWire);

    for (i = 1; i <= aNbEdges; i++) {
      const TopoDS_Shape &aKey     = anOldNewE.FindKey(i);
      const TopoDS_Shape &aNewEdge = anOldNewE.FindFromIndex(i);

      aBuilder.Add(aNewWire, aNewEdge);
      myModifShapes.Add(aKey, aNewEdge);
    }

    if (myIsClosed(currentContour))
      aNewWire.Closed(Standard_True);

    //  Modified by skv - Fri Nov 12 17:22:12 2004 Integration Begin
    //  The orientation of wire is already taken into account.
    //    aNewWire.Orientation(Spine.Orientation());
    //  Modified by skv - Fri Nov 12 17:22:12 2004 Integration End
    myModifShapes.Add(Spine, aNewWire);
  } else
    aNewWire = Spine;

  aBuilder.Add(aNewFace, aNewWire);
//  Modified by Sergey KHROMOV - Tue Nov 26 14:25:53 2002 End
}

//=======================================================================
//function : CheckConnection
//purpose  : 
//=======================================================================

//  Modified by Sergey KHROMOV - Tue Nov 26 17:21:44 2002 Begin
// void BRepMAT2d_Explorer::CheckConnection()
// {
//   for (Standard_Integer i = 1; i <= theCurves.Length(); i++)
//     for (Standard_Integer j = 2; j <= theCurves(i).Length(); j++)
//       {
// 	gp_Pnt2d P1 = theCurves(i)(j-1)->Value( theCurves(i)(j-1)->LastParameter() );
// 	gp_Pnt2d P2 = theCurves(i)(j)->Value( theCurves(i)(j)->FirstParameter() );
// 	if (P1.Distance( P2 ) > Precision::Confusion())
// 	  {
// 	    Handle( Geom2d_BSplineCurve ) BCurve;
// 	    if (theCurves(i)(j)->DynamicType() != STANDARD_TYPE(Geom2d_BSplineCurve))
// 	      BCurve = Geom2dConvert::CurveToBSplineCurve( theCurves(i)(j) );
// 	    else
// 	      BCurve = Handle( Geom2d_BSplineCurve )::DownCast( theCurves(i)(j) );
// 	    BCurve->SetPole( 1, P1 );
// 	    theCurves(i)(j) = new Geom2d_TrimmedCurve( BCurve, BCurve->FirstParameter(), BCurve->LastParameter() );
// 	  }
//       }
// }
//  Modified by Sergey KHROMOV - Tue Nov 26 17:21:29 2002 End

//=======================================================================
//function : Clear
//purpose  : 
//=======================================================================

void BRepMAT2d_Explorer::Clear()
{  
  theCurves.Clear() ;
  currentContour = 0;
//  Modified by Sergey KHROMOV - Wed Mar  6 16:07:55 2002 Begin
  myIsClosed.Clear();
  myModifShapes.Clear();
//  Modified by Sergey KHROMOV - Wed Mar  6 16:07:55 2002 End
}


//=======================================================================
//function : NewContour
//purpose  : 
//=======================================================================

void BRepMAT2d_Explorer::NewContour()
{  
  TColGeom2d_SequenceOfCurve Contour;
  theCurves.Append(Contour);
//  Modified by Sergey KHROMOV - Wed Mar  6 16:12:05 2002 Begin
  myIsClosed.Append(Standard_False);
//  Modified by Sergey KHROMOV - Wed Mar  6 16:12:05 2002 End
  currentContour ++ ;
}


//=======================================================================
//function : Add
//purpose  : 
//=======================================================================

void BRepMAT2d_Explorer::Add(const Handle(Geom2d_Curve)& aCurve)
{  
  theCurves.ChangeValue(currentContour).Append(aCurve);
}

//=======================================================================
//function : NumberOfContours
//purpose  : 
//=======================================================================

Standard_Integer BRepMAT2d_Explorer::NumberOfContours() const 
{  
  return theCurves.Length() ;
}


//=======================================================================
//function : NumberOfCurves
//purpose  : 
//=======================================================================

Standard_Integer BRepMAT2d_Explorer::NumberOfCurves
  (const Standard_Integer IndexContour)
const 
{  
  return theCurves.Value(IndexContour).Length();
}


//=======================================================================
//function : Init
//purpose  : 
//=======================================================================

void BRepMAT2d_Explorer::Init(const Standard_Integer IndexContour)
{  
  currentContour = IndexContour;
  current        = 1;
}


//=======================================================================
//function : More
//purpose  : 
//=======================================================================

Standard_Boolean BRepMAT2d_Explorer::More() const 
{  
  return (current <= NumberOfCurves(currentContour));
}


//=======================================================================
//function : Next
//purpose  : 
//=======================================================================

void BRepMAT2d_Explorer::Next()
{ 
  current++;
}


//=======================================================================
//function : Value
//purpose  : 
//=======================================================================

Handle(Geom2d_Curve) BRepMAT2d_Explorer::Value() const 
{  
  return theCurves.Value(currentContour).Value(current);
}

//=======================================================================
//function : Shape
//purpose  : 
//=======================================================================

TopoDS_Shape BRepMAT2d_Explorer::Shape() const
{
  return myShape;
}


//=======================================================================
//function : Contour
//purpose  : 
//=======================================================================

const TColGeom2d_SequenceOfCurve& BRepMAT2d_Explorer::Contour
  (const Standard_Integer IC)
const
{
  return theCurves.Value(IC);
}


//  Modified by Sergey KHROMOV - Wed Mar  6 17:40:07 2002 Begin
//=======================================================================
//function : IsModified
//purpose  : 
//=======================================================================

Standard_Boolean BRepMAT2d_Explorer::IsModified
                                     (const TopoDS_Shape &aShape) const
{
  if (myModifShapes.Contains(aShape)) {
    const TopoDS_Shape     &aNewShape = myModifShapes.FindFromKey(aShape);
    const Standard_Boolean  isSame    = aNewShape.IsSame(aShape);

    return !isSame;
  }

  return Standard_False;
}

//=======================================================================
//function : ModifiedShape
//purpose  : 
//=======================================================================

TopoDS_Shape BRepMAT2d_Explorer::ModifiedShape
                                     (const TopoDS_Shape &aShape) const
{
  if (myModifShapes.Contains(aShape)) {
    const TopoDS_Shape &aNewShape = myModifShapes.FindFromKey(aShape);

    return aNewShape;
  }

  return aShape;
}

//=======================================================================
//function : GetIsClosed
//purpose  : 
//=======================================================================

const TColStd_SequenceOfBoolean &BRepMAT2d_Explorer::GetIsClosed() const
{
  return myIsClosed;
}

//=======================================================================
//function : MakeEdge
//purpose  : Creation of an edge by 2d curve, face and two vertices.
//=======================================================================

TopoDS_Edge MakeEdge(const Handle(Geom2d_Curve) &theCurve,
		     const TopoDS_Face          &theFace,
		     const TopoDS_Vertex        &theVFirst,
		     const TopoDS_Vertex        &theVLast)
{
  TopoDS_Edge   aNewEdge;
  BRep_Builder  aBuilder;
  Standard_Real aTol  = Precision::Confusion();
  Standard_Real aFPar = theCurve->FirstParameter();
  Standard_Real aLPar = theCurve->LastParameter();

  aBuilder.MakeEdge(aNewEdge);
  aBuilder.UpdateEdge(aNewEdge, theCurve, theFace, aTol);
  aBuilder.Add(aNewEdge, theVFirst.Oriented(TopAbs_FORWARD));
  aBuilder.Add(aNewEdge, theVLast.Oriented(TopAbs_REVERSED));
  aBuilder.Range(aNewEdge, aFPar, aLPar);

  return aNewEdge;
}
//  Modified by Sergey KHROMOV - Wed Mar  6 17:40:14 2002 End