0022627: Change OCCT memory management defaults
[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>
d7325741 16#include <BRepCheck_Wire.hxx>
7fd59977 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) {
b2342827 84 // consecutive numbers
7fd59977 85 if (I2==I1+1) {
86 E1 = e1;
87 E2 = e2;
88 }
89 else {
90 E1 = e2;
91 E2 = e1;
92 }
93 }
94 else {
b2342827 95 // non consecutive numbers on a closed wire
7fd59977 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
b2342827
Y
136// shielding for particular cases : only one edge circle or ellipse
137// on a closed wire !
7fd59977 138 Standard_Integer nbEdges = 0;
139 BRepTools_WireExplorer anExp;
140 anExp.Init(W);
141 Standard_Boolean wClosed = W.Closed();
142 if (!wClosed) {
b2342827 143 // it is checked if the vertices are the same.
7fd59977 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 {
b2342827 179 // wire not plane !
7fd59977 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) {
b2342827 294 // from first to last
7fd59977 295 m0 = first;
296 V0 = Vf;
297 for (j=1; j<=ndec; j++) {
b2342827 298 // piece of edge
7fd59977 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) {
b2342827 306 // last piece
7fd59977 307 TopoDS_Edge LastE = BRepLib_MakeEdge(C,V0,Vl,m0,last);
308 LastE.Orientation(CurrentOrient);
309 S.Append(LastE);
310 }
311 }
312 }
313 else {
b2342827 314 // from last to first
7fd59977 315 m1 = last;
316 V1 = Vl;
317 for (j=ndec; j>=1; j--) {
b2342827 318 // piece of edge
7fd59977 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) {
b2342827 326 // last piece
7fd59977 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
b2342827 404 // construction of the edge of intersection
7fd59977 405 Standard_Boolean NewVertex = Standard_False;
406 gp_Lin droite(P1,gp_Dir(gp_Vec(P1,P2)));
b2342827
Y
407 // ATTENTION : it is required to construct a half-straight
408 // but there is a bug in BRepExtrema_DistShapeShape
409 // it is enough to take 100 * distance between P1 and P2
410 // hoping that it is enough until the bug is corrected
7fd59977 411 // Standard_Real dernierparam = Precision::Infinite();
b2342827
Y
412 // ATTENTION : return !!
413 // 100 is better than 10 but it is too much !
414 // finally, nothing is better than a blocking box
7fd59977 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
b2342827 426 // calculate the intersection by BRepExtrema (point of min distance)
7fd59977 427 BRepExtrema_DistShapeShape DSS(ME.Edge(),W);
428 if (DSS.IsDone()) {
b2342827 429 // choose the solution closest to P2
7fd59977 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);
b2342827 442 // is the solution a new vertex ?
7fd59977 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 }
b2342827 461 // check
7fd59977 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
b2342827 473 // it is required to cut the edge
7fd59977 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));
7fd59977 478 Standard_Real first,last,param;
479 DSS.ParOnEdgeS2(isol,param);
480 BRep_Tool::Range(E,first,last);
481 BRepLib_MakeWire MW;
482 for (anExp.Init(W); anExp.More(); anExp.Next()) {
483 if (E.IsSame(anExp.Current())) {
484 Standard_Boolean SO
485 = (anExp.CurrentVertex().IsSame(TopExp::FirstVertex(E)));
486 TopTools_SequenceOfShape SE;
487 SE.Clear();
488 TColStd_SequenceOfReal SR;
489 SR.Clear();
490 SR.Append(param);
491 TrimEdge(E,SR,first,last,SO,SE);
492 TopoDS_Vertex VV1,VV2;
493 TopExp::Vertices(TopoDS::Edge(SE.Value(1)),VV1,VV2);
494 if (TopExp::FirstVertex(E).IsSame(VV1)
495 || TopExp::LastVertex(E).IsSame(VV1)) {
496 Vsol = VV2;
497 }
498 if (TopExp::FirstVertex(E).IsSame(VV2)
499 || TopExp::LastVertex(E).IsSame(VV2)) {
500 Vsol = VV1;
501 }
502 for (Standard_Integer k=1; k<=SE.Length(); k++) {
503 MW.Add(TopoDS::Edge(SE.Value(k)));
504 }
505 }
506 else {
507 MW.Add(anExp.Current());
508 }
509 }
510 newW = MW.Wire();
511 }
512 else {
513 newW = W;
514 }
515
516
517 }
518
519 return NewVertex;
520
521}
522
523
524static void Transform (const Standard_Boolean WithRotation,
525 const gp_Pnt& P,
526 const gp_Pnt& Pos1,
527 const gp_Vec& Ax1,
528 const gp_Pnt& Pos2,
529 const gp_Vec& Ax2,
530 gp_Pnt& Pnew)
531{
532
533 Pnew = P.Translated (Pos1,Pos2);
534 gp_Vec axe1 = Ax1, axe2 = Ax2;
535 if (!axe1.IsParallel(axe2,1.e-4)) {
536 gp_Vec Vtrans(Pos1,Pos2),Vsign;
537 Standard_Real alpha,beta,sign=1;
538 alpha = Vtrans.Dot(axe1);
539 beta = Vtrans.Dot(axe2);
540 if (alpha<-1.e-7) axe1 *=-1;
541 if (beta<1.e-7) axe2 *=-1;
542 alpha = Vtrans.Dot(axe1);
543 beta = Vtrans.Dot(axe2);
544 gp_Vec norm2 = axe1 ^ axe2;
545 Vsign.SetLinearForm(Vtrans.Dot(axe1),axe2,-Vtrans.Dot(axe2),axe1);
546 alpha = Vsign.Dot(axe1);
547 beta = Vsign.Dot(axe2);
548 Standard_Boolean pasnul = (Abs(alpha)>1.e-4 && Abs(beta)>1.e-4);
549 if ( alpha*beta>0.0 && pasnul ) sign=-1;
550 gp_Ax1 Norm(Pos2,norm2);
551 Standard_Real ang = axe1.AngleWithRef(axe2,norm2);
552 if (!WithRotation) {
c6541a0c
D
553 if (ang>M_PI/2) ang = ang - M_PI;
554 if (ang<-M_PI/2) ang = ang + M_PI;
7fd59977 555 }
556 ang *= sign;
557 Pnew = Pnew.Rotated (Norm,ang);
558 }
559}
560
561static void BuildConnectedEdges(const TopoDS_Wire& aWire,
562 const TopoDS_Edge& StartEdge,
563 const TopoDS_Vertex& StartVertex,
564 TopTools_ListOfShape& ConnectedEdges)
565{
566 TopTools_IndexedDataMapOfShapeListOfShape MapVE;
567 TopExp::MapShapesAndAncestors(aWire, TopAbs_VERTEX, TopAbs_EDGE, MapVE);
568 TopoDS_Edge CurEdge = StartEdge;
569 TopoDS_Vertex CurVertex = StartVertex;
570 TopoDS_Vertex Origin, V1, V2;
571 TopExp::Vertices(StartEdge, V1, V2);
572 Origin = (V1.IsSame(StartVertex))? V2 : V1;
573
574 for (;;)
575 {
576 TopTools_ListIteratorOfListOfShape itE( MapVE.FindFromKey(CurVertex) );
577 for (; itE.More(); itE.Next())
578 {
579 TopoDS_Edge anEdge = TopoDS::Edge(itE.Value());
580 if (!anEdge.IsSame(CurEdge))
581 {
582 ConnectedEdges.Append(anEdge);
583 TopExp::Vertices(anEdge, V1, V2);
584 CurVertex = (V1.IsSame(CurVertex))? V2 : V1;
585 CurEdge = anEdge;
586 break;
587 }
588 }
589 if (CurVertex.IsSame(Origin))
590 break;
591 }
592}
593
594//=======================================================================
595//function : BRepFill_CompatibleWires
596//purpose :
597//=======================================================================
598
599BRepFill_CompatibleWires::BRepFill_CompatibleWires()
600:myIsDone(Standard_False)
601{
602}
603
604
605//=======================================================================
606//function : BRepFill_CompatibleWires
607//purpose :
608//=======================================================================
609
610BRepFill_CompatibleWires::BRepFill_CompatibleWires(const TopTools_SequenceOfShape& Sections)
611{
612 Init(Sections);
613}
614
615
616//=======================================================================
617//function : Init
618//purpose :
619//=======================================================================
620
621void BRepFill_CompatibleWires::Init(const TopTools_SequenceOfShape& Sections)
622{
623 myInit = Sections;
624 myWork = Sections;
625 myPercent = 0.01;
626 myIsDone = Standard_False;
627 myMap.Clear();
628
629}
630
631
632//=======================================================================
633//function : SetPercent
634//purpose :
635//=======================================================================
636
637void BRepFill_CompatibleWires::SetPercent(const Standard_Real Percent)
638{
639 if (0.<Percent && Percent<1.) myPercent = Percent;
640
641}
642
643
644//=======================================================================
645//function : IsDone
646//purpose :
647//=======================================================================
648
649Standard_Boolean BRepFill_CompatibleWires::IsDone() const
650{
651 return myIsDone;
652}
653
654
655//=======================================================================
656//function : Shape
657//purpose :
658//=======================================================================
659
660const TopTools_SequenceOfShape& BRepFill_CompatibleWires::Shape() const
661{
662 return myWork;
663}
664
665
666//=======================================================================
667//function : GeneratedShapes
668//purpose :
669//=======================================================================
670
671const TopTools_ListOfShape& BRepFill_CompatibleWires::GeneratedShapes
672(const TopoDS_Edge& SubSection) const
673{
674
675 if (myMap.IsBound(SubSection)) {
676 return myMap(SubSection);
677 }
678 else {
679 static TopTools_ListOfShape Empty;
680 return Empty;
681 }
682}
683
684
685//=======================================================================
686//function : Perform
687//purpose :
688//=======================================================================
689
690void BRepFill_CompatibleWires::Perform (const Standard_Boolean WithRotation)
691{
692 // compute origin and orientation on wires to avoid twisted results
693 // and update wires to have same number of edges
694
b2342827
Y
695 // determination of report:
696 // if the number of elements is the same and if the wires have discontinuities
697 // by tangency, the report is not carried out by curvilinear abscissa
7fd59977 698 Standard_Integer nbSects = myWork.Length(), i;
699 BRepTools_WireExplorer anExp;
700 Standard_Integer nbmax=0, nbmin=0;
701 TColStd_Array1OfInteger nbEdges(1,nbSects);
702 Standard_Boolean report;
703 GeomAbs_Shape contS=GeomAbs_CN;
704 GeomAbs_Shape cont;
705 for (i=1; i<=nbSects; i++) {
706 TopoDS_Shape aLocalShape = myWork(i).Oriented(TopAbs_FORWARD);
707 myWork(i) = TopoDS::Wire(aLocalShape);
708// myWork(i) = TopoDS::Wire(myWork(i).Oriented(TopAbs_FORWARD));
709 TopoDS_Wire W = TopoDS::Wire(myWork(i));
710 WireContinuity(W,cont);
711 if (cont<contS) contS=cont;
712 nbEdges(i) = 0;
713 for(anExp.Init(W); anExp.More(); anExp.Next() ) nbEdges(i)++;
714 if (i==1) nbmin = nbEdges(i);
715 if (nbmax<nbEdges(i)) nbmax = nbEdges(i);
716 if (nbmin>nbEdges(i)) nbmin = nbEdges(i);
717 }
b2342827
Y
718 // if the number of elements is not the same or if all wires are at least
719 // C1, the report is carried out by curvilinear abscissa of cuts, otherwise
720 // a report vertex / Vertex is done
7fd59977 721 report = (nbmax != nbmin || contS >= GeomAbs_C1 );
722
b2342827 723 // initialization of the map
7fd59977 724 Standard_Integer nbE = 0;
725 TopTools_ListOfShape Empty;
726 for (i=1; i<=nbSects; i++) {
727 TopoDS_Wire W = TopoDS::Wire(myWork(i));
728 for(anExp.Init(W); anExp.More(); anExp.Next() ) {
729 TopoDS_Edge E = TopoDS::Edge(anExp.Current());
730 myMap.Bind(E,Empty);
731 myMap(E).Append(E);
732 nbE++;
733 }
734 }
735
b2342827
Y
736 // open/closed sections
737 // initialisation of myDegen1, myDegen2
7fd59977 738 Standard_Integer ideb=1, ifin=myWork.Length();
b2342827 739 // check if the first wire is punctual
7fd59977 740 myDegen1 = Standard_True;
741 for(anExp.Init(TopoDS::Wire(myWork(ideb))); anExp.More(); anExp.Next()) {
742 myDegen1 = myDegen1 && (BRep_Tool::Degenerated(anExp.Current()));
743 }
744 if (myDegen1) ideb++;
b2342827 745 // check if the last wire is punctual
7fd59977 746 myDegen2 = Standard_True;
747 for(anExp.Init(TopoDS::Wire(myWork(ifin))); anExp.More(); anExp.Next()) {
748 myDegen2 = myDegen2 && (BRep_Tool::Degenerated(anExp.Current()));
749 }
750 if (myDegen2) ifin--;
751
752 Standard_Boolean wClosed, allClosed = Standard_True, allOpen = Standard_True;
753 for (i=ideb; i<=ifin; i++) {
754 wClosed = myWork(i).Closed();
755 if (!wClosed) {
b2342827 756 // check if the vertices are the same.
7fd59977 757 TopoDS_Vertex V1, V2;
758 TopExp::Vertices(TopoDS::Wire(myWork(i)),V1,V2);
759 if ( V1.IsSame(V2)) wClosed = Standard_True;
760 }
761 allClosed = (allClosed && wClosed);
762 allOpen = (allOpen && !wClosed);
763 }
764
765 if (allClosed) {
b2342827 766 // All sections are closed
7fd59977 767 if (report) {
768 // same number of elements
769 SameNumberByPolarMethod(WithRotation);
770 }
771 else {
b2342827 772 // origin
7fd59977 773 ComputeOrigin(Standard_False);
774 }
775 myIsDone = Standard_True;
776 }
777 else if (allOpen) {
b2342827
Y
778 // All sections are open
779 // origin
7fd59977 780 SearchOrigin();
781 // same number of elements
782 if (report) {
783 SameNumberByACR(report);
784 }
785 myIsDone = Standard_True;
786 }
787 else {
b2342827
Y
788 // There are open and closed sections :
789 // not processed
7fd59977 790 Standard_DomainError::Raise("Sections must be all closed or all open");
791 }
792
793}
794
795
796
797
798//=======================================================================
799//function : Generated
800//purpose :
801//=======================================================================
802
803const TopTools_DataMapOfShapeListOfShape& BRepFill_CompatibleWires::Generated() const
804{
805 return myMap;
806}
807
808
809//=======================================================================
810//function : SameNumberByPolarMethod
811//purpose :
812//=======================================================================
813
814void BRepFill_CompatibleWires::
815 SameNumberByPolarMethod(const Standard_Boolean WithRotation)
816{
817
818 // initialisation
819 Standard_Integer NbSects=myWork.Length();
820 BRepTools_WireExplorer anExp;
821 TopoDS_Vertex V1, V2;
822
823 Standard_Boolean allClosed = Standard_True;
824 Standard_Integer i,ii,ideb=1,ifin=NbSects;
825 for (i=1; i<=NbSects; i++) {
d7325741
J
826 Handle(BRepCheck_Wire) Checker = new BRepCheck_Wire(TopoDS::Wire(myWork(i)));
827 allClosed = (allClosed && (Checker->Closed() == BRepCheck_NoError));
828 //allClosed = (allClosed && myWork(i).Closed());
7fd59977 829 }
830 if (!allClosed)
831 Standard_NoSuchObject::Raise("BRepFill_CompatibleWires::SameNumberByPolarMethod : the wires must be closed");
832
0a0cf813 833 // sections ponctuelles, sections bouclantes ?
834 if (myDegen1) ideb++;
835 if (myDegen2) ifin--;
836 Standard_Boolean vClosed = (!myDegen1) && (!myDegen2)
837 && (myWork(ideb).IsSame(myWork(ifin)));
838
839 //Removing degenerated edges
840 for (i = ideb; i <= ifin; i++)
841 {
842 Standard_Boolean hasDegEdge = Standard_False;
843 TopoDS_Iterator anItw(myWork(i));
844 for (; anItw.More(); anItw.Next())
845 {
846 const TopoDS_Edge& anEdge = TopoDS::Edge(anItw.Value());
847 if (BRep_Tool::Degenerated(anEdge))
848 {
849 hasDegEdge = Standard_True;
850 break;
851 }
852 }
853 if (hasDegEdge)
854 {
855 TopoDS_Wire aNewWire;
856 BRep_Builder aBBuilder;
857 aBBuilder.MakeWire(aNewWire);
858 for (anItw.Initialize(myWork(i)); anItw.More(); anItw.Next())
859 {
860 const TopoDS_Edge& anEdge = TopoDS::Edge(anItw.Value());
861 if (!BRep_Tool::Degenerated(anEdge))
862 aBBuilder.Add(aNewWire, anEdge);
863 }
864 myWork(i) = aNewWire;
865 }
866 }
867
7fd59977 868 // Nombre max de decoupes possibles
869 Standard_Integer NbMaxV = 0;
870 for (i=1; i<=NbSects; i++) {
871 for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next()) {
872 NbMaxV++;
873 }
874 }
875
b2342827 876 // construction of tables of planes of wires
7fd59977 877 gp_Pln P;
878 Handle(TColgp_HArray1OfPnt) Pos
879 = new (TColgp_HArray1OfPnt) (1,NbSects);
880 Handle(TColgp_HArray1OfVec) Axe
881 = new (TColgp_HArray1OfVec) (1,NbSects);
882 for (i=ideb;i<=ifin;i++) {
883 if (PlaneOfWire(TopoDS::Wire(myWork(i)),P)) {
884 Pos->SetValue(i,P.Location());
885 Axe->SetValue(i,gp_Vec(P.Axis().Direction()));
886 }
887 }
888 TopTools_SequenceOfShape SeqV;
889 if (myDegen1) {
890 SeqOfVertices(TopoDS::Wire(myWork(1)),SeqV);
891 Pos->SetValue(1,BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(1))));
892 Axe->SetValue(1,Axe->Value(ideb));
893 }
894 if (myDegen2) {
895 SeqOfVertices(TopoDS::Wire(myWork(NbSects)),SeqV);
896 Pos->SetValue(NbSects,BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(1))));
897 Axe->SetValue(NbSects,Axe->Value(ifin));
898 }
899
b2342827 900 // construction of RMap, map of reports of wire i to wire i-1
7fd59977 901 TopTools_DataMapOfShapeListOfShape RMap;
902 RMap.Clear();
903
b2342827 904 // loop on i
7fd59977 905 for (i=ifin; i>ideb; i--) {
906
907 const TopoDS_Wire& wire1 = TopoDS::Wire(myWork(i));
908
b2342827 909 // sequence of vertices of the first wire
7fd59977 910 SeqOfVertices(wire1,SeqV);
911 if (SeqV.Length()>NbMaxV)
912 Standard_NoSuchObject::Raise("BRepFill::SameNumberByPolarMethod failed");
913
b2342827 914 // extremity of the first wire
7fd59977 915 V1 = TopoDS::Vertex(SeqV.Value(1));
b2342827 916 // previous wire
7fd59977 917#ifdef DEB
918 const TopoDS_Wire& wire2 =
919#endif
920 TopoDS::Wire(myWork(i-1));
b2342827 921 // loop on vertices of wire1
7fd59977 922 for (ii=1;ii<=SeqV.Length();ii++) {
923
924 TopoDS_Vertex Vi = TopoDS::Vertex(SeqV.Value(ii));
925
b2342827 926 // init of RMap for Vi
7fd59977 927 TopTools_ListOfShape Init;
928 Init.Clear();
929 RMap.Bind(Vi,Init);
930
b2342827 931 // it is required to find intersection Vi - wire2
7fd59977 932 gp_Pnt Pi = BRep_Tool::Pnt(Vi);
933
b2342827 934 // return Pi in the current plane
7fd59977 935 gp_Pnt Pnew;
936 Transform(WithRotation,Pi,
937 Pos->Value(i),Axe->Value(i),
938 Pos->Value(i-1),Axe->Value(i-1),Pnew);
939
b2342827 940 // calculate the intersection
7fd59977 941 TopoDS_Shape Support;
942 Standard_Boolean NewVertex;
943 TopoDS_Vertex Vsol;
944 TopoDS_Wire newwire;
945 if (Pnew.Distance(Pos->Value(i-1))>Precision::Confusion()) {
946 Standard_Real percent = myPercent;
947 NewVertex = EdgeIntersectOnWire(Pos->Value(i-1),Pnew,percent,
948 RMap,TopoDS::Wire(myWork(i-1)),
949 Vsol,newwire);
950 if (NewVertex) myWork(i-1) = newwire;
951 RMap(Vi).Append(Vsol);
952 }
953
b2342827
Y
954 } // loop on ii
955 } // loop on i
7fd59977 956
b2342827 957 // initialisation of MapVLV, map of correspondences vertex - list of vertices
7fd59977 958 TopTools_DataMapOfShapeListOfShape MapVLV;
959 SeqOfVertices(TopoDS::Wire(myWork(ideb)),SeqV);
960 Standard_Integer SizeMap = SeqV.Length();
961 MapVLV.Clear();
962 for (ii=1;ii<=SizeMap;ii++) {
963 TopoDS_Vertex Vi = TopoDS::Vertex(SeqV.Value(ii));
964 TopTools_ListOfShape Init;
965 Init.Clear();
966 Init.Append(Vi);
967 MapVLV.Bind(Vi,Init);
968 Standard_Integer NbV = 1;
969 TopoDS_Vertex V0,V1;
970 V0 = Vi;
971 Standard_Boolean tantque = SearchRoot(V0,RMap,V1);
972 while (tantque) {
973 MapVLV(Vi).Append(V1);
974 NbV++;
b2342827 975 // test on NbV required for looping sections
7fd59977 976 if (V1.IsSame(Vi) || NbV >= myWork.Length()) {
977 tantque = Standard_False;
978 }
979 else {
980 V0 = V1;
981 tantque = SearchRoot(V0,RMap,V1);
982 }
983 }
984 }
985
b2342827 986 // loop on i
7fd59977 987 for (i=ideb; i<ifin; i++) {
988
989 const TopoDS_Wire& wire1 = TopoDS::Wire(myWork(i));
990
b2342827 991 // sequence of vertices of the first wire
7fd59977 992 SeqOfVertices(wire1,SeqV);
993 if ( SeqV.Length()>NbMaxV || SeqV.Length()>SizeMap )
994 Standard_NoSuchObject::Raise("BRepFill::SameNumberByPolarMethod failed");
995
b2342827 996 // extremity of the first wire
7fd59977 997 V1 = TopoDS::Vertex(SeqV.Value(1));
998
b2342827 999 // next wire
7fd59977 1000 const TopoDS_Wire& wire2 = TopoDS::Wire(myWork(i+1));
1001
b2342827 1002 // loop on vertices of wire1
7fd59977 1003 for (ii=1;ii<=SeqV.Length();ii++) {
1004
1005 TopoDS_Vertex Vi = TopoDS::Vertex(SeqV.Value(ii));
1006 TopoDS_Vertex VRoot;
1007 VRoot.Nullify();
1008 Standard_Boolean intersect = Standard_True;
1009 if (SearchRoot(Vi,MapVLV,VRoot)) {
1010 const TopTools_ListOfShape& LVi = MapVLV(VRoot);
1011 TopoDS_Vertex VonW;
1012 VonW.Nullify();
1013 intersect = (!SearchVertex(LVi,wire2,VonW));
1014 }
1015
1016 if (intersect) {
b2342827 1017 // it is necessary to find intersection Vi - wire2
7fd59977 1018 gp_Pnt Pi = BRep_Tool::Pnt(Vi);
1019
b2342827 1020 // return Pi in the current plane
7fd59977 1021 gp_Pnt Pnew;
1022 Transform(WithRotation,Pi,
1023 Pos->Value(i),Axe->Value(i),
1024 Pos->Value(i+1),Axe->Value(i+1),Pnew);
1025
b2342827 1026 // calculate the intersection
7fd59977 1027 TopoDS_Shape Support;
1028 Standard_Boolean NewVertex;
1029 TopoDS_Vertex Vsol;
1030 TopoDS_Wire newwire;
1031 if (Pnew.Distance(Pos->Value(i+1))>Precision::Confusion()) {
1032 Standard_Real percent = myPercent;
1033 NewVertex = EdgeIntersectOnWire(Pos->Value(i+1),Pnew,percent,
1034 MapVLV,TopoDS::Wire(myWork(i+1)),
1035 Vsol,newwire);
1036 MapVLV(VRoot).Append(Vsol);
1037 if (NewVertex) myWork(i+1) = newwire;
1038 }
1039
1040 }
b2342827
Y
1041 } // loop on ii
1042 } // loop on i
7fd59977 1043
b2342827 1044 // regularize wires following MapVLV
7fd59977 1045 TopoDS_Wire wire = TopoDS::Wire(myWork(ideb));
1046
b2342827 1047 // except for the last if the sections loop
7fd59977 1048 Standard_Integer ibout = ifin;
1049 if (vClosed) ibout--;
1050
1051 for ( i=ideb+1; i<=ibout; i++) {
1052
1053 BRepLib_MakeWire MW;
1054
1055 anExp.Init(wire);
1056 TopoDS_Edge ECur = anExp.Current();
1057 TopoDS_Vertex VF,VL;
1058 TopExp::Vertices(ECur,VF,VL,Standard_True);
1059 Standard_Real U1 = BRep_Tool::Parameter(VF,ECur);
1060 Standard_Real U2 = BRep_Tool::Parameter(VL,ECur);
1061 BRepAdaptor_Curve Curve(ECur);
1062 gp_Pnt PPs = Curve.Value(0.1*(U1+9*U2));
1063 TopTools_ListIteratorOfListOfShape itF(MapVLV(VF)),itL(MapVLV(VL));
1064 Standard_Integer rang = ideb;
1065 while (rang < i) {
1066 itF.Next();
1067 itL.Next();
1068 rang++;
1069 }
1070 TopoDS_Vertex V1 = TopoDS::Vertex(itF.Value()), V2 = TopoDS::Vertex(itL.Value());
1071 TopoDS_Edge Esol;
1072 Standard_Real scalmax=0.;
1073 TopoDS_Iterator itW( myWork(i) );
1074
1075 for(; itW.More(); itW.Next())
1076 {
1077 TopoDS_Edge E = TopoDS::Edge(itW.Value());
1078 TopoDS_Vertex VVF,VVL;
1079 TopExp::Vertices(E,VVF,VVL,Standard_True);
1080
b2342827 1081 // parse candidate edges
7fd59977 1082 Standard_Real scal1,scal2;
1083 if ( (V1.IsSame(VVF)&&V2.IsSame(VVL)) || (V2.IsSame(VVF)&&V1.IsSame(VVL)) ) {
1084 Standard_Real U1 = BRep_Tool::Parameter(VVF,E);
1085 Standard_Real U2 = BRep_Tool::Parameter(VVL,E);
1086 BRepAdaptor_Curve Curve(E);
1087 gp_Pnt PP1 = Curve.Value(0.1*(U1+9*U2));
1088 gp_Pnt PP2 = Curve.Value(0.1*(9*U1+U2));
1089
1090 for (rang=i;rang>ideb;rang--) {
1091 Transform(WithRotation, PP1,
1092 Pos->Value(rang), Axe->Value(rang),
1093 Pos->Value(rang-1), Axe->Value(rang-1), PP1);
1094 Transform(WithRotation, PP2,
1095 Pos->Value(rang), Axe->Value(rang),
1096 Pos->Value(rang-1), Axe->Value(rang-1), PP2);
1097 }
1098 gp_Vec Ns(Pos->Value(ideb),PPs);
1099 Ns = Ns.Normalized();
1100 gp_Vec N1(Pos->Value(ideb),PP1);
1101 N1 = N1.Normalized();
1102 gp_Vec N2(Pos->Value(ideb),PP2);
1103 N2 = N2.Normalized();
1104 scal1 = N1.Dot(Ns);
1105 if (scal1>scalmax) {
1106 scalmax = scal1;
1107 Esol = E;
1108 }
1109 scal2 = N2.Dot(Ns);
1110 if (scal2>scalmax) {
1111 scalmax = scal2;
1112 TopoDS_Shape aLocalShape = E.Reversed();
1113 Esol = TopoDS::Edge(aLocalShape);
1114 }
1115 }
1116 } //end of for(; itW.More(); itW.Next())
1117 MW.Add(Esol);
1118
1119 TopTools_ListOfShape ConnectedEdges;
1120 BuildConnectedEdges( TopoDS::Wire(myWork(i)), Esol, V2, ConnectedEdges );
1121
1122 TopTools_ListIteratorOfListOfShape itCE(ConnectedEdges);
1123 for(; anExp.More(), itCE.More(); anExp.Next(), itCE.Next())
1124 {
1125 ECur = anExp.Current();
1126 TopExp::Vertices(ECur,VF,VL,Standard_True);
1127 U1 = BRep_Tool::Parameter(VF,ECur);
1128 U2 = BRep_Tool::Parameter(VL,ECur);
1129 Curve.Initialize(ECur);
1130 PPs = Curve.Value(0.1*(U1+9*U2));
1131
1132 TopoDS_Edge E = TopoDS::Edge(itCE.Value());
1133 TopoDS_Vertex VVF,VVL;
1134 TopExp::Vertices(E,VVF,VVL,Standard_True);
1135
b2342827 1136 // parse candidate edges
7fd59977 1137 Standard_Real scal1,scal2;
1138 U1 = BRep_Tool::Parameter(VVF,E);
1139 U2 = BRep_Tool::Parameter(VVL,E);
1140 Curve.Initialize(E);
1141 gp_Pnt PP1 = Curve.Value(0.1*(U1+9*U2));
1142 gp_Pnt PP2 = Curve.Value(0.1*(9*U1+U2));
1143
1144 for (rang=i;rang>ideb;rang--) {
1145 Transform(WithRotation, PP1,
1146 Pos->Value(rang), Axe->Value(rang),
1147 Pos->Value(rang-1), Axe->Value(rang-1), PP1);
1148 Transform(WithRotation, PP2,
1149 Pos->Value(rang), Axe->Value(rang),
1150 Pos->Value(rang-1), Axe->Value(rang-1), PP2);
1151 }
1152 gp_Vec Ns(Pos->Value(ideb),PPs);
1153 Ns = Ns.Normalized();
1154 gp_Vec N1(Pos->Value(ideb),PP1);
1155 N1 = N1.Normalized();
1156 gp_Vec N2(Pos->Value(ideb),PP2);
1157 N2 = N2.Normalized();
1158 scal1 = N1.Dot(Ns);
1159 scal2 = N2.Dot(Ns);
1160 if (scal2>scal1)
1161 E.Reverse();
1162 MW.Add(E);
1163 }
1164 myWork(i) = MW.Wire();
1165 }
1166
b2342827 1167 // blocking sections?
7fd59977 1168 if (vClosed) myWork(myWork.Length()) = myWork(1);
1169
b2342827 1170 // check the number of edges for debug
7fd59977 1171 Standard_Integer nbmax=0, nbmin=0;
1172 for ( i=ideb; i<=ifin; i++) {
1173 Standard_Integer nbEdges=0;
1174 for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next()) {
1175 nbEdges++;
1176 }
1177 if (i==ideb) nbmin = nbEdges;
1178 if (nbmax<nbEdges) nbmax = nbEdges;
1179 if (nbmin>nbEdges) nbmin = nbEdges;
1180 }
1181 if (nbmin!=nbmax) {
1182 Standard_NoSuchObject::Raise("BRepFill_CompatibleWires::SameNumberByPolarMethod failed");
1183 }
1184
1185}
1186
1187//=======================================================================
1188//function : SameNumberByACR
1189//purpose :
1190//=======================================================================
1191
1192void BRepFill_CompatibleWires::SameNumberByACR(const Standard_Boolean report)
1193{
1194 // find the dimension
1195 Standard_Integer ideb=1, ifin=myWork.Length();
1196 BRepTools_WireExplorer anExp;
1197
b2342827 1198 // point sections, blocking sections?
7fd59977 1199 if (myDegen1) ideb++;
1200 if (myDegen2) ifin--;
1201 Standard_Boolean vClosed = (!myDegen1) && (!myDegen2)
1202 && (myWork(ideb).IsSame(myWork(ifin)));
1203
1204 Standard_Integer nbSects = myWork.Length(), i;
1205 Standard_Integer nbmax=0, nbmin=0;
1206 TColStd_Array1OfInteger nbEdges(1,nbSects);
1207 for (i=1; i<=nbSects; i++) {
1208 nbEdges(i) = 0;
1209 for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next()) {
1210 nbEdges(i)++;
1211 }
1212 if (i==1) nbmin = nbEdges(i);
1213 if (nbmax<nbEdges(i)) nbmax = nbEdges(i);
1214 if (nbmin>nbEdges(i)) nbmin = nbEdges(i);
1215 }
1216
1217 if (nbmax>1) {
b2342827 1218 // several edges
7fd59977 1219
1220 if (report || nbmin<nbmax) {
b2342827 1221 // insertion of cuts
7fd59977 1222 Standard_Integer nbdec=(nbmax-1)*nbSects+1;
1223 Standard_Real tol = 0.01;
1224 TColStd_Array1OfReal dec(1,nbdec);
1225 dec.Init(0);
1226 dec(2)=1;
b2342827 1227 // calculate the table of cuts
7fd59977 1228 Standard_Integer j,k,l;
1229 for (i=1; i<=nbSects; i++) {
b2342827 1230 // current wire
7fd59977 1231 const TopoDS_Wire& wire1 = TopoDS::Wire(myWork(i));
1232 Standard_Integer nbE = 0;
1233 for(anExp.Init(wire1); anExp.More(); anExp.Next()) {
1234 nbE++;
1235 }
b2342827 1236 // length and ACR of the wire
7fd59977 1237 TColStd_Array1OfReal ACR(0,nbE);
1238 ACR.Init(0);
1239 BRepFill::ComputeACR(wire1, ACR);
b2342827 1240 // insertion of ACR of the wire in the table of cuts
7fd59977 1241 for (j=1; j<ACR.Length()-1; j++) {
1242 k=1;
1243 while (dec(k)<ACR(j)) {
1244 k++;
1245 if (k>nbdec) break;
1246 }
1247 if (dec(k-1)+tol<ACR(j)&& ACR(j)+tol<dec(k)) {
1248 for (l=nbdec-1;l>=k;l--) {
1249 dec(l+1)=dec(l);
1250 }
1251 dec(k) = ACR(j);
1252 }
1253 }
1254 }
1255
b2342827 1256 // table of cuts
7fd59977 1257 k=1;
1258 while (dec(k)<1) {
1259 k++;
1260 if (k>nbdec) break;
1261 }
1262 nbdec = k-1;
1263 TColStd_Array1OfReal dec2(1,nbdec);
1264 for (k=1;k<=nbdec;k++) {
1265 dec2(k) = dec(k);
1266 }
1267
b2342827 1268 // insertion of cuts in each wire
7fd59977 1269 for (i=1; i<=nbSects; i++) {
1270 const TopoDS_Wire& oldwire = TopoDS::Wire(myWork(i));
1271 TopoDS_Wire newwire = BRepFill::InsertACR(oldwire, dec2, tol);
1272 BRepTools_WireExplorer anExp1,anExp2;
1273 anExp1.Init(oldwire);
1274 anExp2.Init(newwire);
1275 for (;anExp1.More();anExp1.Next()) {
1276 const TopoDS_Edge& Ecur = anExp1.Current();
1277 if (!Ecur.IsSame(TopoDS::Edge(anExp2.Current()))) {
1278 TopTools_ListOfShape LE;
1279 LE.Clear();
1280 gp_Pnt P1,P2;
1281 const TopoDS_Vertex& V1 = anExp1.CurrentVertex();
1282 TopoDS_Vertex VF,VR;
1283 TopExp::Vertices(Ecur,VF,VR,Standard_True);
1284 if (V1.IsSame(VF)) P1 = BRep_Tool::Pnt(VR);
1285 if (V1.IsSame(VR)) P1 = BRep_Tool::Pnt(VF);
1286 TopoDS_Vertex V2 = anExp2.CurrentVertex();
1287 TopExp::Vertices(TopoDS::Edge(anExp2.Current()),
1288 VF,VR,Standard_True);
1289 if (V2.IsSame(VF)) P2 = BRep_Tool::Pnt(VR);
1290 if (V2.IsSame(VR)) P2 = BRep_Tool::Pnt(VF);
1291 while (P1.Distance(P2)>1.e-3) {
1292 LE.Append(anExp2.Current());
1293 anExp2.Next();
1294 V2 = anExp2.CurrentVertex();
1295 TopExp::Vertices(TopoDS::Edge(anExp2.Current()),
1296 VF,VR,Standard_True);
1297 if (V2.IsSame(VF)) P2 = BRep_Tool::Pnt(VR);
1298 if (V2.IsSame(VR)) P2 = BRep_Tool::Pnt(VF);
1299 if (P1.Distance(P2)<=1.e-3) {
1300 LE.Append(anExp2.Current());
1301 anExp2.Next();
1302 }
1303 }
1304
1305 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itmap;
1306 //TopTools_ListIteratorOfListOfShape itlist;
1307 TopoDS_Edge Ancestor;
1308 Standard_Integer nbedge, nblist=0;
1309 Standard_Boolean found = Standard_False;
1310
1311 for (itmap.Initialize(myMap);itmap.More()&&(!found);itmap.Next()) {
1312 nblist++;
1313 TopTools_ListIteratorOfListOfShape itlist(itmap.Value());
1314 nbedge = 0;
1315 while (itlist.More()&&(!found)) {
1316 nbedge++;
1317 TopoDS_Edge ECur = TopoDS::Edge(itlist.Value());
1318
1319 if (Ecur.IsSame(ECur)) {
1320 Ancestor = TopoDS::Edge(itmap.Key());
1321 found = Standard_True;
1322 myMap(Ancestor).InsertBefore(LE,itlist);
1323 myMap(Ancestor).Remove(itlist);
1324 }
1325 if (itlist.More()) itlist.Next();
1326 }
1327
1328 }
1329
1330 }
1331 else {
1332 anExp2.Next();
1333 }
1334
1335 }
1336 myWork(i) = newwire;
1337 }
1338
1339 }
1340 }
1341
b2342827 1342 // blocking sections ?
7fd59977 1343 if (vClosed) myWork(myWork.Length()) = myWork(1);
1344
b2342827 1345 // check the number of edges for debug
7fd59977 1346 nbmax = 0;
1347 for (i=ideb; i<=ifin; i++) {
1348 nbEdges(i) = 0;
1349 for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next()) {
1350 nbEdges(i)++;
1351 }
1352 if (i==ideb) nbmin = nbEdges(i);
1353 if (nbmax<nbEdges(i)) nbmax = nbEdges(i);
1354 if (nbmin>nbEdges(i)) nbmin = nbEdges(i);
1355 }
1356 if (nbmax!=nbmin)
1357 Standard_NoSuchObject::Raise("BRepFill_CompatibleWires::SameNumberByACR failed");
1358}
1359
1360//=======================================================================
1361//function : ComputeOrigin
1362//purpose :
1363//=======================================================================
1364
1365void BRepFill_CompatibleWires::ComputeOrigin(const Standard_Boolean polar )
1366{
1367 // reorganize the wires respecting orientation and origin
1368
1369 TopoDS_Vertex Vdeb, Vfin;
1370 gp_Pnt Pdeb, Psuiv, PPs;
1371
1372 BRepTools_WireExplorer anExp;
1373
1374 Standard_Boolean wClosed, allClosed = Standard_True;
1375
1376 Standard_Integer NbSects = myWork.Length();
1377 Standard_Integer i, ideb=1,ifin=NbSects;
1378
b2342827 1379 // point sections, blocking sections
7fd59977 1380 if (myDegen1) ideb++;
1381 if (myDegen2) ifin--;
1382 Standard_Boolean vClosed = (!myDegen1) && (!myDegen2)
1383 && (myWork(ideb).IsSame(myWork(ifin)));
1384
1385
1386 for (i=ideb; i<=ifin; i++) {
1387 wClosed = myWork(i).Closed();
1388 if (!wClosed) {
b2342827 1389 // check if the vertices are the same.
7fd59977 1390 TopoDS_Vertex V1, V2;
1391 TopExp::Vertices(TopoDS::Wire(myWork(i)),V1,V2);
1392 if ( V1.IsSame(V2)) wClosed = Standard_True;
1393 }
1394 allClosed = (allClosed && wClosed);
1395 }
1396/*
1397 for (i=ideb; i<=ifin; i++) {
1398 allClosed = (allClosed && myWork(i).Closed());
1399 }
1400*/
1401 if (!allClosed)
1402 Standard_NoSuchObject::Raise("BRepFill_CompatibleWires::ComputeOrigin : the wires must be closed");
1403
1404/*
b2342827 1405 // Max number of possible cuts
7fd59977 1406 Standard_Integer NbMaxV = 0;
1407 for (i=1; i<=NbSects; i++) {
1408 for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next()) {
1409 NbMaxV++;
1410 }
1411 }
1412
b2342827 1413 // construction of tables of planes of wires
7fd59977 1414 gp_Pln P;
1415 Handle(TColgp_HArray1OfPnt) Pos
1416 = new (TColgp_HArray1OfPnt) (1,NbSects);
1417 Handle(TColgp_HArray1OfVec) Axe
1418 = new (TColgp_HArray1OfVec) (1,NbSects);
1419 for (i=ideb;i<=ifin;i++) {
1420 if (PlaneOfWire(TopoDS::Wire(myWork(i)),P)) {
1421 Pos->SetValue(i,P.Location());
1422 Axe->SetValue(i,gp_Vec(P.Axis().Direction()));
1423 }
1424 }
1425 TopTools_SequenceOfShape SeqV;
1426 if (myDegen1) {
1427 SeqOfVertices(TopoDS::Wire(myWork(1)),SeqV);
1428 Pos->SetValue(1,BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(1))));
1429 Axe->SetValue(1,Axe->Value(ideb));
1430 }
1431 if (myDegen2) {
1432 SeqOfVertices(TopoDS::Wire(myWork(NbSects)),SeqV);
1433 Pos->SetValue(NbSects,BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(1))));
1434 Axe->SetValue(NbSects,Axe->Value(ifin));
1435 }
1436*/
1437
1438 //Consider that all wires have same number of edges (polar==Standard_False)
1439 TopTools_SequenceOfShape PrevSeq;
7ba3b47c 1440 TopTools_SequenceOfShape PrevEseq;
7fd59977 1441 Standard_Integer theLength = 0;
1442 const TopoDS_Wire& wire = TopoDS::Wire( myWork(ideb) );
1443 for (anExp.Init(wire); anExp.More(); anExp.Next())
1444 {
1445 PrevSeq.Append(anExp.CurrentVertex());
7ba3b47c 1446 PrevEseq.Append(anExp.Current());
7fd59977 1447 theLength++;
1448 }
1449
7ba3b47c
J
1450 Standard_Integer nbs, NbSamples = 0;
1451 if (theLength <= 2)
1452 NbSamples = 4;
7fd59977 1453 for (i = ideb+1; i <= ifin; i++)
1454 {
1455 const TopoDS_Wire& wire = TopoDS::Wire(myWork(i));
1456 TopoDS_Wire newwire;
1457 BRep_Builder BB;
1458 BB.MakeWire(newwire);
1459
1460 TopTools_SequenceOfShape SeqVertices, SeqEdges;
1461 for (anExp.Init(wire); anExp.More(); anExp.Next())
1462 {
1463 SeqVertices.Append( anExp.CurrentVertex() );
1464 SeqEdges.Append( anExp.Current() );
1465 }
1466
1467 Standard_Real MinSumDist = Precision::Infinite();
1468 Standard_Integer jmin, j, k, n;
1469 Standard_Boolean forward;
1470 if (i == myWork.Length() && myDegen2)
1471 {
b2342827 1472 // last point section
7fd59977 1473 jmin = 1;
1474 forward = Standard_True;
1475 }
1476 else
1477 for (j = 1; j <= theLength; j++)
1478 {
1479 //Forward
1480 Standard_Real SumDist = 0.;
1481 for (k = j, n = 1; k <= theLength; k++, n++)
1482 {
1483 const TopoDS_Vertex& Vprev = TopoDS::Vertex( PrevSeq(n) );
1484 gp_Pnt Pprev = BRep_Tool::Pnt(Vprev);
1485 const TopoDS_Vertex& V = TopoDS::Vertex( SeqVertices(k) );
1486 gp_Pnt P = BRep_Tool::Pnt(V);
1487 SumDist += Pprev.Distance(P);
7ba3b47c
J
1488 if (NbSamples > 0)
1489 {
1490 const TopoDS_Edge& PrevEdge = TopoDS::Edge(PrevEseq(n));
1491 const TopoDS_Edge& CurEdge = TopoDS::Edge(SeqEdges(k));
1492 BRepAdaptor_Curve PrevEcurve(PrevEdge);
1493 BRepAdaptor_Curve Ecurve(CurEdge);
1494 Standard_Real SampleOnPrev = (PrevEcurve.LastParameter()-PrevEcurve.FirstParameter())/NbSamples;
1495 Standard_Real SampleOnCur = (Ecurve.LastParameter()-Ecurve.FirstParameter())/NbSamples;
1496 for (nbs = 1; nbs <= NbSamples-1; nbs++)
1497 {
1498 Standard_Real ParOnPrev = (PrevEdge.Orientation() == TopAbs_FORWARD)?
1499 (PrevEcurve.FirstParameter() + nbs*SampleOnPrev) :
1500 (PrevEcurve.FirstParameter() + (NbSamples-nbs)*SampleOnPrev);
1501 Standard_Real ParOnCur = (CurEdge.Orientation() == TopAbs_FORWARD)?
1502 (Ecurve.FirstParameter() + nbs*SampleOnCur) :
1503 (Ecurve.FirstParameter() + (NbSamples-nbs)*SampleOnCur);
1504 gp_Pnt PonPrev = PrevEcurve.Value(ParOnPrev);
1505 gp_Pnt PonCur = Ecurve.Value(ParOnCur);
1506 SumDist += PonPrev.Distance(PonCur);
1507 }
1508 }
7fd59977 1509 }
1510 for (k = 1; k < j; k++, n++)
1511 {
1512 const TopoDS_Vertex& Vprev = TopoDS::Vertex( PrevSeq(n) );
1513 gp_Pnt Pprev = BRep_Tool::Pnt(Vprev);
1514 const TopoDS_Vertex& V = TopoDS::Vertex( SeqVertices(k) );
1515 gp_Pnt P = BRep_Tool::Pnt(V);
1516 SumDist += Pprev.Distance(P);
7ba3b47c
J
1517 if (NbSamples > 0)
1518 {
1519 const TopoDS_Edge& PrevEdge = TopoDS::Edge(PrevEseq(n));
1520 const TopoDS_Edge& CurEdge = TopoDS::Edge(SeqEdges(k));
1521 BRepAdaptor_Curve PrevEcurve(PrevEdge);
1522 BRepAdaptor_Curve Ecurve(CurEdge);
1523 Standard_Real SampleOnPrev = (PrevEcurve.LastParameter()-PrevEcurve.FirstParameter())/NbSamples;
1524 Standard_Real SampleOnCur = (Ecurve.LastParameter()-Ecurve.FirstParameter())/NbSamples;
1525 for (nbs = 1; nbs <= NbSamples-1; nbs++)
1526 {
1527 Standard_Real ParOnPrev = (PrevEdge.Orientation() == TopAbs_FORWARD)?
1528 (PrevEcurve.FirstParameter() + nbs*SampleOnPrev) :
1529 (PrevEcurve.FirstParameter() + (NbSamples-nbs)*SampleOnPrev);
1530 Standard_Real ParOnCur = (CurEdge.Orientation() == TopAbs_FORWARD)?
1531 (Ecurve.FirstParameter() + nbs*SampleOnCur) :
1532 (Ecurve.FirstParameter() + (NbSamples-nbs)*SampleOnCur);
1533 gp_Pnt PonPrev = PrevEcurve.Value(ParOnPrev);
1534 gp_Pnt PonCur = Ecurve.Value(ParOnCur);
1535 SumDist += PonPrev.Distance(PonCur);
1536 }
1537 }
7fd59977 1538 }
1539 if (SumDist < MinSumDist)
1540 {
1541 MinSumDist = SumDist;
1542 jmin = j;
1543 forward = Standard_True;
1544 }
1545
1546 //Backward
1547 SumDist = 0.;
1548 for (k = j, n = 1; k >= 1; k--, n++)
1549 {
1550 const TopoDS_Vertex& Vprev = TopoDS::Vertex( PrevSeq(n) );
1551 gp_Pnt Pprev = BRep_Tool::Pnt(Vprev);
1552 const TopoDS_Vertex& V = TopoDS::Vertex( SeqVertices(k) );
1553 gp_Pnt P = BRep_Tool::Pnt(V);
1554 SumDist += Pprev.Distance(P);
7ba3b47c
J
1555 if (NbSamples > 0)
1556 {
1557 Standard_Integer k_cur = k-1;
1558 if (k_cur == 0)
1559 k_cur = theLength;
1560 const TopoDS_Edge& PrevEdge = TopoDS::Edge(PrevEseq(n));
1561 const TopoDS_Edge& CurEdge = TopoDS::Edge(SeqEdges(k_cur));
1562 BRepAdaptor_Curve PrevEcurve(PrevEdge);
1563 BRepAdaptor_Curve Ecurve(CurEdge);
1564 Standard_Real SampleOnPrev = (PrevEcurve.LastParameter()-PrevEcurve.FirstParameter())/NbSamples;
1565 Standard_Real SampleOnCur = (Ecurve.LastParameter()-Ecurve.FirstParameter())/NbSamples;
1566 for (nbs = 1; nbs <= NbSamples-1; nbs++)
1567 {
1568 Standard_Real ParOnPrev = (PrevEdge.Orientation() == TopAbs_FORWARD)?
1569 (PrevEcurve.FirstParameter() + nbs*SampleOnPrev) :
1570 (PrevEcurve.FirstParameter() + (NbSamples-nbs)*SampleOnPrev);
1571 Standard_Real ParOnCur = (CurEdge.Orientation() == TopAbs_FORWARD)?
1572 (Ecurve.FirstParameter() + (NbSamples-nbs)*SampleOnCur) :
1573 (Ecurve.FirstParameter() + nbs*SampleOnCur);
1574 gp_Pnt PonPrev = PrevEcurve.Value(ParOnPrev);
1575 gp_Pnt PonCur = Ecurve.Value(ParOnCur);
1576 SumDist += PonPrev.Distance(PonCur);
1577 }
1578 }
7fd59977 1579 }
1580 for (k = theLength; k > j; k--, n++)
1581 {
1582 const TopoDS_Vertex& Vprev = TopoDS::Vertex( PrevSeq(n) );
1583 gp_Pnt Pprev = BRep_Tool::Pnt(Vprev);
1584 const TopoDS_Vertex& V = TopoDS::Vertex( SeqVertices(k) );
1585 gp_Pnt P = BRep_Tool::Pnt(V);
1586 SumDist += Pprev.Distance(P);
7ba3b47c
J
1587 if (NbSamples > 0)
1588 {
1589 const TopoDS_Edge& PrevEdge = TopoDS::Edge(PrevEseq(n));
1590 const TopoDS_Edge& CurEdge = TopoDS::Edge(SeqEdges(k-1));
1591 BRepAdaptor_Curve PrevEcurve(PrevEdge);
1592 BRepAdaptor_Curve Ecurve(CurEdge);
1593 Standard_Real SampleOnPrev = (PrevEcurve.LastParameter()-PrevEcurve.FirstParameter())/NbSamples;
1594 Standard_Real SampleOnCur = (Ecurve.LastParameter()-Ecurve.FirstParameter())/NbSamples;
1595 for (nbs = 1; nbs <= NbSamples-1; nbs++)
1596 {
1597 Standard_Real ParOnPrev = (PrevEdge.Orientation() == TopAbs_FORWARD)?
1598 (PrevEcurve.FirstParameter() + nbs*SampleOnPrev) :
1599 (PrevEcurve.FirstParameter() + (NbSamples-nbs)*SampleOnPrev);
1600 Standard_Real ParOnCur = (CurEdge.Orientation() == TopAbs_FORWARD)?
1601 (Ecurve.FirstParameter() + (NbSamples-nbs)*SampleOnCur) :
1602 (Ecurve.FirstParameter() + nbs*SampleOnCur);
1603 gp_Pnt PonPrev = PrevEcurve.Value(ParOnPrev);
1604 gp_Pnt PonCur = Ecurve.Value(ParOnCur);
1605 SumDist += PonPrev.Distance(PonCur);
1606 }
1607 }
7fd59977 1608 }
1609 if (SumDist < MinSumDist)
1610 {
1611 MinSumDist = SumDist;
1612 jmin = j;
1613 forward = Standard_False;
1614 }
1615 }
1616
1617 PrevSeq.Clear();
7ba3b47c 1618 PrevEseq.Clear();
7fd59977 1619 if (forward)
1620 {
1621 for (j = jmin; j <= theLength; j++)
1622 {
1623 BB.Add( newwire, TopoDS::Edge(SeqEdges(j)) );
1624 PrevSeq.Append( SeqVertices(j) );
7ba3b47c 1625 PrevEseq.Append( SeqEdges(j) );
7fd59977 1626 }
1627 for (j = 1; j < jmin; j++)
1628 {
1629 BB.Add( newwire, TopoDS::Edge(SeqEdges(j)) );
1630 PrevSeq.Append( SeqVertices(j) );
7ba3b47c 1631 PrevEseq.Append( SeqEdges(j) );
7fd59977 1632 }
1633 }
1634 else
1635 {
1636 for (j = jmin-1; j >= 1; j--)
1637 {
1638 TopoDS_Shape aLocalShape = SeqEdges(j).Reversed();
1639 BB.Add( newwire, TopoDS::Edge(aLocalShape) );
1640 //PrevSeq.Append( SeqVertices(j) );
7ba3b47c 1641 PrevEseq.Append( SeqEdges(j).Reversed() );
7fd59977 1642 }
1643 for (j = theLength; j >= jmin; j--)
1644 {
1645 TopoDS_Shape aLocalShape = SeqEdges(j).Reversed();
1646 BB.Add( newwire, TopoDS::Edge(aLocalShape) );
1647 //PrevSeq.Append( SeqVertices(j) );
7ba3b47c 1648 PrevEseq.Append( SeqEdges(j).Reversed() );
7fd59977 1649 }
1650 for (j = jmin; j >= 1; j--)
1651 PrevSeq.Append( SeqVertices(j) );
1652 for (j = theLength; j > jmin; j--)
1653 PrevSeq.Append( SeqVertices(j) );
1654 }
1655
1656 newwire.Closed( Standard_True );
1657 newwire.Orientation( TopAbs_FORWARD );
1658 myWork(i) = newwire;
1659 }
1660
1661/*
1662 for ( i=ideb; i<=myWork.Length(); i++) {
1663
1664 const TopoDS_Wire& wire = TopoDS::Wire(myWork(i));
1665
1666 Standard_Integer nbEdges=0;
1667 for(anExp.Init(TopoDS::Wire(myWork(i))); anExp.More(); anExp.Next())
1668 nbEdges++;
1669 TopExp::Vertices(wire,Vdeb,Vfin);
1670 Standard_Boolean wClosed = wire.Closed();
1671 if (!wClosed) {
1672 // on regarde quand meme si les vertex sont les memes.
1673 if ( Vdeb.IsSame(Vfin)) wClosed = Standard_True;
1674 }
1675
1676
1677 TopoDS_Vertex Vsuiv, VF, VR;
1678 TopoDS_Wire newwire;
1679 BRep_Builder BW;
1680 BW.MakeWire(newwire);
1681 if (i==ideb) {
1682 anExp.Init(wire);
1683 const TopoDS_Edge Ecur = TopoDS::Edge(anExp.Current());
1684 TopExp::Vertices(Ecur,VF,VR);
1685 if (Vdeb.IsSame(VF)) Vsuiv=VR;
1686 else if (Vdeb.IsSame(VR)) Vsuiv=VF;
1687 else {
1688 // par defaut on prend l'origine sur cette arete
1689 if (VR.IsSame(TopoDS::Vertex(anExp.CurrentVertex()))) {
1690 Vdeb = VR;
1691 Vsuiv = VF;
1692 }
1693 else {
1694 Vdeb = VF;
1695 Vsuiv = VR;
1696 }
1697 }
1698 Pdeb=BRep_Tool::Pnt(Vdeb);
1699 Psuiv=BRep_Tool::Pnt(Vsuiv);
1700 Standard_Real U1 = BRep_Tool::Parameter(Vdeb,Ecur);
1701 Standard_Real U2 = BRep_Tool::Parameter(Vsuiv,Ecur);
1702 BRepAdaptor_Curve Curve(Ecur);
1703 PPs = Curve.Value(0.25*(U1+3*U2));
1704 myWork(ideb) = wire;
1705 }
1706 else {
1707 // on ramene Pdeb, Psuiv et PPs dans le plan courant
1708 gp_Pnt Pnew,Pnext,PPn;
1709 Transform(Standard_True,Pdeb,Pos->Value(i-1),Axe->Value(i-1),
1710 Pos->Value(i),Axe->Value(i),Pnew);
1711 Transform(Standard_True,Psuiv,Pos->Value(i-1),Axe->Value(i-1),
1712 Pos->Value(i),Axe->Value(i),Pnext);
1713 Transform(Standard_True,PPs,Pos->Value(i-1),Axe->Value(i-1),
1714 Pos->Value(i),Axe->Value(i),PPn);
1715
1716 Standard_Real distmini,dist;
1717 Standard_Integer rang=0,rangdeb=0;
1718 TopoDS_Vertex Vmini;
1719 gp_Pnt Pmini,P1,P2;
1720 SeqOfVertices(wire,SeqV);
1721 if (SeqV.Length()>NbMaxV)
1722 Standard_NoSuchObject::Raise("BRepFill::ComputeOrigin failed");
1723 if (!polar) {
1724 // choix du vertex le plus proche comme origine
1725 distmini = Precision::Infinite();
1726 for (Standard_Integer ii=1;ii<=SeqV.Length();ii++) {
1727 P1 = BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(ii)));
1728 dist = P1.Distance(Pnew);
1729 if (dist<distmini) {
1730 distmini = dist;
1731 Vmini = TopoDS::Vertex(SeqV.Value(ii));
1732 }
1733 }
1734 if (!Vmini.IsNull()) Pmini = BRep_Tool::Pnt(Vmini);
1735 }
1736 else {
1737
1738 // recherche du vertex correspondant a la projection conique
1739 Standard_Real angmin, angV, eta = Precision::Angular();
1740 TopoDS_Vertex Vopti;
c6541a0c 1741 angmin = M_PI/2;
7fd59977 1742 distmini = Precision::Infinite();
1743 gp_Dir dir0(gp_Vec(Pnew,P.Location()));
1744 for (Standard_Integer ii=1;ii<=SeqV.Length();ii++) {
1745 P1 = BRep_Tool::Pnt(TopoDS::Vertex(SeqV.Value(ii)));
1746 dist = Pnew.Distance(P1);
1747 if (dist<Precision::Confusion()) {
1748 angV = 0.0;
1749 }
1750 else {
1751 gp_Dir dir1(gp_Vec(Pnew,P1));
1752 angV = dir1.Angle(dir0);
1753 }
c6541a0c 1754 if (angV>M_PI/2) angV = M_PI - angV;
7fd59977 1755 if (angmin>angV+eta) {
1756 distmini = dist;
1757 angmin = angV;
1758 Vopti = TopoDS::Vertex(SeqV.Value(ii));
1759 }
1760 else if (Abs(angmin-angV)<eta) {
1761 if (dist<distmini) {
1762 distmini = dist;
1763 angmin = angV;
1764 Vopti = TopoDS::Vertex(SeqV.Value(ii));
1765 }
1766 }
1767 }
1768 gp_Pnt Popti;
1769 if (!Vopti.IsNull()) Popti = BRep_Tool::Pnt(Vopti);
1770 Vmini = Vopti;
1771
1772 }
1773
1774 distmini = Precision::Infinite();
1775 for (anExp.Init(wire); anExp.More(); anExp.Next()) {
1776 TopoDS_Edge Ecur = anExp.Current();
1777 TopoDS_Vertex Vcur = anExp.CurrentVertex();
1778 TopExp::Vertices(Ecur,VF,VR);
1779 if (VF.IsSame(Vmini)) {
1780 P1 = BRep_Tool::Pnt(VR);
1781 dist = P1.Distance(Pnext);
1782 if (dist<=distmini) {
1783 distmini = dist;
1784 Vsuiv = VR;
1785 }
1786 }
1787 if (VR.IsSame(Vmini)) {
1788 P1 = BRep_Tool::Pnt(VF);
1789 dist = P1.Distance(Pnext);
1790 if (dist<distmini) {
1791 distmini = dist;
1792 Vsuiv = VF;
1793 }
1794 }
1795 }
1796
1797 // choix du sens de parcours en fonction de Pnext
1798 Standard_Boolean parcours = Standard_False;
1799 if (i==myWork.Length() && myDegen2) {
1800 // derniere section ponctuelle
1801 rangdeb = 1;
1802 parcours = Standard_True;
1803 }
1804 else {
1805 // cas general
1806 gp_Pnt Pbout = Pnext;
1807 TopoDS_Edge E1,E2;
1808 TopoDS_Vertex V1,V2;
1809 EdgesFromVertex(wire,Vmini,E1,E2);
1810
1811 TopExp::Vertices(E1,V1,V2,Standard_True);
1812#ifndef DEB
1813 Standard_Real U1=0, U2=0;
1814#else
1815 Standard_Real U1, U2;
1816#endif
1817 if (Vmini.IsSame(V1)) {
1818 P1 = BRep_Tool::Pnt(V2);
1819 U1 = 0.25*(BRep_Tool::Parameter(V1,E1)+3*BRep_Tool::Parameter(V2,E1));
1820 }
1821 if (Vmini.IsSame(V2)) {
1822 P1 = BRep_Tool::Pnt(V1);
1823 U1 = 0.25*(3*BRep_Tool::Parameter(V1,E1)+BRep_Tool::Parameter(V2,E1));
1824 }
1825
1826 TopExp::Vertices(E2,V1,V2,Standard_True);
1827 if (Vmini.IsSame(V1)) {
1828 P2 = BRep_Tool::Pnt(V2);
1829 U2 = 0.25*(BRep_Tool::Parameter(V1,E2)+3*BRep_Tool::Parameter(V2,E2));
1830 }
1831 if (Vmini.IsSame(V2)) {
1832 P2 = BRep_Tool::Pnt(V1);
1833 U2 = 0.25*(3*BRep_Tool::Parameter(V1,E2)+BRep_Tool::Parameter(V2,E2));
1834 }
1835
1836 if (Abs(Pbout.Distance(P1)-Pbout.Distance(P2))<Precision::Confusion()) {
1837 // cas limite ; on se decale un peu
1838 Pbout = PPn;
1839 BRepAdaptor_Curve Curve1(E1);
1840 P1 = Curve1.Value(U1);
1841 BRepAdaptor_Curve Curve2(E2);
1842 P2 = Curve2.Value(U2);
1843 }
1844
1845 // calcul de rangdeb
1846 rangdeb = 0;
1847 if (Pbout.Distance(P1)<Pbout.Distance(P2)){
1848 // P1 est plus proche; parcours = False
1849 parcours = Standard_False;
1850 rang = 0;
1851 for (anExp.Init(wire); anExp.More(); anExp.Next()) {
1852 rang++;
1853 TopoDS_Edge Ecur = anExp.Current();
1854 if (E1.IsSame(Ecur)) {
1855 rangdeb = rang;
1856 }
1857 }
1858 BRepAdaptor_Curve Curve(E1);
1859 PPs = Curve.Value(U1);
1860 }
1861 else {
1862 // P2 est plus proche; parcours = True
1863 parcours = Standard_True;
1864 rang = 0;
1865 for (anExp.Init(wire); anExp.More(); anExp.Next()) {
1866 rang++;
1867 TopoDS_Edge Ecur = anExp.Current();
1868 if (E2.IsSame(Ecur)) {
1869 rangdeb = rang;
1870 }
1871 }
1872 BRepAdaptor_Curve Curve(E2);
1873 PPs = Curve.Value(U2);
1874 }
1875 }
1876
1877 // reconstruction du wire a partir de rangdeb
1878 TopTools_SequenceOfShape SeqEdges;
1879 SeqEdges.Clear();
1880 for (anExp.Init(TopoDS::Wire(wire)); anExp.More(); anExp.Next()) {
1881 SeqEdges.Append(anExp.Current());
1882 }
1883 if (parcours) {
1884 for (rang=rangdeb;rang<=nbEdges;rang++) {
1885 BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang)));
1886 }
1887 for (rang=1;rang<rangdeb;rang++) {
1888 BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang)));
1889 }
1890 }
1891 else {
1892 for (rang=rangdeb;rang>=1;rang--) {
1893 TopoDS_Shape aLocalShape = SeqEdges.Value(rang).Reversed();
1894 BW.Add(newwire,TopoDS::Edge(aLocalShape));
1895// BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang).Reversed()));
1896 }
1897 for (rang=nbEdges;rang>rangdeb;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 }
1903
1904 myWork(i) = newwire.Oriented(TopAbs_FORWARD);
1905
1906 // on passe au wire suivant
1907 if (!Vmini.IsNull()) Pdeb=BRep_Tool::Pnt(Vmini);
1908 if (!Vsuiv.IsNull()) Psuiv=BRep_Tool::Pnt(Vsuiv);
1909 }
1910 }
1911*/
1912
b2342827 1913 // blocking sections ?
7fd59977 1914 if (vClosed) myWork(myWork.Length()) = myWork(1);
1915}
1916
1917//=======================================================================
1918//function : SearchOrigin
1919//purpose :
1920//=======================================================================
1921
1922void BRepFill_CompatibleWires::SearchOrigin()
1923{
1924 // reorganize the open wires respecting orientation and origin
1925
1926 gp_Pln P0,P;
1927
1928 TopoDS_Vertex Vdeb, Vfin;
1929 gp_Pnt Pdeb, Pfin;//,Psuiv;
1930
1931 BRepTools_WireExplorer anExp;
1932
1933 Standard_Boolean allOpen = Standard_True;
1934 Standard_Integer ideb=1, ifin=myWork.Length();
1935 if (myDegen1) ideb++;
1936 if (myDegen2) ifin--;
1937 Standard_Boolean vClosed = (!myDegen1) && (!myDegen2)
1938 && (myWork(ideb).IsSame(myWork(ifin)));
1939
1940// for (Standard_Integer i=ideb; i<=ifin; i++) {
1941 Standard_Integer i;
1942 for (i=ideb; i<=ifin; i++) {
1943 allOpen = (allOpen && !myWork(i).Closed());
1944 }
1945 if (!allOpen)
1946 Standard_NoSuchObject::Raise("BRepFill_CompatibleWires::SearchOrigin : the wires must be open");
1947
1948 // init
1949
1950 TopoDS_Wire wire1 = TopoDS::Wire(myWork(ideb));
1951 wire1.Orientation(TopAbs_FORWARD);
1952 TopExp::Vertices(wire1,Vdeb,Vfin);
1953 Pdeb = BRep_Tool::Pnt(Vdeb);
1954 Pfin = BRep_Tool::Pnt(Vfin);
1955 Standard_Boolean isline0 = (!PlaneOfWire(wire1,P0)), isline;
1956 myWork(ideb) = wire1;
1957 //OCC86
1958 anExp.Init(wire1);
1959 TopoDS_Edge E0 = anExp.Current(), E;
1960
1961 for ( i=ideb+1; i<=ifin; i++) {
1962
1963 TopoDS_Wire wire = TopoDS::Wire(myWork(i));
1964 wire.Orientation(TopAbs_FORWARD);
1965
1966 TopTools_SequenceOfShape SeqEdges;
1967 SeqEdges.Clear();
1968 Standard_Integer nbEdges=0;
1969 //OCC86 for(anExp.Init(wire); anExp.More(); anExp.Next()) {
1970 for(anExp.Init(wire), E = anExp.Current(); anExp.More(); anExp.Next()) {
1971 SeqEdges.Append(anExp.Current());
1972 nbEdges++;
1973 }
1974 TopExp::Vertices(wire,Vdeb,Vfin);
1975 isline = (!PlaneOfWire(wire,P));
1976
1977 TopoDS_Vertex Vmini;
1978 TopoDS_Wire newwire;
1979 BRep_Builder BW;
1980 BW.MakeWire(newwire);
1981 Standard_Boolean parcours = Standard_True;
1982
1983 if (isline0 || isline) {
1984
b2342827 1985 // particular case of straight segments
7fd59977 1986 gp_Pnt P1 = BRep_Tool::Pnt(Vdeb),
1987 P2 = BRep_Tool::Pnt(Vfin);
1988 Standard_Real dist1, dist2;
1989 dist1 = Pdeb.Distance(P1)+Pfin.Distance(P2);
1990 dist2 = Pdeb.Distance(P2)+Pfin.Distance(P1);
1991 parcours = (dist2>=dist1);
1992 }
1993
1994 else {
1995 //OCC86
1996 gp_Pnt P1 = BRep_Tool::Pnt(Vdeb), P1o = Pdeb,
1997 P2 = BRep_Tool::Pnt(Vfin), P2o = Pfin;
b2342827 1998/* // return Pdeb in the current plane
7fd59977 1999 gp_Pnt Pnew = Pdeb.Translated (P0.Location(),P.Location());
2000 gp_Ax1 A0 = P0.Axis();
2001 gp_Ax1 A1 = P.Axis();
2002
2003 if (!A0.IsParallel(A1,1.e-4)) {
2004 gp_Vec vec1(A0.Direction()), vec2(A1.Direction()),
2005 norm = vec1 ^ vec2;
2006 gp_Ax1 Norm(P.Location(),norm);
2007 Standard_Real ang = vec1.AngleWithRef(vec2,norm);
c6541a0c
D
2008 if (ang > M_PI/2.0)
2009 ang = M_PI - ang;
2010 if (ang < -M_PI/2.0)
2011 ang = -M_PI - ang;
2012 if (Abs(ang-M_PI/2.0)<Precision::Angular()) {
7fd59977 2013 // cas d'ambiguite
2014 gp_Vec Vtrans(P0.Location(),P.Location()),Vsign;
2015 Standard_Real alpha,beta,sign=1;
2016 Vsign.SetLinearForm(Vtrans.Dot(vec1),vec2,-Vtrans.Dot(vec2),vec1);
2017 alpha = Vsign.Dot(vec1);
2018 beta = Vsign.Dot(vec2);
2019 Standard_Boolean pasnul = (Abs(alpha)>1.e-4 && Abs(beta)>1.e-4);
2020 if ( alpha*beta>0.0 && pasnul ) sign=-1;
2021 ang *= sign;
2022 }
2023 Pnew = Pnew.Rotated (Norm,ang);
2024 }
2025 // choix entre Vdeb et Vfin
2026 Standard_Real dist = Pnew.Distance(P1);
2027 parcours = (dist<Pnew.Distance(P2));
2028*/
2029 if(P1.IsEqual(P2,Precision::Confusion()) || P1o.IsEqual(P2o,Precision::Confusion())){
2030 BRepAdaptor_Curve Curve0(E0), Curve(E);
2031 Curve0.D0(Curve0.FirstParameter() + Precision::Confusion(), P2o);
2032 Curve.D0(Curve.FirstParameter() + Precision::Confusion(), P2);
2033 };
2034 gp_Vec VDebFin0(P1o,P2o), VDebFin(P1,P2);
2035 Standard_Real AStraight = VDebFin0.Angle(VDebFin);
c6541a0c 2036 parcours = (AStraight < M_PI/2.0? Standard_True: Standard_False);
7fd59977 2037 }
2038
b2342827 2039 // reconstruction of the wire
7fd59977 2040 Standard_Integer rang;
2041 if (parcours) {
2042 for (rang=1;rang<=nbEdges;rang++) {
2043 TopoDS_Shape alocalshape = SeqEdges.Value(rang);
2044 BW.Add(newwire,TopoDS::Edge(alocalshape));
2045// BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang)));
2046 }
2047 }
2048 else {
2049 for (rang=nbEdges;rang>=1;rang--) {
2050 TopoDS_Shape alocalshape = SeqEdges.Value(rang).Reversed();
2051 BW.Add(newwire,TopoDS::Edge(alocalshape));
2052// BW.Add(newwire,TopoDS::Edge(SeqEdges.Value(rang).Reversed()));
2053 }
2054 }
2055
b2342827 2056 // orientation of the wire
7fd59977 2057 newwire.Oriented(TopAbs_FORWARD);
2058 myWork(i) = newwire;
2059
b2342827 2060 // passe to the next wire
7fd59977 2061 if (parcours) {
2062 Pdeb = BRep_Tool::Pnt(Vdeb);
2063 Pfin = BRep_Tool::Pnt(Vfin);
2064 }
2065 else {
2066 Pfin = BRep_Tool::Pnt(Vdeb);
2067 Pdeb = BRep_Tool::Pnt(Vfin);
2068 }
2069 P0 = P;
2070 isline0 = isline;
2071 //OCC86
2072 E0 = E;
2073 }
2074
b2342827 2075 // blocking sections ?
7fd59977 2076 if (vClosed) myWork(myWork.Length()) = myWork(1);
2077}