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