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