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