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