0024166: Unable to create file with "Save" menu of voxeldemo Qt sample
[occt.git] / src / TopOpeBRepBuild / TopOpeBRepBuild_CorrectFace2d.cxx
CommitLineData
b311480e 1// Created on: 2000-01-26
2// Created by: Peter KURNEV
3// Copyright (c) 2000-2012 OPEN CASCADE SAS
4//
5// The content of this file is subject to the Open CASCADE Technology Public
6// License Version 6.5 (the "License"). You may not use the content of this file
7// except in compliance with the License. Please obtain a copy of the License
8// at http://www.opencascade.org and read it completely before using this file.
9//
10// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12//
13// The Original Code and all software distributed under the License is
14// distributed on an "AS IS" basis, without warranty of any kind, and the
15// Initial Developer hereby disclaims all such warranties, including without
16// limitation, any warranties of merchantability, fitness for a particular
17// purpose or non-infringement. Please see the License for the specific terms
18// and conditions governing the rights and limitations under the License.
19
7fd59977 20
21
22#include <TopOpeBRepBuild_CorrectFace2d.ixx>
23
24#include <TopoDS.hxx>
25#include <TopoDS_Shape.hxx>
26#include <TopoDS_Wire.hxx>
27#include <TopoDS_Vertex.hxx>
28#include <TopoDS_Wire.hxx>
29#include <TopoDS_Edge.hxx>
30
31#include <TopExp.hxx>
32
33#include <TopLoc_Location.hxx>
34#include <TopExp_Explorer.hxx>
35#include <TopOpeBRepBuild_Tools2d.hxx>
36
37#include <TopTools_ListOfShape.hxx>
38#include <TopTools_ListIteratorOfListOfShape.hxx>
39#include <TopTools_IndexedMapOfShape.hxx>
40#include <TopTools_SequenceOfShape.hxx>
41#include <TopTools_IndexedDataMapOfShapeShape.hxx>
42
43#include <Geom2d_TrimmedCurve.hxx>
44#include <Geom_Surface.hxx>
45#include <Geom2d_Curve.hxx>
46
47#include <BRepTopAdaptor_FClass2d.hxx>
48#include <BRepAdaptor_Curve2d.hxx>
49#include <BRep_Tool.hxx>
50#include <BRep_Builder.hxx>
51
52#include <Bnd_Box2d.hxx>
53#include <BndLib_Add2dCurve.hxx>
54
55#include <gp_Pnt.hxx>
56#include <Precision.hxx>
57#include <BRepAdaptor_Surface.hxx>
58
59
60//=======================================================================
61// function :TopOpeBRepBuild_CorrectFace2d::TopOpeBRepBuild_CorrectFace2d
62// purpose:
63//=======================================================================
b311480e 64TopOpeBRepBuild_CorrectFace2d::TopOpeBRepBuild_CorrectFace2d()
7fd59977 65{
66 myIsDone=Standard_False;
67 myErrorStatus=1;
68
69}
70//=======================================================================
71// function :TopOpeBRepBuild_CorrectFace2d::TopOpeBRepBuild_CorrectFace2d
72// purpose:
73//=======================================================================
74 TopOpeBRepBuild_CorrectFace2d::TopOpeBRepBuild_CorrectFace2d(const TopoDS_Face& aFace,
75 const TopTools_IndexedMapOfOrientedShape& anAvoidMap,
76 TopTools_IndexedDataMapOfShapeShape& aMap)
77{
78 myFace=aFace;
79 myAvoidMap=anAvoidMap;
80 myIsDone=Standard_False;
81 myErrorStatus=1;
82 myMap=(Standard_Address) &aMap;
83
84}
85//=======================================================================
86// function : TopOpeBRepBuild_CorrectFace2d::SetMapOfTrans2dInfo
87// purpose:
88//=======================================================================
89 void TopOpeBRepBuild_CorrectFace2d::SetMapOfTrans2dInfo (TopTools_IndexedDataMapOfShapeShape& aMap)
90{
91 myMap=(Standard_Address) &aMap;
92}
93
94//=======================================================================
95// function : TopOpeBRepBuild_CorrectFace2d::MapOfTrans2dInfo
96// purpose:
97//=======================================================================
98 TopTools_IndexedDataMapOfShapeShape& TopOpeBRepBuild_CorrectFace2d::MapOfTrans2dInfo ()
99{
100 return *(TopTools_IndexedDataMapOfShapeShape*) myMap;
101}
102//=======================================================================
103// function :TopOpeBRepBuild_CorrectFace2d::Face
104// purpose:
105//=======================================================================
106 const TopoDS_Face& TopOpeBRepBuild_CorrectFace2d::Face() const
107{
108 return myFace;
109}
110
111//=======================================================================
112// function :TopOpeBRepBuild_CorrectFace2d::IsDone
113// purpose:
114//=======================================================================
115 Standard_Boolean TopOpeBRepBuild_CorrectFace2d::IsDone() const
116{
117 return myIsDone;
118}
119//=======================================================================
120// function :TopOpeBRepBuild_CorrectFace2d::ErrorStatus
121// purpose:
122//=======================================================================
123 Standard_Integer TopOpeBRepBuild_CorrectFace2d::ErrorStatus() const
124{
125 return myErrorStatus;
126}
127//=======================================================================
128// function :TopOpeBRepBuild_CorrectFace2d::CorrectedFace
129// purpose:
130//=======================================================================
131 const TopoDS_Face& TopOpeBRepBuild_CorrectFace2d::CorrectedFace() const
132{
133 return myCorrectedFace;
134}
135//=======================================================================
136// function :TopOpeBRepBuild_CorrectFace2d::BuildCopyData
137// purpose:
138//=======================================================================
139 void TopOpeBRepBuild_CorrectFace2d::BuildCopyData(const TopoDS_Face& aFace,
140 const TopTools_IndexedMapOfOrientedShape& anAvoidMap,
141 TopoDS_Face& aCopyFace,
142 TopTools_IndexedMapOfOrientedShape& aCopyAvoidMap,
143 const Standard_Boolean aNeedToUsePMap)
144{
145 TopTools_IndexedDataMapOfShapeShape EdMap;
146
147 BRep_Builder BB;
148
149 TopTools_IndexedDataMapOfShapeShape* pMap=
150 (TopTools_IndexedDataMapOfShapeShape*) myMap;
151 //
152 // 1. Copy myFace =>> myCopyFace
153 TopoDS_Shape aLocalShape = aFace.EmptyCopied();
154 aCopyFace=TopoDS::Face(aLocalShape);
155 // aCopyFace=TopoDS::Face(aFace.EmptyCopied());
156
157 TopExp_Explorer anExpWires(aFace, TopAbs_WIRE);
158 for (; anExpWires.More(); anExpWires.Next()) {
159 const TopoDS_Wire& W=TopoDS::Wire(anExpWires.Current());
160
161 aLocalShape = W.EmptyCopied();
162 TopoDS_Wire aWire = TopoDS::Wire(aLocalShape);
163 // TopoDS_Wire aWire = TopoDS::Wire(W.EmptyCopied());
164
165 TopExp_Explorer anExpEdges(W, TopAbs_EDGE);
166 for (; anExpEdges.More(); anExpEdges.Next()) {
167 const TopoDS_Edge& E = TopoDS::Edge(anExpEdges.Current());
168
169 if (EdMap.Contains(E)) {
170 TopoDS_Shape anEdge = EdMap.ChangeFromKey(E);
171 anEdge.Orientation(E.Orientation());
172 BB.Add (aWire, anEdge);
173 continue;
174 }
175
176 if (aNeedToUsePMap) {
177 if (pMap->Contains(E)) {
178 TopoDS_Shape& anEdge=pMap->ChangeFromKey(E);
179 anEdge.Orientation(E.Orientation());
180 EdMap.Add(E, anEdge);
181 BB.Add (aWire, anEdge);
182 continue;
183 }
184 }
185
186 // add edges
187 aLocalShape = E.EmptyCopied();
188 TopoDS_Shape anEdge = TopoDS::Edge(aLocalShape);
189 // TopoDS_Shape anEdge = TopoDS::Edge(E.EmptyCopied());
190
191 EdMap.Add(E, anEdge);
192
193 TopExp_Explorer anExpVertices(E, TopAbs_VERTEX);
194 for (; anExpVertices.More(); anExpVertices.Next()) {
195 const TopoDS_Shape& aV=anExpVertices.Current();
196 BB.Add(anEdge, aV);
197 }
198
199 anEdge.Orientation(E.Orientation());
200 BB.Add (aWire, anEdge);
201 }
202 // Add wires
203 aWire.Orientation(W.Orientation());
204 EdMap.Add(W, aWire);
205
206 BB.Add (aCopyFace, aWire);
207 }
208
209 //
210 // 2. Copy myAvoidMap =>> myCopyAvoidMap
211 Standard_Integer i, aNb;
212 aNb=anAvoidMap.Extent();
213
214 for (i=1; i<=aNb; i++) {
215 const TopoDS_Shape& aSh=anAvoidMap(i);
216
217 if (EdMap.Contains (aSh)) {
218 TopoDS_Shape& aCopyShape=EdMap.ChangeFromKey(aSh);
219 aCopyShape.Orientation(aSh.Orientation());
220 aCopyAvoidMap.Add(aCopyShape);
221 }
222 }
223
224 //
225 // 3. Inversed EdMap
226 if (aNeedToUsePMap) {
227 aNb=EdMap.Extent();
228 myEdMapInversed.Clear();
229 for (i=1; i<=aNb; i++) {
230 const TopoDS_Shape& aSh =EdMap.FindKey(i);
231 const TopoDS_Shape& aShCopy=EdMap.FindFromIndex(i);
232 myEdMapInversed.Add (aShCopy, aSh);
233 }
234 }
235}
236//=======================================================================
237// function :TopOpeBRepBuild_CorrectFace2d::CheckFace
238// purpose:
239//=======================================================================
240 void TopOpeBRepBuild_CorrectFace2d::CheckFace()
241{
242 //
243 // I. Is the surface periodic
244 TopLoc_Location aLocF;
245 Handle(Geom_Surface) Surf = BRep_Tool::Surface(myCopyFace, aLocF);
246 if (!(Surf->IsUPeriodic() || Surf->IsVPeriodic())) {
247 myIsDone=Standard_True;
248 myErrorStatus=4;
249 return;
250 }
251
252 //modified by NIZHNY-MZV Mon Apr 24 11:29:56 2000
253 //don't treat torus surfaces
254 if(Surf->IsUPeriodic() && Surf->IsVPeriodic()) {
255 myIsDone=Standard_True;
256 myErrorStatus=4;
257 return;
258 }
259
260 //
261 // II. Has each wire at least one "licit" edge
262 TopTools_IndexedMapOfOrientedShape aVoidWires;
263 Standard_Integer i, aNbVoidWires, anEdgeExists=0, priz;
264 TopExp_Explorer aFExp,aWExp;
265 aFExp.Init (myCopyFace, TopAbs_WIRE);
266 for (; aFExp.More(); aFExp.Next()) {
267 const TopoDS_Shape& aWire=aFExp.Current();
268 if (myCopyAvoidMap.Contains(aWire)) {
269 anEdgeExists=1;
270 continue;
271 }
272
273 anEdgeExists=0;
274 aWExp.Init(aWire, TopAbs_EDGE);
275 for (; aWExp.More(); aWExp.Next()) {
276 TopoDS_Shape anEdge=aWExp.Current();
277 if (myCopyAvoidMap.Contains(anEdge)) {
278 anEdgeExists=1;
279 break;
280 }
281 }
282
283 if (!anEdgeExists) {
284 // This is the wire without any "Right" information
285 aVoidWires.Add(aWire);
286 }
287 }
288
289 // For Void Wires .
290 // We assume the first edge from the wire is non-movable edge
291 // PKV 24-Feb-2000
292 aNbVoidWires=aVoidWires.Extent();
293 for (i=1; i<=aNbVoidWires; i++) {
294 TopTools_IndexedMapOfShape aEM;
295 TopExp::MapShapes(aVoidWires(i), TopAbs_EDGE, aEM);
296 if (aEM.Extent())
297 myCopyAvoidMap.Add (aEM(1));
298 }
299
300 // III. Check all wires to know whether they are closed or not
301 aFExp.Init (myCopyFace, TopAbs_WIRE);
302 for (; aFExp.More(); aFExp.Next()) {
303 myCurrentWire = TopoDS::Wire(aFExp.Current());
304 priz=MakeRightWire ();
305 if (priz) {
306 // This myFace contais a wire (myCurrentWire) that is not closed.
307 myIsDone=Standard_True;
308 myErrorStatus=3;
309 return;
310 }
311 }
312
313 //
314 // VI. Check connectability wires in 2d
315 TopoDS_Face aCopyFace;
316 TopTools_IndexedMapOfOrientedShape aCopyAvoidMap;
317
318 // Coping data
319 BuildCopyData(myCopyFace, myCopyAvoidMap, aCopyFace, aCopyAvoidMap, Standard_False);
320
321 aFExp.Init (aCopyFace, TopAbs_WIRE);
322 for (; aFExp.More(); aFExp.Next()) {
323 myCurrentWire = TopoDS::Wire(aFExp.Current());
324 if (!aCopyAvoidMap.Contains(myCurrentWire)) {
325 priz=ConnectWire (aCopyFace, aCopyAvoidMap, Standard_True);
326 if (priz) {
327 myIsDone=Standard_True;
328 myErrorStatus=6;
329 return;
330 }
331 }
332 }
333
334 // Face seems to be OK
335}
336//=======================================================================
337// function : TopOpeBRepBuild_CorrectFace2d::ConnectWire
338// purpose:
339//=======================================================================
340 Standard_Integer TopOpeBRepBuild_CorrectFace2d::ConnectWire (TopoDS_Face& aCopyFace,
341 const TopTools_IndexedMapOfOrientedShape& aCopyAvoidMap,
342 const Standard_Boolean aTryFlag)
343{
344 BRep_Builder BB;
345 //
346 // 1.Make right order
347 Standard_Integer priz;
348 priz=MakeRightWire ();
349 if (priz) return priz;
350 //
351 // 2. Define the First Edge on the Wire from aCopyAvoidMap
352 Standard_Integer i, aNbEdges=0, aNbAvoidEdgesOnWire;
353 Standard_Boolean IsAllAvoidEdgesDegenerated=Standard_False;
354 Standard_Real aDMax=0, aR;
355
356 TopExp_Explorer aWExp;
357 TopoDS_Edge aFEdge;
358 TopoDS_Shape aFirstEdge;
359 TopTools_IndexedMapOfOrientedShape anAvoidMap;
360
361 aWExp.Init(myCurrentWire, TopAbs_EDGE);
362 for (; aWExp.More(); aWExp.Next(), aNbEdges++) {
363 TopoDS_Shape anEdge=aWExp.Current();
364 if (aCopyAvoidMap.Contains(anEdge))
365 anAvoidMap.Add(anEdge);
366 }
367
368 if (aNbEdges==1) // nothing to do with this wire.
369 return 0;
370
371 aNbAvoidEdgesOnWire=anAvoidMap.Extent();
372 if (aNbAvoidEdgesOnWire==aNbEdges) // nothing to do. all edges on wire are good.
373 return 0;
374
375 // if at least one non-degenerated edge exists
376 // among anAvoidMap set it as aFirstEdge
377 priz=0;
378 for (i=1; i<=aNbAvoidEdgesOnWire; i++) {
379 const TopoDS_Edge& anEdge=TopoDS::Edge(anAvoidMap(i));
380 if (!BRep_Tool::Degenerated(anEdge)) {
381 aFirstEdge=anEdge;
382 priz=1;
383 break;
384 }
385 }
386
387
388 if (!priz) {
389 // All of anAvoidMap edges are degenerated
390 // So take the edge with max dist. between
391 //First and Last 2d points as the First edge
392 IsAllAvoidEdgesDegenerated=Standard_True;
393 //if(aNbAvoidEdgesOnWire != 1)
394 // return 1; //in case of several degenerated edges we cannot connect wire by right way
395 for (i=1; i<=aNbAvoidEdgesOnWire; i++) {
396 gp_Pnt2d PF, PL;
397 const TopoDS_Edge& aDegenEdge=TopoDS::Edge(anAvoidMap(i));
398 GetP2dFL(aCopyFace, aDegenEdge, PF, PL);
399 aR=PF.Distance(PL);
400 if ((aR - aDMax) > 1e-7) {
401 aDMax=aR;
402 aFirstEdge=anAvoidMap(i);
403 }
404 }
405 }
406
407
408
409 //
410 // 3. Build HeadList (from myOrderedWireList), where aFirstEdge will be the first
411 TopTools_ListOfShape HeadList;
412 MakeHeadList(aFirstEdge, HeadList);
413 //
414 // 4. Check HeadList to provide toward point-arrow direction
415//modified by NIZNHY-PKV Mon Apr 24 14:43:20 2000 f
416 //CheckList (HeadList);
417 //modified by NIZNHY-PKV Tue Apr 25 12:08:29 2000CheckList (aCopyFace, HeadList);
418//modified by NIZNHY-PKV Mon Apr 24 14:43:24 2000t
419 //
420 // 5. Connect Edges
421 TopTools_IndexedMapOfShape anEdMap;
422 gp_Pnt2d PF, PL, PA, PB, PA1, PB1;
423 Handle(Geom2d_Curve) aTrCF, aTrCR, aTrC;
424 Standard_Real aD, aDTolerance=Precision::Confusion();
425
426 TopTools_SequenceOfShape aSeqEdges;
427
428 TopTools_ListIteratorOfListOfShape anIt;
429 anIt.Initialize(HeadList);
430 for (; anIt.More(); anIt.Next())
431 aSeqEdges.Append(anIt.Value());
432 aNbEdges=aSeqEdges.Length();
433
434 //
435 // First Edge
436 TopoDS_Edge aFstEdge=TopoDS::Edge(aSeqEdges(1));
437 GetP2dFL(aCopyFace, aFstEdge, PA, PB);
438 PA1=PA;
439 PB1=PB;
440
441 for (i=2; i<=aNbEdges; i++) {
442 TopoDS_Edge anEdge= TopoDS::Edge(aSeqEdges(i));
443 GetP2dFL(aCopyFace, anEdge, PF, PL);
444
445 aD=PF.Distance(PB);
446 if (aD<aDTolerance) {
447 PA=PF; PB=PL;
448 continue; // nothing to do with the edge cose it already connected
449 }
450
451 // tralslation's vector
452 gp_Vec2d aTrV(PF, PB);
453
454 //Begin modified by NIZHNY-MZV Mon Mar 27 16:04:04 2000
455 //translation vector must be equal to 2PI*n or it is wrong wire
456 Standard_Real U = aTrV.X();
457 Standard_Real V = aTrV.Y();
458
459 BRepAdaptor_Surface BAS(aCopyFace);
460 Standard_Boolean UP = BAS.IsUPeriodic();
461 Standard_Boolean VP = BAS.IsVPeriodic();
462
463 Standard_Boolean nonPU = (fabs(U) < 1e-7) ? Standard_True : Standard_False;
464 Standard_Boolean nonPV = (fabs(V) < 1e-7) ? Standard_True : Standard_False;
465
466 if(!nonPU && UP) {
c6541a0c
D
467 Standard_Real dU = fmod(fabs(U), 2*M_PI);
468 nonPU = (dU > 1e-7 && (2*M_PI - dU > 1e-7)) ? Standard_True : Standard_False;
7fd59977 469 }
470
471 if(!nonPV && VP) {
c6541a0c
D
472 Standard_Real dV = fmod(fabs(V), 2*M_PI);
473 nonPV = (dV > 1e-7 && (2*M_PI - dV > 1e-7)) ? Standard_True : Standard_False;
7fd59977 474 }
475
c6541a0c
D
476// printf("(fmod(fabs(U), 2*M_PI) =%lf\n", (fmod(fabs(U), 2*M_PI)));
477// printf(" (fmod(fabs(V), 2*M_PI) > 1e-7)=%lf\n", (fmod(fabs(V), 2*M_PI)));
7fd59977 478
479 if(nonPU && nonPV && !BRep_Tool::Degenerated(anEdge))
480 return 1;
481 //End modified by NIZHNY-MZV Mon Mar 27 16:04:11 2000
482
483 if (BRep_Tool::IsClosed(anEdge, aCopyFace)) {
484 // a. Closed edge <--->
485 if (anEdMap.Contains(anEdge)) continue;
486 anEdMap.Add(anEdge);
487
488 TopAbs_Orientation anOri = anEdge.Orientation();
489
490 TopoDS_Edge anEF, anER;
491 if (anOri==TopAbs_FORWARD) {
492 anEF=anEdge;
493 TopoDS_Shape aLocalShape = anEdge.Reversed();
494 anER=TopoDS::Edge(aLocalShape);
495 // anER=TopoDS::Edge(anEdge.Reversed());
496 }
497
498 else {
499 anER=anEdge;
500 TopoDS_Shape aLocalShape = anEdge.Reversed();
501 anEF=TopoDS::Edge(aLocalShape);
502 // anEF=TopoDS::Edge(anEdge.Reversed());
503 }
504
505 TranslateCurve2d (anEF, aCopyFace, aTrV, aTrCF);
506 TranslateCurve2d (anER, aCopyFace, aTrV, aTrCR);
507
508 if (aTryFlag) // Use Builder in a trying case
509 BB.UpdateEdge(anEdge, aTrCF, aTrCR, aCopyFace, myFaceTolerance);
510
511 else // Use "False-Builder" otherwise
512 UpdateEdge(anEdge, aTrCF, aTrCR, aCopyFace, myFaceTolerance);
513
514 }
515
516 else {
517 // b. Usual Edge
518 TranslateCurve2d (anEdge, aCopyFace, aTrV, aTrC);
519
520 if (aTryFlag)
521 BB.UpdateEdge(anEdge, aTrC, aCopyFace, myFaceTolerance);
522 else
523 UpdateEdge(anEdge, aTrC, aCopyFace, myFaceTolerance);
524 }
525
526 GetP2dFL(aCopyFace, anEdge, PF, PL);
527
528 PA=PF;
529 PB=PL;
530
531 ////////////////////////////////////////////
532 // In case of a trying we check the first
533 // and last 2d point of the contour
534 if (aTryFlag) {
535 if (i==aNbEdges) {
536 aD=PA1.Distance(PB);
537 if (aD>aDTolerance)
538 return 1;
539 }
540 }
541 ////////////////////////////////////////////
542
543 } //end of for (i=2; i<=aNbEdges; i++)
544
545 return 0;
546}
547
548
549//=======================================================================
550// function :TopOpeBRepBuild_CorrectFace2d::Perform
551// purpose:
552//=======================================================================
553 void TopOpeBRepBuild_CorrectFace2d::Perform()
554{
555 /////////////
556 // 0.
557 myCopyAvoidMap.Clear();
558 BuildCopyData(myFace, myAvoidMap, myCopyFace, myCopyAvoidMap, Standard_True);
559 /////////////
560
561 myCorrectedFace=myCopyFace;
562 myCorrectedFace.Orientation(myCopyFace.Orientation());
563 myFaceTolerance=BRep_Tool::Tolerance(myCopyFace);
564 //
565 // 1. Check the input face first
566 CheckFace ();
567 if (myIsDone)
568 return ;
569
570 //
571 // 2. Make all wires connected
572 Standard_Integer priz;
573 TopExp_Explorer aFExp;
574
575 aFExp.Init (myCopyFace, TopAbs_WIRE);
576 for (; aFExp.More(); aFExp.Next()) {
577 myCurrentWire = TopoDS::Wire(aFExp.Current());
578 if (!myCopyAvoidMap.Contains(myCurrentWire)) {
579 priz=ConnectWire (myCopyFace, myCopyAvoidMap, Standard_False);
580 if (priz) {
581 // This myFace contais a wire (myCurrentWire) that is not closed.
582 myIsDone=Standard_False;
583 myErrorStatus=3;
584 return;
585 }
586 }
587 }
588 //
589 // 3. Define Outer Wire
590 TopoDS_Wire anOuterWire;
591 priz=OuterWire (anOuterWire);
592 if (priz) {
593 myIsDone=Standard_False;
594 myErrorStatus=5; // can't find outer wire
595 return;
596 }
597 //
598 // 4. Moving the anOuterWire and other wires in 2d space
599 MoveWires2d(anOuterWire);
600
601 myIsDone=Standard_True;
602 myErrorStatus=0;
603}
604
605//=======================================================================
606// function : TopOpeBRepBuild_CorrectFace2d::MakeRightWire
607// purpose:
608//=======================================================================
609 Standard_Integer TopOpeBRepBuild_CorrectFace2d::MakeRightWire ()
610{
611 Standard_Integer aNbEdgesReally=0;
612 myOrderedWireList.Clear();
613
614 //1. Real amount of the edges on aWire
615 TopExp_Explorer aWExp;
616 aWExp.Init(myCurrentWire, TopAbs_EDGE);
617 for (; aWExp.More(); aWExp.Next()) aNbEdgesReally++;
618
619 //2. We'll use TopOpeBRepBuild_Tools::Path
620 TopTools_ListOfShape aL;
621 TopOpeBRepBuild_Tools2d::Path (myCurrentWire, aL);
622 if (aL.Extent()!=aNbEdgesReally) {
623 myErrorStatus=4;
624 return 1;
625 }
626
627 //Begin modified by NIZNHY-PKV Tue Apr 25 12:04:45 2000
628 //from path we obtained list in reverse order, so to have right wire
629 //we need to reverse it
630 TopTools_ListOfShape aFL;
631 TopTools_ListIteratorOfListOfShape lit(aL);
632 for(; lit.More(); lit.Next())
633 aFL.Prepend(lit.Value());
634
635 myOrderedWireList=aFL;
636 //End modified by NIZNHY-PKV Tue Apr 25 12:06:45 2000
637 return 0;
638}
639
640//=======================================================================
641// function : TopOpeBRepBuild_CorrectFace2d::GetP2dFL
642// purpose:
643//=======================================================================
644 void TopOpeBRepBuild_CorrectFace2d::GetP2dFL (const TopoDS_Face& aF, const TopoDS_Edge& anEdge,
645 gp_Pnt2d& P2dF, gp_Pnt2d& P2dL)
646{
647 Standard_Real aFirst, aLast;
648 const Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface (anEdge, aF, aFirst, aLast);
649 C2d->D0 (aFirst, P2dF);
650 C2d->D0 (aLast , P2dL);
651 if (anEdge.Orientation()==TopAbs_REVERSED) {
652 gp_Pnt2d P2dTmp;
653 P2dTmp=P2dF; P2dF=P2dL; P2dL=P2dTmp;
654 }
655}
656
657
658//=======================================================================
659// function :TopOpeBRepBuild_CorrectFace2d::MakeHeadList
660// purpose:
661//=======================================================================
662 void TopOpeBRepBuild_CorrectFace2d::MakeHeadList(const TopoDS_Shape& aFirstEdge,
663 TopTools_ListOfShape& HeadList) const
664{
665 TopoDS_Shape aFE = aFirstEdge;
666 TopTools_ListOfShape aTailList;
667 TopTools_ListIteratorOfListOfShape anIt;
668 Standard_Integer aFlag=0;
669
670 anIt.Initialize(myOrderedWireList);
671 for (; anIt.More(); anIt.Next()) {
672 const TopoDS_Shape& anEdge=anIt.Value();
673 //modified by NIZHNY-MZV Mon Mar 27 11:40:00 2000
674 if(aFE.IsNull() && !BRep_Tool::Degenerated(TopoDS::Edge(anEdge)))
675 aFE = anEdge;
676 if (anEdge==aFE) aFlag=1; //turn the switch ON
677 if (aFlag) HeadList.Append(anEdge);
678 }
679
680 anIt.Initialize(myOrderedWireList);
681 for (; anIt.More(); anIt.Next()) {
682 const TopoDS_Shape& anEdge=anIt.Value();
683 if (anEdge==aFE) break;
684 aTailList.Append(anEdge);
685 }
686 HeadList.Append(aTailList);
687}
688//=======================================================================
689// function :TopOpeBRepBuild_CorrectFace2d::CheckList
690// purpose:
691//=======================================================================
692 void TopOpeBRepBuild_CorrectFace2d::CheckList (const TopoDS_Face& aFace,
693 TopTools_ListOfShape& HeadList)
694{
695 TopAbs_Orientation r1, r2;
696 Standard_Real aDTolerance=Precision::Confusion();
697 TopTools_SequenceOfShape aSeq;
698 TopTools_ListIteratorOfListOfShape anIt(HeadList);
699 for (; anIt.More(); anIt.Next()) {
700 aSeq.Append(anIt.Value());
701 }
702
703 r1=aSeq(1).Orientation();
704 r2=aSeq(2).Orientation();
705 Standard_Integer i, aNb=aSeq.Length();
706//modified by NIZNHY-PKV Mon Apr 24 14:43:57 2000f
707 Standard_Boolean aFirstCheck=Standard_False;
708 if (r1==TopAbs_REVERSED ) {
709 // when the orientation of the first edge is Revesed,
710 // and when everything in 2d is Ok :
711 // if at least one Forward edge exists in the List
712 // we consider that no necessity to reverse
713 // the list (aFirstCheck=Standard_True) .
714
715 Standard_Real aD;
716 gp_Pnt2d PF, PL, PA, PB;
717
718
719 TopoDS_Edge aFstEdge=TopoDS::Edge(aSeq(1));
720 GetP2dFL(aFace, aFstEdge, PA, PB);
721 for (i=2; i<=aNb; i++) {
722 TopoDS_Edge anEdge= TopoDS::Edge(aSeq(i));
723 GetP2dFL(aFace, anEdge, PF, PL);
724
725 aD=PF.Distance(PB);
726 if (aD<aDTolerance) {
727 PA=PF; PB=PL;
728 if (anEdge.Orientation()==TopAbs_FORWARD) {
729 aFirstCheck=Standard_True;
730 break;
731 }
732 }
733 }
734 }
735//modified by NIZNHY-PKV Mon Apr 24 14:43:59 2000t
736
737 r1=aSeq(1).Orientation();
738 r2=aSeq(2).Orientation();
739
740 TopoDS_Vertex aV1R, aV2F;
741
742 TopoDS_Edge aFirstEdge=TopoDS::Edge(aSeq(1));
743 TopExp_Explorer anExp;
744 anExp.Init (aFirstEdge, TopAbs_VERTEX);
745 for (; anExp.More(); anExp.Next()) {
746 const TopoDS_Shape& aV1=anExp.Current();
747 if (aV1.Orientation()==TopAbs_REVERSED){
748 aV1R=TopoDS::Vertex(aV1);
749 break;
750 }
751 }
752
753 TopoDS_Edge aSecondEdge=TopoDS::Edge(aSeq(2));
754 anExp.Init (aSecondEdge, TopAbs_VERTEX);
755 for (; anExp.More(); anExp.Next()) {
756 const TopoDS_Shape& aV1=anExp.Current();
757 if (aV1.Orientation()==TopAbs_FORWARD){
758 aV2F=TopoDS::Vertex(aV1);
759 break;
760 }
761 }
762
763 gp_Pnt P1, P2;
764 P1=BRep_Tool::Pnt(aV1R);
765 P2=BRep_Tool::Pnt(aV2F);
766
767
768 //modified by NIZNHY-PKV Mon Apr 24 13:24:06 2000 f
769 Standard_Real dist=P1.Distance(P2);
770 if (
771 (!(dist < aDTolerance) && r1==TopAbs_FORWARD)||
772 //(r1==TopAbs_REVERSED)) {
773 (!aFirstCheck && r1==TopAbs_REVERSED)
774 ) {
775 //modified by NIZNHY-PKV Mon Apr 24 14:28:06 2000 t
776 // We have to reverse the order in list
777 aSeq.Append(aFirstEdge);
778 HeadList.Clear();
779 aNb=aSeq.Length();
780 for (i=aNb; i>1; i--) {
781 HeadList.Append(aSeq(i));
782 }
783 }
784}
785
786//=======================================================================
787// function :TopOpeBRepBuild_CorrectFace2d::TranslateCurve2d
788// purpose:
789//=======================================================================
790 void TopOpeBRepBuild_CorrectFace2d::TranslateCurve2d(const TopoDS_Edge& anE,
791 const TopoDS_Face& aFace,
792 const gp_Vec2d& aTrV,
793 Handle(Geom2d_Curve)& aC2DOut)
794{
795 Standard_Real aFirst, aLast;
796 Handle(Geom2d_Curve) C2d=BRep_Tool::CurveOnSurface (anE, aFace, aFirst, aLast);
797 Handle(Geom2d_Curve) aTrC;
798 aTrC = Handle(Geom2d_Curve)::DownCast(C2d->Copy());
799 Handle(Geom2d_TrimmedCurve) newC2D = new Geom2d_TrimmedCurve(aTrC, aFirst, aLast);
800 newC2D -> Translate(aTrV);
801 aC2DOut=newC2D;
802}
803//=======================================================================
804// function :TopOpeBRepBuild_CorrectFace2d::OuterWire
805// purpose:
806//=======================================================================
807 Standard_Integer TopOpeBRepBuild_CorrectFace2d::OuterWire(TopoDS_Wire& anOuterWire) const
808{
809 TopLoc_Location Loc;
810 Handle(Geom_Surface) Surf = BRep_Tool::Surface(TopoDS::Face(myCorrectedFace), Loc);
811
812 TopExp_Explorer ex(myCorrectedFace, TopAbs_WIRE);
813 for (; ex.More(); ex.Next()) {
814 const TopoDS_Wire& aWire=TopoDS::Wire(ex.Current());
815
816 TopoDS_Face newFace;
817 BRep_Builder BB;
818 BB.MakeFace(newFace, Surf, Loc, myFaceTolerance);
819 BB.Add(newFace, aWire);
820
821 BRepTopAdaptor_FClass2d aClass2d(newFace, myFaceTolerance);
822 TopAbs_State aState=aClass2d.PerformInfinitePoint();
823 if (aState==TopAbs_OUT) {
824 anOuterWire=aWire;
825 return 0;
826 }
827 }
828 return 1; // such wire is not found
829}
830
831//=======================================================================
832// function :TopOpeBRepBuild_CorrectFace2d::BndBoxWire
833// purpose:
834//=======================================================================
835 void TopOpeBRepBuild_CorrectFace2d::BndBoxWire(const TopoDS_Wire& aWire,
836 Bnd_Box2d& B2d) const
837{
838 Bnd_Box2d aB2d;
839 TopExp_Explorer aWEx (aWire, TopAbs_EDGE);
840 for (; aWEx.More(); aWEx.Next()) {
841 const TopoDS_Edge& anEdge = TopoDS::Edge(aWEx.Current());
842 Standard_Real aTolE = BRep_Tool::Tolerance(anEdge);
843 BRepAdaptor_Curve2d aBAC2d (anEdge,myCorrectedFace);
844 BndLib_Add2dCurve::Add(aBAC2d, aTolE, aB2d);
845 }
846 B2d=aB2d;
847}
848
849//=======================================================================
850// function : TopOpeBRepBuild_CorrectFace2d::MoveWire2d
851// purpose:
852//=======================================================================
853 void TopOpeBRepBuild_CorrectFace2d::MoveWire2d (TopoDS_Wire& aWire,
854 const gp_Vec2d& aTrV)
855{
856 if (aTrV.Magnitude()<Precision::Confusion())
857 return;
858
859 Standard_Integer i, aNbEdges;
860 TopTools_SequenceOfShape aSeqEdges;
861 TopTools_IndexedMapOfShape anEdMap;
862 Handle(Geom2d_Curve) aTrCF, aTrCR, aTrC;
863
864 TopExp_Explorer aWExp;
865
866 aWExp.Init(aWire, TopAbs_EDGE);
867 for (; aWExp.More(); aWExp.Next()) {
868 aSeqEdges.Append(aWExp.Current());
869 }
870 aNbEdges=aSeqEdges.Length();
871
872 //
873 // First Edge
874 for (i=1; i<=aNbEdges; i++) {
875 TopoDS_Edge anEdge= TopoDS::Edge(aSeqEdges(i));
876 if (BRep_Tool::IsClosed(anEdge, myCorrectedFace)) {
877 // a. Closed edge <--->
878 if (anEdMap.Contains(anEdge)) continue;
879 anEdMap.Add(anEdge);
880
881 TopAbs_Orientation anOri = anEdge.Orientation();
882
883 TopoDS_Edge anEF, anER;
884
885 if (anOri==TopAbs_FORWARD) {
886 anEF=anEdge;
887 TopoDS_Shape aLocalShape = anEdge.Reversed();
888 anER=TopoDS::Edge(aLocalShape);
889 // anER=TopoDS::Edge(anEdge.Reversed());
890 }
891
892 else {
893 anER=anEdge;
894 TopoDS_Shape aLocalShape = anEdge.Reversed();
895 anEF=TopoDS::Edge(aLocalShape);
896 // anEF=TopoDS::Edge(anEdge.Reversed());
897 }
898
899 TranslateCurve2d (anEF, myCorrectedFace, aTrV, aTrCF);
900 TranslateCurve2d (anER, myCorrectedFace, aTrV, aTrCR);
901 UpdateEdge(anEdge, aTrCF, aTrCR, myCorrectedFace, myFaceTolerance);
902 }
903
904 else {
905 // b. Usual Edge
906 TranslateCurve2d (anEdge, myCorrectedFace, aTrV, aTrC);
907 UpdateEdge(anEdge, aTrC, myCorrectedFace, myFaceTolerance);
908 }
909 } //end of for (i=1; i<=aNbEdges; i++)
910}
911//=======================================================================
912// function : TopOpeBRepBuild_CorrectFace2d::MoveWires2d
913// purpose:
914//=======================================================================
915 void TopOpeBRepBuild_CorrectFace2d::MoveWires2d (TopoDS_Wire& anOuterWire)
916{
917 Bnd_Box2d B2d, B2dOuterWire;
918 Standard_Real OuterU1,OuterV1,OuterU2,OuterV2, x, a, TwoPI;
919 Standard_Integer b, k;
920 gp_Vec2d aTrV;
921
c6541a0c 922 TwoPI=2.*M_PI;
7fd59977 923
924 BndBoxWire(anOuterWire, B2dOuterWire);
925 B2dOuterWire.Get(OuterU1,OuterV1,OuterU2,OuterV2);
926
927 a=.5*(OuterU1+OuterU2);
928 b=Standard_Integer(-a/TwoPI);
929 k=(a<0.)? 1 : 0;
930 x=(b+k)*TwoPI;
931 //
932 // 1. Move the Outer Wire to [0, 2*PI]
933 aTrV.SetCoord (x, 0.);
934 MoveWire2d (anOuterWire, aTrV);
935
936 BndBoxWire(anOuterWire, B2dOuterWire);
937 B2dOuterWire.Get(OuterU1,OuterV1,OuterU2,OuterV2);
938 //
939 // 2. Move all other wires into bounding box of the Outer Wire
940 TopExp_Explorer aFExp;
941 aFExp.Init (myCorrectedFace, TopAbs_WIRE);
942 for (; aFExp.More(); aFExp.Next()) {
943 myCurrentWire = TopoDS::Wire(aFExp.Current());
944 if (myCurrentWire!=anOuterWire) {
945 BndBoxWire(myCurrentWire, B2d);
946 Standard_Real u1,v1,u2,v2;
947 B2d.Get(u1,v1,u2,v2);
948
949 if (B2d.IsOut(B2dOuterWire)) {
950 //printf(" Need to Move\n" );
951 a=u1-OuterU1;
952 b=Standard_Integer(-a/TwoPI);
953 k= (a<0.) ? 1 : 0;
954 x=(b+k)*TwoPI;
955 aTrV.SetCoord (x, 0.);
956 MoveWire2d (myCurrentWire, aTrV);
957 }
958 }
959 }
960}
961//=======================================================================
962// function : TopOpeBRepBuild_CorrectFace2d::UpdateEdge
963// purpose:
964//=======================================================================
965 void TopOpeBRepBuild_CorrectFace2d::UpdateEdge (const TopoDS_Edge& ECopy,
966 const Handle(Geom2d_Curve)& C,
967 const TopoDS_Face& F,
968 const Standard_Real Tol)
969{
970 BRep_Builder BB;
971
972 TopTools_IndexedDataMapOfShapeShape* pMap=
973 (TopTools_IndexedDataMapOfShapeShape*) myMap;
974
975 // E is the Original Edge from Original Face.
976 if (myEdMapInversed.Contains(ECopy)) {
977 const TopoDS_Shape& E=myEdMapInversed.FindFromKey(ECopy);
978
979 if (!pMap->Contains(E)) {
980 TopExp_Explorer anExp;
981
982 TopoDS_Shape anEdge=E.EmptyCopied();
983
984 anExp.Init(E, TopAbs_VERTEX);
985 for (; anExp.More(); anExp.Next()) {
986 const TopoDS_Shape& aV=anExp.Current();
987 BB.Add(anEdge, aV);
988 }
989
990 BB.UpdateEdge(TopoDS::Edge(anEdge), C, F, Tol);
991 pMap->Add(E, anEdge);
992 //printf("pMap->Extent()=%d\n", pMap->Extent());
993 }
994
995 else {
996 TopoDS_Shape& anEdge=pMap->ChangeFromKey(E);
997 BB.UpdateEdge(TopoDS::Edge(anEdge), C, F, Tol);
998 }
999 }
1000
1001 BB.UpdateEdge (ECopy, C, F, Tol);
1002}
1003
1004
1005//=======================================================================
1006// function : TopOpeBRepBuild_CorrectFace2d::UpdateEdge
1007// purpose:
1008//=======================================================================
1009 void TopOpeBRepBuild_CorrectFace2d::UpdateEdge (const TopoDS_Edge& ECopy,
1010 const Handle(Geom2d_Curve)& C1,
1011 const Handle(Geom2d_Curve)& C2,
1012 const TopoDS_Face& F,
1013 const Standard_Real Tol)
1014{
1015 BRep_Builder BB;
1016
1017 TopTools_IndexedDataMapOfShapeShape* pMap=
1018 (TopTools_IndexedDataMapOfShapeShape*) myMap;
1019
1020 // E is the Original Edge from Original Face.
1021 if (myEdMapInversed.Contains(ECopy)) {
1022 const TopoDS_Shape& E=myEdMapInversed.FindFromKey(ECopy);
1023
1024 if (!pMap->Contains(E)) {
1025 TopoDS_Shape anEdge=E.EmptyCopied();
1026 TopExp_Explorer anExp;
1027 anExp.Init(E, TopAbs_VERTEX);
1028 for (; anExp.More(); anExp.Next()) {
1029 const TopoDS_Shape& aV=anExp.Current();
1030 BB.Add(anEdge, aV);
1031 }
1032 BB.UpdateEdge(TopoDS::Edge(anEdge), C1, C2, F, Tol);
1033 pMap->Add(E, anEdge);
1034 //printf("pMap->Extent()=%d\n", pMap->Extent());
1035 }
1036
1037 else {
1038 TopoDS_Shape& anEdge=pMap->ChangeFromKey(E);
1039 BB.UpdateEdge(TopoDS::Edge(anEdge), C1, C2, F, Tol);
1040 }
1041 }
1042
1043 BB.UpdateEdge (ECopy, C1, C2, F, Tol);
1044}
1045
1046//
1047// Description for ErrorStatus
1048// ErrorStatus=0 : All is done;
1049// ErrorStatus=1 : Nothing is done;
1050// ErrorStatus=2 : The wire doesn't contain any licit edges and the wire is not closed;
1051// ErrorStatus=3 : The face contains a wire that is not connectable
1052// ErrorStatus=4 : The base surface is not periodic;
1053// ErrorStatus=5 : an outer wir can not be found;
1054// ErrorStatus=6 : Wrong connectability of a wire in 2d
1055