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