0031642: Visualization - crash in Graphic3d_Structure::SetVisual() on redisplaying...
[occt.git] / src / ChFi2d / ChFi2d_Builder.cxx
CommitLineData
b311480e 1// Created on: 1995-07-07
2// Created by: Joelle CHAUVET
3// Copyright (c) 1995-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
b311480e 16
7fd59977 17
42cf5bc1 18#include <BRep_Builder.hxx>
19#include <BRep_Tool.hxx>
7fd59977 20#include <BRepAdaptor_Surface.hxx>
21#include <BRepLib.hxx>
22#include <BRepLib_MakeEdge.hxx>
23#include <BRepLib_MakeFace.hxx>
42cf5bc1 24#include <ChFi2d.hxx>
25#include <ChFi2d_Builder.hxx>
7fd59977 26#include <ElCLib.hxx>
7fd59977 27#include <GccEnt_Position.hxx>
7fd59977 28#include <Geom2d_Circle.hxx>
29#include <Geom2d_Curve.hxx>
30#include <Geom2d_Line.hxx>
42cf5bc1 31#include <Geom2d_TrimmedCurve.hxx>
7fd59977 32#include <Geom2dGcc_Circ2d2TanRad.hxx>
33#include <Geom2dGcc_QualifiedCurve.hxx>
42cf5bc1 34#include <Geom2dInt_GInter.hxx>
35#include <Geom_Circle.hxx>
36#include <Geom_Curve.hxx>
37#include <Geom_Line.hxx>
38#include <Geom_Plane.hxx>
39#include <Geom_Surface.hxx>
40#include <gp_Circ2d.hxx>
7fd59977 41#include <gp_Pln.hxx>
42#include <gp_Pnt.hxx>
43#include <gp_Pnt2d.hxx>
7fd59977 44#include <gp_Vec2d.hxx>
42cf5bc1 45#include <IntRes2d_IntersectionPoint.hxx>
7fd59977 46#include <Precision.hxx>
7fd59977 47#include <TopAbs_Orientation.hxx>
48#include <TopExp.hxx>
49#include <TopExp_Explorer.hxx>
50#include <TopLoc_Location.hxx>
7fd59977 51#include <TopoDS.hxx>
52#include <TopoDS_Edge.hxx>
42cf5bc1 53#include <TopoDS_Face.hxx>
54#include <TopoDS_Vertex.hxx>
7fd59977 55#include <TopoDS_Wire.hxx>
42cf5bc1 56#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
57#include <TopTools_IndexedMapOfShape.hxx>
58#include <TopTools_ListIteratorOfListOfShape.hxx>
7fd59977 59
60static Standard_Boolean IsIssuedFrom(const TopoDS_Edge& E,
61 const TopTools_IndexedMapOfShape& Map,
62 TopoDS_Edge& BasisEdge);
63
64static Standard_Boolean IsLineOrCircle(const TopoDS_Edge& E,
65 const TopoDS_Face& F);
66
67
68//=======================================================================
69//function : ChFi2d_Builder
70//purpose :
71//=======================================================================
72
73 ChFi2d_Builder::ChFi2d_Builder()
74{
75}
76
77//=======================================================================
78//function : ChFi2d_Builder
79//purpose :
80//=======================================================================
81
82 ChFi2d_Builder::ChFi2d_Builder(const TopoDS_Face& F)
83{
84 if (F.IsNull()) {
85 status = ChFi2d_NoFace;
86 return;
87 }
88 TopLoc_Location Loc;
89// syntaxe invalide sur NT
90// const Handle(Geom_Surface)& surf = BRep_Tool::Surface( F, Loc);
91// if (surf->IsKind(STANDARD_TYPE(Geom_Plane))) {
92 if ( BRep_Tool::Surface( F, Loc)
93 -> IsKind(STANDARD_TYPE(Geom_Plane)) ) {
94 newFace = refFace = F;
95 newFace.Orientation(TopAbs_FORWARD);
96 BRepLib::BuildCurves3d(newFace);
97 status = ChFi2d_Ready;
98 }
99 else status = ChFi2d_NotPlanar;
100} // ChFi2d_Builder
101
102//=======================================================================
103//function : Init
104//purpose :
105//=======================================================================
106
107void ChFi2d_Builder::Init(const TopoDS_Face& F)
108{
109 if (F.IsNull()) {
110 status = ChFi2d_NoFace;
111 return;
112 }
113 fillets.Clear();
114 chamfers.Clear();
115 history.Clear();
116 TopLoc_Location Loc;
117// syntaxe invalide sur NT
118// const Handle(Geom_Surface)& surf = BRep_Tool::Surface( F, Loc);
119// if (surf->IsKind(STANDARD_TYPE(Geom_Plane))) {
120 if ( BRep_Tool::Surface( F, Loc)
121 -> IsKind(STANDARD_TYPE(Geom_Plane)) ) {
122 newFace = refFace = F;
123 newFace.Orientation(TopAbs_FORWARD);
124 status = ChFi2d_Ready;
125 }
126 else status = ChFi2d_NotPlanar;
127} // Init
128
129
130//=======================================================================
131//function : Init
132//purpose :
133//=======================================================================
134
135void ChFi2d_Builder::Init(const TopoDS_Face& RefFace,
136 const TopoDS_Face& ModFace)
137{
138 if (RefFace.IsNull() || ModFace.IsNull()) {
139 status = ChFi2d_NoFace;
140 return;
141 }
142 fillets.Clear();
143 chamfers.Clear();
144 history.Clear();
145 TopLoc_Location loc;
146// syntaxe invalide sur NT
147// const Handle(Geom_Surface)& surf = BRep_Tool::Surface( RefFace, Loc);
148// if (!surf->IsKind(STANDARD_TYPE(Geom_Plane))) {
149 if ( ! BRep_Tool::Surface( RefFace, loc)
150 -> IsKind(STANDARD_TYPE(Geom_Plane)) ) {
151 status = ChFi2d_NotPlanar;
152 return;
153 }
154
155 refFace = RefFace;
156 newFace = ModFace;
157 newFace.Orientation(TopAbs_FORWARD);
158 status = ChFi2d_Ready;
159
160 // Research in newFace all the edges which not appear in RefFace
161 // The sequence newEdges will contains this edges.
162
163 TopTools_SequenceOfShape newEdges;
164 TopTools_IndexedMapOfShape refEdgesMap;
165 TopExp::MapShapes(refFace, TopAbs_EDGE, refEdgesMap);
166 TopExp_Explorer ex(newFace, TopAbs_EDGE);
167 while (ex.More()){
168 const TopoDS_Edge& currentEdge = TopoDS::Edge(ex.Current());
169 if (!refEdgesMap.Contains(currentEdge))
170 newEdges.Append(currentEdge);
171 ex.Next();
172 } // while (ex ...
173
174 // update of history, fillets and chamfers fields
175 Standard_Integer i = 1;
176 Standard_Real first, last;
177 TopoDS_Edge basisEdge;
178 while ( i <= newEdges.Length()) {
179 const TopoDS_Edge& currentEdge = TopoDS::Edge(newEdges.Value(i));
180 if (IsIssuedFrom(currentEdge, refEdgesMap, basisEdge))
181 history.Bind(basisEdge, currentEdge);
182 else {
183 // this edge is a chamfer or a fillet
184// syntaxe invalide sur NT
185// const Handle(Geom_Curve)& curve =
186// BRep_Tool::Curve(currentEdge, loc, first, last);
187 Handle(Geom_Curve) curve =
188 BRep_Tool::Curve(currentEdge, loc, first, last);
189 if (curve->IsKind(STANDARD_TYPE(Geom_Circle))) {
190 fillets.Append(currentEdge);
191 }
192 else if (curve->IsKind(STANDARD_TYPE(Geom_Line))) {
193 chamfers.Append(currentEdge);
194 }
195 else {
196 status = ChFi2d_InitialisationError;
197 return;
198 } // else ...
199 } // this edge is ...
200 i++;
201 } // while ...
202} // Init
203
204
205//=======================================================================
206//function : IsIssuedFrom
207//purpose : Search in <Map> if <E> has a parent edge. If a parent has
208// been find, this edge is returned in <BasisEdge>, else <E> is
209// returned in <BasisEdge>.
210//=======================================================================
211Standard_Boolean IsIssuedFrom(const TopoDS_Edge& E,
212 const TopTools_IndexedMapOfShape& Map,
213 TopoDS_Edge& BasisEdge)
214{
215 TopLoc_Location loc1, loc2;
216 Standard_Real f1, L1, f2, L2;
217// syntaxe invalide sur NT
218// const Handle(Geom_Curve)& c1 =
219// BRep_Tool::Curve(E, loc1, f1, L1);
220 Handle(Geom_Curve) c1 = BRep_Tool::Curve(E, loc1, f1, L1);
221
222 for (Standard_Integer i = 1; i <= Map.Extent(); i++ ) {
223 const TopoDS_Edge& currentEdge = TopoDS::Edge(Map.FindKey(i));
224// syntaxe invalide sur NT
225// const Handle(Geom_Curve)& c2 =
226// BRep_Tool::Curve(currentEdge, loc2, f2, L2);
227 Handle(Geom_Curve) c2 = BRep_Tool::Curve(currentEdge, loc2, f2, L2);
228 if (c1 == c2 &&
229 (((f1 > f2 && f1 < L2) || (L1 > f2 && L1 < L2) ) ||
230 ( (f1 > L2 && f1 < f2) || (L1 > L2 && L1 < f2) )) ) {
231 BasisEdge = currentEdge;
232 BasisEdge.Orientation(E.Orientation());
233 return Standard_True;
234 } // if (c1 == c2
235 } // for (Standard_Integer i ...
236
237 return Standard_False;
238} // IsIssuedFrom
239
240
241//=======================================================================
242//function : AddFillet
243//purpose :
244//=======================================================================
245 TopoDS_Edge ChFi2d_Builder::AddFillet(const TopoDS_Vertex& V,
246 const Standard_Real Radius)
247{
248 TopoDS_Edge adjEdge1, adjEdge2, basisEdge1, basisEdge2;
249 TopoDS_Edge adjEdge1Mod, adjEdge2Mod, fillet;
250 status = ChFi2d::FindConnectedEdges(newFace, V, adjEdge1, adjEdge2);
251 if (status == ChFi2d_ConnexionError) return fillet;
252
253 if (IsAFillet(adjEdge1) || IsAChamfer(adjEdge1) ||
254 IsAFillet(adjEdge2) || IsAChamfer(adjEdge2)) {
255 status = ChFi2d_NotAuthorized;
256 return fillet;
257 } // if (IsAFillet ...
258
259 if (!IsLineOrCircle(adjEdge1,newFace)
260 || !IsLineOrCircle(adjEdge2,newFace) ) {
261 status = ChFi2d_NotAuthorized;
262 return fillet;
263 } // if (!IsLineOrCircle ...
264
265 ComputeFillet(V, adjEdge1, adjEdge2, Radius,
266 adjEdge1Mod, adjEdge2Mod, fillet);
267 if (status == ChFi2d_IsDone
268 || status == ChFi2d_FirstEdgeDegenerated
269 || status == ChFi2d_LastEdgeDegenerated
270 || status == ChFi2d_BothEdgesDegenerated) {
271 BuildNewWire(adjEdge1, adjEdge2, adjEdge1Mod, fillet, adjEdge2Mod);
272 basisEdge1 = BasisEdge(adjEdge1);
273 basisEdge2 = BasisEdge(adjEdge2);
274 UpDateHistory(basisEdge1, basisEdge2,
275 adjEdge1Mod, adjEdge2Mod, fillet, 1);
276 status = ChFi2d_IsDone;
277 return TopoDS::Edge(fillets.Value(fillets.Length()));
278 }
279 return fillet;
280} // AddFillet
281
282//=======================================================================
283//function : ModifyFillet
284//purpose :
285//=======================================================================
286
287TopoDS_Edge ChFi2d_Builder::ModifyFillet(const TopoDS_Edge& Fillet,
288 const Standard_Real Radius)
289{
290 TopoDS_Vertex aVertex = RemoveFillet(Fillet);
291 TopoDS_Edge aFillet = AddFillet(aVertex, Radius);
292 return aFillet;
293} // ModifyFillet
294
295//=======================================================================
296//function : RemoveFillet
297//purpose :
298//=======================================================================
299
300TopoDS_Vertex ChFi2d_Builder::RemoveFillet(const TopoDS_Edge& Fillet)
301{
302 TopoDS_Vertex commonVertex;
303 Standard_Integer i = 1;
304 Standard_Integer IsFind = Standard_False;
305 while (i <= fillets.Length()) {
306 const TopoDS_Edge& aFillet = TopoDS::Edge(fillets.Value(i));
307 if (aFillet.IsSame(Fillet)) {
308 fillets.Remove(i);
309 IsFind = Standard_True;
310 break;
311 }
312 i++;
313 }
314 if (!IsFind) return commonVertex;
315
316
317 TopoDS_Vertex firstVertex, lastVertex;
318 TopExp::Vertices(Fillet, firstVertex, lastVertex);
319
320
321 TopoDS_Edge adjEdge1, adjEdge2;
322 status = ChFi2d::FindConnectedEdges(newFace, firstVertex,
323 adjEdge1, adjEdge2);
324 if (status == ChFi2d_ConnexionError) return commonVertex;
325
326 TopoDS_Edge basisEdge1, basisEdge2, E1, E2;
81bba717 327 // E1 and E2 are the adjacent edges to Fillet
7fd59977 328
329 if (adjEdge1.IsSame(Fillet)) E1 = adjEdge2;
330 else E1 = adjEdge1;
331 basisEdge1 = BasisEdge(E1);
332 status = ChFi2d::FindConnectedEdges(newFace, lastVertex,adjEdge1, adjEdge2);
333 if (status == ChFi2d_ConnexionError) return commonVertex;
334 if (adjEdge1.IsSame(Fillet)) E2 = adjEdge2;
335 else E2 = adjEdge1;
336 basisEdge2 = BasisEdge(E2);
337 TopoDS_Vertex connectionE1Fillet, connectionE2Fillet;
338 Standard_Boolean hasConnection =
339 ChFi2d::CommonVertex(basisEdge1, basisEdge2, commonVertex);
340 if (!hasConnection) {
341 status = ChFi2d_ConnexionError;
342 return commonVertex;
343 }
344 hasConnection = ChFi2d::CommonVertex(E1, Fillet, connectionE1Fillet);
345 if (!hasConnection) {
346 status = ChFi2d_ConnexionError;
347 return commonVertex;
348 }
349 hasConnection = ChFi2d::CommonVertex(E2, Fillet, connectionE2Fillet);
350 if (!hasConnection) {
351 status = ChFi2d_ConnexionError;
352 return commonVertex;
353 }
354
355 // rebuild edges on wire
356 TopoDS_Edge newEdge1, newEdge2;
357 TopoDS_Vertex v, v1, v2;
358 BRepLib_MakeEdge makeEdge;
359 TopLoc_Location loc;
360 Standard_Real first, last;
361
362 TopExp::Vertices(E1, firstVertex, lastVertex);
363 TopExp::Vertices(basisEdge1, v1, v2);
364 if (v1.IsSame(commonVertex)) v = v2;
365 else v = v1;
366
367 if ( firstVertex.IsSame(v) || lastVertex.IsSame(v))
368 // It means the edge support only one fillet. In this case
369 // the new edge must be the basis edge.
370 newEdge1 = basisEdge1;
371 else {
372 // It means the edge support one fillet on each end.
373 if (firstVertex.IsSame(connectionE1Fillet)) {
374// syntaxe invalide sur NT
375// const Handle(Geom_Curve)& curve =
376// BRep_Tool::Curve(E1, loc, first, last);
377 Handle(Geom_Curve) curve = BRep_Tool::Curve(E1, loc, first, last);
378 makeEdge.Init(curve, commonVertex, lastVertex);
379 newEdge1 = makeEdge.Edge();
380 newEdge1.Orientation(E1.Orientation());
381 newEdge1.Location(E1.Location());
382 } // if (firstVertex ...
383 else if (lastVertex.IsSame(connectionE1Fillet)) {
81bba717 384// syntax wrong on NT
7fd59977 385// const Handle(Geom_Curve)& curve =
386// BRep_Tool::Curve(E1, loc, first, last);
387 Handle(Geom_Curve) curve = BRep_Tool::Curve(E1, loc, first, last);
388 makeEdge.Init(curve, firstVertex, commonVertex);
389 newEdge1 = makeEdge.Edge();
390 newEdge1.Orientation(E1.Orientation());
391 newEdge1.Location(E1.Location());
392 } // else if (lastVertex ...
393 } // else ...
394
395 TopExp::Vertices(basisEdge2, v1, v2);
396 if (v1.IsSame(commonVertex)) v = v2;
397 else v = v1;
398
399 TopExp::Vertices(E2, firstVertex, lastVertex);
400 if ( firstVertex.IsSame(v) || lastVertex.IsSame(v))
401 // It means the edge support only one fillet. In this case
402 // the new edge must be the basis edge.
403 newEdge2 = basisEdge2;
404 else {
405 // It means the edge support one fillet on each end.
406 if (firstVertex.IsSame(connectionE2Fillet)) {
81bba717 407// syntax wrong on NT
7fd59977 408// const Handle(Geom_Curve)& curve =
409// BRep_Tool::Curve(E2, loc, first, last);
410 Handle(Geom_Curve) curve = BRep_Tool::Curve(E2, loc, first, last);
411 makeEdge.Init(curve, commonVertex, lastVertex);
412 newEdge2 = makeEdge.Edge();
413 newEdge2.Orientation(E2.Orientation());
414 newEdge2.Location(E2.Location());
415 } // if (firstVertex ...
416 else if (lastVertex.IsSame(connectionE2Fillet)) {
81bba717 417// syntax wrong on NT
7fd59977 418// const Handle(Geom_Curve)& curve =
419// BRep_Tool::Curve(E2, loc, first, last);
420 Handle(Geom_Curve) curve = BRep_Tool::Curve(E2, loc, first, last);
421 makeEdge.Init(curve, firstVertex, commonVertex);
422 newEdge2 = makeEdge.Edge();
423 newEdge2.Orientation(E2.Orientation());
424 newEdge2.Location(E2.Location());
425 } // else if (lastVertex ...
426 } // else ...
427
428 // rebuild the newFace
429 TopExp_Explorer Ex(newFace, TopAbs_EDGE);
430 TopoDS_Wire newWire;
431
432 BRep_Builder B;
433 B.MakeWire(newWire);
434
435 while (Ex.More()) {
436 const TopoDS_Edge& theEdge = TopoDS::Edge(Ex.Current());
437 if (!theEdge.IsSame(E1) &&
438 !theEdge.IsSame(E2) &&
439 !theEdge.IsSame(Fillet))
440 B.Add(newWire, theEdge);
441 else {
442 if (theEdge == E1)
443 B.Add(newWire, newEdge1);
444 else if (theEdge == E2)
445 B.Add(newWire, newEdge2);
446 } // else
447 Ex.Next();
448 } // while ...
449 BRepAdaptor_Surface Adaptor3dSurface(refFace);
450 BRepLib_MakeFace mFace(Adaptor3dSurface.Plane(), newWire);
451 newFace.Nullify();
452 newFace = mFace;
453
454 UpDateHistory(basisEdge1, basisEdge2, newEdge1, newEdge2);
455
456 return commonVertex;
457} // RemoveFillet
458
459
460//=======================================================================
461//function : ComputeFillet
462//purpose :
463//=======================================================================
464
465void ChFi2d_Builder::ComputeFillet(const TopoDS_Vertex& V,
466 const TopoDS_Edge& E1,
467 const TopoDS_Edge& E2,
468 const Standard_Real Radius,
469 TopoDS_Edge& TrimE1,
470 TopoDS_Edge& TrimE2,
471 TopoDS_Edge& Fillet)
472{
473 TopoDS_Vertex newExtr1, newExtr2;
474 Standard_Boolean Degen1, Degen2;
475 Fillet = BuildFilletEdge(V, E1, E2, Radius, newExtr1, newExtr2);
476 if ( status != ChFi2d_IsDone) return;
477 TrimE1 = BuildNewEdge(E1, V, newExtr1, Degen1);
478 TrimE2 = BuildNewEdge(E2, V, newExtr2, Degen2);
479 if (Degen1 && Degen2 ) status = ChFi2d_BothEdgesDegenerated;
480 if (Degen1 && !Degen2 ) status = ChFi2d_FirstEdgeDegenerated;
481 if (!Degen1 && Degen2 ) status = ChFi2d_LastEdgeDegenerated;
482} // ComputeFillet
483
484
485
486//=======================================================================
487//function : BuildNewWire
488//purpose :
489//=======================================================================
490
491void ChFi2d_Builder::BuildNewWire (const TopoDS_Edge& OldE1,
492 const TopoDS_Edge& OldE2,
493 const TopoDS_Edge& E1,
494 const TopoDS_Edge& Fillet,
495 const TopoDS_Edge& E2)
496{
497
498 Standard_Boolean aClosedStatus = Standard_True;
499
500 TopExp_Explorer Ex(refFace, TopAbs_WIRE);
501 while (Ex.More()) {
502 const TopoDS_Wire& aWire = TopoDS::Wire(Ex.Current());
503 aClosedStatus = aWire.Closed();
504 break;
505 }
506
507
508 Standard_Boolean filletIsAdded = Standard_False;
509
510 Ex.Init(newFace, TopAbs_EDGE);
511 TopoDS_Wire newWire;
512 BRep_Builder B;
513 B.MakeWire(newWire);
514
515 while (Ex.More()) {
516 const TopoDS_Edge& theEdge = TopoDS::Edge(Ex.Current());
517 if (!theEdge.IsSame(OldE1) && !theEdge.IsSame(OldE2)) {
518 B.Add(newWire, theEdge);
519 }
520 else {
521 if (theEdge == OldE1) {
522 if (status != ChFi2d_FirstEdgeDegenerated
523 && status != ChFi2d_BothEdgesDegenerated) {
524 B.Add(newWire, E1);
525 }
526 if ( !filletIsAdded) {
527 B.Add(newWire, Fillet);
528 filletIsAdded = Standard_True;
529 } // if ( !filletIsAdded ...
530 } // if (theEdge == ...
531 else {
532 if (status != ChFi2d_LastEdgeDegenerated
533 && status != ChFi2d_BothEdgesDegenerated) {
534 B.Add(newWire, E2);
535 }
536 if ( !filletIsAdded) {
537 B.Add(newWire, Fillet);
538 filletIsAdded = Standard_True;
539 }// if ( !filletIsAdded ...
540 } // else ...
541 } // else ...
542 Ex.Next();
543 } // while ...
544
545 newWire.Closed(aClosedStatus);
546 BRepAdaptor_Surface Adaptor3dSurface(refFace);
547 BRepLib_MakeFace mFace(Adaptor3dSurface.Plane(), newWire);
548 newFace = mFace;
549
550} // BuildNewWire
551
552
553//=======================================================================
554//function : BuildNewEdge
555//purpose :
556//=======================================================================
557
558TopoDS_Edge ChFi2d_Builder::BuildNewEdge(const TopoDS_Edge& E1,
559 const TopoDS_Vertex& OldExtr,
560 const TopoDS_Vertex& NewExtr) const
561{
562 BRepLib_MakeEdge makeEdge;
563 TopLoc_Location loc;
564 Standard_Real first, last;
565 TopoDS_Vertex firstVertex, lastVertex;
566 TopExp::Vertices(E1, firstVertex, lastVertex);
567// syntaxe invalide sur NT
568// const Handle(Geom_Curve)& curve =
569// BRep_Tool::Curve(E1, first, last);
570 Handle(Geom_Curve) curve = BRep_Tool::Curve(E1, first, last);
571 if (firstVertex.IsSame(OldExtr))
572 makeEdge.Init(curve, NewExtr, lastVertex);
573 else
574 makeEdge.Init(curve, firstVertex, NewExtr);
575 TopoDS_Edge anEdge = makeEdge;
576 anEdge.Orientation(E1.Orientation());
577// anEdge.Location(E1.Location());
7fd59977 578 return anEdge;
579}
580
581
582//=======================================================================
583//function : BuildNewEdge
584//purpose : special flag if the new edge is degenerated
585//=======================================================================
586
587TopoDS_Edge ChFi2d_Builder::BuildNewEdge(const TopoDS_Edge& E1,
588 const TopoDS_Vertex& OldExtr,
589 const TopoDS_Vertex& NewExtr,
590 Standard_Boolean& IsDegenerated) const
591{
592 BRepLib_MakeEdge makeEdge;
593 TopLoc_Location loc;
594 Standard_Real first, last;
595 IsDegenerated = Standard_False;
596 TopoDS_Vertex firstVertex, lastVertex;
597 TopExp::Vertices(E1, firstVertex, lastVertex);
598 gp_Pnt Pnew = BRep_Tool::Pnt(NewExtr);
599 Standard_Boolean PonctualEdge = Standard_False;
600 Standard_Real Tol = Precision::Confusion();
81bba717 601// syntax wrong on NT
7fd59977 602// const Handle(Geom_Curve)& curve =
603// BRep_Tool::Curve(E1, first, last);
604 Handle(Geom_Curve) curve = BRep_Tool::Curve(E1, first, last);
605 if (firstVertex.IsSame(OldExtr)) {
606 makeEdge.Init(curve, NewExtr, lastVertex);
607 gp_Pnt PV = BRep_Tool::Pnt(lastVertex);
608 PonctualEdge = (Pnew.Distance(PV)<Tol);
609 }
610 else {
611 makeEdge.Init(curve, firstVertex, NewExtr);
612 gp_Pnt PV = BRep_Tool::Pnt(firstVertex);
613 PonctualEdge = (Pnew.Distance(PV)<Tol);
614 }
615 TopoDS_Edge anEdge;
616 BRepLib_EdgeError error = makeEdge.Error();
617 if (error==BRepLib_LineThroughIdenticPoints || PonctualEdge) {
618 IsDegenerated = Standard_True;
619 anEdge = E1;
620 }
621 else {
622 anEdge = makeEdge;
623 anEdge.Orientation(E1.Orientation());
624// anEdge.Location(E1.Location());
625 }
626 return anEdge;
627}
628
629
630//=======================================================================
631//function : UpDateHistory
632//purpose :
633//=======================================================================
634void ChFi2d_Builder::UpDateHistory(const TopoDS_Edge& E1,
635 const TopoDS_Edge& E2,
636 const TopoDS_Edge& TrimE1,
637 const TopoDS_Edge& TrimE2,
638 const TopoDS_Edge& NewEdge,
639 const Standard_Integer Id)
640{
641 if (Id == 1) // the new edge is a fillet
c48e2889 642 {
7fd59977 643 fillets.Append(NewEdge);
c48e2889 644 }
7fd59977 645 else // the new edge is a chamfer
c48e2889 646 {
7fd59977 647 chamfers.Append(NewEdge);
7fd59977 648 }
c48e2889 649
650 history.UnBind(E1);
651 if (status != ChFi2d_FirstEdgeDegenerated
652 && status != ChFi2d_BothEdgesDegenerated)
653 {
654 if (!E1.IsSame(TrimE1))
655 {
656 history.Bind(E1, TrimE1);
657 }
658 }
659 history.UnBind(E2);
660 if (status != ChFi2d_LastEdgeDegenerated
661 && status != ChFi2d_BothEdgesDegenerated)
662 {
663 if (!E2.IsSame(TrimE2))
664 {
665 history.Bind(E2, TrimE2);
666 }
7fd59977 667 }
668} // UpDateHistory
669
670
671//=======================================================================
672//function : UpDateHistory
673//purpose :
674//=======================================================================
675void ChFi2d_Builder::UpDateHistory(const TopoDS_Edge& E1,
676 const TopoDS_Edge& E2,
677 const TopoDS_Edge& TrimE1,
678 const TopoDS_Edge& TrimE2)
679{
680
681
682 if (history.IsBound(E1)) history.UnBind(E1);
683 if (!E1.IsSame(TrimE1)) history.Bind(E1, TrimE1);
684 if (history.IsBound(E2)) history.UnBind(E2);
685 if (!E2.IsSame(TrimE2)) history.Bind(E2, TrimE2);
686} // UpDateHistory
687
688
689//=======================================================================
690//function : BasisEdge
691//purpose :
692//=======================================================================
693const TopoDS_Edge& ChFi2d_Builder::BasisEdge(const TopoDS_Edge& E) const
694{
695 TopTools_DataMapIteratorOfDataMapOfShapeShape iterator(history);
696 TopoDS_Edge anEdge;
697 while (iterator.More()) {
698 anEdge = TopoDS::Edge(iterator.Value());
699 if (anEdge.IsSame(E)) {
700 const TopoDS_Edge& anotherEdge = TopoDS::Edge(iterator.Key());
701 return anotherEdge;
702 } // if (anEdge.IsSame ...
703 iterator.Next();
704 } // while (Iterator.More ...
705 return E;
706} // BasisEdge
707
708
709//=======================================================================
710//function : BuildFilletEdge
711//purpose :
712//=======================================================================
713TopoDS_Edge ChFi2d_Builder::BuildFilletEdge(const TopoDS_Vertex& V,
714 const TopoDS_Edge& AdjEdge1,
715 const TopoDS_Edge& AdjEdge2,
716 const Standard_Real Radius,
717 TopoDS_Vertex& NewExtr1,
718 TopoDS_Vertex& NewExtr2)
719{
720 TopoDS_Edge E1, E2;
721 E1 = AdjEdge1;
722 E2 = AdjEdge2;
723 TopoDS_Vertex V1 = TopExp::FirstVertex(E1);
724 TopoDS_Vertex V2 = TopExp::LastVertex(E1);
725 TopoDS_Vertex V3 = TopExp::FirstVertex(E2);
726 TopoDS_Vertex V4 = TopExp::LastVertex(E2);
727
728 //========================================================================
81bba717 729 // The first arc is found. +
7fd59977 730 //========================================================================
731
96a95605
DB
732 TopAbs_Orientation O1;
733 TopAbs_Orientation OE1;
7fd59977 734 OE1 = E1.Orientation();
7fd59977 735 E1.Orientation(TopAbs_FORWARD);
736 E2.Orientation(TopAbs_FORWARD);
737 TopoDS_Shape aLocalShape = E1.EmptyCopied();
738 TopoDS_Edge Ebid1 = TopoDS::Edge(aLocalShape);
739 aLocalShape = E2.EmptyCopied();
740 TopoDS_Edge Ebid2 = TopoDS::Edge(aLocalShape);
741// TopoDS_Edge Ebid1 = TopoDS::Edge(E1.EmptyCopied());
742// TopoDS_Edge Ebid2 = TopoDS::Edge(E2.EmptyCopied());
743 Standard_Real param1,param2,param3,param4;
744
745 //========================================================================
81bba717 746 // Save non-modified parts of edges concerned. +
7fd59977 747 //========================================================================
748
749 if (V1.IsSame(V)) {
750 param1 = BRep_Tool::Parameter(V1,E1);
751 param2 = BRep_Tool::Parameter(V2,E1);
752 O1 = V2.Orientation();
753 }
754 else {
755 param1 = BRep_Tool::Parameter(V2,E1);
756 param2 = BRep_Tool::Parameter(V1,E1);
757 O1 = V1.Orientation();
758 }
759 if (V3.IsSame(V)) {
760 param3 = BRep_Tool::Parameter(V3,E2);
761 param4 = BRep_Tool::Parameter(V4,E2);
7fd59977 762 }
763 else {
764 param3 = BRep_Tool::Parameter(V4,E2);
765 param4 = BRep_Tool::Parameter(V3,E2);
7fd59977 766 }
767
768 //========================================================================
81bba717 769 // Restore geometric supports. +
7fd59977 770 //========================================================================
771
772 Handle(Geom2d_Curve) C1,C2;
773 Standard_Real ufirst1,ulast1,ufirst2,ulast2,U1,U2,PU1,PU2,Vv1,Vv2;
774 Standard_Real PPU1,PPU2;
775 C1 = BRep_Tool::CurveOnSurface(E1,newFace,ufirst1,ulast1);
776 C2 = BRep_Tool::CurveOnSurface(E2,newFace,ufirst2,ulast2);
777
778 //========================================================================
81bba717 779 // Determination of the face for fillet. +
7fd59977 780 //========================================================================
781
782 gp_Pnt2d p;
783 gp_Vec2d Ve1,Ve2;
784 gp_Vec2d Ve3,Ve4;
785 Standard_Boolean Sens1 , Sens2;
786
787 Handle(Geom2d_Curve) basisC1,basisC2;
788 Handle(Geom2d_TrimmedCurve) T1 = Handle(Geom2d_TrimmedCurve)::DownCast(C1);
789 if (!T1.IsNull())
a9dde4a3 790 basisC1 = T1->BasisCurve();
7fd59977 791 else
a9dde4a3 792 basisC1 = C1;
7fd59977 793 Handle(Geom2d_TrimmedCurve) T2 = Handle(Geom2d_TrimmedCurve)::DownCast(C2);
794 if (!T2.IsNull())
a9dde4a3 795 basisC2 = T2->BasisCurve();
7fd59977 796 else
a9dde4a3 797 basisC2 = C2;
7fd59977 798
799 if (basisC1->DynamicType() == STANDARD_TYPE(Geom2d_Circle)) {
800 Handle(Geom2d_Circle) CC1 = Handle(Geom2d_Circle)::DownCast(basisC1);
801 ElCLib::D1(param1,CC1->Circ2d(),p,Ve1);
802 Sens1 = (CC1->Circ2d()).IsDirect();
803 } // if (C1->DynamicType() ...
804 else {
805 Handle(Geom2d_Line) CC1 = Handle(Geom2d_Line)::DownCast(basisC1);
806 ElCLib::D1(param1,CC1->Lin2d(),p,Ve1);
807 Sens1=Standard_True;
808 } // else ...
809 if (basisC2->DynamicType() == STANDARD_TYPE(Geom2d_Circle)) {
810 Handle(Geom2d_Circle) CC2 = Handle(Geom2d_Circle)::DownCast(basisC2);
811 ElCLib::D1(param3,CC2->Circ2d(),p,Ve2);
812 Sens2 = (CC2->Circ2d()).IsDirect();
813 } // if if (C2->DynamicType() ...
814 else {
815 Handle(Geom2d_Line) CC2 = Handle(Geom2d_Line)::DownCast(basisC2);
816 ElCLib::D1(param3,CC2->Lin2d(),p,Ve2);
817 Sens2=Standard_True;
818 } // else ...
819
820 TopoDS_Edge filletEdge;
821
822 Standard_Real cross = Ve1.Crossed(Ve2);
823 Ve3 = Ve1;
824 Ve4 = Ve2;
825
81bba717 826 // processing of tangency or downcast point
7fd59977 827 if (Ve1.IsParallel(Ve2,Precision::Angular())) {
81bba717 828 // Ve1 and Ve2 are parallel : cross at 0
7fd59977 829 cross = 0.;
830 if (param1<param2) {
831 Ve3 = -Ve1;
832 }
833 if (param3>param4) {
834 Ve4 = -Ve2;
835 }
836
837 if (! Ve4.IsOpposite(Ve3,Precision::Angular())) {
81bba717 838 // There is a true tangency point and the calculation is stopped
7fd59977 839 status = ChFi2d_TangencyError;
840 return filletEdge;
841 }
81bba717 842 // Otherwise this is a downcast point, and the calculation is continued
7fd59977 843 }
844
845 GccEnt_Position Qual1,Qual2;
846 if (cross < 0.) {
847 if (param3 > param4 ) {
848 if(Sens1 == Standard_True){
849 Qual1 = GccEnt_enclosed;
850 }
851 else {
852 Qual1 = GccEnt_outside;
853 }
854 }
855 else {
856 if(Sens1 == Standard_True){
857 Qual1 = GccEnt_outside;
858 }
859 else {
860 Qual1 = GccEnt_enclosed;
861 }
862 }
863 if (param1 > param2) {
864 if(Sens2 == Standard_True)
865 Qual2 = GccEnt_outside;
866 else
867 Qual2 = GccEnt_enclosed;
868 }
869 else {
870 if(Sens2 == Standard_True)
871 Qual2 = GccEnt_enclosed;
872 else
873 Qual2 = GccEnt_outside;
874 }
875 } // if (cross < 0 ...
876 else {
877 if (param3 > param4 ) {
878 if( Sens1 == Standard_True)
879 Qual1 = GccEnt_outside;
880 else
881 Qual1 = GccEnt_enclosed;
882 }
883 else {
884 if( Sens1 == Standard_True)
885 Qual1 = GccEnt_enclosed;
886 else
887 Qual1 = GccEnt_outside;
888 }
889 if (param1 > param2 ) {
890 if( Sens2 == Standard_True)
891 Qual2 = GccEnt_enclosed;
892 else
893 Qual2 = GccEnt_outside;
894 }
895 else {
896 if( Sens2 == Standard_True)
897 Qual2 = GccEnt_outside;
898 else
899 Qual2 = GccEnt_enclosed;
900 }
901 } // else ...
902
903 Standard_Real Tol = Precision::Confusion();
904 Geom2dGcc_Circ2d2TanRad Fillet(Geom2dGcc_QualifiedCurve(basisC1,Qual1),
905 Geom2dGcc_QualifiedCurve(basisC2,Qual2),
906 Radius, Tol);
907 if (!Fillet.IsDone() || Fillet.NbSolutions()==0) {
908 status = ChFi2d_ComputationError;
909 return filletEdge;
910 }
911 else if (Fillet.NbSolutions() >= 1) {
912 status = ChFi2d_IsDone;
913 Standard_Integer numsol = 1;
914 Standard_Integer nsol = 1;
915 TopoDS_Vertex Vertex1,Vertex2;
916 gp_Pnt2d Ptg1,Ptg2;
917 Standard_Real dist;
918 Standard_Real dist1 = 1.e40;
919 Standard_Boolean inside = Standard_False;
920 while (nsol<=Fillet.NbSolutions()) {
921 Fillet.Tangency1(nsol,PU1,PU2,Ptg1);
922 dist = Ptg1.Distance(p);
923 if (basisC1->DynamicType() == STANDARD_TYPE(Geom2d_Line)) {
924 inside = (PU2<param1 && PU2>param2) || (PU2<param2 && PU2>param1);
925 if ( inside && dist < dist1) {
926 numsol = nsol;
927 dist1 = dist;
928 } // if ((((inside && ...
929 } // if (C1->DynamicType( ...
930 else {
931 Fillet.Tangency2(nsol,PPU1,PPU2,Ptg2);
932 dist = Ptg2.Distance(p);
933 inside = (PPU2<param3 && PPU2>param4) || (PPU2<param4 && PPU2>param3);
81bba717 934 // case of arc of circle passing on the sewing
7fd59977 935 if ( ( basisC2->DynamicType() == STANDARD_TYPE(Geom2d_Circle) ) &&
c6541a0c 936 ( (2*M_PI<param3 && 2*M_PI>param4) || (2*M_PI<param4 && 2*M_PI>param3) ) ) {
7fd59977 937 // cas param3<param4
c6541a0c
D
938 inside = (param3<PPU2 && PPU2<2*M_PI)
939 || (0<=PPU2 && PPU2<param4-2*M_PI);
7fd59977 940 // cas param4<param3
c6541a0c
D
941 inside = inside || (param4<PPU2 && PPU2<2*M_PI)
942 || (0<=PPU2 && PPU2<param3-2*M_PI);
7fd59977 943 }
944 if ( inside && dist < dist1) {
945 numsol = nsol;
946 dist1 = dist;
947 } // if ((((param3 ...
948 } // else ...
949 nsol++;
950 } // while (nsol ...
951 gp_Circ2d cir(Fillet.ThisSolution(numsol));
952 Handle(Geom2d_Circle) circle = new Geom2d_Circle(cir);
953
954 BRep_Builder B;
955 BRepAdaptor_Surface Adaptor3dSurface(refFace);
956 Handle(Geom_Plane) refSurf = new Geom_Plane(Adaptor3dSurface.Plane());
957 Fillet.Tangency1(numsol,U1,U2,Ptg1);
958 Fillet.Tangency2(numsol,Vv1,Vv2,Ptg2);
959
81bba717 960 // check the validity of parameters
f10018ad
J
961 //// modified by jgv, 08.08.2011 for bug 0022695 ////
962 //inside = (U2<param1 && U2>param2) || (U2<param2 && U2>param1);
963 inside = (U2 < param1 && U2 >= param2) || (U2 <= param2 && U2 > param1);
964 /////////////////////////////////////////////////////
7fd59977 965 if ( (basisC1->DynamicType() == STANDARD_TYPE(Geom2d_Circle))
c6541a0c 966 && ( (2*M_PI<param1 && 2*M_PI>param2) || (2*M_PI<param2 && 2*M_PI>param1) ) ) {
81bba717 967 // arc of circle containing the circle origin
968 // case param1<param2
c6541a0c 969 inside = (param1<U2 && U2<2*M_PI) || (0<=U2 && U2<param2-2*M_PI);
81bba717 970 // case param2<param1
c6541a0c 971 inside = inside || (param2<U2 && U2<2*M_PI) || (0<=U2 && U2<param1-2*M_PI);
7fd59977 972 }
973 if (!inside) {
974 status = ChFi2d_ComputationError;
975 return filletEdge;
976 }
977
f10018ad
J
978 //// modified by jgv, 08.08.2011 for bug 0022695 ////
979 //inside = (Vv2<param3 && Vv2>param4) || (Vv2<param4 && Vv2>param3);
980 inside = (Vv2 < param3 && Vv2 >= param4) || (Vv2 <= param4 && Vv2 > param3);
981 /////////////////////////////////////////////////////
7fd59977 982 if ( (basisC2->DynamicType() == STANDARD_TYPE(Geom2d_Circle))
c6541a0c 983 && ( (2*M_PI<param3 && 2*M_PI>param4) || (2*M_PI<param4 && 2*M_PI>param3) ) ) {
81bba717 984 // arc of circle containing the circle origin
7fd59977 985 // cas param3<param4
c6541a0c 986 inside = (param3<Vv2 && Vv2<2*M_PI) || (0<=Vv2 && Vv2<param4-2*M_PI);
7fd59977 987 // cas param4<param3
c6541a0c 988 inside = inside || (param4<Vv2 && Vv2<2*M_PI) || (0<=Vv2 && Vv2<param3-2*M_PI);
7fd59977 989 }
990 if (!inside) {
991 status = ChFi2d_ComputationError;
992 return filletEdge;
993 }
994
995 gp_Pnt p1 = Adaptor3dSurface.Value(Ptg1.X(), Ptg1.Y());
996 gp_Pnt p2 = Adaptor3dSurface.Value(Ptg2.X(), Ptg2.Y());
997 B.MakeVertex(Vertex1, p1,Tol);
998 NewExtr1 = Vertex1;
999 if (Abs(U2-ufirst1) <= Precision::PConfusion()) {
1000 NewExtr1 = V1;
1001 }
1002 if (Abs(U2-ulast1) <= Precision::PConfusion()) {
1003 NewExtr1 = V2;
1004 }
1005
1006 B.MakeVertex(Vertex2, p2,Tol);
1007 NewExtr2 = Vertex2;
1008 if (Abs(Vv2-ufirst2) <= Precision::PConfusion()) {
1009 NewExtr2 = V3;
1010 }
1011 if (Abs(Vv2-ulast2) <= Precision::PConfusion()) {
1012 NewExtr2 = V4;
1013 }
1014
1015 //=======================================================================
81bba717 1016 // Update tops of the fillet. +
7fd59977 1017 //=======================================================================
1018 gp_Pnt Pntbid;
1019 gp_Pnt2d sommet;
1020 Pntbid = BRep_Tool::Pnt(V);
1021 sommet = gp_Pnt2d(Pntbid.X(),Pntbid.Y());
1022
1023 gp_Pnt pntBid;
1024 gp_Pnt2d somBid;
1025 if (V1.IsSame(V)) {
1026 pntBid = BRep_Tool::Pnt(V2);
1027 somBid = gp_Pnt2d(pntBid.X(),pntBid.Y());
1028 }
1029 else {
1030 pntBid = BRep_Tool::Pnt(V1);
1031 somBid = gp_Pnt2d(pntBid.X(),pntBid.Y());
1032 }
1033
1034 gp_Vec2d vec;
1035 ElCLib::D1(U1,cir,Ptg1,vec);
1036
1037 gp_Vec2d vec1;
1038 if (basisC1->DynamicType() == STANDARD_TYPE(Geom2d_Circle)) {
1039 Handle(Geom2d_Circle) CC1 = Handle(Geom2d_Circle)::DownCast(basisC1);
1040 gp_Circ2d cir2d(CC1->Circ2d());
1041 Standard_Real par = ElCLib::Parameter(cir2d,Ptg1);
1042 gp_Pnt2d Pd;
1043 ElCLib::D1(par,cir2d,Pd,vec1);
1044 } // if (C1->DynamicType() ...
1045 else if (basisC1->DynamicType() == STANDARD_TYPE(Geom2d_Line)) {
1046 Handle(Geom2d_Line) CC1 = Handle(Geom2d_Line)::DownCast(basisC1);
1047 gp_Lin2d lin2d(CC1->Lin2d());
1048 Standard_Real par = ElCLib::Parameter(lin2d,sommet);
1049 vec1 = gp_Vec2d(sommet.X()-somBid.X(),sommet.Y()-somBid.Y());
1050 gp_Pnt2d Pd;
1051 ElCLib::D1(par,lin2d,Pd,vec1);
1052 } // else if ...
1053
1054 if (OE1 == TopAbs_REVERSED) {
1055 vec1.Reverse();
1056 } // if (OE1 ...
51740958 1057 Standard_Boolean Sense = ( vec1*vec ) > 0.;
c6541a0c
D
1058 if (U1 > Vv1 && U1 > 2.*M_PI) {
1059 ElCLib::AdjustPeriodic(0.,2.*M_PI,Precision::Confusion(),U1,Vv1);
7fd59977 1060 } // if (U1 ...
0ebaa4db 1061 if ( (O1 == TopAbs_FORWARD && OE1 == TopAbs_FORWARD) ||
1062 (O1 == TopAbs_REVERSED && OE1 == TopAbs_REVERSED) ) {
7fd59977 1063 filletEdge = BRepLib_MakeEdge(circle, refSurf,
1064 NewExtr1, NewExtr2, U1, Vv1);
1065 } // if (O1 == ...
1066 else {
1067 filletEdge = BRepLib_MakeEdge(circle, refSurf,
1068 NewExtr2, NewExtr1, Vv1, U1);
1069 } // else ...
1070 if (!Sense) {
1071 TopAbs_Orientation S1 = filletEdge.Orientation();
0ebaa4db 1072 if ((O1 == TopAbs_FORWARD && OE1 == TopAbs_FORWARD) ||
1073 (O1 == TopAbs_REVERSED && OE1 == TopAbs_REVERSED) ) {
7fd59977 1074 filletEdge = BRepLib_MakeEdge(circle, refSurf,
1075 NewExtr2, NewExtr1, Vv1, U1);
1076 }
1077 else {
1078 filletEdge = BRepLib_MakeEdge(circle, refSurf,
1079 NewExtr1, NewExtr2, U1, Vv1);
1080 }
1081 if (S1 == TopAbs_FORWARD) {
1082 filletEdge.Orientation(TopAbs_REVERSED);
1083 }
1084 else {
1085 filletEdge.Orientation(TopAbs_FORWARD);
1086 }
1087 } // if (!Sense
1088
1089 } // else if
1090
1091 BRepLib::BuildCurves3d(filletEdge);
1092 return filletEdge;
1093} // BuildFilletEdge
1094
1095
1096//=======================================================================
1097//function : IsAFillet
1098//purpose :
1099//=======================================================================
1100
1101Standard_Boolean ChFi2d_Builder::IsAFillet(const TopoDS_Edge& E) const
1102{
1103 Standard_Integer i = 1;
1104 while (i <= fillets.Length()) {
1105 const TopoDS_Edge& currentEdge = TopoDS::Edge(fillets.Value(i));
1106 if (currentEdge.IsSame(E)) return Standard_True;
1107 i++;
1108 }
1109 return Standard_False;
1110} // IsAFillet
1111
1112
1113//=======================================================================
1114//function : IsAChamfer
1115//purpose :
1116//=======================================================================
1117
1118Standard_Boolean ChFi2d_Builder::IsAChamfer(const TopoDS_Edge& E) const
1119{
1120 Standard_Integer i = 1;
1121 while (i <= chamfers.Length()) {
1122 const TopoDS_Edge& currentEdge = TopoDS::Edge(chamfers.Value(i));
1123 if (currentEdge.IsSame(E)) return Standard_True;
1124 i++;
1125 }
1126 return Standard_False;
1127} // IsAChamfer
1128
1129
1130
1131//=======================================================================
1132//function : IsLineOrCircle
1133//purpose :
1134//=======================================================================
1135
1136Standard_Boolean IsLineOrCircle(const TopoDS_Edge& E,
1137 const TopoDS_Face& F)
1138{
1139 Standard_Real first, last;
1140 TopLoc_Location loc;
1141// syntaxe invalide sur NT
1142// const Handle(Geom2d_Curve)& C =
1143// BRep_Tool::CurveOnSurface(E,F,first,last);
1144 Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,first,last);
1145 Handle(Geom2d_Curve) basisC;
1146 Handle(Geom2d_TrimmedCurve) TC = Handle(Geom2d_TrimmedCurve)::DownCast(C);
1147 if (!TC.IsNull())
a9dde4a3 1148 basisC = TC->BasisCurve();
7fd59977 1149 else
a9dde4a3 1150 basisC = C;
7fd59977 1151
1152 if ( basisC->DynamicType() == STANDARD_TYPE(Geom2d_Circle)
1153 || basisC->DynamicType() == STANDARD_TYPE(Geom2d_Line) ) {
1154 return Standard_True;
1155 }
1156 else {
1157 return Standard_False;
1158 } // else ...
1159} // IsLineOrCircle