0028577: Get rid of the TopOpeBRep* algorithms in TKOffset toolkit
[occt.git] / src / BRepOffsetAPI / BRepOffsetAPI_DraftAngle.cxx
CommitLineData
b311480e 1// Created on: 1995-02-22
2// Created by: Jacques GOUSSARD
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_GCurve.hxx>
20#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
21#include <BRep_TEdge.hxx>
22#include <BRep_Tool.hxx>
23#include <BRepAdaptor_Curve.hxx>
24#include <BRepAdaptor_Curve2d.hxx>
7fd59977 25#include <BRepFill_DataMapIteratorOfDataMapOfShapeSequenceOfReal.hxx>
42cf5bc1 26#include <BRepFill_DataMapOfShapeSequenceOfReal.hxx>
27#include <BRepLib.hxx>
28#include <BRepLib_MakeVertex.hxx>
29#include <BRepOffsetAPI_DraftAngle.hxx>
7fd59977 30#include <BRepOffsetAPI_SequenceOfSequenceOfReal.hxx>
31#include <BRepOffsetAPI_SequenceOfSequenceOfShape.hxx>
42cf5bc1 32#include <BRepTools.hxx>
7fd59977 33#include <BRepTools_Substitution.hxx>
42cf5bc1 34#include <Draft_Modification.hxx>
35#include <Geom2d_Curve.hxx>
36#include <Geom_Surface.hxx>
37#include <gp_Dir.hxx>
38#include <gp_Pln.hxx>
39#include <Precision.hxx>
40#include <Standard_ConstructionError.hxx>
41#include <Standard_NoSuchObject.hxx>
42#include <Standard_NullObject.hxx>
43#include <StdFail_NotDone.hxx>
44#include <TColgp_SequenceOfPnt.hxx>
45#include <TColStd_SequenceOfReal.hxx>
7fd59977 46#include <TopExp.hxx>
42cf5bc1 47#include <TopExp_Explorer.hxx>
48#include <TopLoc_Location.hxx>
49#include <TopoDS.hxx>
50#include <TopoDS_Face.hxx>
51#include <TopoDS_Iterator.hxx>
52#include <TopoDS_Shape.hxx>
7fd59977 53#include <TopoDS_Wire.hxx>
42cf5bc1 54#include <TopTools_DataMapOfShapeSequenceOfShape.hxx>
55#include <TopTools_ListIteratorOfListOfShape.hxx>
56#include <TopTools_SequenceOfShape.hxx>
7fd59977 57
3b77eff6 58#include <Geom2dInt_GInter.hxx>
59#include <IntRes2d_IntersectionPoint.hxx>
60
7fd59977 61//=======================================================================
62//function : BRepOffsetAPI_DraftAngle
63//purpose :
64//=======================================================================
7fd59977 65BRepOffsetAPI_DraftAngle::BRepOffsetAPI_DraftAngle () {}
66
67
68//=======================================================================
69//function : BRepOffsetAPI_DraftAngle
70//purpose :
71//=======================================================================
72
73BRepOffsetAPI_DraftAngle::BRepOffsetAPI_DraftAngle (const TopoDS_Shape& S)
74{
75 myInitialShape = S;
76 myModification = new Draft_Modification(S);
77}
78
79
80//=======================================================================
81//function : Clear
82//purpose :
83//=======================================================================
84
85void BRepOffsetAPI_DraftAngle::Clear ()
86{
87 if (!myModification.IsNull()) {
c5f3a425 88 Handle(Draft_Modification)::DownCast (myModification)->Clear();
7fd59977 89 }
90}
91
92
93//=======================================================================
94//function : Init
95//purpose :
96//=======================================================================
97
98void BRepOffsetAPI_DraftAngle::Init (const TopoDS_Shape& S)
99{
100 myInitialShape = S;
101 NotDone();
102 if (!myModification.IsNull()) {
c5f3a425 103 Handle(Draft_Modification)::DownCast (myModification)->Init(S);
7fd59977 104 }
105 else {
106 myModification = new Draft_Modification(S);
107 }
108}
109
110
111//=======================================================================
112//function : Add
113//purpose :
114//=======================================================================
115
116void BRepOffsetAPI_DraftAngle::Add(const TopoDS_Face& F,
117 const gp_Dir& D,
118 const Standard_Real Angle,
119 const gp_Pln& Plane,
120 const Standard_Boolean Flag)
121{
122// POP-DPF : protection
123 if ( Abs(Angle) <= 1.e-04 )
124 return;
125 Standard_NullObject_Raise_if(myInitialShape.IsNull(),"");
c5f3a425 126 Handle(Draft_Modification)::DownCast (myModification)->Add(F,D,Angle,Plane, Flag);
7fd59977 127}
128
129
130//=======================================================================
131//function : AddDone
132//purpose :
133//=======================================================================
134
135Standard_Boolean BRepOffsetAPI_DraftAngle::AddDone () const
136{
137 Standard_NullObject_Raise_if(myInitialShape.IsNull(),"");
c5f3a425 138 return Handle(Draft_Modification)::DownCast (myModification)
7fd59977 139 ->ProblematicShape().IsNull();
140}
141
142
143//=======================================================================
144//function : Remove
145//purpose :
146//=======================================================================
147
148void BRepOffsetAPI_DraftAngle::Remove(const TopoDS_Face& F)
149{
150 Standard_NullObject_Raise_if(myInitialShape.IsNull(),"");
c5f3a425 151 Handle(Draft_Modification)::DownCast (myModification)->Remove(F);
7fd59977 152}
153
154
155//=======================================================================
156//function : ProblematicShape
157//purpose :
158//=======================================================================
159
160const TopoDS_Shape& BRepOffsetAPI_DraftAngle::ProblematicShape () const
161{
162 Standard_NullObject_Raise_if(myInitialShape.IsNull(),"");
c5f3a425 163 return Handle(Draft_Modification)::DownCast (myModification)->ProblematicShape();
7fd59977 164}
165
166
167//=======================================================================
168//function : ErrorStatus
169//purpose :
170//=======================================================================
171
172Draft_ErrorStatus BRepOffsetAPI_DraftAngle::Status () const
173{
174 Standard_NullObject_Raise_if(myInitialShape.IsNull(),"");
c5f3a425 175 return Handle(Draft_Modification)::DownCast (myModification)->Error();
7fd59977 176}
177
178
179//=======================================================================
180//function : ConnectedFaces
181//purpose :
182//=======================================================================
183
184const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::ConnectedFaces
185 (const TopoDS_Face& F) const
186{
187 Standard_NullObject_Raise_if(myInitialShape.IsNull(),"");
c5f3a425 188 return Handle(Draft_Modification)::DownCast (myModification)->ConnectedFaces(F);
7fd59977 189}
190
191
192//=======================================================================
193//function : ModifiedFaces
194//purpose :
195//=======================================================================
196
197const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::ModifiedFaces() const
198{
199 Standard_NullObject_Raise_if(myInitialShape.IsNull(),"");
c5f3a425 200 return Handle(Draft_Modification)::DownCast (myModification)->ModifiedFaces();
7fd59977 201}
202
203//=======================================================================
2651bfde 204//function : Generated
7fd59977 205//purpose :
206//=======================================================================
207
208const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::Generated(const TopoDS_Shape& S)
209{
210 myGenerated.Clear();
211 Standard_NullObject_Raise_if(myInitialShape.IsNull(),"");
c5f3a425 212 Handle(Draft_Modification) DMod = Handle(Draft_Modification)::DownCast (myModification);
7fd59977 213
214 if (S.ShapeType() == TopAbs_FACE) {
215 Handle(Geom_Surface) Surf;
216 TopLoc_Location L;
217 Standard_Real Tol;
218 Standard_Boolean RW,RF;
219 if (DMod->NewSurface(TopoDS::Face(S), Surf, L, Tol, RW, RF)) {
2651bfde 220 if(myVtxToReplace.IsEmpty())
221 {
222 myGenerated.Append(ModifiedShape (S));
223 }
224 else
225 {
226 myGenerated.Append(mySubs.Value(ModifiedShape (S)));
227 }
7fd59977 228 }
229 }
230 return myGenerated;
231}
232
233//=======================================================================
2651bfde 234//function : Modified
7fd59977 235//purpose :
236//=======================================================================
237
238const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::Modified(const TopoDS_Shape& S)
239{
240 myGenerated.Clear();
241 Standard_NullObject_Raise_if(myInitialShape.IsNull(),"");
c5f3a425 242 Handle(Draft_Modification) DMod = Handle(Draft_Modification)::DownCast (myModification);
7fd59977 243
244 if (S.ShapeType() == TopAbs_FACE) {
245 Handle(Geom_Surface) Surf;
246 TopLoc_Location L;
247 Standard_Real Tol;
248 Standard_Boolean RW,RF;
249
250 if (!DMod->NewSurface(TopoDS::Face(S), Surf, L, Tol, RW, RF)) {
251 // Ce n est pas une generation => peut etre une modif
2651bfde 252 if(myVtxToReplace.IsEmpty())
253 {
254 myGenerated.Append(ModifiedShape (S));
255 }
256 else
257 {
258 myGenerated.Append(mySubs.Value(ModifiedShape (S)));
259 }
7fd59977 260 if (myGenerated.Extent() == 1 && myGenerated.First().IsSame(S)) {
2651bfde 261 myGenerated.Clear();
7fd59977 262 }
263 }
264 }
265 return myGenerated;
266}
267
345d3056 268//=======================================================================
269//function : ModifiedShape
270//purpose :
271//=======================================================================
272
273TopoDS_Shape BRepOffsetAPI_DraftAngle::ModifiedShape
274 (const TopoDS_Shape& S) const
275{
276 if(S.ShapeType() == TopAbs_VERTEX)
277 {
278 if(myVtxToReplace.IsBound(S))
279 {
280 return myVtxToReplace(S);
281 }
282 }
2651bfde 283 if(myVtxToReplace.IsEmpty())
284 {
285 return myModifier.ModifiedShape(S);
286 }
287 else
288 {
289 const TopoDS_Shape& aNS = myModifier.ModifiedShape(S);
290 return mySubs.Value(aNS);
291 }
345d3056 292}
7fd59977 293
294//=======================================================================
295//function : Build
296//purpose :
297//=======================================================================
298
299void BRepOffsetAPI_DraftAngle::Build()
300{
c5f3a425 301 Handle(Draft_Modification)::DownCast (myModification)->Perform();
302 if (!Handle(Draft_Modification)::DownCast (myModification)->IsDone()) {
7fd59977 303 NotDone();
304 }
305 else {
306 DoModif(myInitialShape);
7fd59977 307 CorrectWires();
345d3056 308 CorrectVertexTol();
7fd59977 309 }
310}
311
312//=======================================================================
313//function : CorrectWires
314//purpose :
315//=======================================================================
316
317void BRepOffsetAPI_DraftAngle::CorrectWires()
318{
319 Standard_Real TolInter = 1.e-7;
320 Standard_Integer i, j, k;
321
322 TopTools_SequenceOfShape Eseq;
323 TopTools_SequenceOfShape Wseq;
324 TopTools_SequenceOfShape Fseq;
325 TopoDS_Shape CurEdge, CurWire, CurFace;
326 TopoDS_Iterator wit, eit;
327
328 TopExp_Explorer fexp( myShape, TopAbs_FACE );
329 for (; fexp.More(); fexp.Next())
345d3056 330 {
331 CurFace = fexp.Current();
332 wit.Initialize( CurFace );
333 for (; wit.More(); wit.Next())
7fd59977 334 {
345d3056 335 CurWire = wit.Value();
336 TopTools_MapOfShape emap;
337 eit.Initialize( CurWire );
338 for (; eit.More(); eit.Next())
339 emap.Add( eit.Value() );
340 TopTools_MapIteratorOfMapOfShape mapit( emap );
341 for (; mapit.More(); mapit.Next())
342 {
343 CurEdge = mapit.Key();
344 if (BRepTools::IsReallyClosed( TopoDS::Edge(CurEdge), TopoDS::Face(CurFace) ))
345 {
346 Eseq.Append( CurEdge );
347 Wseq.Append( CurWire );
348 Fseq.Append( CurFace );
349 }
350 }
7fd59977 351 }
345d3056 352 }
7fd59977 353
354 BRepFill_DataMapOfShapeSequenceOfReal Emap;
355
356 TopTools_SequenceOfShape NonSeam;
357 TopTools_SequenceOfShape NonSeamWires;
358 BRepOffsetAPI_SequenceOfSequenceOfReal ParsNonSeam;
359 BRepOffsetAPI_SequenceOfSequenceOfShape Seam;
360 BRepOffsetAPI_SequenceOfSequenceOfReal ParsSeam;
361
362 TopTools_DataMapOfShapeShape WFmap;
363 TopTools_DataMapOfShapeListOfShape WWmap;
364 for (i = 1; i <= Eseq.Length(); i++)
345d3056 365 {
366 CurEdge = Eseq(i);
367 CurWire = Wseq(i);
368 CurFace = Fseq(i);
3b77eff6 369 //
370 const TopoDS_Face& aFace = TopoDS::Face(CurFace);
371 //
372 // Prepare 2D adaptors for intersection.
373 // The seam edge has two 2D curve, thus we have to create 2 adaptors
374 BRepAdaptor_Curve2d aBAC2D1(TopoDS::Edge(CurEdge), aFace);
375 BRepAdaptor_Curve2d aBAC2D1R(TopoDS::Edge(CurEdge.Reversed()), aFace);
376 // Get surface of the face to get 3D intersection point
377 TopLoc_Location aLoc;
378 const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(aFace, aLoc);
379 // Get the tolerance of the current edge to compare intersection points
380 Standard_Real aTolCurE = BRep_Tool::Tolerance(TopoDS::Edge(CurEdge));
381 //
345d3056 382 wit.Initialize( CurFace );
383 for (; wit.More(); wit.Next())
7fd59977 384 {
345d3056 385 TopoDS_Shape aWire = wit.Value();
386 if (! aWire.IsSame( CurWire ))
387 {
388 TColgp_SequenceOfPnt pts;
345d3056 389 Standard_Boolean Wadd = Standard_False;
390 eit.Initialize( aWire );
391 for (; eit.More(); eit.Next())
392 {
3b77eff6 393 const TopoDS_Edge& anEdge = TopoDS::Edge(eit.Value());
394 //
395 // Prepare 2D adaptor for intersection
396 BRepAdaptor_Curve2d aBAC2D2(anEdge, aFace);
397 // Perform intersection
398 Geom2dInt_GInter aGInter;
399 aGInter.Perform(aBAC2D1, aBAC2D2, TolInter, TolInter);
400 if (!aGInter.IsDone() || aGInter.IsEmpty()) {
401 // If first intersection is empty try intersection with reversed edge
402 aGInter.Perform(aBAC2D1R, aBAC2D2, TolInter, TolInter);
403 if (!aGInter.IsDone() || aGInter.IsEmpty()) {
345d3056 404 continue;
3b77eff6 405 }
345d3056 406 }
3b77eff6 407 //
345d3056 408 Wadd = Standard_True;
409 if (! WFmap.IsBound( aWire ))
410 WFmap.Bind( aWire, CurFace );
411 Standard_Integer ind = 0;
3b77eff6 412 for (j = 1; j <= NonSeam.Length(); j++) {
413 if (anEdge.IsSame(NonSeam(j)))
345d3056 414 {
415 ind = j;
416 break;
417 }
3b77eff6 418 }
419 if (ind == 0)
420 {
421 NonSeam.Append(anEdge);
422 NonSeamWires.Append(aWire);
423 ind = NonSeam.Length();
424 TColStd_SequenceOfReal emptyseq1, emptyseq2;
425 TopTools_SequenceOfShape emptyedgeseq;
426 ParsNonSeam.Append(emptyseq1);
427 Seam.Append(emptyedgeseq);
428 ParsSeam.Append(emptyseq2);
429 }
430 if (!Emap.IsBound(CurEdge))
431 {
432 TColStd_SequenceOfReal emptyseq;
433 Emap.Bind(CurEdge, emptyseq);
434 }
435 //
436 // Get the tolerance of edge to compare intersection points
437 Standard_Real aTolE = BRep_Tool::Tolerance(anEdge);
438 // Tolerance to compare the intersection points is the maximal
439 // tolerance of intersecting edges
440 Standard_Real aTolCmp = Max(aTolCurE, aTolE);
441 //
442 Standard_Integer k, aNbIntPnt = aGInter.NbPoints();
443 for (k = 1; k <= aNbIntPnt; ++k) {
444 const IntRes2d_IntersectionPoint& aP2DInt = aGInter.Point(k);
445 const gp_Pnt2d& aP2D = aP2DInt.Value();
446 gp_Pnt aP3D = aSurf->Value(aP2D.X(), aP2D.Y());
447 //
448 // Check if the intersection point is new
449 Standard_Integer ied = 0;
450 for (j = 1; j <= pts.Length(); j++) {
451 if (aP3D.IsEqual(pts(j), aTolCmp))
452 {
453 ied = j;
454 break;
455 }
345d3056 456 }
3b77eff6 457 if (ied == 0)
345d3056 458 {
3b77eff6 459 pts.Append(aP3D);
460 Emap(CurEdge).Append(aP2DInt.ParamOnFirst());
461 ParsNonSeam(ind).Append(aP2DInt.ParamOnSecond());
462 Seam(ind).Append(CurEdge);
463 ParsSeam(ind).Append(aP2DInt.ParamOnFirst());
345d3056 464 }
3b77eff6 465 }
345d3056 466 } //for (; eit.More(); eit.Next())
467 if (Wadd)
468 {
469 if (! WWmap.IsBound( CurWire ))
470 {
471 TopTools_ListOfShape emptylist;
472 WWmap.Bind( CurWire, emptylist );
473 }
474 WWmap(CurWire).Append( aWire );
475 }
476 } //if (! aWire.IsSame( CurWire ))
477 } //for (; wit.More(); wit.Next())
478 } //for (i = 1; i <= Eseq.Length(); i++)
7fd59977 479
480 //Sorting
481 for (i = 1; i <= NonSeam.Length(); i++)
482 for (j = 1; j < ParsNonSeam(i).Length(); j++)
483 for (k = j+1; k <= ParsNonSeam(i).Length(); k++)
345d3056 484 if (ParsNonSeam(i)(k) < ParsNonSeam(i)(j))
485 {
486 Standard_Real temp = ParsNonSeam(i)(j);
487 ParsNonSeam(i)(j) = ParsNonSeam(i)(k);
488 ParsNonSeam(i)(k) = temp;
489 TopoDS_Shape tmp = Seam(i)(j);
490 Seam(i)(j) = Seam(i)(k);
491 Seam(i)(k) = tmp;
492 temp = ParsSeam(i)(j);
493 ParsSeam(i)(j) = ParsSeam(i)(k);
494 ParsSeam(i)(k) = temp;
495 }
496 BRepFill_DataMapIteratorOfDataMapOfShapeSequenceOfReal iter( Emap );
497 for (; iter.More(); iter.Next())
498 {
499 TColStd_SequenceOfReal Seq;
500 Seq = iter.Value();
501 for (i = 1; i < Seq.Length(); i++)
502 for (j = i+1; j <= Seq.Length(); j++)
503 if (Seq(j) < Seq(i))
504 {
505 Standard_Real temp = Seq(i);
506 Seq(i) = Seq(j);
507 Seq(j) = temp;
508 }
509 Emap( iter.Key() ) = Seq;
510 }
511 BRepFill_DataMapOfShapeSequenceOfReal EPmap;
512 TopTools_DataMapOfShapeSequenceOfShape EVmap; //Seam
513 TopTools_DataMapOfShapeSequenceOfShape EWmap; //Seam and wires intersecting it
514 iter.Initialize( Emap );
515 for (; iter.More(); iter.Next())
516 {
517 TColStd_SequenceOfReal parseq;
518 EPmap.Bind( iter.Key(), parseq );
519 TopTools_SequenceOfShape shapeseq;
520 EVmap.Bind( iter.Key(), shapeseq );
521 TopTools_SequenceOfShape shapeseq2;
522 EWmap.Bind( iter.Key(), shapeseq2 );
523 }
524
525 //Reconstruction of non-seam edges
526 BRepTools_Substitution aSub;
527 BRep_Builder BB;
528 for (i = 1; i <= NonSeam.Length(); i++)
529 {
530 TopoDS_Edge anEdge = TopoDS::Edge( NonSeam(i) );
531 TopTools_ListOfShape NewEdges;
532 TopoDS_Edge NewE;
533 TopoDS_Vertex Vfirst, Vlast;
534 TopExp::Vertices( anEdge, Vfirst, Vlast );
535 Standard_Real par, FirstPar, LastPar;
536 BRep_Tool::Range( anEdge, FirstPar, LastPar );
537 Standard_Integer firstind = 1;
538 par = ParsNonSeam(i)(1);
539 TopoDS_Edge SeamEdge = TopoDS::Edge( Seam(i)(1) );
540 //Find the face
541 for (j = 1; j <= Eseq.Length(); j++)
542 if (SeamEdge.IsSame( Eseq(j) ))
543 break;
544 TopoDS_Face theFace = TopoDS::Face( Fseq(j) );
545 TopLoc_Location L;
546 Handle( Geom_Surface ) theSurf = BRep_Tool::Surface( theFace, L );
547 if (Abs(par-FirstPar) <= Precision::Confusion())
548 {
549 BB.UpdateVertex( Vfirst, ParsSeam(i)(1), SeamEdge, BRep_Tool::Tolerance(Vfirst) );
550 EPmap( SeamEdge ).Append( ParsSeam(i)(1) );
551 EVmap( SeamEdge ).Append( Vfirst );
552 EWmap( SeamEdge ).Append( NonSeamWires(i) );
553 firstind = 2;
554 }
555 Standard_Real prevpar = FirstPar;
556 TopoDS_Vertex PrevV = Vfirst;
557 for (j = firstind; j <= ParsNonSeam(i).Length(); j++)
558 {
559 TopoDS_Shape aLocalShape = anEdge.EmptyCopied();
560 NewE = TopoDS::Edge( aLocalShape );
561 //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
562 TopoDS_Vertex NewV;
563 par = ParsNonSeam(i)(j);
564 BB.Range( NewE, prevpar, par );
565 SeamEdge = TopoDS::Edge( Seam(i)(j) );
566 if (j == ParsNonSeam(i).Length() && Abs(par-LastPar) <= Precision::Confusion())
567 {
568 NewV = Vlast;
569 if (firstind == 2 && j == 2)
570 {
571 BB.UpdateVertex( Vlast, ParsSeam(i)(j), SeamEdge, BRep_Tool::Tolerance(Vlast) );
572 EPmap( SeamEdge ).Append( ParsSeam(i)(j) );
573 EVmap( SeamEdge ).Append( Vlast );
574 EWmap( SeamEdge ).Append( NonSeamWires(i) );
575 break;
576 }
577 }
578 else
579 {
580 BRepAdaptor_Curve bcur( NewE );
581 gp_Pnt Point = bcur.Value( par );
582 NewV = BRepLib_MakeVertex( Point );
583 BB.UpdateVertex( NewV, par, NewE, 10.*Precision::Confusion() );
584 }
585 BB.UpdateVertex( NewV, ParsSeam(i)(j), SeamEdge, 10.*Precision::Confusion() );
586 NewE.Orientation( TopAbs_FORWARD );
587 BB.Add( NewE, PrevV.Oriented(TopAbs_FORWARD) );
588 BB.Add( NewE, NewV.Oriented(TopAbs_REVERSED) );
589
590 NewEdges.Append( NewE );
591 EPmap( SeamEdge ).Append( ParsSeam(i)(j) );
592 EVmap( SeamEdge ).Append( NewV );
593 EWmap( SeamEdge ).Append( NonSeamWires(i) );
594
595 prevpar = par;
596 PrevV = NewV;
597 }
598 //The last edge
599 TopoDS_Shape aLocalShape = anEdge.EmptyCopied();
600 NewE = TopoDS::Edge( aLocalShape );
601 //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
602 par = LastPar;
603 if (Abs(prevpar-par) > Precision::Confusion())
604 {
605 BB.Range( NewE, prevpar, par );
606 NewE.Orientation( TopAbs_FORWARD );
607 BB.Add( NewE, PrevV.Oriented(TopAbs_FORWARD) );
608 BB.Add( NewE, Vlast.Oriented(TopAbs_REVERSED) );
609 NewEdges.Append( NewE );
610 }
611
612 //Substitute anEdge by NewEdges
613 aSub.Substitute( anEdge, NewEdges );
614 }
615
616 //Sorting of EPmap and EVmap and removing repeating points from them
617 iter.Initialize( EPmap );
618 for (; iter.More(); iter.Next())
619 {
620 TColStd_SequenceOfReal Seq;
621 Seq = iter.Value();
622 TopTools_SequenceOfShape SeqShape;
623 SeqShape = EVmap( iter.Key() );
624 TopTools_SequenceOfShape SeqShape2;
625 SeqShape2 = EWmap( iter.Key() );
626 for (i = 1; i < Seq.Length(); i++)
627 for (j = i+1; j <= Seq.Length(); j++)
628 if (Seq(j) < Seq(i))
629 {
630 Standard_Real temp = Seq(i);
631 Seq(i) = Seq(j);
632 Seq(j) = temp;
633 TopoDS_Shape tmp = SeqShape(i);
634 SeqShape(i) = SeqShape(j);
635 SeqShape(j) = tmp;
636 tmp = SeqShape2(i);
637 SeqShape2(i) = SeqShape2(j);
638 SeqShape2(j) = tmp;
639 }
640 EPmap( iter.Key() ) = Seq;
641 EVmap( iter.Key() ) = SeqShape;
642 EWmap( iter.Key() ) = SeqShape2;
643 }
644 iter.Initialize( EPmap );
645 for (; iter.More(); iter.Next())
646 {
647 TColStd_SequenceOfReal Seq;
648 Seq = iter.Value();
649 TopTools_SequenceOfShape SeqShape;
650 SeqShape = EVmap( iter.Key() );
651 TopTools_SequenceOfShape SeqShape2;
652 SeqShape2 = EWmap( iter.Key() );
653 Standard_Boolean remove = Standard_True;
654 while (remove)
655 {
656 remove = Standard_False;
657 for (i = 1; i < Seq.Length(); i++)
658 if (Abs(Seq(i)-Seq(i+1)) <= Precision::Confusion())
659 {
660 Seq.Remove(i+1);
661 SeqShape.Remove(i+1);
662 SeqShape2.Remove(i+1);
663 remove = Standard_True;
664 }
665 }
666 EPmap( iter.Key() ) = Seq;
667 EVmap( iter.Key() ) = SeqShape;
668 EWmap( iter.Key() ) = SeqShape2;
669 }
670
671 //Reconstruction of seam edges
672 TopTools_DataMapOfShapeShape VEmap;
673 iter.Initialize( Emap );
674 for (; iter.More(); iter.Next())
675 {
676 TopoDS_Edge anEdge = TopoDS::Edge( iter.Key() );
677 Standard_Boolean onepoint = Standard_False;
678 TopTools_ListOfShape NewEdges;
679 TColStd_SequenceOfReal Seq;
680 Seq = iter.Value();
681 TColStd_SequenceOfReal Seq2;
682 Seq2 = EPmap( anEdge );
683 TopTools_SequenceOfShape SeqVer;
684 SeqVer = EVmap( anEdge );
685 TopTools_SequenceOfShape SeqWire;
686 SeqWire = EWmap( anEdge );
687 TopoDS_Vertex Vfirst, Vlast;
688 TopExp::Vertices( anEdge, Vfirst, Vlast );
689 Standard_Real fpar, lpar, FirstPar, LastPar;
690 BRep_Tool::Range( anEdge, FirstPar, LastPar );
691 fpar = FirstPar;
692 lpar = Seq(1);
693 TopoDS_Edge NewE;
694 Standard_Integer firstind = 1;
695 if (Abs(fpar-lpar) <= Precision::Confusion())
696 {
697 firstind = 2;
698 fpar = Seq(1);
699 lpar = Seq(2);
700 }
701 else
702 {
703 if (Seq.Length()%2 != 0)
704 {
705 VEmap.Bind( Vfirst, anEdge );
706 firstind = 2;
707 fpar = Seq(1);
708 if (Seq.Length() > 2)
709 lpar = Seq(2);
710 else
711 onepoint = Standard_True;
712 }
713 }
714 if (!onepoint)
715 {
716 TopoDS_Shape aLocalShape = anEdge.EmptyCopied();
717 NewE = TopoDS::Edge( aLocalShape );
718 //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
719 BB.Range( NewE, fpar, lpar );
720 NewE.Orientation( TopAbs_FORWARD );
721 if (firstind == 1)
722 {
723 BB.Add( NewE, Vfirst.Oriented(TopAbs_FORWARD) );
724 aLocalShape = SeqVer(1).Oriented(TopAbs_REVERSED);
725 BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
726 //BB.Add( NewE, TopoDS::Vertex( SeqVer(1).Oriented(TopAbs_REVERSED) ) );
727 }
728 else
729 {
730 aLocalShape = SeqVer(1).Oriented(TopAbs_FORWARD);
731 BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
732 aLocalShape = SeqVer(2).Oriented(TopAbs_REVERSED);
733 BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
734 //BB.Add( NewE, TopoDS::Vertex( SeqVer(1).Oriented(TopAbs_FORWARD) ) );
735 //BB.Add( NewE, TopoDS::Vertex( SeqVer(2).Oriented(TopAbs_REVERSED) ) );
736 }
737 NewEdges.Append( NewE );
738
739 firstind++;
740 for (i = firstind; i < Seq.Length(); i += 2)
741 {
742 aLocalShape = anEdge.EmptyCopied();
743 NewE = TopoDS::Edge( aLocalShape );
744 //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
745 fpar = Seq(i);
746 lpar = Seq(i+1);
747 BB.Range( NewE, fpar, lpar );
748 //Find vertices
749 for (j = 1; j <= Seq2.Length(); j++)
750 if (Abs(fpar-Seq2(j)) <= Precision::Confusion())
751 break;
752 NewE.Orientation( TopAbs_FORWARD );
753 TopoDS_Shape aLocalShapeCur = SeqVer(j).Oriented(TopAbs_FORWARD);
754 BB.Add( NewE, TopoDS::Vertex( aLocalShapeCur) );
755 aLocalShapeCur = SeqVer(j+1).Oriented(TopAbs_REVERSED);
756 BB.Add( NewE, TopoDS::Vertex( aLocalShapeCur ) );
757 //BB.Add( NewE, TopoDS::Vertex( SeqVer(j).Oriented(TopAbs_FORWARD) ) );
758 //BB.Add( NewE, TopoDS::Vertex( SeqVer(j+1).Oriented(TopAbs_REVERSED) ) );
759 NewEdges.Append( NewE );
760 }
761 }
762
763 i = Seq.Length();
764 fpar = Seq(i);
765 lpar = LastPar;
766 if (Abs(fpar-lpar) <= Precision::Confusion())
767 continue;
768 TopoDS_Shape aLocalShape = anEdge.EmptyCopied();
769 NewE = TopoDS::Edge( aLocalShape );
770 //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
771 BB.Range( NewE, fpar, lpar );
772 NewE.Orientation( TopAbs_FORWARD );
773 aLocalShape = SeqVer(SeqVer.Length()).Oriented(TopAbs_FORWARD);
774 BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
775 //BB.Add( NewE, TopoDS::Vertex( SeqVer(SeqVer.Length()).Oriented(TopAbs_FORWARD) ) );
776 BB.Add( NewE, Vlast.Oriented(TopAbs_REVERSED) );
777 NewEdges.Append( NewE );
778
779 //Substitute anEdge by NewEdges
780 aSub.Substitute( anEdge, NewEdges );
781 }
782
783 //Removing edges connected with missing extremities of seam edges
784 TopTools_DataMapIteratorOfDataMapOfShapeShape itve( VEmap );
785 for (; itve.More(); itve.Next())
786 {
787 TopoDS_Shape V = itve.Key();
788 TopoDS_Shape E = itve.Value();
789 TopoDS_Shape W;
790 for (i = 1; i <= Eseq.Length(); i++)
791 if (E.IsSame( Eseq(i) ))
792 {
793 W = Wseq(i);
794 break;
795 }
796 TopoDS_Shape Etoremove;
797 eit.Initialize( W );
798 for (; eit.More(); eit.Next())
799 {
800 TopoDS_Edge CurE = TopoDS::Edge( eit.Value() );
801 if (CurE.IsSame( E ))
802 continue;
803 TopoDS_Vertex Vfirst, Vlast;
804 TopExp::Vertices( CurE, Vfirst, Vlast );
805 if (Vfirst.IsSame( V ) || Vlast.IsSame( V ))
806 {
807 Etoremove = CurE;
808 break;
809 }
810 }
811 if (! Etoremove.IsNull())
812 {
813 W.Free( Standard_True );
814 BB.Remove( W, Etoremove );
815 }
816 }
817
818 aSub.Build( myShape );
819 if (aSub.IsCopied( myShape ))
820 {
821 const TopTools_ListOfShape& listSh = aSub.Copy( myShape );
822 if (! listSh.IsEmpty())
823 myShape = listSh.First();
824 }
825
826 //Reconstruction of wires
827 TopTools_ListOfShape theCopy;
828 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itww( WWmap );
829 for (; itww.More(); itww.Next())
830 {
831 CurWire = itww.Key();
832 theCopy = aSub.Copy( CurWire );
833 CurWire = theCopy.First();
834 CurWire.Free( Standard_True );
835 TopTools_ListIteratorOfListOfShape itl( itww.Value() );
836 for (; itl.More(); itl.Next())
837 {
838 TopoDS_Shape aWire = itl.Value();
839 CurFace = WFmap( aWire );
840 theCopy = aSub.Copy( aWire );
841 aWire = theCopy.First();
842 //Adjusting period
843 TopLoc_Location L;
844 Handle( Geom_Surface ) theSurf = BRep_Tool::Surface( TopoDS::Face(CurFace), L );
845 eit.Initialize( aWire );
846 for (; eit.More(); eit.Next())
847 {
848 TopoDS_Edge anEdge = TopoDS::Edge( eit.Value() );
849 gp_Pnt2d Pfirst, Plast, Pmid;
850 BRep_Tool::UVPoints( anEdge, TopoDS::Face(CurFace), Pfirst, Plast );
851 BRepAdaptor_Curve2d bc2d( anEdge, TopoDS::Face(CurFace) );
852 Pmid = bc2d.Value( (bc2d.FirstParameter()+bc2d.LastParameter())/2. );
853 gp_Vec2d offset;
854 Standard_Boolean translate = Standard_False;
855 if (Pfirst.X()-2.*M_PI > Precision::Confusion() ||
856 Plast.X()-2.*M_PI > Precision::Confusion() ||
857 Pmid.X()-2.*M_PI > Precision::Confusion())
858 {
859 offset.SetCoord( -2.*M_PI, 0 );
860 translate = Standard_True;
861 }
862 if (Pfirst.X() < -Precision::Confusion() ||
863 Plast.X() < -Precision::Confusion() ||
864 Pmid.X() < -Precision::Confusion())
865 {
866 offset.SetCoord( 2.*M_PI, 0 );
867 translate = Standard_True;
868 }
869 if (translate)
870 {
871 const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &anEdge.TShape());
872 BRep_ListIteratorOfListOfCurveRepresentation itcr( TE->ChangeCurves() );
873 Handle(BRep_GCurve) GC;
874
875 for (; itcr.More(); itcr.Next())
876 {
877 GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
878 if (!GC.IsNull() && GC->IsCurveOnSurface( theSurf, L ))
879 {
880 Handle(Geom2d_Curve) PC = GC->PCurve();
881 PC = Handle(Geom2d_Curve)::DownCast( PC->Translated( offset ) );
882 GC->PCurve( PC );
883 TE->ChangeCurves().Remove( itcr );
884 TE->ChangeCurves().Append( GC );
885 break;
886 }
887 }
888 }
889 }
890 ///////////////////
891 eit.Initialize( aWire, Standard_False );
892 for (; eit.More(); eit.Next())
893 {
894 TopoDS_Shape anEdge = eit.Value();
895 BB.Add( CurWire, anEdge );
896 }
897 if (aSub.IsCopied( CurFace ))
898 {
899 theCopy = aSub.Copy( CurFace );
900 CurFace = theCopy.First();
901 }
902 CurFace.Free( Standard_True );
903 BB.Remove( CurFace, aWire );
904 }
905 }
906}
907//=======================================================================
908//function : CorrectVertexTol
909//purpose :
910//=======================================================================
7fd59977 911
345d3056 912void BRepOffsetAPI_DraftAngle::CorrectVertexTol()
913{
914 TopTools_MapOfShape anInitVertices, anInitEdges, aNewEdges;
915 TopExp_Explorer anExp(myInitialShape, TopAbs_EDGE);
916 for(; anExp.More(); anExp.Next())
917 {
918 anInitEdges.Add(anExp.Current());
919 TopoDS_Iterator anIter(anExp.Current());
920 for(; anIter.More(); anIter.Next())
7fd59977 921 {
345d3056 922 anInitVertices.Add(anIter.Value());
7fd59977 923 }
345d3056 924 }
925 //
926
927 BRep_Builder aBB;
928 myVtxToReplace.Clear();
929 anExp.Init(myShape, TopAbs_EDGE);
930 for(; anExp.More(); anExp.Next())
931 {
932 const TopoDS_Shape& anE = anExp.Current();
933 //Skip old (not modified) edges
934 if(anInitEdges.Contains(anE))
935 continue;
936 //
937 //Skip processed edges
938 if(aNewEdges.Contains(anE))
939 continue;
940 //
941 aNewEdges.Add(anE);
942 //
943 Standard_Real anETol = BRep_Tool::Tolerance(TopoDS::Edge(anE));
944 TopoDS_Iterator anIter(anE);
945 for(; anIter.More(); anIter.Next())
7fd59977 946 {
345d3056 947 const TopoDS_Vertex& aVtx = TopoDS::Vertex(anIter.Value());
948 if(anInitVertices.Contains(aVtx))
949 {
950 if(myVtxToReplace.IsBound(aVtx))
951 {
952 aBB.UpdateVertex(TopoDS::Vertex(myVtxToReplace(aVtx)), anETol + Epsilon(anETol));
953 }
954 else
955 {
956 Standard_Real aVTol = BRep_Tool::Tolerance(aVtx);
957 if(aVTol < anETol)
958 {
959 TopoDS_Vertex aNewVtx;
960 gp_Pnt aVPnt = BRep_Tool::Pnt(aVtx);
961 aBB.MakeVertex(aNewVtx, aVPnt,anETol + Epsilon(anETol));
2651bfde 962 aNewVtx.Orientation(aVtx.Orientation());
345d3056 963 myVtxToReplace.Bind(aVtx, aNewVtx);
964 }
965 }
966 }
7fd59977 967 else
345d3056 968 {
969 aBB.UpdateVertex(aVtx, anETol + Epsilon(anETol));
970 }
7fd59977 971 }
345d3056 972 }
973 //
974 if(myVtxToReplace.IsEmpty())
975 {
976 return;
977 }
978 //
2651bfde 979 mySubs.Clear();
345d3056 980 TopTools_DataMapIteratorOfDataMapOfShapeShape anIter(myVtxToReplace);
981 for(; anIter.More(); anIter.Next())
982 {
2651bfde 983 mySubs.Replace(anIter.Key(), anIter.Value());
345d3056 984 }
2651bfde 985 mySubs.Apply( myShape );
986 myShape = mySubs.Value(myShape);
345d3056 987 //
7fd59977 988}