0024510: Remove unused local variables
[occt.git] / src / BRepOffsetAPI / BRepOffsetAPI_MiddlePath.cxx
... / ...
CommitLineData
1// Created on: 2012-08-06
2// Created by: jgv@ROLEX
3// Copyright (c) 2012-2014 OPEN CASCADE SAS
4//
5// This file is part of Open CASCADE Technology software library.
6//
7// This library is free software; you can redistribute it and / or modify it
8// under the terms of the GNU Lesser General Public version 2.1 as published
9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
12//
13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
15
16#include <BRepOffsetAPI_MiddlePath.ixx>
17#include <BRepOffsetAPI_MiddlePath.hxx>
18
19#include <ShapeUpgrade_UnifySameDomain.hxx>
20
21#include <gp_Lin.hxx>
22#include <Geom_Curve.hxx>
23#include <Geom_TrimmedCurve.hxx>
24#include <Geom_Line.hxx>
25#include <Geom_BezierCurve.hxx>
26#include <Geom_BSplineCurve.hxx>
27#include <BRep_Tool.hxx>
28#include <gce_MakeLin.hxx>
29
30#include <BRepLib_MakeWire.hxx>
31
32#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
33#include <TopTools_MapIteratorOfMapOfShape.hxx>
34#include <TopExp.hxx>
35#include <TopTools_ListIteratorOfListOfShape.hxx>
36#include <TopoDS.hxx>
37#include <BRepTools.hxx>
38#include <TopTools_SequenceOfShape.hxx>
39#include <BRepTools_WireExplorer.hxx>
40#include <TopoDS_Iterator.hxx>
41#include <BRep_Builder.hxx>
42#include <Precision.hxx>
43#include <TopExp_Explorer.hxx>
44#include <BRepExtrema_DistShapeShape.hxx>
45#include <Geom2d_Curve.hxx>
46#include <Geom2d_Line.hxx>
47#include <GCE2d_MakeLine.hxx>
48#include <BRepLib_MakeEdge.hxx>
49#include <BRepLib.hxx>
50#include <GeomAbs_CurveType.hxx>
51#include <BRepAdaptor_Curve.hxx>
52#include <TopTools_Array1OfShape.hxx>
53#include <BRepLib_MakeFace.hxx>
54#include <TColgp_Array1OfPnt.hxx>
55#include <TColgp_HArray1OfPnt.hxx>
56#include <TColgp_Array1OfVec.hxx>
57#include <TColStd_HArray1OfBoolean.hxx>
58#include <GProp_GProps.hxx>
59#include <BRepGProp.hxx>
60#include <Geom_Circle.hxx>
61#include <gp_Circ.hxx>
62#include <GC_MakeCircle.hxx>
63#include <TColgp_SequenceOfPnt.hxx>
64#include <GeomLib.hxx>
65#include <GeomAPI_Interpolate.hxx>
66
67static Standard_Boolean IsLinear(const TopoDS_Edge& anEdge,
68 gp_Lin& aLine)
69{
70 Standard_Real fpar, lpar;
71 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
72 if (aCurve->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
73 aCurve = ((Handle(Geom_TrimmedCurve)&) aCurve)->BasisCurve();
74
75 gp_Pnt Pnt1, Pnt2;
76 if (aCurve->IsKind(STANDARD_TYPE(Geom_Line)))
77 {
78 aLine = ((Handle(Geom_Line)&) aCurve)->Lin();
79 return Standard_True;
80 }
81 else if (aCurve->IsKind(STANDARD_TYPE(Geom_BezierCurve)))
82 {
83 Handle(Geom_BezierCurve) theBezier = (Handle(Geom_BezierCurve)&) aCurve;
84 if (theBezier->NbPoles() == 2)
85 {
86 Pnt1 = theBezier->Pole(1);
87 Pnt2 = theBezier->Pole(2);
88 aLine = gce_MakeLin(Pnt1, Pnt2);
89 return Standard_True;
90 }
91 }
92 else if (aCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
93 {
94 Handle(Geom_BSplineCurve) theBSpline = (Handle(Geom_BSplineCurve)&) aCurve;
95 if (theBSpline->NbPoles() == 2)
96 {
97 Pnt1 = theBSpline->Pole(1);
98 Pnt2 = theBSpline->Pole(2);
99 aLine = gce_MakeLin(Pnt1, Pnt2);
100 return Standard_True;
101 }
102 }
103
104 return Standard_False;
105}
106
107static GeomAbs_CurveType TypeOfEdge(const TopoDS_Edge& anEdge)
108{
109 gp_Lin aLin;
110 if (IsLinear(anEdge, aLin))
111 return GeomAbs_Line;
112
113 BRepAdaptor_Curve BAcurve(anEdge);
114 return BAcurve.GetType();
115}
116
117static gp_Vec TangentOfEdge(const TopoDS_Shape& aShape,
118 const Standard_Boolean OnFirst)
119{
120 TopoDS_Edge anEdge = TopoDS::Edge(aShape);
121 TopAbs_Orientation anOr = anEdge.Orientation();
122
123 Standard_Real fpar, lpar;
124 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
125 Standard_Real thePar;
126 if (OnFirst)
127 thePar = (anOr == TopAbs_FORWARD)? fpar : lpar;
128 else
129 thePar = (anOr == TopAbs_FORWARD)? lpar : fpar;
130
131 gp_Pnt thePoint;
132 gp_Vec theTangent;
133 aCurve->D1(thePar, thePoint, theTangent);
134 if (anOr == TopAbs_REVERSED)
135 theTangent.Reverse();
136
137 return theTangent;
138}
139
140
141static Standard_Boolean IsValidEdge(const TopoDS_Edge& theEdge,
142 const TopoDS_Face& theFace)
143{
144 TopoDS_Vertex V1, V2;
145 TopExp::Vertices(theEdge, V1, V2);
146
147 Standard_Real Tol = Precision::Confusion();
148 Standard_Integer i;
149
150 TopExp_Explorer Explo(theFace, TopAbs_EDGE);
151 for (; Explo.More(); Explo.Next())
152 {
153 const TopoDS_Shape& anEdge = Explo.Current();
154 BRepExtrema_DistShapeShape DistMini(theEdge, anEdge);
155 if (DistMini.Value() <= Tol)
156 {
157 for (i = 1; i <= DistMini.NbSolution(); i++)
158 {
159 BRepExtrema_SupportType theType = DistMini.SupportTypeShape2(i);
160 if (theType == BRepExtrema_IsOnEdge)
161 return Standard_False;
162 //theType is "IsVertex"
163 TopoDS_Shape aVertex = DistMini.SupportOnShape2(i);
164 if (!(aVertex.IsSame(V1) || aVertex.IsSame(V2)))
165 return Standard_False;
166 }
167 }
168 }
169
170 return Standard_True;
171}
172
173/*
174//=======================================================================
175//function : BRepOffsetAPI_MiddlePath
176//purpose : Constructor
177//=======================================================================
178
179BRepOffsetAPI_MiddlePath::BRepOffsetAPI_MiddlePath(const TopoDS_Shape& aShape,
180 const TopoDS_Wire& StartWire)
181{
182 myInitialShape = aShape;
183 myStartWire = StartWire;
184 myClosedSection = myStartWire.Closed();
185}
186
187//=======================================================================
188//function : BRepOffsetAPI_MiddlePath
189//purpose : Constructor
190//=======================================================================
191
192BRepOffsetAPI_MiddlePath::BRepOffsetAPI_MiddlePath(const TopoDS_Shape& aShape,
193 const TopoDS_Edge& StartEdge)
194{
195 myInitialShape = aShape;
196
197 BRepLib_MakeWire MW(StartEdge);
198
199 //BB.Add(myStartWire, StartEdge);
200
201 TopTools_IndexedDataMapOfShapeListOfShape EFmap;
202 TopTools_IndexedDataMapOfShapeListOfShape VEmap;
203 TopExp::MapShapesAndAncestors(myInitialShape, TopAbs_EDGE, TopAbs_FACE, EFmap);
204 TopExp::MapShapesAndAncestors(myInitialShape, TopAbs_VERTEX, TopAbs_EDGE, VEmap);
205
206 //Standard_Boolean Start = Standard_True;
207 //if (Start)
208 //{
209 //TopExp::Vertices(CurEdge, V1, V2);
210 // StartVertex = V1;
211 // CurVertex = V2;
212 // if (VEmap(CurVertex).Extent() == 2) //end: two free edges
213 // {
214 // StartVertex = V2;
215 // CurVertex = V1;
216 // if (VEmap(CurVertex).Extent() == 2) //end: two free edges
217 // break;
218 // }
219 // Start = Standard_False;
220 // continue;
221 //}
222
223 TopoDS_Vertex StartVertex, CurVertex, V1, V2;
224 TopExp::Vertices(StartEdge, StartVertex, CurVertex);
225 TopoDS_Edge CurEdge = StartEdge;
226 Standard_Integer i;
227 for (i = 1; i <= 2; i++)
228 {
229 for (;;)
230 {
231 const TopTools_ListOfShape& LE = VEmap.FindFromKey(CurVertex);
232 if (LE.Extent() == 2) //end: two free edges or one closed free edge
233 break;
234 TopTools_ListIteratorOfListOfShape itl(LE);
235 TopoDS_Edge anEdge;
236 for (; itl.More(); itl.Next())
237 {
238 anEdge = TopoDS::Edge(itl.Value());
239 if (anEdge.IsSame(CurEdge))
240 continue;
241 if (EFmap.FindFromKey(anEdge).Extent() == 1) //another free edge found
242 break;
243 }
244 //BB.Add(myStartWire, anEdge);
245 MW.Add(anEdge);
246 TopExp::Vertices(anEdge, V1, V2);
247 CurVertex = (V1.IsSame(CurVertex))? V2 : V1;
248 CurEdge = anEdge;
249 if (CurVertex.IsSame(StartVertex))
250 break;
251 }
252 if (CurVertex.IsSame(StartVertex))
253 break;
254 CurVertex = StartVertex;
255 CurEdge = StartEdge;
256 }
257
258 myStartWire = MW.Wire();
259 myClosedSection = myStartWire.Closed();
260}
261*/
262
263//=======================================================================
264//function : BRepOffsetAPI_MiddlePath
265//purpose : Constructor
266//=======================================================================
267
268BRepOffsetAPI_MiddlePath::BRepOffsetAPI_MiddlePath(const TopoDS_Shape& aShape,
269 const TopoDS_Shape& StartShape,
270 const TopoDS_Shape& EndShape)
271{
272 ShapeUpgrade_UnifySameDomain Unifier(aShape);
273 Unifier.Build();
274 myInitialShape = Unifier.Shape();
275
276 TopoDS_Wire aStartWire, anEndWire;
277 if (StartShape.ShapeType() == TopAbs_FACE)
278 {
279 const TopoDS_Face& StartFace = TopoDS::Face(StartShape);
280 aStartWire = BRepTools::OuterWire(StartFace);
281 }
282 else
283 aStartWire = TopoDS::Wire(StartShape);
284
285 if (EndShape.ShapeType() == TopAbs_FACE)
286 {
287 const TopoDS_Face& EndFace = TopoDS::Face(EndShape);
288 anEndWire = BRepTools::OuterWire(EndFace);
289 }
290 else
291 anEndWire = TopoDS::Wire(EndShape);
292
293 BRepLib_MakeWire MWstart;
294 //TopTools_MapOfShape MapEdges;
295 BRepTools_WireExplorer wexp(aStartWire);
296 for (; wexp.More(); wexp.Next())
297 {
298 TopoDS_Shape anEdge = wexp.Current();
299 TopoDS_Shape NewEdge = Unifier.Generated(anEdge);
300 if (!NewEdge.IsNull())
301 MWstart.Add(TopoDS::Edge(NewEdge));
302 }
303 myStartWire = MWstart.Wire();
304
305 BRepLib_MakeWire MWend;
306 //MapEdges.Clear();
307 for (wexp.Init(anEndWire); wexp.More(); wexp.Next())
308 {
309 TopoDS_Shape anEdge = wexp.Current();
310 TopoDS_Shape NewEdge = Unifier.Generated(anEdge);
311 if (!NewEdge.IsNull())
312 MWend.Add(TopoDS::Edge(NewEdge));
313 }
314 myEndWire = MWend.Wire();
315
316 myClosedSection = myStartWire.Closed();
317 myClosedRing = myStartWire.IsSame(myEndWire);
318}
319
320//=======================================================================
321//function : Build
322//purpose :
323//=======================================================================
324
325void BRepOffsetAPI_MiddlePath::Build()
326{
327 TopTools_ListIteratorOfListOfShape itl;
328
329 TopTools_SequenceOfShape StartVertices;
330 TopTools_MapOfShape EndVertices;
331 TopTools_MapOfShape EndEdges;
332 BRepOffsetAPI_SequenceOfSequenceOfShape SectionsEdges;
333
334 BRepTools_WireExplorer wexp(myStartWire);
335 TopTools_SequenceOfShape EdgeSeq;
336 for (; wexp.More(); wexp.Next())
337 {
338 StartVertices.Append(wexp.CurrentVertex());
339 EdgeSeq.Append(wexp.Current());
340 }
341 if (!myClosedSection)
342 StartVertices.Append(wexp.CurrentVertex());
343 SectionsEdges.Append(EdgeSeq);
344
345 for (wexp.Init(myEndWire); wexp.More(); wexp.Next())
346 {
347 EndVertices.Add(wexp.CurrentVertex());
348 EndEdges.Add(wexp.Current());
349 }
350 if (!myClosedSection)
351 EndVertices.Add(wexp.CurrentVertex());
352
353
354 TopoDS_Iterator itw(myStartWire);
355 for (; itw.More(); itw.Next())
356 myStartWireEdges.Add(itw.Value());
357 for (itw.Initialize(myEndWire); itw.More(); itw.Next())
358 myEndWireEdges.Add(itw.Value());
359
360 TopTools_IndexedDataMapOfShapeListOfShape VEmap;
361 TopTools_IndexedDataMapOfShapeListOfShape EFmap;
362 TopExp::MapShapesAndAncestors(myInitialShape, TopAbs_VERTEX, TopAbs_EDGE, VEmap);
363 TopExp::MapShapesAndAncestors(myInitialShape, TopAbs_EDGE, TopAbs_FACE, EFmap);
364
365 TopTools_MapOfShape CurVertices;
366
367 Standard_Integer i, j, k;
368 TopoDS_Edge anEdge;
369 TopoDS_Vertex V1, V2, NextVertex;
370 //Initialization of <myPaths>
371 for (i = 1; i <= StartVertices.Length(); i++)
372 {
373 TopTools_SequenceOfShape Edges;
374 const TopTools_ListOfShape& LE = VEmap.FindFromKey(StartVertices(i));
375 for (itl.Initialize(LE); itl.More(); itl.Next())
376 {
377 anEdge = TopoDS::Edge(itl.Value());
378 if (!myStartWireEdges.Contains(anEdge))
379 {
380 TopExp::Vertices(anEdge, V1, V2, Standard_True);
381 if (V1.IsSame(StartVertices(i)))
382 CurVertices.Add(V2);
383 else
384 {
385 anEdge.Reverse();
386 CurVertices.Add(V1);
387 }
388 Edges.Append(anEdge);
389 break;
390 }
391 }
392 myPaths.Append(Edges);
393 }
394
395 //Filling of "myPaths"
396 TopTools_ListOfShape NextVertices;
397 for (;;)
398 {
399 for (i = 1; i <= myPaths.Length(); i++)
400 {
401 const TopoDS_Shape& theShape = myPaths(i).Last();
402 TopoDS_Edge theEdge;
403 TopoDS_Vertex theVertex;
404 if (theShape.ShapeType() == TopAbs_EDGE)
405 {
406 theEdge = TopoDS::Edge(theShape);
407 theVertex = TopExp::LastVertex(theEdge, Standard_True);
408 }
409 else //last segment of path was punctual
410 {
411 theEdge = TopoDS::Edge(myPaths(i)(myPaths(i).Length()-1));
412 theVertex = TopoDS::Vertex(theShape);
413 }
414
415 if (EndVertices.Contains(theVertex))
416 continue;
417 const TopTools_ListOfShape& LE = VEmap.FindFromKey(theVertex);
418 TopTools_MapOfShape NextEdgeCandidates;
419 for (itl.Initialize(LE); itl.More(); itl.Next())
420 {
421 anEdge = TopoDS::Edge(itl.Value());
422 if (anEdge.IsSame(theEdge))
423 continue;
424 TopExp::Vertices(anEdge, V1, V2, Standard_True);
425 if (V1.IsSame(theVertex))
426 NextVertex = V2;
427 else
428 {
429 anEdge.Reverse();
430 NextVertex = V1;
431 }
432 if (!CurVertices.Contains(NextVertex))
433 NextEdgeCandidates.Add(anEdge);
434 }
435 if (!NextEdgeCandidates.IsEmpty())
436 {
437 if (NextEdgeCandidates.Extent() > 1)
438 myPaths(i).Append(theVertex); //punctual segment of path
439 else
440 {
441 TopTools_MapIteratorOfMapOfShape mapit(NextEdgeCandidates);
442 anEdge = TopoDS::Edge(mapit.Key());
443 myPaths(i).Append(anEdge);
444 NextVertex = TopExp::LastVertex(anEdge, Standard_True);
445 NextVertices.Append(NextVertex);
446 }
447 }
448 }
449 if (NextVertices.IsEmpty())
450 break;
451 for (itl.Initialize(NextVertices); itl.More(); itl.Next())
452 CurVertices.Add(itl.Value());
453 NextVertices.Clear();
454 }
455
456 //Temporary
457 /*
458 TopoDS_Compound aCompound, aCmp1;
459 BRep_Builder BB;
460 BB.MakeCompound(aCompound);
461 BB.MakeCompound(aCmp1);
462 for (i = 1; i <= myPaths.Length(); i++)
463 {
464 TopoDS_Compound aCmp;
465 BB.MakeCompound(aCmp);
466 for (j = 1; j <= myPaths(i).Length(); j++)
467 BB.Add(aCmp, myPaths(i)(j));
468 BB.Add(aCmp1, aCmp);
469 }
470 BB.Add(aCompound, aCmp1);
471
472 myShape = aCompound;
473
474 Done();
475 return;
476 */
477 ////////////
478
479 //Building of set of sections
480 Standard_Integer NbE = EdgeSeq.Length();
481 Standard_Integer NbPaths = myPaths.Length();
482 Standard_Integer NbVer = myPaths.Length();
483 if (myClosedSection)
484 NbVer++;
485 i = 1;
486 for (;;)
487 {
488 for (j = 1; j <= EdgeSeq.Length(); j++)
489 EdgeSeq(j).Nullify();
490
491 Standard_Boolean ToInsertVertex = Standard_False;
492
493 for (j = 2; j <= NbVer; j++)
494 {
495 if (!EdgeSeq(j-1).IsNull())
496 continue;
497
498 //for the end of initial shape
499 if (myPaths(j-1).Length() < i)
500 {
501 TopoDS_Edge aE1 = TopoDS::Edge(myPaths(j-1)(i-1));
502 TopoDS_Shape LastVer = TopExp::LastVertex(aE1, Standard_True);
503 myPaths(j-1).Append(LastVer);
504 }
505 if (myPaths((j<=NbPaths)? j : 1).Length() < i)
506 {
507 TopoDS_Edge aE2 = TopoDS::Edge(myPaths((j<=NbPaths)? j : 1)(i-1));
508 TopoDS_Shape LastVer = TopExp::LastVertex(aE2, Standard_True);
509 myPaths((j<=NbPaths)? j : 1).Append(LastVer);
510 }
511 //////////////////////////////
512
513 if (ToInsertVertex)
514 {
515 if (myPaths(j-1)(i).ShapeType() == TopAbs_EDGE)
516 {
517 TopoDS_Edge aE1 = TopoDS::Edge(myPaths(j-1)(i));
518 TopoDS_Shape fver = TopExp::FirstVertex(aE1, Standard_True);
519 myPaths(j-1).InsertBefore(i, fver);
520 }
521 if (myPaths((j<=NbPaths)? j : 1)(i).ShapeType() == TopAbs_EDGE)
522 {
523 TopoDS_Edge aE2 = TopoDS::Edge(myPaths((j<=NbPaths)? j : 1)(i));
524 TopoDS_Shape fver = TopExp::FirstVertex(aE2, Standard_True);
525 myPaths((j<=NbPaths)? j : 1).InsertBefore(i, fver);
526 }
527 ToInsertVertex = Standard_False;
528 }
529
530 TopoDS_Edge E1, E2;
531 if (myPaths(j-1)(i).ShapeType() == TopAbs_EDGE)
532 E1 = TopoDS::Edge(myPaths(j-1)(i));
533 if (myPaths((j<=NbPaths)? j : 1)(i).ShapeType() == TopAbs_EDGE)
534 E2 = TopoDS::Edge(myPaths((j<=NbPaths)? j : 1)(i));
535 TopoDS_Edge E12 = TopoDS::Edge(SectionsEdges(i)(j-1));
536
537 TopoDS_Vertex PrevVertex = (E1.IsNull())? TopoDS::Vertex(myPaths(j-1)(i))
538 : TopExp::LastVertex(E1, Standard_True);
539 TopoDS_Vertex CurVertex = (E2.IsNull())? TopoDS::Vertex(myPaths((j<=NbPaths)? j : 1)(i))
540 : TopExp::LastVertex(E2, Standard_True);
541
542 TopoDS_Edge ProperEdge;
543 const TopTools_ListOfShape& LE = VEmap.FindFromKey(PrevVertex);
544
545 for (itl.Initialize(LE); itl.More(); itl.Next())
546 {
547 anEdge = TopoDS::Edge(itl.Value());
548 TopExp::Vertices(anEdge, V1, V2);
549 if (((V1.IsSame(PrevVertex) && V2.IsSame(CurVertex)) ||
550 (V1.IsSame(CurVertex) && V2.IsSame(PrevVertex))) &&
551 !anEdge.IsSame(E1))
552 {
553 ProperEdge = anEdge;
554 break;
555 }
556 }
557
558 if ((myPaths(j-1)(i)).ShapeType() == TopAbs_VERTEX &&
559 (myPaths((j<=NbPaths)? j : 1)(i)).ShapeType() == TopAbs_VERTEX)
560 {
561 EdgeSeq(j-1) = ProperEdge;
562 continue;
563 }
564
565 TopoDS_Vertex PrevPrevVer = (E1.IsNull())? PrevVertex
566 : TopExp::FirstVertex(E1, Standard_True);
567 TopoDS_Vertex PrevCurVer = (E2.IsNull())? CurVertex
568 : TopExp::FirstVertex(E2, Standard_True);
569 if (ProperEdge.IsNull()) //no connection between these two vertices
570 {
571 //Find the face on which E1, E2 and E12 lie
572 //ToInsertVertex = Standard_False;
573 const TopoDS_Shape& EE1 = (E1.IsNull())?
574 myPaths(j-1)(i-1) : E1;
575 const TopoDS_Shape& EE2 = (E2.IsNull())?
576 myPaths((j<=NbPaths)? j : 1)(i-1) : E2;
577 const TopTools_ListOfShape& LF = EFmap.FindFromKey(EE1);
578 TopoDS_Face theFace;
579 for (itl.Initialize(LF); itl.More(); itl.Next())
580 {
581 const TopoDS_Shape& aFace = itl.Value();
582 TopExp_Explorer Explo(aFace, TopAbs_EDGE);
583 for (; Explo.More(); Explo.Next())
584 {
585 if (EE2.IsSame(Explo.Current()))
586 {
587 const TopTools_ListOfShape& LFsec = EFmap.FindFromKey(E12);
588 TopTools_ListIteratorOfListOfShape itlsec(LFsec);
589 for (; itlsec.More(); itlsec.Next())
590 if (aFace.IsSame(itlsec.Value()))
591 {
592 theFace = TopoDS::Face(aFace);
593 break;
594 }
595 if (!theFace.IsNull())
596 break;
597 }
598 }
599 if (!theFace.IsNull())
600 break;
601 }
602 TopTools_ListOfShape ListOneFace;
603 ListOneFace.Append(theFace);
604
605 if (E1.IsNull() || E2.IsNull())
606 {
607 if (E1.IsNull())
608 E1 = TopoDS::Edge(myPaths(j-1)(i-1));
609 if (E2.IsNull())
610 E2 = TopoDS::Edge(myPaths((j<=NbPaths)? j : 1)(i-1));
611 Standard_Real fpar1, lpar1, fpar2, lpar2;
612 Standard_Real LastPar1, LastPar2;
613 Handle(Geom2d_Curve) PCurve1 = BRep_Tool::CurveOnSurface(E1, theFace, fpar1, lpar1);
614 Handle(Geom2d_Curve) PCurve2 = BRep_Tool::CurveOnSurface(E2, theFace, fpar2, lpar2);
615 if (E1.Orientation() == TopAbs_FORWARD)
616 { LastPar1 = lpar1; }
617 else
618 { LastPar1 = fpar1; }
619 if (E2.Orientation() == TopAbs_FORWARD)
620 { LastPar2 = lpar2; }
621 else
622 { LastPar2 = fpar2; }
623 gp_Pnt2d FirstPnt2d = PCurve1->Value(LastPar1);
624 gp_Pnt2d LastPnt2d = PCurve2->Value(LastPar2);
625 Handle(Geom_Surface) theSurf = BRep_Tool::Surface(theFace);
626 Handle(Geom2d_Line) theLine = GCE2d_MakeLine(FirstPnt2d, LastPnt2d);
627 Standard_Real len_ne = FirstPnt2d.Distance(LastPnt2d);
628 TopoDS_Edge NewEdge = BRepLib_MakeEdge(theLine, theSurf,
629 PrevVertex, CurVertex,
630 0., len_ne);
631 BRepLib::BuildCurve3d(NewEdge);
632 EdgeSeq(j-1) = NewEdge;
633 EFmap.Add(NewEdge, ListOneFace);
634 }
635 else //E1 is edge
636 {
637 //Extract points 2d
638 Standard_Real fpar1, lpar1, fpar2, lpar2;
639 Standard_Real FirstPar1, LastPar1, FirstPar2, LastPar2;
640 Handle(Geom2d_Curve) PCurve1 = BRep_Tool::CurveOnSurface(E1, theFace, fpar1, lpar1);
641 Handle(Geom2d_Curve) PCurve2 = BRep_Tool::CurveOnSurface(E2, theFace, fpar2, lpar2);
642 if (E1.Orientation() == TopAbs_FORWARD)
643 { FirstPar1 = fpar1; LastPar1 = lpar1; }
644 else
645 { FirstPar1 = lpar1; LastPar1 = fpar1; }
646 if (E2.Orientation() == TopAbs_FORWARD)
647 { FirstPar2 = fpar2; LastPar2 = lpar2; }
648 else
649 { FirstPar2 = lpar2; LastPar2 = fpar2; }
650 gp_Pnt2d FirstPnt2d = PCurve1->Value(LastPar1);
651 gp_Pnt2d LastPnt2d = PCurve2->Value(LastPar2);
652 Handle(Geom_Surface) theSurf = BRep_Tool::Surface(theFace);
653 Handle(Geom2d_Line) theLine = GCE2d_MakeLine(FirstPnt2d, LastPnt2d);
654 Standard_Real len_ne = FirstPnt2d.Distance(LastPnt2d);
655 TopoDS_Edge NewEdge = BRepLib_MakeEdge(theLine, theSurf,
656 PrevVertex, CurVertex,
657 0., len_ne);
658 BRepLib::BuildCurve3d(NewEdge);
659 gp_Pnt2d PrevFirstPnt2d = PCurve1->Value(FirstPar1);
660 gp_Pnt2d PrevLastPnt2d = PCurve2->Value(FirstPar2);
661 Handle(Geom2d_Line) Line1 = GCE2d_MakeLine(PrevFirstPnt2d, LastPnt2d);
662 Handle(Geom2d_Line) Line2 = GCE2d_MakeLine(FirstPnt2d, PrevLastPnt2d);
663 Standard_Real len_ne1 = PrevFirstPnt2d.Distance(LastPnt2d);
664 TopoDS_Edge NewEdge1 = BRepLib_MakeEdge(Line1, theSurf,
665 PrevPrevVer, CurVertex,
666 0., len_ne1);
667 BRepLib::BuildCurve3d(NewEdge1);
668 Standard_Real len_ne2 = FirstPnt2d.Distance(PrevLastPnt2d);
669 TopoDS_Edge NewEdge2 = BRepLib_MakeEdge(Line2, theSurf,
670 PrevVertex, PrevCurVer,
671 0., len_ne2);
672 BRepLib::BuildCurve3d(NewEdge2);
673 Standard_Boolean good_ne = IsValidEdge(NewEdge, theFace);
674 Standard_Boolean good_ne1 = IsValidEdge(NewEdge1, theFace);
675
676 GeomAbs_CurveType type_E1 = TypeOfEdge(E1);
677 GeomAbs_CurveType type_E2 = TypeOfEdge(E2);
678
679 Standard_Integer ChooseEdge = 0;
680
681 if (!good_ne || type_E1 != type_E2)
682 {
683 if (type_E1 == type_E2) //!good_ne
684 {
685 if (good_ne1)
686 ChooseEdge = 1;
687 else
688 ChooseEdge = 2;
689 }
690 else //types are different
691 {
692 if (type_E1 == GeomAbs_Line)
693 ChooseEdge = 1;
694 else if (type_E2 == GeomAbs_Line)
695 ChooseEdge = 2;
696 else //to be developed later...
697 {}
698 }
699 }
700
701 if (ChooseEdge == 0)
702 {
703 EdgeSeq(j-1) = NewEdge;
704 EFmap.Add(NewEdge, ListOneFace);
705 }
706 else if (ChooseEdge == 1)
707 {
708 EdgeSeq(j-1) = NewEdge1;
709 EFmap.Add(NewEdge1, ListOneFace);
710 for (k = 1; k < j-1; k++)
711 EdgeSeq(k).Nullify();
712 for (k = 1; k <= j-1; k++)
713 {
714 TopoDS_Edge aLastEdge = TopoDS::Edge(myPaths(k)(i));
715 TopoDS_Shape VertexAsEdge = TopExp::FirstVertex(aLastEdge, Standard_True);
716 myPaths(k).InsertBefore(i, VertexAsEdge);
717 }
718 j = 1; //start from beginning
719 }
720 else if (ChooseEdge == 2)
721 {
722 EdgeSeq(j-1) = NewEdge2;
723 EFmap.Add(NewEdge2, ListOneFace);
724 ToInsertVertex = Standard_True;
725 }
726 } //else //E1 is edge
727 } //if (ProperEdge.IsNull())
728 else //connecting edge exists
729 {
730 /*
731 if (ToInsertVertex)
732 {
733 myPaths(j-1).InsertBefore(i, PrevPrevVer);
734 myPaths((j<=NbPaths)? j : 1).InsertBefore(i, PrevCurVer);
735 EdgeSeq(j-1) = E12;
736 }
737 else
738 */
739 EdgeSeq(j-1) = ProperEdge;
740 }
741 } //for (j = 2; j <= NbVer; j++)
742 SectionsEdges.Append(EdgeSeq);
743
744 //check for exit from for(;;)
745 Standard_Integer NbEndEdges = 0;
746 for (j = 1; j <= EdgeSeq.Length(); j++)
747 if (EndEdges.Contains(EdgeSeq(j)))
748 NbEndEdges++;
749 if (NbEndEdges == NbE)
750 break;
751
752 i++;
753 } //for (;;)
754
755
756 //final phase: building of middle path
757 Standard_Integer NbSecFaces = SectionsEdges.Length();
758 TopTools_Array1OfShape SecFaces(1, NbSecFaces);
759 for (i = 1; i <= NbSecFaces; i++)
760 {
761 BRepLib_MakeWire MW;
762 for (j = 1; j <= NbE; j++)
763 {
764 anEdge = TopoDS::Edge(SectionsEdges(i)(j));
765 MW.Add(anEdge);
766 }
767 if (!myClosedSection)
768 {
769 TopExp::Vertices(MW.Wire(), V1, V2);
770 anEdge = BRepLib_MakeEdge(V2, V1);
771 MW.Add(anEdge);
772 }
773 TopoDS_Wire aWire = MW.Wire();
774 BRepLib_MakeFace MF(aWire, Standard_True); //Only plane
775 if (MF.IsDone())
776 SecFaces(i) = MF.Face();
777 else
778 SecFaces(i) = aWire;
779 }
780
781 TColgp_Array1OfPnt Centers(1, NbSecFaces);
782 for (i = 1; i <= NbSecFaces; i++)
783 {
784 GProp_GProps Properties;
785 if (SecFaces(i).ShapeType() == TopAbs_FACE)
786 BRepGProp::SurfaceProperties(SecFaces(i), Properties);
787 else //wire
788 BRepGProp::LinearProperties(SecFaces(i), Properties);
789
790 Centers(i) = Properties.CentreOfMass();
791 }
792
793 TopTools_Array1OfShape MidEdges(1, NbSecFaces-1);
794 Standard_Real LinTol = 1.e-5;
795 Standard_Real AngTol = 1.e-7;
796 gp_Pnt Pnt1, Pnt2;
797 for (i = 1; i < NbSecFaces; i++)
798 {
799 GeomAbs_CurveType TypeOfMidEdge = GeomAbs_OtherCurve;
800 for (j = 1; j <= myPaths.Length(); j++)
801 {
802 const TopoDS_Shape& aShape = myPaths(j)(i);
803 if (aShape.ShapeType() == TopAbs_VERTEX)
804 {
805 TypeOfMidEdge = GeomAbs_OtherCurve;
806 break;
807 }
808 anEdge = TopoDS::Edge(aShape);
809 GeomAbs_CurveType aType = TypeOfEdge(anEdge);
810 if (j == 1)
811 TypeOfMidEdge = aType;
812 else
813 {
814 if (aType != TypeOfMidEdge)
815 {
816 TypeOfMidEdge = GeomAbs_OtherCurve;
817 break;
818 }
819 }
820 }
821 if (TypeOfMidEdge == GeomAbs_Line)
822 MidEdges(i) = BRepLib_MakeEdge(Centers(i), Centers(i+1));
823 else if (TypeOfMidEdge == GeomAbs_Circle)
824 {
825 gp_Ax1 theAxis;
826 gp_Dir theDir1, theDir2;
827 Standard_Real theAngle = 0.;
828 gp_Vec theTangent;
829 Standard_Boolean SimilarArcs = Standard_True;
830 for (j = 1; j <= myPaths.Length(); j++)
831 {
832 anEdge = TopoDS::Edge(myPaths(j)(i));
833 Standard_Real fpar, lpar;
834 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
835 if (aCurve->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
836 aCurve = ((Handle(Geom_TrimmedCurve)&) aCurve)->BasisCurve();
837 Pnt1 = aCurve->Value(fpar);
838 Pnt2 = aCurve->Value(lpar);
839 Handle(Geom_Circle) aCircle = Handle(Geom_Circle)::DownCast(aCurve);
840 gp_Circ aCirc = aCircle->Circ();
841 if (j == 1)
842 {
843 theAxis = aCirc.Axis();
844 theDir1 = gp_Vec(aCirc.Location(), Pnt1);
845 theDir2 = gp_Vec(aCirc.Location(), Pnt2);
846 theAngle = lpar - fpar;
847 Standard_Real theParam = (anEdge.Orientation() == TopAbs_FORWARD)?
848 fpar : lpar;
849 aCurve->D1(theParam, Pnt1, theTangent);
850 if (anEdge.Orientation() == TopAbs_REVERSED)
851 theTangent.Reverse();
852 }
853 else
854 {
855 gp_Ax1 anAxis = aCirc.Axis();
856 gp_Lin aLin(anAxis);
857 if (!aLin.Contains(theAxis.Location(), LinTol) ||
858 !anAxis.IsParallel(theAxis, AngTol))
859 {
860 SimilarArcs = Standard_False;
861 break;
862 }
863 gp_Dir aDir1 = gp_Vec(aCirc.Location(), Pnt1);
864 gp_Dir aDir2 = gp_Vec(aCirc.Location(), Pnt2);
865 if (!((aDir1.IsEqual(theDir1, AngTol) && aDir2.IsEqual(theDir2, AngTol)) ||
866 (aDir1.IsEqual(theDir2, AngTol) && aDir2.IsEqual(theDir1, AngTol))))
867 {
868 SimilarArcs = Standard_False;
869 break;
870 }
871 }
872 }
873 if (SimilarArcs)
874 {
875 gp_XYZ AxisLoc = theAxis.Location().XYZ();
876 gp_XYZ AxisDir = theAxis.Direction().XYZ();
877 Standard_Real Parameter = (Centers(i).XYZ() - AxisLoc) * AxisDir;
878 gp_Pnt theCenterOfCirc(AxisLoc + Parameter*AxisDir);
879
880 gp_Vec Vec1(theCenterOfCirc, Centers(i));
881 gp_Vec Vec2(theCenterOfCirc, Centers(i+1));
882 /*
883 gp_Dir VecProd = Vec1 ^ Vec2;
884 if (theAxis.Direction() * VecProd < 0.)
885 theAxis.Reverse();
886 */
887
888 Standard_Real anAngle = Vec1.AngleWithRef(Vec2, theAxis.Direction());
889 if (anAngle < 0.)
890 anAngle += 2.*M_PI;
891 if (Abs(anAngle - theAngle) > AngTol)
892 theAxis.Reverse();
893 gp_Ax2 theAx2(theCenterOfCirc, theAxis.Direction(), Vec1);
894 Handle(Geom_Circle) theCircle = GC_MakeCircle(theAx2, Vec1.Magnitude());
895 gp_Vec aTangent;
896 theCircle->D1( 0., Pnt1, aTangent );
897 if (aTangent * theTangent < 0.)
898 {
899 theAxis.Reverse();
900 theAx2 = gp_Ax2(theCenterOfCirc, theAxis.Direction(), Vec1);
901 theCircle = GC_MakeCircle(theAx2, Vec1.Magnitude());
902 }
903 BRepLib_MakeEdge aME (theCircle, 0., theAngle);
904 aME.Build();
905
906 MidEdges(i) = aME.IsDone() ?
907 aME.Shape() :
908 TopoDS_Edge();
909 }
910 }
911 }
912
913 //Build missed edges
914 for (i = 1; i < NbSecFaces; i++)
915 {
916 if (MidEdges(i).IsNull())
917 {
918 for (j = i+1; j < NbSecFaces; j++)
919 {
920 if (!MidEdges(j).IsNull())
921 break;
922 }
923 //from i to j-1 all edges are null
924 Handle(TColgp_HArray1OfPnt) thePoints = new TColgp_HArray1OfPnt(1, j-i+1);
925 TColgp_Array1OfVec theTangents(1, j-i+1);
926 Handle(TColStd_HArray1OfBoolean) theFlags = new TColStd_HArray1OfBoolean(1, j-i+1);
927 for (k = i; k <= j; k++)
928 thePoints->SetValue(k-i+1, Centers(k));
929 for (k = i; k <= j; k++)
930 {
931 TColgp_SequenceOfPnt PntSeq;
932 for (Standard_Integer indp = 1; indp <= myPaths.Length(); indp++)
933 {
934 gp_Vec aTangent;
935 if (k == i)
936 {
937 if (myPaths(indp)(k).ShapeType() == TopAbs_VERTEX)
938 continue;
939 aTangent = TangentOfEdge(myPaths(indp)(k), Standard_True); //at begin
940 }
941 else if (k == j)
942 {
943 if (myPaths(indp)(k-1).ShapeType() == TopAbs_VERTEX)
944 continue;
945 aTangent = TangentOfEdge(myPaths(indp)(k-1), Standard_False); //at end
946 }
947 else
948 {
949 if (myPaths(indp)(k-1).ShapeType() == TopAbs_VERTEX ||
950 myPaths(indp)(k).ShapeType() == TopAbs_VERTEX)
951 continue;
952 gp_Vec Tangent1 = TangentOfEdge(myPaths(indp)(k-1), Standard_False); //at end
953 gp_Vec Tangent2 = TangentOfEdge(myPaths(indp)(k), Standard_True); //at begin
954 aTangent = Tangent1 + Tangent2;
955 }
956 aTangent.Normalize();
957 gp_Pnt aPnt(aTangent.XYZ());
958 PntSeq.Append(aPnt);
959 }
960 TColgp_Array1OfPnt PntArray(1, PntSeq.Length());
961 for (Standard_Integer ip = 1; ip <= PntSeq.Length(); ip++)
962 PntArray(ip) = PntSeq(ip);
963 gp_Pnt theBary;
964 gp_Dir xdir, ydir;
965 Standard_Real xgap, ygap, zgap;
966 GeomLib::Inertia(PntArray, theBary, xdir, ydir, xgap, ygap, zgap);
967 gp_Vec theTangent(theBary.XYZ());
968 theTangents(k-i+1) = theTangent;
969 }
970 theFlags->Init(Standard_True);
971
972 GeomAPI_Interpolate Interpol(thePoints, Standard_False, LinTol);
973 Interpol.Load(theTangents, theFlags);
974 Interpol.Perform();
975 if (!Interpol.IsDone())
976 {
977 cout<<endl<<"Interpolation failed"<<endl;
978 }
979 Handle(Geom_Curve) InterCurve = Interpol.Curve();
980 MidEdges(i) = BRepLib_MakeEdge(InterCurve);
981 i = j;
982 }
983 }
984
985 BRepLib_MakeWire MakeFinalWire;
986 for (i = 1; i < NbSecFaces; i++)
987 if (!MidEdges(i).IsNull())
988 MakeFinalWire.Add(TopoDS::Edge(MidEdges(i)));
989
990 TopoDS_Wire FinalWire = MakeFinalWire.Wire();
991 myShape = MakeFinalWire.Wire();
992
993 //Temporary
994 /*
995 TopoDS_Compound aCompound, aCmp1, aCmp2;
996 BRep_Builder BB;
997 BB.MakeCompound(aCompound);
998 BB.MakeCompound(aCmp1);
999 BB.MakeCompound(aCmp2);
1000 for (i = 1; i <= myPaths.Length(); i++)
1001 {
1002 TopoDS_Compound aCmp;
1003 BB.MakeCompound(aCmp);
1004 for (j = 1; j <= myPaths(i).Length(); j++)
1005 BB.Add(aCmp, myPaths(i)(j));
1006 BB.Add(aCmp1, aCmp);
1007 }
1008 for (i = 1; i <= SectionsEdges.Length(); i++)
1009 {
1010 TopoDS_Wire aWire;
1011 BB.MakeWire(aWire);
1012 for (j = 1; j <= SectionsEdges(i).Length(); j++)
1013 BB.Add(aWire, SectionsEdges(i)(j));
1014 BB.Add(aCmp2, aWire);
1015 }
1016 BB.Add(aCompound, aCmp1);
1017 BB.Add(aCompound, aCmp2);
1018 BB.Add(aCompound, FinalWire);
1019
1020 myShape = aCompound;
1021 */
1022 ////////////
1023
1024 Done();
1025}