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