0026377: Passing Handle objects as arguments to functions as non-const reference...
[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
642 fillets.Append(NewEdge);
643 else // the new edge is a chamfer
644 chamfers.Append(NewEdge);
645 if (history.IsBound(E1)) history.UnBind(E1);
646 if ( status != ChFi2d_FirstEdgeDegenerated
647 && status != ChFi2d_BothEdgesDegenerated) {
648 if (!E1.IsSame(TrimE1)) history.Bind(E1, TrimE1);
649 }
650 if (history.IsBound(E2)) history.UnBind(E2);
651 if ( status != ChFi2d_LastEdgeDegenerated
652 && status != ChFi2d_BothEdgesDegenerated) {
653 if (!E2.IsSame(TrimE2)) history.Bind(E2, TrimE2);
654 }
655} // UpDateHistory
656
657
658//=======================================================================
659//function : UpDateHistory
660//purpose :
661//=======================================================================
662void ChFi2d_Builder::UpDateHistory(const TopoDS_Edge& E1,
663 const TopoDS_Edge& E2,
664 const TopoDS_Edge& TrimE1,
665 const TopoDS_Edge& TrimE2)
666{
667
668
669 if (history.IsBound(E1)) history.UnBind(E1);
670 if (!E1.IsSame(TrimE1)) history.Bind(E1, TrimE1);
671 if (history.IsBound(E2)) history.UnBind(E2);
672 if (!E2.IsSame(TrimE2)) history.Bind(E2, TrimE2);
673} // UpDateHistory
674
675
676//=======================================================================
677//function : BasisEdge
678//purpose :
679//=======================================================================
680const TopoDS_Edge& ChFi2d_Builder::BasisEdge(const TopoDS_Edge& E) const
681{
682 TopTools_DataMapIteratorOfDataMapOfShapeShape iterator(history);
683 TopoDS_Edge anEdge;
684 while (iterator.More()) {
685 anEdge = TopoDS::Edge(iterator.Value());
686 if (anEdge.IsSame(E)) {
687 const TopoDS_Edge& anotherEdge = TopoDS::Edge(iterator.Key());
688 return anotherEdge;
689 } // if (anEdge.IsSame ...
690 iterator.Next();
691 } // while (Iterator.More ...
692 return E;
693} // BasisEdge
694
695
696//=======================================================================
697//function : BuildFilletEdge
698//purpose :
699//=======================================================================
700TopoDS_Edge ChFi2d_Builder::BuildFilletEdge(const TopoDS_Vertex& V,
701 const TopoDS_Edge& AdjEdge1,
702 const TopoDS_Edge& AdjEdge2,
703 const Standard_Real Radius,
704 TopoDS_Vertex& NewExtr1,
705 TopoDS_Vertex& NewExtr2)
706{
707 TopoDS_Edge E1, E2;
708 E1 = AdjEdge1;
709 E2 = AdjEdge2;
710 TopoDS_Vertex V1 = TopExp::FirstVertex(E1);
711 TopoDS_Vertex V2 = TopExp::LastVertex(E1);
712 TopoDS_Vertex V3 = TopExp::FirstVertex(E2);
713 TopoDS_Vertex V4 = TopExp::LastVertex(E2);
714
715 //========================================================================
81bba717 716 // The first arc is found. +
7fd59977 717 //========================================================================
718
96a95605
DB
719 TopAbs_Orientation O1;
720 TopAbs_Orientation OE1;
7fd59977 721 OE1 = E1.Orientation();
7fd59977 722 E1.Orientation(TopAbs_FORWARD);
723 E2.Orientation(TopAbs_FORWARD);
724 TopoDS_Shape aLocalShape = E1.EmptyCopied();
725 TopoDS_Edge Ebid1 = TopoDS::Edge(aLocalShape);
726 aLocalShape = E2.EmptyCopied();
727 TopoDS_Edge Ebid2 = TopoDS::Edge(aLocalShape);
728// TopoDS_Edge Ebid1 = TopoDS::Edge(E1.EmptyCopied());
729// TopoDS_Edge Ebid2 = TopoDS::Edge(E2.EmptyCopied());
730 Standard_Real param1,param2,param3,param4;
731
732 //========================================================================
81bba717 733 // Save non-modified parts of edges concerned. +
7fd59977 734 //========================================================================
735
736 if (V1.IsSame(V)) {
737 param1 = BRep_Tool::Parameter(V1,E1);
738 param2 = BRep_Tool::Parameter(V2,E1);
739 O1 = V2.Orientation();
740 }
741 else {
742 param1 = BRep_Tool::Parameter(V2,E1);
743 param2 = BRep_Tool::Parameter(V1,E1);
744 O1 = V1.Orientation();
745 }
746 if (V3.IsSame(V)) {
747 param3 = BRep_Tool::Parameter(V3,E2);
748 param4 = BRep_Tool::Parameter(V4,E2);
7fd59977 749 }
750 else {
751 param3 = BRep_Tool::Parameter(V4,E2);
752 param4 = BRep_Tool::Parameter(V3,E2);
7fd59977 753 }
754
755 //========================================================================
81bba717 756 // Restore geometric supports. +
7fd59977 757 //========================================================================
758
759 Handle(Geom2d_Curve) C1,C2;
760 Standard_Real ufirst1,ulast1,ufirst2,ulast2,U1,U2,PU1,PU2,Vv1,Vv2;
761 Standard_Real PPU1,PPU2;
762 C1 = BRep_Tool::CurveOnSurface(E1,newFace,ufirst1,ulast1);
763 C2 = BRep_Tool::CurveOnSurface(E2,newFace,ufirst2,ulast2);
764
765 //========================================================================
81bba717 766 // Determination of the face for fillet. +
7fd59977 767 //========================================================================
768
769 gp_Pnt2d p;
770 gp_Vec2d Ve1,Ve2;
771 gp_Vec2d Ve3,Ve4;
772 Standard_Boolean Sens1 , Sens2;
773
774 Handle(Geom2d_Curve) basisC1,basisC2;
775 Handle(Geom2d_TrimmedCurve) T1 = Handle(Geom2d_TrimmedCurve)::DownCast(C1);
776 if (!T1.IsNull())
777 basisC1 = Handle(Geom2d_Curve)::DownCast(T1->BasisCurve());
778 else
779 basisC1 = Handle(Geom2d_Curve)::DownCast(C1);
780 Handle(Geom2d_TrimmedCurve) T2 = Handle(Geom2d_TrimmedCurve)::DownCast(C2);
781 if (!T2.IsNull())
782 basisC2 = Handle(Geom2d_Curve)::DownCast(T2->BasisCurve());
783 else
784 basisC2 = Handle(Geom2d_Curve)::DownCast(C2);
785
786 if (basisC1->DynamicType() == STANDARD_TYPE(Geom2d_Circle)) {
787 Handle(Geom2d_Circle) CC1 = Handle(Geom2d_Circle)::DownCast(basisC1);
788 ElCLib::D1(param1,CC1->Circ2d(),p,Ve1);
789 Sens1 = (CC1->Circ2d()).IsDirect();
790 } // if (C1->DynamicType() ...
791 else {
792 Handle(Geom2d_Line) CC1 = Handle(Geom2d_Line)::DownCast(basisC1);
793 ElCLib::D1(param1,CC1->Lin2d(),p,Ve1);
794 Sens1=Standard_True;
795 } // else ...
796 if (basisC2->DynamicType() == STANDARD_TYPE(Geom2d_Circle)) {
797 Handle(Geom2d_Circle) CC2 = Handle(Geom2d_Circle)::DownCast(basisC2);
798 ElCLib::D1(param3,CC2->Circ2d(),p,Ve2);
799 Sens2 = (CC2->Circ2d()).IsDirect();
800 } // if if (C2->DynamicType() ...
801 else {
802 Handle(Geom2d_Line) CC2 = Handle(Geom2d_Line)::DownCast(basisC2);
803 ElCLib::D1(param3,CC2->Lin2d(),p,Ve2);
804 Sens2=Standard_True;
805 } // else ...
806
807 TopoDS_Edge filletEdge;
808
809 Standard_Real cross = Ve1.Crossed(Ve2);
810 Ve3 = Ve1;
811 Ve4 = Ve2;
812
81bba717 813 // processing of tangency or downcast point
7fd59977 814 if (Ve1.IsParallel(Ve2,Precision::Angular())) {
81bba717 815 // Ve1 and Ve2 are parallel : cross at 0
7fd59977 816 cross = 0.;
817 if (param1<param2) {
818 Ve3 = -Ve1;
819 }
820 if (param3>param4) {
821 Ve4 = -Ve2;
822 }
823
824 if (! Ve4.IsOpposite(Ve3,Precision::Angular())) {
81bba717 825 // There is a true tangency point and the calculation is stopped
7fd59977 826 status = ChFi2d_TangencyError;
827 return filletEdge;
828 }
81bba717 829 // Otherwise this is a downcast point, and the calculation is continued
7fd59977 830 }
831
832 GccEnt_Position Qual1,Qual2;
833 if (cross < 0.) {
834 if (param3 > param4 ) {
835 if(Sens1 == Standard_True){
836 Qual1 = GccEnt_enclosed;
837 }
838 else {
839 Qual1 = GccEnt_outside;
840 }
841 }
842 else {
843 if(Sens1 == Standard_True){
844 Qual1 = GccEnt_outside;
845 }
846 else {
847 Qual1 = GccEnt_enclosed;
848 }
849 }
850 if (param1 > param2) {
851 if(Sens2 == Standard_True)
852 Qual2 = GccEnt_outside;
853 else
854 Qual2 = GccEnt_enclosed;
855 }
856 else {
857 if(Sens2 == Standard_True)
858 Qual2 = GccEnt_enclosed;
859 else
860 Qual2 = GccEnt_outside;
861 }
862 } // if (cross < 0 ...
863 else {
864 if (param3 > param4 ) {
865 if( Sens1 == Standard_True)
866 Qual1 = GccEnt_outside;
867 else
868 Qual1 = GccEnt_enclosed;
869 }
870 else {
871 if( Sens1 == Standard_True)
872 Qual1 = GccEnt_enclosed;
873 else
874 Qual1 = GccEnt_outside;
875 }
876 if (param1 > param2 ) {
877 if( Sens2 == Standard_True)
878 Qual2 = GccEnt_enclosed;
879 else
880 Qual2 = GccEnt_outside;
881 }
882 else {
883 if( Sens2 == Standard_True)
884 Qual2 = GccEnt_outside;
885 else
886 Qual2 = GccEnt_enclosed;
887 }
888 } // else ...
889
890 Standard_Real Tol = Precision::Confusion();
891 Geom2dGcc_Circ2d2TanRad Fillet(Geom2dGcc_QualifiedCurve(basisC1,Qual1),
892 Geom2dGcc_QualifiedCurve(basisC2,Qual2),
893 Radius, Tol);
894 if (!Fillet.IsDone() || Fillet.NbSolutions()==0) {
895 status = ChFi2d_ComputationError;
896 return filletEdge;
897 }
898 else if (Fillet.NbSolutions() >= 1) {
899 status = ChFi2d_IsDone;
900 Standard_Integer numsol = 1;
901 Standard_Integer nsol = 1;
902 TopoDS_Vertex Vertex1,Vertex2;
903 gp_Pnt2d Ptg1,Ptg2;
904 Standard_Real dist;
905 Standard_Real dist1 = 1.e40;
906 Standard_Boolean inside = Standard_False;
907 while (nsol<=Fillet.NbSolutions()) {
908 Fillet.Tangency1(nsol,PU1,PU2,Ptg1);
909 dist = Ptg1.Distance(p);
910 if (basisC1->DynamicType() == STANDARD_TYPE(Geom2d_Line)) {
911 inside = (PU2<param1 && PU2>param2) || (PU2<param2 && PU2>param1);
912 if ( inside && dist < dist1) {
913 numsol = nsol;
914 dist1 = dist;
915 } // if ((((inside && ...
916 } // if (C1->DynamicType( ...
917 else {
918 Fillet.Tangency2(nsol,PPU1,PPU2,Ptg2);
919 dist = Ptg2.Distance(p);
920 inside = (PPU2<param3 && PPU2>param4) || (PPU2<param4 && PPU2>param3);
81bba717 921 // case of arc of circle passing on the sewing
7fd59977 922 if ( ( basisC2->DynamicType() == STANDARD_TYPE(Geom2d_Circle) ) &&
c6541a0c 923 ( (2*M_PI<param3 && 2*M_PI>param4) || (2*M_PI<param4 && 2*M_PI>param3) ) ) {
7fd59977 924 // cas param3<param4
c6541a0c
D
925 inside = (param3<PPU2 && PPU2<2*M_PI)
926 || (0<=PPU2 && PPU2<param4-2*M_PI);
7fd59977 927 // cas param4<param3
c6541a0c
D
928 inside = inside || (param4<PPU2 && PPU2<2*M_PI)
929 || (0<=PPU2 && PPU2<param3-2*M_PI);
7fd59977 930 }
931 if ( inside && dist < dist1) {
932 numsol = nsol;
933 dist1 = dist;
934 } // if ((((param3 ...
935 } // else ...
936 nsol++;
937 } // while (nsol ...
938 gp_Circ2d cir(Fillet.ThisSolution(numsol));
939 Handle(Geom2d_Circle) circle = new Geom2d_Circle(cir);
940
941 BRep_Builder B;
942 BRepAdaptor_Surface Adaptor3dSurface(refFace);
943 Handle(Geom_Plane) refSurf = new Geom_Plane(Adaptor3dSurface.Plane());
944 Fillet.Tangency1(numsol,U1,U2,Ptg1);
945 Fillet.Tangency2(numsol,Vv1,Vv2,Ptg2);
946
81bba717 947 // check the validity of parameters
f10018ad
J
948 //// modified by jgv, 08.08.2011 for bug 0022695 ////
949 //inside = (U2<param1 && U2>param2) || (U2<param2 && U2>param1);
950 inside = (U2 < param1 && U2 >= param2) || (U2 <= param2 && U2 > param1);
951 /////////////////////////////////////////////////////
7fd59977 952 if ( (basisC1->DynamicType() == STANDARD_TYPE(Geom2d_Circle))
c6541a0c 953 && ( (2*M_PI<param1 && 2*M_PI>param2) || (2*M_PI<param2 && 2*M_PI>param1) ) ) {
81bba717 954 // arc of circle containing the circle origin
955 // case param1<param2
c6541a0c 956 inside = (param1<U2 && U2<2*M_PI) || (0<=U2 && U2<param2-2*M_PI);
81bba717 957 // case param2<param1
c6541a0c 958 inside = inside || (param2<U2 && U2<2*M_PI) || (0<=U2 && U2<param1-2*M_PI);
7fd59977 959 }
960 if (!inside) {
961 status = ChFi2d_ComputationError;
962 return filletEdge;
963 }
964
f10018ad
J
965 //// modified by jgv, 08.08.2011 for bug 0022695 ////
966 //inside = (Vv2<param3 && Vv2>param4) || (Vv2<param4 && Vv2>param3);
967 inside = (Vv2 < param3 && Vv2 >= param4) || (Vv2 <= param4 && Vv2 > param3);
968 /////////////////////////////////////////////////////
7fd59977 969 if ( (basisC2->DynamicType() == STANDARD_TYPE(Geom2d_Circle))
c6541a0c 970 && ( (2*M_PI<param3 && 2*M_PI>param4) || (2*M_PI<param4 && 2*M_PI>param3) ) ) {
81bba717 971 // arc of circle containing the circle origin
7fd59977 972 // cas param3<param4
c6541a0c 973 inside = (param3<Vv2 && Vv2<2*M_PI) || (0<=Vv2 && Vv2<param4-2*M_PI);
7fd59977 974 // cas param4<param3
c6541a0c 975 inside = inside || (param4<Vv2 && Vv2<2*M_PI) || (0<=Vv2 && Vv2<param3-2*M_PI);
7fd59977 976 }
977 if (!inside) {
978 status = ChFi2d_ComputationError;
979 return filletEdge;
980 }
981
982 gp_Pnt p1 = Adaptor3dSurface.Value(Ptg1.X(), Ptg1.Y());
983 gp_Pnt p2 = Adaptor3dSurface.Value(Ptg2.X(), Ptg2.Y());
984 B.MakeVertex(Vertex1, p1,Tol);
985 NewExtr1 = Vertex1;
986 if (Abs(U2-ufirst1) <= Precision::PConfusion()) {
987 NewExtr1 = V1;
988 }
989 if (Abs(U2-ulast1) <= Precision::PConfusion()) {
990 NewExtr1 = V2;
991 }
992
993 B.MakeVertex(Vertex2, p2,Tol);
994 NewExtr2 = Vertex2;
995 if (Abs(Vv2-ufirst2) <= Precision::PConfusion()) {
996 NewExtr2 = V3;
997 }
998 if (Abs(Vv2-ulast2) <= Precision::PConfusion()) {
999 NewExtr2 = V4;
1000 }
1001
1002 //=======================================================================
81bba717 1003 // Update tops of the fillet. +
7fd59977 1004 //=======================================================================
1005 gp_Pnt Pntbid;
1006 gp_Pnt2d sommet;
1007 Pntbid = BRep_Tool::Pnt(V);
1008 sommet = gp_Pnt2d(Pntbid.X(),Pntbid.Y());
1009
1010 gp_Pnt pntBid;
1011 gp_Pnt2d somBid;
1012 if (V1.IsSame(V)) {
1013 pntBid = BRep_Tool::Pnt(V2);
1014 somBid = gp_Pnt2d(pntBid.X(),pntBid.Y());
1015 }
1016 else {
1017 pntBid = BRep_Tool::Pnt(V1);
1018 somBid = gp_Pnt2d(pntBid.X(),pntBid.Y());
1019 }
1020
1021 gp_Vec2d vec;
1022 ElCLib::D1(U1,cir,Ptg1,vec);
1023
1024 gp_Vec2d vec1;
1025 if (basisC1->DynamicType() == STANDARD_TYPE(Geom2d_Circle)) {
1026 Handle(Geom2d_Circle) CC1 = Handle(Geom2d_Circle)::DownCast(basisC1);
1027 gp_Circ2d cir2d(CC1->Circ2d());
1028 Standard_Real par = ElCLib::Parameter(cir2d,Ptg1);
1029 gp_Pnt2d Pd;
1030 ElCLib::D1(par,cir2d,Pd,vec1);
1031 } // if (C1->DynamicType() ...
1032 else if (basisC1->DynamicType() == STANDARD_TYPE(Geom2d_Line)) {
1033 Handle(Geom2d_Line) CC1 = Handle(Geom2d_Line)::DownCast(basisC1);
1034 gp_Lin2d lin2d(CC1->Lin2d());
1035 Standard_Real par = ElCLib::Parameter(lin2d,sommet);
1036 vec1 = gp_Vec2d(sommet.X()-somBid.X(),sommet.Y()-somBid.Y());
1037 gp_Pnt2d Pd;
1038 ElCLib::D1(par,lin2d,Pd,vec1);
1039 } // else if ...
1040
1041 if (OE1 == TopAbs_REVERSED) {
1042 vec1.Reverse();
1043 } // if (OE1 ...
51740958 1044 Standard_Boolean Sense = ( vec1*vec ) > 0.;
c6541a0c
D
1045 if (U1 > Vv1 && U1 > 2.*M_PI) {
1046 ElCLib::AdjustPeriodic(0.,2.*M_PI,Precision::Confusion(),U1,Vv1);
7fd59977 1047 } // if (U1 ...
0ebaa4db 1048 if ( (O1 == TopAbs_FORWARD && OE1 == TopAbs_FORWARD) ||
1049 (O1 == TopAbs_REVERSED && OE1 == TopAbs_REVERSED) ) {
7fd59977 1050 filletEdge = BRepLib_MakeEdge(circle, refSurf,
1051 NewExtr1, NewExtr2, U1, Vv1);
1052 } // if (O1 == ...
1053 else {
1054 filletEdge = BRepLib_MakeEdge(circle, refSurf,
1055 NewExtr2, NewExtr1, Vv1, U1);
1056 } // else ...
1057 if (!Sense) {
1058 TopAbs_Orientation S1 = filletEdge.Orientation();
0ebaa4db 1059 if ((O1 == TopAbs_FORWARD && OE1 == TopAbs_FORWARD) ||
1060 (O1 == TopAbs_REVERSED && OE1 == TopAbs_REVERSED) ) {
7fd59977 1061 filletEdge = BRepLib_MakeEdge(circle, refSurf,
1062 NewExtr2, NewExtr1, Vv1, U1);
1063 }
1064 else {
1065 filletEdge = BRepLib_MakeEdge(circle, refSurf,
1066 NewExtr1, NewExtr2, U1, Vv1);
1067 }
1068 if (S1 == TopAbs_FORWARD) {
1069 filletEdge.Orientation(TopAbs_REVERSED);
1070 }
1071 else {
1072 filletEdge.Orientation(TopAbs_FORWARD);
1073 }
1074 } // if (!Sense
1075
1076 } // else if
1077
1078 BRepLib::BuildCurves3d(filletEdge);
1079 return filletEdge;
1080} // BuildFilletEdge
1081
1082
1083//=======================================================================
1084//function : IsAFillet
1085//purpose :
1086//=======================================================================
1087
1088Standard_Boolean ChFi2d_Builder::IsAFillet(const TopoDS_Edge& E) const
1089{
1090 Standard_Integer i = 1;
1091 while (i <= fillets.Length()) {
1092 const TopoDS_Edge& currentEdge = TopoDS::Edge(fillets.Value(i));
1093 if (currentEdge.IsSame(E)) return Standard_True;
1094 i++;
1095 }
1096 return Standard_False;
1097} // IsAFillet
1098
1099
1100//=======================================================================
1101//function : IsAChamfer
1102//purpose :
1103//=======================================================================
1104
1105Standard_Boolean ChFi2d_Builder::IsAChamfer(const TopoDS_Edge& E) const
1106{
1107 Standard_Integer i = 1;
1108 while (i <= chamfers.Length()) {
1109 const TopoDS_Edge& currentEdge = TopoDS::Edge(chamfers.Value(i));
1110 if (currentEdge.IsSame(E)) return Standard_True;
1111 i++;
1112 }
1113 return Standard_False;
1114} // IsAChamfer
1115
1116
1117
1118//=======================================================================
1119//function : IsLineOrCircle
1120//purpose :
1121//=======================================================================
1122
1123Standard_Boolean IsLineOrCircle(const TopoDS_Edge& E,
1124 const TopoDS_Face& F)
1125{
1126 Standard_Real first, last;
1127 TopLoc_Location loc;
1128// syntaxe invalide sur NT
1129// const Handle(Geom2d_Curve)& C =
1130// BRep_Tool::CurveOnSurface(E,F,first,last);
1131 Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,first,last);
1132 Handle(Geom2d_Curve) basisC;
1133 Handle(Geom2d_TrimmedCurve) TC = Handle(Geom2d_TrimmedCurve)::DownCast(C);
1134 if (!TC.IsNull())
1135 basisC = Handle(Geom2d_Curve)::DownCast(TC->BasisCurve());
1136 else
1137 basisC = Handle(Geom2d_Curve)::DownCast(C);
1138
1139 if ( basisC->DynamicType() == STANDARD_TYPE(Geom2d_Circle)
1140 || basisC->DynamicType() == STANDARD_TYPE(Geom2d_Line) ) {
1141 return Standard_True;
1142 }
1143 else {
1144 return Standard_False;
1145 } // else ...
1146} // IsLineOrCircle