Integration of OCCT 6.5.0 from SVN
[occt.git] / src / BRepFill / BRepFill_CompatibleWires.cxx
CommitLineData
7fd59977 1// File: BRepFill_CompatibleWires.cxx
2// Created: Thu Jul 2 16:47:25 1998
3// Author: Joelle CHAUVET
4// <jct@sgi64>
5
6
7#include <BRepFill_CompatibleWires.ixx>
8
9#include <BRepAdaptor_Curve.hxx>
10
11#include <BRepFill.hxx>
12#include <BRepLib.hxx>
13#include <BRepLib_FindSurface.hxx>
14#include <BRepLib_MakeWire.hxx>
15#include <BRepLib_MakeEdge.hxx>
16#include <BRepExtrema_DistShapeShape.hxx>
17#include <Bnd_Box.hxx>
18#include <BRepBndLib.hxx>
19#include <BRep_Builder.hxx>
20#include <BRep_Tool.hxx>
21#include <BRepTools_WireExplorer.hxx>
22#include <BRepLProp.hxx>
23#include <BRepGProp.hxx>
24#include <GProp_GProps.hxx>
25#include <GProp_PrincipalProps.hxx>
26#include <Geom_Surface.hxx>
27#include <Geom_Plane.hxx>
28#include <Precision.hxx>
29#include <TopAbs.hxx>
30#include <TopExp.hxx>
31#include <TopExp_Explorer.hxx>
32#include <TopoDS.hxx>
33#include <TopoDS_Wire.hxx>
34#include <TopTools_ListIteratorOfListOfShape.hxx>
35#include <TopTools_DataMapOfShapeListOfShape.hxx>
36#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
37#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
38#include <TopTools_HSequenceOfShape.hxx>
39#include <TopTools_SequenceOfShape.hxx>
40#include <TopTools_ListOfShape.hxx>
41
42#include <gp.hxx>
43#include <gp_Vec.hxx>
44#include <gp_Ax2.hxx>
45#include <gp_Pln.hxx>
46#include <gp_Circ.hxx>
47#include <gp_Elips.hxx>
48#include <TColgp_HArray1OfVec.hxx>
49#include <TColgp_HArray1OfPnt.hxx>
50
51#include <TColStd_Array1OfInteger.hxx>
52#include <TColStd_Array1OfReal.hxx>
53#include <TColStd_SequenceOfReal.hxx>
54
55
56static void EdgesFromVertex (const TopoDS_Wire& W,
57 const TopoDS_Vertex& V,
58 TopoDS_Edge& E1,
59 TopoDS_Edge& E2)
60{
61 TopTools_IndexedDataMapOfShapeListOfShape Map;
62 TopExp::MapShapesAndAncestors(W,TopAbs_VERTEX,TopAbs_EDGE,Map);
63
64 const TopTools_ListOfShape& List = Map.FindFromKey(V);
65 TopoDS_Edge e1 = TopoDS::Edge(List.First());
66 TopoDS_Edge e2 = TopoDS::Edge(List. Last());
67
68 BRepTools_WireExplorer anExp;
69 Standard_Integer I1=0, I2=0, NE=0;
70
71 for(anExp.Init(W); anExp.More(); anExp.Next()) {
72 NE++;
73 const TopoDS_Edge& ECur = anExp.Current();
74 if (e1.IsSame(ECur)) {
75 I1 = NE;
76 }
77 if (e2.IsSame(ECur)) {
78 I2 = NE;
79 }
80 }
81
82 if (Abs(I2-I1)==1) {
83 // numeros consecutifs
84 if (I2==I1+1) {
85 E1 = e1;
86 E2 = e2;
87 }
88 else {
89 E1 = e2;
90 E2 = e1;
91 }
92 }
93 else {
94 // numeros non consecutifs sur un wire ferme
95 if (I1==1&&I2==NE) {
96 E1 = e2;
97 E2 = e1;
98 }
99 else {
100 E1 = e1;
101 E2 = e2;
102 }
103 }
104}
105
106
107static void SeqOfVertices (const TopoDS_Wire& W,
108 TopTools_SequenceOfShape& S)
109{
110 S.Clear();
111 Standard_Integer jj, cpt = 0;
112 TopExp_Explorer PE;
113 for (PE.Init(W,TopAbs_VERTEX); PE.More(); PE.Next()) {
114 cpt++;
115 Standard_Boolean trouve=Standard_False;
116 for (jj=1;jj<=S.Length() && (!trouve);jj++) {
117 if (S.Value(jj).IsSame(PE.Current())) trouve = Standard_True;
118 }
119 if (!trouve) S.Append(PE.Current());
120 }
121}
122
123
124static Standard_Boolean PlaneOfWire (const TopoDS_Wire& W, gp_Pln& P)
125{
126 Standard_Boolean isplane = Standard_True;
127 BRepLib_FindSurface findPlanarSurf;
128 Handle(Geom_Surface) S;
129 TopLoc_Location L;
130
131 GProp_GProps GP;
132 BRepGProp::LinearProperties(W,GP);
133 gp_Pnt Bary = GP.CentreOfMass();
134
135// blindage pour les cas particuliers : 1 seule edge cercle ou ellipse
136// sur un wire ferme !
137 Standard_Integer nbEdges = 0;
138 BRepTools_WireExplorer anExp;
139 anExp.Init(W);
140 Standard_Boolean wClosed = W.Closed();
141 if (!wClosed) {
142 // on regarde quand meme si les vertex sont les memes.
143 TopoDS_Vertex V1, V2;
144 TopExp::Vertices(W,V1,V2);
145 if ( V1.IsSame(V2)) wClosed = Standard_True;
146 }
147 TopoDS_Edge Edge = TopoDS::Edge(anExp.Current());
148 Standard_Real first, last;
149 TopLoc_Location loc;
150 Handle(Geom_Curve) curv;
151 curv = BRep_Tool::Curve(Edge, loc, first, last);
152 curv =
153 Handle(Geom_Curve)::DownCast(curv->Transformed(loc.Transformation()));
154 if (wClosed) {
155 GeomAdaptor_Curve AdC;
156 AdC.Load(curv);
157 for(; anExp.More(); anExp.Next()) {
158 nbEdges ++;
159 }
160 if ( nbEdges==1 && AdC.GetType() == GeomAbs_Circle ) {
161 Bary = AdC.Circle().Location();
162 }
163 if ( nbEdges==1 && AdC.GetType() == GeomAbs_Ellipse ) {
164 Bary = AdC.Ellipse().Location();
165 }
166 }
167
168 findPlanarSurf.Init(W, -1, Standard_True);
169 if ( findPlanarSurf.Found()) {
170 S = findPlanarSurf.Surface();
171 L = findPlanarSurf.Location();
172 if (!L.IsIdentity()) S = Handle(Geom_Surface)::
173 DownCast(S->Transformed(L.Transformation()));
174 P = (Handle(Geom_Plane)::DownCast(S))->Pln();
175 P.SetLocation(Bary);
176 }
177 else {
178 // wire non plan !
179 GProp_PrincipalProps Pp = GP.PrincipalProperties();
180 gp_Vec Vec;
181 Standard_Real R1, R2, R3,Tol = Precision::Confusion();
182 Pp.RadiusOfGyration(R1,R2,R3);
183 Standard_Real RMax = Max(Max(R1,R2),R3);
184 if ( ( Abs(RMax-R1)<Tol && Abs(RMax-R2)<Tol )
185 || ( Abs(RMax-R1)<Tol && Abs(RMax-R3)<Tol )
186 || ( Abs(RMax-R2)<Tol && Abs(RMax-R3)<Tol ) )
187 isplane = Standard_False;
188 else {
189 if (R1>=R2 && R1>=R3) {
190 Vec = Pp.FirstAxisOfInertia();
191 }
192 else if (R2>=R1 && R2>=R3) {
193 Vec = Pp.SecondAxisOfInertia();
194 }
195 else if (R3>=R1 && R3>=R2) {
196 Vec = Pp.ThirdAxisOfInertia();
197 }
198 gp_Dir NDir(Vec);
199 if (R3<=R2 && R3<=R1) {
200 Vec = Pp.ThirdAxisOfInertia();
201 }
202 else if (R2<=R1 && R2<=R3) {
203 Vec = Pp.SecondAxisOfInertia();
204 }
205 else if (R1<=R2 && R1<=R3) {
206 Vec = Pp.FirstAxisOfInertia();
207 }
208 gp_Dir XDir(Vec);
209 gp_Ax3 repere(Bary,NDir,XDir);
210 Geom_Plane GPlan(repere);
211 P = GPlan.Pln();
212 }
213 }
214
215 return isplane;
216
217}
218
219
220static void WireContinuity (const TopoDS_Wire& W,
221 GeomAbs_Shape& contW)
222{
223 contW = GeomAbs_CN;
224 GeomAbs_Shape cont;
225 Standard_Boolean IsDegenerated = Standard_False;
226
227 BRepTools_WireExplorer anExp;
228 Standard_Integer nbEdges=0;
229 Handle(TopTools_HSequenceOfShape) Edges = new TopTools_HSequenceOfShape();
230 for(anExp.Init(W); anExp.More(); anExp.Next()) {
231 nbEdges++;
232 Edges->Append(anExp.Current());
233 if (BRep_Tool::Degenerated(anExp.Current())) IsDegenerated = Standard_True;
234 }
235
236 if (!IsDegenerated) {
237
238 Standard_Boolean testconti = Standard_True;
239
240 for (Standard_Integer j=1;j<=nbEdges;j++) {
241
242 TopoDS_Edge Edge1, Edge2;
243
244 if (j == nbEdges) {
245 Edge1 = TopoDS::Edge (Edges->Value(nbEdges));
246 Edge2 = TopoDS::Edge (Edges->Value(1));
247 }
248 else {
249 Edge1 = TopoDS::Edge (Edges->Value(j));
250 Edge2 = TopoDS::Edge (Edges->Value(j+1));
251 }
252
253 TopoDS_Vertex V1,V2,Vbid;
254 TopExp::Vertices(Edge1,Vbid,V1,Standard_True);
255 TopExp::Vertices(Edge2,V2,Vbid,Standard_True);
256 Standard_Real U1 = BRep_Tool::Parameter(V1,Edge1);
257 Standard_Real U2 = BRep_Tool::Parameter(V2,Edge2);
258 BRepAdaptor_Curve Curve1(Edge1);
259 BRepAdaptor_Curve Curve2(Edge2);
260 Standard_Real Eps = BRep_Tool::Tolerance(V2) + BRep_Tool::Tolerance(V1);
261
262 if(j == nbEdges)
263 testconti = Curve1.Value(U1).IsEqual(Curve2.Value(U2), Eps);
264
265 if(testconti) {
266 cont = BRepLProp::Continuity(Curve1,Curve2,U1,U2,
267 Eps, Precision::Angular());
268 if (cont <= contW) contW = cont;
269 }
270 }
271 }
272
273}
274
275static void TrimEdge (const TopoDS_Edge& CurrentEdge,
276 const TColStd_SequenceOfReal& CutValues,
277 const Standard_Real t0, const Standard_Real t1,
278 const Standard_Boolean SeqOrder,
279 TopTools_SequenceOfShape& S)
280
281{
282 S.Clear();
283 Standard_Integer j, ndec=CutValues.Length();
284 Standard_Real first,last,m0,m1;
285 Handle(Geom_Curve) C = BRep_Tool::Curve(CurrentEdge,first,last);
286
287 TopoDS_Vertex Vf,Vl,Vbid,V0,V1;
288 TopAbs_Orientation CurrentOrient = CurrentEdge.Orientation();
289 TopExp::Vertices(CurrentEdge,Vf,Vl);
290 Vbid.Nullify();
291
292 if (SeqOrder) {
293 // de first vers last
294 m0 = first;
295 V0 = Vf;
296 for (j=1; j<=ndec; j++) {
297 // morceau d'edge
298 m1 = (CutValues.Value(j)-t0)*(last-first)/(t1-t0)+first;
299 TopoDS_Edge CutE = BRepLib_MakeEdge(C,V0,Vbid,m0,m1);
300 CutE.Orientation(CurrentOrient);
301 S.Append(CutE);
302 m0 = m1;
303 V0 = TopExp::LastVertex(CutE);
304 if (j==ndec) {
305 // dernier morceau
306 TopoDS_Edge LastE = BRepLib_MakeEdge(C,V0,Vl,m0,last);
307 LastE.Orientation(CurrentOrient);
308 S.Append(LastE);
309 }
310 }
311 }
312 else {
313 // de last vers first
314 m1 = last;
315 V1 = Vl;
316 for (j=ndec; j>=1; j--) {
317 // morceau d'edge
318 m0 = (CutValues.Value(j)-t0)*(last-first)/(t1-t0)+first;
319 TopoDS_Edge CutE = BRepLib_MakeEdge(C,Vbid,V1,m0,m1);
320 CutE.Orientation(CurrentOrient);
321 S.Append(CutE);
322 m1 = m0;
323 V1 = TopExp::FirstVertex(CutE);
324 if (j==1) {
325 // dernier morceau
326 TopoDS_Edge LastE = BRepLib_MakeEdge(C,Vf,V1,first,m1);
327 LastE.Orientation(CurrentOrient);
328 S.Append(LastE);
329 }
330 }
331 }
332}
333
334
335
336static Standard_Boolean SearchRoot (const TopoDS_Vertex& V,
337 const TopTools_DataMapOfShapeListOfShape& Map,
338 TopoDS_Vertex& VRoot)
339{
340 Standard_Boolean trouve = Standard_False;
341 VRoot.Nullify();
342 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape it;
343 for (it.Initialize(Map); it.More(); it.Next()) {
344 const TopTools_ListOfShape & List = it.Value();
345 TopTools_ListIteratorOfListOfShape itL;
346 Standard_Boolean ilyest = Standard_False;
347 for (itL.Initialize(List); itL.More(); itL.Next()) {
348 TopoDS_Vertex Vcur = TopoDS::Vertex(itL.Value());
349 if (Vcur.IsSame(V)) {
350 ilyest = Standard_True;
351 }
352 if (ilyest) break;
353 }
354 if (ilyest) {
355 trouve = Standard_True;
356 VRoot = TopoDS::Vertex(it.Key());
357 }
358 if (trouve) break;
359 }
360 return trouve;
361}
362
363static Standard_Boolean SearchVertex (const TopTools_ListOfShape& List,
364 const TopoDS_Wire& W,
365 TopoDS_Vertex& VonW)
366{
367 Standard_Boolean trouve = Standard_False;
368 VonW.Nullify();
369 TopTools_SequenceOfShape SeqV;
370 SeqOfVertices(W,SeqV);
371 for (Standard_Integer ii=1;ii<=SeqV.Length();ii++) {
372 TopoDS_Vertex Vi = TopoDS::Vertex(SeqV.Value(ii));
373 TopTools_ListIteratorOfListOfShape itL;
374 Standard_Boolean ilyest = Standard_False;
375 for (itL.Initialize(List); itL.More(); itL.Next()) {
376 TopoDS_Vertex Vcur = TopoDS::Vertex(itL.Value());
377 if (Vcur.IsSame(Vi)) {
378 ilyest = Standard_True;
379 }
380 if (ilyest) break;
381 }
382 if (ilyest) {
383 trouve = Standard_True;
384 VonW = Vi;
385 }
386 if (trouve) break;
387 }
388 return trouve;
389}
390
391
392static Standard_Boolean EdgeIntersectOnWire (const gp_Pnt& P1,
393 const gp_Pnt& P2,
394 Standard_Real percent,
395 const TopTools_DataMapOfShapeListOfShape& Map,
396 const TopoDS_Wire& W,
397 TopoDS_Vertex& Vsol,
398 TopoDS_Wire& newW)
399{
400
401 BRepTools_WireExplorer anExp;
402
403 // construction de l'edge d'intersection
404 Standard_Boolean NewVertex = Standard_False;
405 gp_Lin droite(P1,gp_Dir(gp_Vec(P1,P2)));
406 // ATTENTION : en toute rigueur, il faudrait construire une demi-droite
407 // mais il y a un bug dans BRepExtrema_DistShapeShape
408 // on se contente de 100 * la distance entre P1 et P2
409 // en esperant que ce soit suffisant jusqu'a ce que le bug
410 // soit corrige
411 // Standard_Real dernierparam = Precision::Infinite();
412 // ATTENTION : le retour !!
413 // 100 c'est mieux que 10 mais quelquefois c'est trop !
414 // finalement, rien ne vaut une bonne boite d'encombrement
415 // Standard_Real dernierparam = 100 * P1.Distance(P2);
416 Bnd_Box B;
417 BRepBndLib::Add(W,B);
418 Standard_Real x1,x2,y1,y2,z1,z2;
419 B.Get(x1,y1,z1,x2,y2,z2);
420 gp_Pnt BP1(x1,y1,z1), BP2(x2,y2,z2);
421 Standard_Real diag = BP1.Distance(BP2);
422 Standard_Real dernierparam = diag;
423 BRepLib_MakeEdge ME(droite,0.,dernierparam);
424 TopoDS_Edge ECur = BRepLib_MakeEdge(droite,0.,P1.Distance(P2));
425
426 // calcul de l'intersection par BRepExtrema (point de distance mini)
427 BRepExtrema_DistShapeShape DSS(ME.Edge(),W);
428 if (DSS.IsDone()) {
429 // on choisit la solution la plus proche de P2
430 Standard_Integer isol = 1;
431 Standard_Real dss = P2.Distance(DSS.PointOnShape2(isol));
432 for (Standard_Integer iss=2; iss<=DSS.NbSolution(); iss++) {
433 if (dss>P2.Distance(DSS.PointOnShape2(iss))) {
434 dss = P2.Distance(DSS.PointOnShape2(iss));
435 isol = iss;
436 }
437 }
438#ifdef DEB
439 gp_Pnt Psol =
440#endif
441 DSS.PointOnShape2(isol);
442 // la solution est-elle un nouveau vertex ?
443 NewVertex = (DSS.SupportTypeShape2(isol) != BRepExtrema_IsVertex);
444 if (NewVertex) {
445 TopoDS_Shape aLocalShape = DSS.SupportOnShape2(isol);
446 TopoDS_Edge E = TopoDS::Edge(aLocalShape);
447// TopoDS_Edge E = TopoDS::Edge(DSS.SupportOnShape2(isol));
448 Standard_Real tol = Precision::PConfusion();
449 Standard_Real first,last,param;
450 BRep_Tool::Range(E,first,last);
451 tol = Max(tol,percent*Abs(last-first));
452 DSS.ParOnEdgeS2(isol,param);
453 if (Abs(first-param)<tol) {
454 NewVertex = Standard_False;
455 Vsol = TopExp::FirstVertex(E);
456 }
457 else if (Abs(last-param)<tol) {
458 NewVertex = Standard_False;
459 Vsol = TopExp::LastVertex(E);
460 }
461 // verif
462 if (!NewVertex) {
463 TopoDS_Vertex VRoot;
464 if (SearchRoot(Vsol,Map,VRoot)) NewVertex = Standard_True;
465 }
466 }
467 else {
468 TopoDS_Shape aLocalShape = DSS.SupportOnShape2(isol);
469 Vsol = TopoDS::Vertex(aLocalShape);
470// Vsol = TopoDS::Vertex(DSS.SupportOnShape2(isol));
471 }
472
473 // il faut decouper l'edge
474 if (NewVertex) {
475 TopoDS_Shape aLocalShape = DSS.SupportOnShape2(isol);
476 TopoDS_Edge E = TopoDS::Edge(aLocalShape);
477// TopoDS_Edge E = TopoDS::Edge(DSS.SupportOnShape2(isol));
478#ifdef DEB
479 Standard_Real tol =
480#endif
481 Precision::PConfusion();
482 Standard_Real first,last,param;
483 DSS.ParOnEdgeS2(isol,param);
484 BRep_Tool::Range(E,first,last);
485 BRepLib_MakeWire MW;
486 for (anExp.Init(W); anExp.More(); anExp.Next()) {
487 if (E.IsSame(anExp.Current())) {
488 Standard_Boolean SO
489 = (anExp.CurrentVertex().IsSame(TopExp::FirstVertex(E)));
490 TopTools_SequenceOfShape SE;
491 SE.Clear();
492 TColStd_SequenceOfReal SR;
493 SR.Clear();
494 SR.Append(param);
495 TrimEdge(E,SR,first,last,SO,SE);
496 TopoDS_Vertex VV1,VV2;
497 TopExp::Vertices(TopoDS::Edge(SE.Value(1)),VV1,VV2);
498 if (TopExp::FirstVertex(E).IsSame(VV1)
499 || TopExp::LastVertex(E).IsSame(VV1)) {
500 Vsol = VV2;
501 }
502 if (TopExp::FirstVertex(E).IsSame(VV2)
503 || TopExp::LastVertex(E).IsSame(VV2)) {
504 Vsol = VV1;
505 }
506 for (Standard_Integer k=1; k<=SE.Length(); k++) {
507 MW.Add(TopoDS::Edge(SE.Value(k)));
508 }
509 }
510 else {
511 MW.Add(anExp.Current());
512 }
513 }
514 newW = MW.Wire();
515 }
516 else {
517 newW = W;
518 }
519
520
521 }
522
523 return NewVertex;
524
525}
526
527
528static void Transform (const Standard_Boolean WithRotation,
529 const gp_Pnt& P,
530 const gp_Pnt& Pos1,
531 const gp_Vec& Ax1,
532 const gp_Pnt& Pos2,
533 const gp_Vec& Ax2,
534 gp_Pnt& Pnew)
535{
536
537 Pnew = P.Translated (Pos1,Pos2);
538 gp_Vec axe1 = Ax1, axe2 = Ax2;
539 if (!axe1.IsParallel(axe2,1.e-4)) {
540 gp_Vec Vtrans(Pos1,Pos2),Vsign;
541 Standard_Real alpha,beta,sign=1;
542 alpha = Vtrans.Dot(axe1);
543 beta = Vtrans.Dot(axe2);
544 if (alpha<-1.e-7) axe1 *=-1;
545 if (beta<1.e-7) axe2 *=-1;
546 alpha = Vtrans.Dot(axe1);
547 beta = Vtrans.Dot(axe2);
548 gp_Vec norm2 = axe1 ^ axe2;
549 Vsign.SetLinearForm(Vtrans.Dot(axe1),axe2,-Vtrans.Dot(axe2),axe1);
550 alpha = Vsign.Dot(axe1);
551 beta = Vsign.Dot(axe2);
552 Standard_Boolean pasnul = (Abs(alpha)>1.e-4 && Abs(beta)>1.e-4);
553 if ( alpha*beta>0.0 && pasnul ) sign=-1;
554 gp_Ax1 Norm(Pos2,norm2);
555 Standard_Real ang = axe1.AngleWithRef(axe2,norm2);
556 if (!WithRotation) {
557 if (ang>PI/2) ang = ang - PI;
558 if (ang<-PI/2) ang = ang + PI;
559 }
560 ang *= sign;
561 Pnew = Pnew.Rotated (Norm,ang);
562 }
563}
564
565static void BuildConnectedEdges(const TopoDS_Wire& aWire,
566 const TopoDS_Edge& StartEdge,
567 const TopoDS_Vertex& StartVertex,
568 TopTools_ListOfShape& ConnectedEdges)
569{
570 TopTools_IndexedDataMapOfShapeListOfShape MapVE;
571 TopExp::MapShapesAndAncestors(aWire, TopAbs_VERTEX, TopAbs_EDGE, MapVE);
572 TopoDS_Edge CurEdge = StartEdge;
573 TopoDS_Vertex CurVertex = StartVertex;
574 TopoDS_Vertex Origin, V1, V2;
575 TopExp::Vertices(StartEdge, V1, V2);
576 Origin = (V1.IsSame(StartVertex))? V2 : V1;
577
578 for (;;)
579 {
580 TopTools_ListIteratorOfListOfShape itE( MapVE.FindFromKey(CurVertex) );
581 for (; itE.More(); itE.Next())
582 {
583 TopoDS_Edge anEdge = TopoDS::Edge(itE.Value());
584 if (!anEdge.IsSame(CurEdge))
585 {
586 ConnectedEdges.Append(anEdge);
587 TopExp::Vertices(anEdge, V1, V2);
588 CurVertex = (V1.IsSame(CurVertex))? V2 : V1;
589 CurEdge = anEdge;
590 break;
591 }
592 }
593 if (CurVertex.IsSame(Origin))
594 break;
595 }
596}
597
598//=======================================================================
599//function : BRepFill_CompatibleWires
600//purpose :
601//=======================================================================
602
603BRepFill_CompatibleWires::BRepFill_CompatibleWires()
604:myIsDone(Standard_False)
605{
606}
607
608
609//=======================================================================
610//function : BRepFill_CompatibleWires
611//purpose :
612//=======================================================================
613
614BRepFill_CompatibleWires::BRepFill_CompatibleWires(const TopTools_SequenceOfShape& Sections)
615{
616 Init(Sections);
617}
618
619
620//=======================================================================
621//function : Init
622//purpose :
623//=======================================================================
624
625void BRepFill_CompatibleWires::Init(const TopTools_SequenceOfShape& Sections)
626{
627 myInit = Sections;
628 myWork = Sections;
629 myPercent = 0.01;
630 myIsDone = Standard_False;
631 myMap.Clear();
632
633}
634
635
636//=======================================================================
637//function : SetPercent
638//purpose :
639//=======================================================================
640
641void BRepFill_CompatibleWires::SetPercent(const Standard_Real Percent)
642{
643 if (0.<Percent && Percent<1.) myPercent = Percent;
644
645}
646
647
648//=======================================================================
649//function : IsDone
650//purpose :
651//=======================================================================
652
653Standard_Boolean BRepFill_CompatibleWires::IsDone() const
654{
655 return myIsDone;
656}
657
658
659//=======================================================================
660//function : Shape
661//purpose :
662//=======================================================================
663
664const TopTools_SequenceOfShape& BRepFill_CompatibleWires::Shape() const
665{
666 return myWork;
667}
668
669
670//=======================================================================
671//function : GeneratedShapes
672//purpose :
673//=======================================================================
674
675const TopTools_ListOfShape& BRepFill_CompatibleWires::GeneratedShapes
676(const TopoDS_Edge& SubSection) const
677{
678
679 if (myMap.IsBound(SubSection)) {
680 return myMap(SubSection);
681 }
682 else {
683 static TopTools_ListOfShape Empty;
684 return Empty;
685 }
686}
687
688
689//=======================================================================
690//function : Perform
691//purpose :
692//=======================================================================
693
694void BRepFill_CompatibleWires::Perform (const Standard_Boolean WithRotation)
695{
696 // compute origin and orientation on wires to avoid twisted results
697 // and update wires to have same number of edges
698
699 // determination de report:
700 // si le nombre d'elements est identique et si les wires ont des discontinuites
701 // en tangence, on n'effectue pas le report par abscisse curviligne, ni
702 Standard_Integer nbSects = myWork.Length(), i;
703 BRepTools_WireExplorer anExp;
704 Standard_Integer nbmax=0, nbmin=0;
705 TColStd_Array1OfInteger nbEdges(1,nbSects);
706 Standard_Boolean report;
707 GeomAbs_Shape contS=GeomAbs_CN;
708 GeomAbs_Shape cont;
709 for (i=1; i<=nbSects; i++) {
710 TopoDS_Shape aLocalShape = myWork(i).Oriented(TopAbs_FORWARD);
711 myWork(i) = TopoDS::Wire(aLocalShape);
712// myWork(i) = TopoDS::Wire(myWork(i).Oriented(TopAbs_FORWARD));
713 TopoDS_Wire W = TopoDS::Wire(myWork(i));
714 WireContinuity(W,cont);
715 if (cont<contS) contS=cont;
716 nbEdges(i) = 0;
717 for(anExp.Init(W); anExp.More(); anExp.Next() ) nbEdges(i)++;
718 if (i==1) nbmin = nbEdges(i);
719 if (nbmax<nbEdges(i)) nbmax = nbEdges(i);
720 if (nbmin>nbEdges(i)) nbmin = nbEdges(i);
721 }
722 // si on n'a pas le meme nombre d'elements ou si tous les wires sont au moins
723 // C1, on effectue le report par abscisse curviligne des decoupes sinon, on se
724 // fait un report vertex / Vertex
725 report = (nbmax != nbmin || contS >= GeomAbs_C1 );
726
727 // initialisation de la map
728 Standard_Integer nbE = 0;
729 TopTools_ListOfShape Empty;
730 for (i=1; i<=nbSects; i++) {
731 TopoDS_Wire W = TopoDS::Wire(myWork(i));
732 for(anExp.Init(W); anExp.More(); anExp.Next() ) {
733 TopoDS_Edge E = TopoDS::Edge(anExp.Current());
734 myMap.Bind(E,Empty);
735 myMap(E).Append(E);
736 nbE++;
737 }
738 }
739
740 // sections ouvertes / sections fermees
741 // initialisation de myDegen1, myDegen2
742 Standard_Integer ideb=1, ifin=myWork.Length();
743 // on regarde si le premier wire est ponctuel
744 myDegen1 = Standard_True;
745 for(anExp.Init(TopoDS::Wire(myWork(ideb))); anExp.More(); anExp.Next()) {
746 myDegen1 = myDegen1 && (BRep_Tool::Degenerated(anExp.Current()));
747 }
748 if (myDegen1) ideb++;
749 // on regarde si le dernier wire est ponctuel
750 myDegen2 = Standard_True;
751 for(anExp.Init(TopoDS::Wire(myWork(ifin))); anExp.More(); anExp.Next()) {
752 myDegen2 = myDegen2 && (BRep_Tool::Degenerated(anExp.Current()));
753 }
754 if (myDegen2) ifin--;
755
756 Standard_Boolean wClosed, allClosed = Standard_True, allOpen = Standard_True;
757 for (i=ideb; i<=ifin; i++) {
758 wClosed = myWork(i).Closed();
759 if (!wClosed) {
760 // on regarde quand meme si les vertex sont les memes.
761 TopoDS_Vertex V1, V2;
762 TopExp::Vertices(TopoDS::Wire(myWork(i)),V1,V2);
763 if ( V1.IsSame(V2)) wClosed = Standard_True;
764 }
765 allClosed = (allClosed && wClosed);
766 allOpen = (allOpen && !wClosed);
767 }
768
769 if (allClosed) {
770 // Toutes les sections sont fermees
771 if (report) {
772 // same number of elements
773 SameNumberByPolarMethod(WithRotation);
774 }
775 else {
776 // origine
777 ComputeOrigin(Standard_False);
778 }
779 myIsDone = Standard_True;
780 }
781 else if (allOpen) {
782 // Toutes les sections sont ouvertes
783 // origine
784 SearchOrigin();
785 // same number of elements
786 if (report) {
787 SameNumberByACR(report);
788 }
789 myIsDone = Standard_True;
790 }
791 else {
792 // Il y a des sections ouvertes et des sections fermees :
793 // on ne traite pas
794 Standard_DomainError::Raise("Sections must be all closed or all open");
795 }
796
797}
798
799
800
801
802//=======================================================================
803//function : Generated
804//purpose :
805//=======================================================================
806
807const TopTools_DataMapOfShapeListOfShape& BRepFill_CompatibleWires::Generated() const
808{
809 return myMap;
810}
811
812
813//=======================================================================
814//function : SameNumberByPolarMethod
815//purpose :
816//=======================================================================
817
818void BRepFill_CompatibleWires::
819 SameNumberByPolarMethod(const Standard_Boolean WithRotation)
820{
821
822 // initialisation
823 Standard_Integer NbSects=myWork.Length();
824 BRepTools_WireExplorer anExp;
825 TopoDS_Vertex V1, V2;
826
827 Standard_Boolean allClosed = Standard_True;
828 Standard_Integer i,ii,ideb=1,ifin=NbSects;
829 for (i=1; i<=NbSects; i++) {
830 allClosed = (allClosed && myWork(i).Closed());
831 }
832 if (!allClosed)
833 Standard_NoSuchObject::Raise("BRepFill_CompatibleWires::SameNumberByPolarMethod : the wires must be closed");
834
835 // Nombre max de decoupes possibles
836 Standard_Integer NbMaxV = 0;
837 for (i=1; i<=NbSects; i++) {
838 for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next()) {
839 NbMaxV++;
840 }
841 }
842
843 // sections ponctuelles, sections bouclantes ?
844 if (myDegen1) ideb++;
845 if (myDegen2) ifin--;
846 Standard_Boolean vClosed = (!myDegen1) && (!myDegen2)
847 && (myWork(ideb).IsSame(myWork(ifin)));
848
849 // construction des tableaux de plans des wires
850 gp_Pln P;
851 Handle(TColgp_HArray1OfPnt) Pos
852 = new (TColgp_HArray1OfPnt) (1,NbSects);
853 Handle(TColgp_HArray1OfVec) Axe
854 = new (TColgp_HArray1OfVec) (1,NbSects);
855 for (i=ideb;i<=ifin;i++) {
856 if (PlaneOfWire(TopoDS::Wire(myWork(i)),P)) {
857 Pos->SetValue(i,P.Location());
858 Axe->SetValue(i,gp_Vec(P.Axis().Direction()));
859 }
860 }
861 TopTools_SequenceOfShape SeqV;
862 if (myDegen1) {
863 SeqOfVertices(TopoDS::Wire(myWork(1)),SeqV);
864 Pos->SetValue(1,BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(1))));
865 Axe->SetValue(1,Axe->Value(ideb));
866 }
867 if (myDegen2) {
868 SeqOfVertices(TopoDS::Wire(myWork(NbSects)),SeqV);
869 Pos->SetValue(NbSects,BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(1))));
870 Axe->SetValue(NbSects,Axe->Value(ifin));
871 }
872
873 // construction de RMap, map des reports du wire i vers le wire i-1
874 TopTools_DataMapOfShapeListOfShape RMap;
875 RMap.Clear();
876
877 // boucle sur i
878 for (i=ifin; i>ideb; i--) {
879
880 const TopoDS_Wire& wire1 = TopoDS::Wire(myWork(i));
881
882 // sequence des vertex du premier wire
883 SeqOfVertices(wire1,SeqV);
884 if (SeqV.Length()>NbMaxV)
885 Standard_NoSuchObject::Raise("BRepFill::SameNumberByPolarMethod failed");
886
887 // extremite du premier wire
888 V1 = TopoDS::Vertex(SeqV.Value(1));
889 // wire precedent
890#ifdef DEB
891 const TopoDS_Wire& wire2 =
892#endif
893 TopoDS::Wire(myWork(i-1));
894 // boucle sur les vertex de wire1
895 for (ii=1;ii<=SeqV.Length();ii++) {
896
897 TopoDS_Vertex Vi = TopoDS::Vertex(SeqV.Value(ii));
898
899 // init de RMap pour Vi
900 TopTools_ListOfShape Init;
901 Init.Clear();
902 RMap.Bind(Vi,Init);
903
904 // il faut chercher l'intersection Vi - wire2
905 gp_Pnt Pi = BRep_Tool::Pnt(Vi);
906
907 // on ramene Pi dans le plan courant
908 gp_Pnt Pnew;
909 Transform(WithRotation,Pi,
910 Pos->Value(i),Axe->Value(i),
911 Pos->Value(i-1),Axe->Value(i-1),Pnew);
912
913 // calcul de l'intersection
914 TopoDS_Shape Support;
915 Standard_Boolean NewVertex;
916 TopoDS_Vertex Vsol;
917 TopoDS_Wire newwire;
918 if (Pnew.Distance(Pos->Value(i-1))>Precision::Confusion()) {
919 Standard_Real percent = myPercent;
920 NewVertex = EdgeIntersectOnWire(Pos->Value(i-1),Pnew,percent,
921 RMap,TopoDS::Wire(myWork(i-1)),
922 Vsol,newwire);
923 if (NewVertex) myWork(i-1) = newwire;
924 RMap(Vi).Append(Vsol);
925 }
926
927 } // boucle sur ii
928 } // boucle sur i
929
930 // initialisation de MapVLV, map des correspondances vertex - liste de vertex
931 TopTools_DataMapOfShapeListOfShape MapVLV;
932 SeqOfVertices(TopoDS::Wire(myWork(ideb)),SeqV);
933 Standard_Integer SizeMap = SeqV.Length();
934 MapVLV.Clear();
935 for (ii=1;ii<=SizeMap;ii++) {
936 TopoDS_Vertex Vi = TopoDS::Vertex(SeqV.Value(ii));
937 TopTools_ListOfShape Init;
938 Init.Clear();
939 Init.Append(Vi);
940 MapVLV.Bind(Vi,Init);
941 Standard_Integer NbV = 1;
942 TopoDS_Vertex V0,V1;
943 V0 = Vi;
944 Standard_Boolean tantque = SearchRoot(V0,RMap,V1);
945 while (tantque) {
946 MapVLV(Vi).Append(V1);
947 NbV++;
948 // test sur NbV necessaire pour les sections bouclantes
949 if (V1.IsSame(Vi) || NbV >= myWork.Length()) {
950 tantque = Standard_False;
951 }
952 else {
953 V0 = V1;
954 tantque = SearchRoot(V0,RMap,V1);
955 }
956 }
957 }
958
959 // boucle sur i
960 for (i=ideb; i<ifin; i++) {
961
962 const TopoDS_Wire& wire1 = TopoDS::Wire(myWork(i));
963
964 // sequence des vertex du premier wire
965 SeqOfVertices(wire1,SeqV);
966 if ( SeqV.Length()>NbMaxV || SeqV.Length()>SizeMap )
967 Standard_NoSuchObject::Raise("BRepFill::SameNumberByPolarMethod failed");
968
969 // extremite du premier wire
970 V1 = TopoDS::Vertex(SeqV.Value(1));
971
972 // wire suivant
973 const TopoDS_Wire& wire2 = TopoDS::Wire(myWork(i+1));
974
975 // boucle sur les vertex de wire1
976 for (ii=1;ii<=SeqV.Length();ii++) {
977
978 TopoDS_Vertex Vi = TopoDS::Vertex(SeqV.Value(ii));
979 TopoDS_Vertex VRoot;
980 VRoot.Nullify();
981 Standard_Boolean intersect = Standard_True;
982 if (SearchRoot(Vi,MapVLV,VRoot)) {
983 const TopTools_ListOfShape& LVi = MapVLV(VRoot);
984 TopoDS_Vertex VonW;
985 VonW.Nullify();
986 intersect = (!SearchVertex(LVi,wire2,VonW));
987 }
988
989 if (intersect) {
990 // il faut chercher l'intersection Vi - wire2
991 gp_Pnt Pi = BRep_Tool::Pnt(Vi);
992
993 // on ramene Pi dans le plan courant
994 gp_Pnt Pnew;
995 Transform(WithRotation,Pi,
996 Pos->Value(i),Axe->Value(i),
997 Pos->Value(i+1),Axe->Value(i+1),Pnew);
998
999 // calcul de l'intersection
1000 TopoDS_Shape Support;
1001 Standard_Boolean NewVertex;
1002 TopoDS_Vertex Vsol;
1003 TopoDS_Wire newwire;
1004 if (Pnew.Distance(Pos->Value(i+1))>Precision::Confusion()) {
1005 Standard_Real percent = myPercent;
1006 NewVertex = EdgeIntersectOnWire(Pos->Value(i+1),Pnew,percent,
1007 MapVLV,TopoDS::Wire(myWork(i+1)),
1008 Vsol,newwire);
1009 MapVLV(VRoot).Append(Vsol);
1010 if (NewVertex) myWork(i+1) = newwire;
1011 }
1012
1013 }
1014 } // boucle sur ii
1015 } // boucle sur i
1016
1017 // mise en ordre des wires en suivant MapVLV
1018 TopoDS_Wire wire = TopoDS::Wire(myWork(ideb));
1019
1020 // sauf le dernier si les sections sont bouclantes
1021 Standard_Integer ibout = ifin;
1022 if (vClosed) ibout--;
1023
1024 for ( i=ideb+1; i<=ibout; i++) {
1025
1026 BRepLib_MakeWire MW;
1027
1028 anExp.Init(wire);
1029 TopoDS_Edge ECur = anExp.Current();
1030 TopoDS_Vertex VF,VL;
1031 TopExp::Vertices(ECur,VF,VL,Standard_True);
1032 Standard_Real U1 = BRep_Tool::Parameter(VF,ECur);
1033 Standard_Real U2 = BRep_Tool::Parameter(VL,ECur);
1034 BRepAdaptor_Curve Curve(ECur);
1035 gp_Pnt PPs = Curve.Value(0.1*(U1+9*U2));
1036 TopTools_ListIteratorOfListOfShape itF(MapVLV(VF)),itL(MapVLV(VL));
1037 Standard_Integer rang = ideb;
1038 while (rang < i) {
1039 itF.Next();
1040 itL.Next();
1041 rang++;
1042 }
1043 TopoDS_Vertex V1 = TopoDS::Vertex(itF.Value()), V2 = TopoDS::Vertex(itL.Value());
1044 TopoDS_Edge Esol;
1045 Standard_Real scalmax=0.;
1046 TopoDS_Iterator itW( myWork(i) );
1047
1048 for(; itW.More(); itW.Next())
1049 {
1050 TopoDS_Edge E = TopoDS::Edge(itW.Value());
1051 TopoDS_Vertex VVF,VVL;
1052 TopExp::Vertices(E,VVF,VVL,Standard_True);
1053
1054 // tri des edges candidates
1055 Standard_Real scal1,scal2;
1056 if ( (V1.IsSame(VVF)&&V2.IsSame(VVL)) || (V2.IsSame(VVF)&&V1.IsSame(VVL)) ) {
1057 Standard_Real U1 = BRep_Tool::Parameter(VVF,E);
1058 Standard_Real U2 = BRep_Tool::Parameter(VVL,E);
1059 BRepAdaptor_Curve Curve(E);
1060 gp_Pnt PP1 = Curve.Value(0.1*(U1+9*U2));
1061 gp_Pnt PP2 = Curve.Value(0.1*(9*U1+U2));
1062
1063 for (rang=i;rang>ideb;rang--) {
1064 Transform(WithRotation, PP1,
1065 Pos->Value(rang), Axe->Value(rang),
1066 Pos->Value(rang-1), Axe->Value(rang-1), PP1);
1067 Transform(WithRotation, PP2,
1068 Pos->Value(rang), Axe->Value(rang),
1069 Pos->Value(rang-1), Axe->Value(rang-1), PP2);
1070 }
1071 gp_Vec Ns(Pos->Value(ideb),PPs);
1072 Ns = Ns.Normalized();
1073 gp_Vec N1(Pos->Value(ideb),PP1);
1074 N1 = N1.Normalized();
1075 gp_Vec N2(Pos->Value(ideb),PP2);
1076 N2 = N2.Normalized();
1077 scal1 = N1.Dot(Ns);
1078 if (scal1>scalmax) {
1079 scalmax = scal1;
1080 Esol = E;
1081 }
1082 scal2 = N2.Dot(Ns);
1083 if (scal2>scalmax) {
1084 scalmax = scal2;
1085 TopoDS_Shape aLocalShape = E.Reversed();
1086 Esol = TopoDS::Edge(aLocalShape);
1087 }
1088 }
1089 } //end of for(; itW.More(); itW.Next())
1090 MW.Add(Esol);
1091
1092 TopTools_ListOfShape ConnectedEdges;
1093 BuildConnectedEdges( TopoDS::Wire(myWork(i)), Esol, V2, ConnectedEdges );
1094
1095 TopTools_ListIteratorOfListOfShape itCE(ConnectedEdges);
1096 for(; anExp.More(), itCE.More(); anExp.Next(), itCE.Next())
1097 {
1098 ECur = anExp.Current();
1099 TopExp::Vertices(ECur,VF,VL,Standard_True);
1100 U1 = BRep_Tool::Parameter(VF,ECur);
1101 U2 = BRep_Tool::Parameter(VL,ECur);
1102 Curve.Initialize(ECur);
1103 PPs = Curve.Value(0.1*(U1+9*U2));
1104
1105 TopoDS_Edge E = TopoDS::Edge(itCE.Value());
1106 TopoDS_Vertex VVF,VVL;
1107 TopExp::Vertices(E,VVF,VVL,Standard_True);
1108
1109 // tri des edges candidates
1110 Standard_Real scal1,scal2;
1111 U1 = BRep_Tool::Parameter(VVF,E);
1112 U2 = BRep_Tool::Parameter(VVL,E);
1113 Curve.Initialize(E);
1114 gp_Pnt PP1 = Curve.Value(0.1*(U1+9*U2));
1115 gp_Pnt PP2 = Curve.Value(0.1*(9*U1+U2));
1116
1117 for (rang=i;rang>ideb;rang--) {
1118 Transform(WithRotation, PP1,
1119 Pos->Value(rang), Axe->Value(rang),
1120 Pos->Value(rang-1), Axe->Value(rang-1), PP1);
1121 Transform(WithRotation, PP2,
1122 Pos->Value(rang), Axe->Value(rang),
1123 Pos->Value(rang-1), Axe->Value(rang-1), PP2);
1124 }
1125 gp_Vec Ns(Pos->Value(ideb),PPs);
1126 Ns = Ns.Normalized();
1127 gp_Vec N1(Pos->Value(ideb),PP1);
1128 N1 = N1.Normalized();
1129 gp_Vec N2(Pos->Value(ideb),PP2);
1130 N2 = N2.Normalized();
1131 scal1 = N1.Dot(Ns);
1132 scal2 = N2.Dot(Ns);
1133 if (scal2>scal1)
1134 E.Reverse();
1135 MW.Add(E);
1136 }
1137 myWork(i) = MW.Wire();
1138 }
1139
1140 // sections bouclantes ?
1141 if (vClosed) myWork(myWork.Length()) = myWork(1);
1142
1143 // verification du nombre d'edges pour debug
1144 Standard_Integer nbmax=0, nbmin=0;
1145 for ( i=ideb; i<=ifin; i++) {
1146 Standard_Integer nbEdges=0;
1147 for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next()) {
1148 nbEdges++;
1149 }
1150 if (i==ideb) nbmin = nbEdges;
1151 if (nbmax<nbEdges) nbmax = nbEdges;
1152 if (nbmin>nbEdges) nbmin = nbEdges;
1153 }
1154 if (nbmin!=nbmax) {
1155 Standard_NoSuchObject::Raise("BRepFill_CompatibleWires::SameNumberByPolarMethod failed");
1156 }
1157
1158}
1159
1160//=======================================================================
1161//function : SameNumberByACR
1162//purpose :
1163//=======================================================================
1164
1165void BRepFill_CompatibleWires::SameNumberByACR(const Standard_Boolean report)
1166{
1167 // find the dimension
1168 Standard_Integer ideb=1, ifin=myWork.Length();
1169 BRepTools_WireExplorer anExp;
1170
1171 // sections ponctuelles, sections bouclantes ?
1172 if (myDegen1) ideb++;
1173 if (myDegen2) ifin--;
1174 Standard_Boolean vClosed = (!myDegen1) && (!myDegen2)
1175 && (myWork(ideb).IsSame(myWork(ifin)));
1176
1177 Standard_Integer nbSects = myWork.Length(), i;
1178 Standard_Integer nbmax=0, nbmin=0;
1179 TColStd_Array1OfInteger nbEdges(1,nbSects);
1180 for (i=1; i<=nbSects; i++) {
1181 nbEdges(i) = 0;
1182 for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next()) {
1183 nbEdges(i)++;
1184 }
1185 if (i==1) nbmin = nbEdges(i);
1186 if (nbmax<nbEdges(i)) nbmax = nbEdges(i);
1187 if (nbmin>nbEdges(i)) nbmin = nbEdges(i);
1188 }
1189
1190 if (nbmax>1) {
1191 // plusieurs edges
1192
1193 if (report || nbmin<nbmax) {
1194 // insertion des decoupes
1195 Standard_Integer nbdec=(nbmax-1)*nbSects+1;
1196 Standard_Real tol = 0.01;
1197 TColStd_Array1OfReal dec(1,nbdec);
1198 dec.Init(0);
1199 dec(2)=1;
1200 // calcul du tableau des decoupes
1201 Standard_Integer j,k,l;
1202 for (i=1; i<=nbSects; i++) {
1203 // wire courant
1204 const TopoDS_Wire& wire1 = TopoDS::Wire(myWork(i));
1205 Standard_Integer nbE = 0;
1206 for(anExp.Init(wire1); anExp.More(); anExp.Next()) {
1207 nbE++;
1208 }
1209 // longueur et ACR du wire
1210 TColStd_Array1OfReal ACR(0,nbE);
1211 ACR.Init(0);
1212 BRepFill::ComputeACR(wire1, ACR);
1213 // insertion des ACR du wire dans le tableau des decoupes
1214 for (j=1; j<ACR.Length()-1; j++) {
1215 k=1;
1216 while (dec(k)<ACR(j)) {
1217 k++;
1218 if (k>nbdec) break;
1219 }
1220 if (dec(k-1)+tol<ACR(j)&& ACR(j)+tol<dec(k)) {
1221 for (l=nbdec-1;l>=k;l--) {
1222 dec(l+1)=dec(l);
1223 }
1224 dec(k) = ACR(j);
1225 }
1226 }
1227 }
1228
1229 // tableau effectif des decoupes
1230 k=1;
1231 while (dec(k)<1) {
1232 k++;
1233 if (k>nbdec) break;
1234 }
1235 nbdec = k-1;
1236 TColStd_Array1OfReal dec2(1,nbdec);
1237 for (k=1;k<=nbdec;k++) {
1238 dec2(k) = dec(k);
1239 }
1240
1241 // insertion des decoupes dans chaque wire
1242 for (i=1; i<=nbSects; i++) {
1243 const TopoDS_Wire& oldwire = TopoDS::Wire(myWork(i));
1244 TopoDS_Wire newwire = BRepFill::InsertACR(oldwire, dec2, tol);
1245 BRepTools_WireExplorer anExp1,anExp2;
1246 anExp1.Init(oldwire);
1247 anExp2.Init(newwire);
1248 for (;anExp1.More();anExp1.Next()) {
1249 const TopoDS_Edge& Ecur = anExp1.Current();
1250 if (!Ecur.IsSame(TopoDS::Edge(anExp2.Current()))) {
1251 TopTools_ListOfShape LE;
1252 LE.Clear();
1253 gp_Pnt P1,P2;
1254 const TopoDS_Vertex& V1 = anExp1.CurrentVertex();
1255 TopoDS_Vertex VF,VR;
1256 TopExp::Vertices(Ecur,VF,VR,Standard_True);
1257 if (V1.IsSame(VF)) P1 = BRep_Tool::Pnt(VR);
1258 if (V1.IsSame(VR)) P1 = BRep_Tool::Pnt(VF);
1259 TopoDS_Vertex V2 = anExp2.CurrentVertex();
1260 TopExp::Vertices(TopoDS::Edge(anExp2.Current()),
1261 VF,VR,Standard_True);
1262 if (V2.IsSame(VF)) P2 = BRep_Tool::Pnt(VR);
1263 if (V2.IsSame(VR)) P2 = BRep_Tool::Pnt(VF);
1264 while (P1.Distance(P2)>1.e-3) {
1265 LE.Append(anExp2.Current());
1266 anExp2.Next();
1267 V2 = anExp2.CurrentVertex();
1268 TopExp::Vertices(TopoDS::Edge(anExp2.Current()),
1269 VF,VR,Standard_True);
1270 if (V2.IsSame(VF)) P2 = BRep_Tool::Pnt(VR);
1271 if (V2.IsSame(VR)) P2 = BRep_Tool::Pnt(VF);
1272 if (P1.Distance(P2)<=1.e-3) {
1273 LE.Append(anExp2.Current());
1274 anExp2.Next();
1275 }
1276 }
1277
1278 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itmap;
1279 //TopTools_ListIteratorOfListOfShape itlist;
1280 TopoDS_Edge Ancestor;
1281 Standard_Integer nbedge, nblist=0;
1282 Standard_Boolean found = Standard_False;
1283
1284 for (itmap.Initialize(myMap);itmap.More()&&(!found);itmap.Next()) {
1285 nblist++;
1286 TopTools_ListIteratorOfListOfShape itlist(itmap.Value());
1287 nbedge = 0;
1288 while (itlist.More()&&(!found)) {
1289 nbedge++;
1290 TopoDS_Edge ECur = TopoDS::Edge(itlist.Value());
1291
1292 if (Ecur.IsSame(ECur)) {
1293 Ancestor = TopoDS::Edge(itmap.Key());
1294 found = Standard_True;
1295 myMap(Ancestor).InsertBefore(LE,itlist);
1296 myMap(Ancestor).Remove(itlist);
1297 }
1298 if (itlist.More()) itlist.Next();
1299 }
1300
1301 }
1302
1303 }
1304 else {
1305 anExp2.Next();
1306 }
1307
1308 }
1309 myWork(i) = newwire;
1310 }
1311
1312 }
1313 }
1314
1315 // sections bouclantes ?
1316 if (vClosed) myWork(myWork.Length()) = myWork(1);
1317
1318 // verification du nombre d'edges pour debug
1319 nbmax = 0;
1320 for (i=ideb; i<=ifin; i++) {
1321 nbEdges(i) = 0;
1322 for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next()) {
1323 nbEdges(i)++;
1324 }
1325 if (i==ideb) nbmin = nbEdges(i);
1326 if (nbmax<nbEdges(i)) nbmax = nbEdges(i);
1327 if (nbmin>nbEdges(i)) nbmin = nbEdges(i);
1328 }
1329 if (nbmax!=nbmin)
1330 Standard_NoSuchObject::Raise("BRepFill_CompatibleWires::SameNumberByACR failed");
1331}
1332
1333//=======================================================================
1334//function : ComputeOrigin
1335//purpose :
1336//=======================================================================
1337
1338void BRepFill_CompatibleWires::ComputeOrigin(const Standard_Boolean polar )
1339{
1340 // reorganize the wires respecting orientation and origin
1341
1342 TopoDS_Vertex Vdeb, Vfin;
1343 gp_Pnt Pdeb, Psuiv, PPs;
1344
1345 BRepTools_WireExplorer anExp;
1346
1347 Standard_Boolean wClosed, allClosed = Standard_True;
1348
1349 Standard_Integer NbSects = myWork.Length();
1350 Standard_Integer i, ideb=1,ifin=NbSects;
1351
1352 // sections ponctuelles, sections bouclantes
1353 if (myDegen1) ideb++;
1354 if (myDegen2) ifin--;
1355 Standard_Boolean vClosed = (!myDegen1) && (!myDegen2)
1356 && (myWork(ideb).IsSame(myWork(ifin)));
1357
1358
1359 for (i=ideb; i<=ifin; i++) {
1360 wClosed = myWork(i).Closed();
1361 if (!wClosed) {
1362 // on regarde quand meme si les vertex sont les memes.
1363 TopoDS_Vertex V1, V2;
1364 TopExp::Vertices(TopoDS::Wire(myWork(i)),V1,V2);
1365 if ( V1.IsSame(V2)) wClosed = Standard_True;
1366 }
1367 allClosed = (allClosed && wClosed);
1368 }
1369/*
1370 for (i=ideb; i<=ifin; i++) {
1371 allClosed = (allClosed && myWork(i).Closed());
1372 }
1373*/
1374 if (!allClosed)
1375 Standard_NoSuchObject::Raise("BRepFill_CompatibleWires::ComputeOrigin : the wires must be closed");
1376
1377/*
1378 // Nombre max de decoupes possibles
1379 Standard_Integer NbMaxV = 0;
1380 for (i=1; i<=NbSects; i++) {
1381 for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next()) {
1382 NbMaxV++;
1383 }
1384 }
1385
1386 // construction des tableaux de plans des wires
1387 gp_Pln P;
1388 Handle(TColgp_HArray1OfPnt) Pos
1389 = new (TColgp_HArray1OfPnt) (1,NbSects);
1390 Handle(TColgp_HArray1OfVec) Axe
1391 = new (TColgp_HArray1OfVec) (1,NbSects);
1392 for (i=ideb;i<=ifin;i++) {
1393 if (PlaneOfWire(TopoDS::Wire(myWork(i)),P)) {
1394 Pos->SetValue(i,P.Location());
1395 Axe->SetValue(i,gp_Vec(P.Axis().Direction()));
1396 }
1397 }
1398 TopTools_SequenceOfShape SeqV;
1399 if (myDegen1) {
1400 SeqOfVertices(TopoDS::Wire(myWork(1)),SeqV);
1401 Pos->SetValue(1,BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(1))));
1402 Axe->SetValue(1,Axe->Value(ideb));
1403 }
1404 if (myDegen2) {
1405 SeqOfVertices(TopoDS::Wire(myWork(NbSects)),SeqV);
1406 Pos->SetValue(NbSects,BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(1))));
1407 Axe->SetValue(NbSects,Axe->Value(ifin));
1408 }
1409*/
1410
1411 //Consider that all wires have same number of edges (polar==Standard_False)
1412 TopTools_SequenceOfShape PrevSeq;
1413 Standard_Integer theLength = 0;
1414 const TopoDS_Wire& wire = TopoDS::Wire( myWork(ideb) );
1415 for (anExp.Init(wire); anExp.More(); anExp.Next())
1416 {
1417 PrevSeq.Append(anExp.CurrentVertex());
1418 theLength++;
1419 }
1420
1421 for (i = ideb+1; i <= ifin; i++)
1422 {
1423 const TopoDS_Wire& wire = TopoDS::Wire(myWork(i));
1424 TopoDS_Wire newwire;
1425 BRep_Builder BB;
1426 BB.MakeWire(newwire);
1427
1428 TopTools_SequenceOfShape SeqVertices, SeqEdges;
1429 for (anExp.Init(wire); anExp.More(); anExp.Next())
1430 {
1431 SeqVertices.Append( anExp.CurrentVertex() );
1432 SeqEdges.Append( anExp.Current() );
1433 }
1434
1435 Standard_Real MinSumDist = Precision::Infinite();
1436 Standard_Integer jmin, j, k, n;
1437 Standard_Boolean forward;
1438 if (i == myWork.Length() && myDegen2)
1439 {
1440 // derniere section ponctuelle
1441 jmin = 1;
1442 forward = Standard_True;
1443 }
1444 else
1445 for (j = 1; j <= theLength; j++)
1446 {
1447 //Forward
1448 Standard_Real SumDist = 0.;
1449 for (k = j, n = 1; k <= theLength; k++, n++)
1450 {
1451 const TopoDS_Vertex& Vprev = TopoDS::Vertex( PrevSeq(n) );
1452 gp_Pnt Pprev = BRep_Tool::Pnt(Vprev);
1453 const TopoDS_Vertex& V = TopoDS::Vertex( SeqVertices(k) );
1454 gp_Pnt P = BRep_Tool::Pnt(V);
1455 SumDist += Pprev.Distance(P);
1456 }
1457 for (k = 1; k < j; k++, n++)
1458 {
1459 const TopoDS_Vertex& Vprev = TopoDS::Vertex( PrevSeq(n) );
1460 gp_Pnt Pprev = BRep_Tool::Pnt(Vprev);
1461 const TopoDS_Vertex& V = TopoDS::Vertex( SeqVertices(k) );
1462 gp_Pnt P = BRep_Tool::Pnt(V);
1463 SumDist += Pprev.Distance(P);
1464 }
1465 if (SumDist < MinSumDist)
1466 {
1467 MinSumDist = SumDist;
1468 jmin = j;
1469 forward = Standard_True;
1470 }
1471
1472 //Backward
1473 SumDist = 0.;
1474 for (k = j, n = 1; k >= 1; k--, n++)
1475 {
1476 const TopoDS_Vertex& Vprev = TopoDS::Vertex( PrevSeq(n) );
1477 gp_Pnt Pprev = BRep_Tool::Pnt(Vprev);
1478 const TopoDS_Vertex& V = TopoDS::Vertex( SeqVertices(k) );
1479 gp_Pnt P = BRep_Tool::Pnt(V);
1480 SumDist += Pprev.Distance(P);
1481 }
1482 for (k = theLength; k > j; k--, n++)
1483 {
1484 const TopoDS_Vertex& Vprev = TopoDS::Vertex( PrevSeq(n) );
1485 gp_Pnt Pprev = BRep_Tool::Pnt(Vprev);
1486 const TopoDS_Vertex& V = TopoDS::Vertex( SeqVertices(k) );
1487 gp_Pnt P = BRep_Tool::Pnt(V);
1488 SumDist += Pprev.Distance(P);
1489 }
1490 if (SumDist < MinSumDist)
1491 {
1492 MinSumDist = SumDist;
1493 jmin = j;
1494 forward = Standard_False;
1495 }
1496 }
1497
1498 PrevSeq.Clear();
1499 if (forward)
1500 {
1501 for (j = jmin; j <= theLength; j++)
1502 {
1503 BB.Add( newwire, TopoDS::Edge(SeqEdges(j)) );
1504 PrevSeq.Append( SeqVertices(j) );
1505 }
1506 for (j = 1; j < jmin; j++)
1507 {
1508 BB.Add( newwire, TopoDS::Edge(SeqEdges(j)) );
1509 PrevSeq.Append( SeqVertices(j) );
1510 }
1511 }
1512 else
1513 {
1514 for (j = jmin-1; j >= 1; j--)
1515 {
1516 TopoDS_Shape aLocalShape = SeqEdges(j).Reversed();
1517 BB.Add( newwire, TopoDS::Edge(aLocalShape) );
1518 //PrevSeq.Append( SeqVertices(j) );
1519 }
1520 for (j = theLength; j >= jmin; j--)
1521 {
1522 TopoDS_Shape aLocalShape = SeqEdges(j).Reversed();
1523 BB.Add( newwire, TopoDS::Edge(aLocalShape) );
1524 //PrevSeq.Append( SeqVertices(j) );
1525 }
1526 for (j = jmin; j >= 1; j--)
1527 PrevSeq.Append( SeqVertices(j) );
1528 for (j = theLength; j > jmin; j--)
1529 PrevSeq.Append( SeqVertices(j) );
1530 }
1531
1532 newwire.Closed( Standard_True );
1533 newwire.Orientation( TopAbs_FORWARD );
1534 myWork(i) = newwire;
1535 }
1536
1537/*
1538 for ( i=ideb; i<=myWork.Length(); i++) {
1539
1540 const TopoDS_Wire& wire = TopoDS::Wire(myWork(i));
1541
1542 Standard_Integer nbEdges=0;
1543 for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next())
1544 nbEdges++;
1545 TopExp::Vertices(wire,Vdeb,Vfin);
1546 Standard_Boolean wClosed = wire.Closed();
1547 if (!wClosed) {
1548 // on regarde quand meme si les vertex sont les memes.
1549 if ( Vdeb.IsSame(Vfin)) wClosed = Standard_True;
1550 }
1551
1552
1553 TopoDS_Vertex Vsuiv, VF, VR;
1554 TopoDS_Wire newwire;
1555 BRep_Builder BW;
1556 BW.MakeWire(newwire);
1557 if (i==ideb) {
1558 anExp.Init(wire);
1559 const TopoDS_Edge Ecur = TopoDS::Edge(anExp.Current());
1560 TopExp::Vertices(Ecur,VF,VR);
1561 if (Vdeb.IsSame(VF)) Vsuiv=VR;
1562 else if (Vdeb.IsSame(VR)) Vsuiv=VF;
1563 else {
1564 // par defaut on prend l'origine sur cette arete
1565 if (VR.IsSame(TopoDS::Vertex(anExp.CurrentVertex()))) {
1566 Vdeb = VR;
1567 Vsuiv = VF;
1568 }
1569 else {
1570 Vdeb = VF;
1571 Vsuiv = VR;
1572 }
1573 }
1574 Pdeb=BRep_Tool::Pnt(Vdeb);
1575 Psuiv=BRep_Tool::Pnt(Vsuiv);
1576 Standard_Real U1 = BRep_Tool::Parameter(Vdeb,Ecur);
1577 Standard_Real U2 = BRep_Tool::Parameter(Vsuiv,Ecur);
1578 BRepAdaptor_Curve Curve(Ecur);
1579 PPs = Curve.Value(0.25*(U1+3*U2));
1580 myWork(ideb) = wire;
1581 }
1582 else {
1583 // on ramene Pdeb, Psuiv et PPs dans le plan courant
1584 gp_Pnt Pnew,Pnext,PPn;
1585 Transform(Standard_True,Pdeb,Pos->Value(i-1),Axe->Value(i-1),
1586 Pos->Value(i),Axe->Value(i),Pnew);
1587 Transform(Standard_True,Psuiv,Pos->Value(i-1),Axe->Value(i-1),
1588 Pos->Value(i),Axe->Value(i),Pnext);
1589 Transform(Standard_True,PPs,Pos->Value(i-1),Axe->Value(i-1),
1590 Pos->Value(i),Axe->Value(i),PPn);
1591
1592 Standard_Real distmini,dist;
1593 Standard_Integer rang=0,rangdeb=0;
1594 TopoDS_Vertex Vmini;
1595 gp_Pnt Pmini,P1,P2;
1596 SeqOfVertices(wire,SeqV);
1597 if (SeqV.Length()>NbMaxV)
1598 Standard_NoSuchObject::Raise("BRepFill::ComputeOrigin failed");
1599 if (!polar) {
1600 // choix du vertex le plus proche comme origine
1601 distmini = Precision::Infinite();
1602 for (Standard_Integer ii=1;ii<=SeqV.Length();ii++) {
1603 P1 = BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(ii)));
1604 dist = P1.Distance(Pnew);
1605 if (dist<distmini) {
1606 distmini = dist;
1607 Vmini = TopoDS::Vertex(SeqV.Value(ii));
1608 }
1609 }
1610 if (!Vmini.IsNull()) Pmini = BRep_Tool::Pnt(Vmini);
1611 }
1612 else {
1613
1614 // recherche du vertex correspondant a la projection conique
1615 Standard_Real angmin, angV, eta = Precision::Angular();
1616 TopoDS_Vertex Vopti;
1617 angmin = PI/2;
1618 distmini = Precision::Infinite();
1619 gp_Dir dir0(gp_Vec(Pnew,P.Location()));
1620 for (Standard_Integer ii=1;ii<=SeqV.Length();ii++) {
1621 P1 = BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(ii)));
1622 dist = Pnew.Distance(P1);
1623 if (dist<Precision::Confusion()) {
1624 angV = 0.0;
1625 }
1626 else {
1627 gp_Dir dir1(gp_Vec(Pnew,P1));
1628 angV = dir1.Angle(dir0);
1629 }
1630 if (angV>PI/2) angV = PI - angV;
1631 if (angmin>angV+eta) {
1632 distmini = dist;
1633 angmin = angV;
1634 Vopti = TopoDS::Vertex(SeqV.Value(ii));
1635 }
1636 else if (Abs(angmin-angV)<eta) {
1637 if (dist<distmini) {
1638 distmini = dist;
1639 angmin = angV;
1640 Vopti = TopoDS::Vertex(SeqV.Value(ii));
1641 }
1642 }
1643 }
1644 gp_Pnt Popti;
1645 if (!Vopti.IsNull()) Popti = BRep_Tool::Pnt(Vopti);
1646 Vmini = Vopti;
1647
1648 }
1649
1650 distmini = Precision::Infinite();
1651 for (anExp.Init(wire); anExp.More(); anExp.Next()) {
1652 TopoDS_Edge Ecur = anExp.Current();
1653 TopoDS_Vertex Vcur = anExp.CurrentVertex();
1654 TopExp::Vertices(Ecur,VF,VR);
1655 if (VF.IsSame(Vmini)) {
1656 P1 = BRep_Tool::Pnt(VR);
1657 dist = P1.Distance(Pnext);
1658 if (dist<=distmini) {
1659 distmini = dist;
1660 Vsuiv = VR;
1661 }
1662 }
1663 if (VR.IsSame(Vmini)) {
1664 P1 = BRep_Tool::Pnt(VF);
1665 dist = P1.Distance(Pnext);
1666 if (dist<distmini) {
1667 distmini = dist;
1668 Vsuiv = VF;
1669 }
1670 }
1671 }
1672
1673 // choix du sens de parcours en fonction de Pnext
1674 Standard_Boolean parcours = Standard_False;
1675 if (i==myWork.Length() && myDegen2) {
1676 // derniere section ponctuelle
1677 rangdeb = 1;
1678 parcours = Standard_True;
1679 }
1680 else {
1681 // cas general
1682 gp_Pnt Pbout = Pnext;
1683 TopoDS_Edge E1,E2;
1684 TopoDS_Vertex V1,V2;
1685 EdgesFromVertex(wire,Vmini,E1,E2);
1686
1687 TopExp::Vertices(E1,V1,V2,Standard_True);
1688#ifndef DEB
1689 Standard_Real U1=0, U2=0;
1690#else
1691 Standard_Real U1, U2;
1692#endif
1693 if (Vmini.IsSame(V1)) {
1694 P1 = BRep_Tool::Pnt(V2);
1695 U1 = 0.25*(BRep_Tool::Parameter(V1,E1)+3*BRep_Tool::Parameter(V2,E1));
1696 }
1697 if (Vmini.IsSame(V2)) {
1698 P1 = BRep_Tool::Pnt(V1);
1699 U1 = 0.25*(3*BRep_Tool::Parameter(V1,E1)+BRep_Tool::Parameter(V2,E1));
1700 }
1701
1702 TopExp::Vertices(E2,V1,V2,Standard_True);
1703 if (Vmini.IsSame(V1)) {
1704 P2 = BRep_Tool::Pnt(V2);
1705 U2 = 0.25*(BRep_Tool::Parameter(V1,E2)+3*BRep_Tool::Parameter(V2,E2));
1706 }
1707 if (Vmini.IsSame(V2)) {
1708 P2 = BRep_Tool::Pnt(V1);
1709 U2 = 0.25*(3*BRep_Tool::Parameter(V1,E2)+BRep_Tool::Parameter(V2,E2));
1710 }
1711
1712 if (Abs(Pbout.Distance(P1)-Pbout.Distance(P2))<Precision::Confusion()) {
1713 // cas limite ; on se decale un peu
1714 Pbout = PPn;
1715 BRepAdaptor_Curve Curve1(E1);
1716 P1 = Curve1.Value(U1);
1717 BRepAdaptor_Curve Curve2(E2);
1718 P2 = Curve2.Value(U2);
1719 }
1720
1721 // calcul de rangdeb
1722 rangdeb = 0;
1723 if (Pbout.Distance(P1)<Pbout.Distance(P2)){
1724 // P1 est plus proche; parcours = False
1725 parcours = Standard_False;
1726 rang = 0;
1727 for (anExp.Init(wire); anExp.More(); anExp.Next()) {
1728 rang++;
1729 TopoDS_Edge Ecur = anExp.Current();
1730 if (E1.IsSame(Ecur)) {
1731 rangdeb = rang;
1732 }
1733 }
1734 BRepAdaptor_Curve Curve(E1);
1735 PPs = Curve.Value(U1);
1736 }
1737 else {
1738 // P2 est plus proche; parcours = True
1739 parcours = Standard_True;
1740 rang = 0;
1741 for (anExp.Init(wire); anExp.More(); anExp.Next()) {
1742 rang++;
1743 TopoDS_Edge Ecur = anExp.Current();
1744 if (E2.IsSame(Ecur)) {
1745 rangdeb = rang;
1746 }
1747 }
1748 BRepAdaptor_Curve Curve(E2);
1749 PPs = Curve.Value(U2);
1750 }
1751 }
1752
1753 // reconstruction du wire a partir de rangdeb
1754 TopTools_SequenceOfShape SeqEdges;
1755 SeqEdges.Clear();
1756 for (anExp.Init(TopoDS::Wire(wire)); anExp.More(); anExp.Next()) {
1757 SeqEdges.Append(anExp.Current());
1758 }
1759 if (parcours) {
1760 for (rang=rangdeb;rang<=nbEdges;rang++) {
1761 BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang)));
1762 }
1763 for (rang=1;rang<rangdeb;rang++) {
1764 BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang)));
1765 }
1766 }
1767 else {
1768 for (rang=rangdeb;rang>=1;rang--) {
1769 TopoDS_Shape aLocalShape = SeqEdges.Value(rang).Reversed();
1770 BW.Add(newwire,TopoDS::Edge(aLocalShape));
1771// BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang).Reversed()));
1772 }
1773 for (rang=nbEdges;rang>rangdeb;rang--) {
1774 TopoDS_Shape aLocalShape = SeqEdges.Value(rang).Reversed();
1775 BW.Add(newwire,TopoDS::Edge(aLocalShape));
1776// BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang).Reversed()));
1777 }
1778 }
1779
1780 myWork(i) = newwire.Oriented(TopAbs_FORWARD);
1781
1782 // on passe au wire suivant
1783 if (!Vmini.IsNull()) Pdeb=BRep_Tool::Pnt(Vmini);
1784 if (!Vsuiv.IsNull()) Psuiv=BRep_Tool::Pnt(Vsuiv);
1785 }
1786 }
1787*/
1788
1789 // sections bouclantes ?
1790 if (vClosed) myWork(myWork.Length()) = myWork(1);
1791}
1792
1793//=======================================================================
1794//function : SearchOrigin
1795//purpose :
1796//=======================================================================
1797
1798void BRepFill_CompatibleWires::SearchOrigin()
1799{
1800 // reorganize the open wires respecting orientation and origin
1801
1802 gp_Pln P0,P;
1803
1804 TopoDS_Vertex Vdeb, Vfin;
1805 gp_Pnt Pdeb, Pfin;//,Psuiv;
1806
1807 BRepTools_WireExplorer anExp;
1808
1809 Standard_Boolean allOpen = Standard_True;
1810 Standard_Integer ideb=1, ifin=myWork.Length();
1811 if (myDegen1) ideb++;
1812 if (myDegen2) ifin--;
1813 Standard_Boolean vClosed = (!myDegen1) && (!myDegen2)
1814 && (myWork(ideb).IsSame(myWork(ifin)));
1815
1816// for (Standard_Integer i=ideb; i<=ifin; i++) {
1817 Standard_Integer i;
1818 for (i=ideb; i<=ifin; i++) {
1819 allOpen = (allOpen && !myWork(i).Closed());
1820 }
1821 if (!allOpen)
1822 Standard_NoSuchObject::Raise("BRepFill_CompatibleWires::SearchOrigin : the wires must be open");
1823
1824 // init
1825
1826 TopoDS_Wire wire1 = TopoDS::Wire(myWork(ideb));
1827 wire1.Orientation(TopAbs_FORWARD);
1828 TopExp::Vertices(wire1,Vdeb,Vfin);
1829 Pdeb = BRep_Tool::Pnt(Vdeb);
1830 Pfin = BRep_Tool::Pnt(Vfin);
1831 Standard_Boolean isline0 = (!PlaneOfWire(wire1,P0)), isline;
1832 myWork(ideb) = wire1;
1833 //OCC86
1834 anExp.Init(wire1);
1835 TopoDS_Edge E0 = anExp.Current(), E;
1836
1837 for ( i=ideb+1; i<=ifin; i++) {
1838
1839 TopoDS_Wire wire = TopoDS::Wire(myWork(i));
1840 wire.Orientation(TopAbs_FORWARD);
1841
1842 TopTools_SequenceOfShape SeqEdges;
1843 SeqEdges.Clear();
1844 Standard_Integer nbEdges=0;
1845 //OCC86 for(anExp.Init(wire); anExp.More(); anExp.Next()) {
1846 for(anExp.Init(wire), E = anExp.Current(); anExp.More(); anExp.Next()) {
1847 SeqEdges.Append(anExp.Current());
1848 nbEdges++;
1849 }
1850 TopExp::Vertices(wire,Vdeb,Vfin);
1851 isline = (!PlaneOfWire(wire,P));
1852
1853 TopoDS_Vertex Vmini;
1854 TopoDS_Wire newwire;
1855 BRep_Builder BW;
1856 BW.MakeWire(newwire);
1857 Standard_Boolean parcours = Standard_True;
1858
1859 if (isline0 || isline) {
1860
1861 // cas particulier des segments de droite
1862 gp_Pnt P1 = BRep_Tool::Pnt(Vdeb),
1863 P2 = BRep_Tool::Pnt(Vfin);
1864 Standard_Real dist1, dist2;
1865 dist1 = Pdeb.Distance(P1)+Pfin.Distance(P2);
1866 dist2 = Pdeb.Distance(P2)+Pfin.Distance(P1);
1867 parcours = (dist2>=dist1);
1868 }
1869
1870 else {
1871 //OCC86
1872 gp_Pnt P1 = BRep_Tool::Pnt(Vdeb), P1o = Pdeb,
1873 P2 = BRep_Tool::Pnt(Vfin), P2o = Pfin;
1874/* // on ramene Pdeb dans le plan courant
1875 gp_Pnt Pnew = Pdeb.Translated (P0.Location(),P.Location());
1876 gp_Ax1 A0 = P0.Axis();
1877 gp_Ax1 A1 = P.Axis();
1878
1879 if (!A0.IsParallel(A1,1.e-4)) {
1880 gp_Vec vec1(A0.Direction()), vec2(A1.Direction()),
1881 norm = vec1 ^ vec2;
1882 gp_Ax1 Norm(P.Location(),norm);
1883 Standard_Real ang = vec1.AngleWithRef(vec2,norm);
1884 if (ang > PI/2.0)
1885 ang = PI - ang;
1886 if (ang < -PI/2.0)
1887 ang = -PI - ang;
1888 if (Abs(ang-PI/2.0)<Precision::Angular()) {
1889 // cas d'ambiguite
1890 gp_Vec Vtrans(P0.Location(),P.Location()),Vsign;
1891 Standard_Real alpha,beta,sign=1;
1892 Vsign.SetLinearForm(Vtrans.Dot(vec1),vec2,-Vtrans.Dot(vec2),vec1);
1893 alpha = Vsign.Dot(vec1);
1894 beta = Vsign.Dot(vec2);
1895 Standard_Boolean pasnul = (Abs(alpha)>1.e-4 && Abs(beta)>1.e-4);
1896 if ( alpha*beta>0.0 && pasnul ) sign=-1;
1897 ang *= sign;
1898 }
1899 Pnew = Pnew.Rotated (Norm,ang);
1900 }
1901 // choix entre Vdeb et Vfin
1902 Standard_Real dist = Pnew.Distance(P1);
1903 parcours = (dist<Pnew.Distance(P2));
1904*/
1905 if(P1.IsEqual(P2,Precision::Confusion()) || P1o.IsEqual(P2o,Precision::Confusion())){
1906 BRepAdaptor_Curve Curve0(E0), Curve(E);
1907 Curve0.D0(Curve0.FirstParameter() + Precision::Confusion(), P2o);
1908 Curve.D0(Curve.FirstParameter() + Precision::Confusion(), P2);
1909 };
1910 gp_Vec VDebFin0(P1o,P2o), VDebFin(P1,P2);
1911 Standard_Real AStraight = VDebFin0.Angle(VDebFin);
1912 parcours = (AStraight < PI/2.0? Standard_True: Standard_False);
1913 }
1914
1915 // reconstruction du wire
1916 Standard_Integer rang;
1917 if (parcours) {
1918 for (rang=1;rang<=nbEdges;rang++) {
1919 TopoDS_Shape alocalshape = SeqEdges.Value(rang);
1920 BW.Add(newwire,TopoDS::Edge(alocalshape));
1921// BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang)));
1922 }
1923 }
1924 else {
1925 for (rang=nbEdges;rang>=1;rang--) {
1926 TopoDS_Shape alocalshape = SeqEdges.Value(rang).Reversed();
1927 BW.Add(newwire,TopoDS::Edge(alocalshape));
1928// BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang).Reversed()));
1929 }
1930 }
1931
1932 // orientation du wire
1933 newwire.Oriented(TopAbs_FORWARD);
1934 myWork(i) = newwire;
1935
1936 // on passe au wire suivant
1937 if (parcours) {
1938 Pdeb = BRep_Tool::Pnt(Vdeb);
1939 Pfin = BRep_Tool::Pnt(Vfin);
1940 }
1941 else {
1942 Pfin = BRep_Tool::Pnt(Vdeb);
1943 Pdeb = BRep_Tool::Pnt(Vfin);
1944 }
1945 P0 = P;
1946 isline0 = isline;
1947 //OCC86
1948 E0 = E;
1949 }
1950
1951 // sections bouclantes ?
1952 if (vClosed) myWork(myWork.Length()) = myWork(1);
1953}
1954
1955
1956
1957
1958
1959
1960
1961