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