1 // Created on: 1995-07-07
2 // Created by: Joelle CHAUVET
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <BRep_Builder.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BRepAdaptor_Surface.hxx>
21 #include <BRepLib.hxx>
22 #include <BRepLib_MakeEdge.hxx>
23 #include <BRepLib_MakeFace.hxx>
25 #include <ChFi2d_Builder.hxx>
27 #include <Geom2d_Circle.hxx>
28 #include <Geom2d_Curve.hxx>
29 #include <Geom2d_Line.hxx>
30 #include <Geom2d_TrimmedCurve.hxx>
31 #include <Geom2dGcc_Circ2d2TanRad.hxx>
32 #include <Geom2dGcc_QualifiedCurve.hxx>
33 #include <Geom2dInt_GInter.hxx>
34 #include <Geom_Circle.hxx>
35 #include <Geom_Curve.hxx>
36 #include <Geom_Line.hxx>
37 #include <Geom_Plane.hxx>
38 #include <Geom_Surface.hxx>
39 #include <gp_Circ2d.hxx>
41 #include <gp_Pnt2d.hxx>
42 #include <gp_Vec2d.hxx>
43 #include <Precision.hxx>
44 #include <TopAbs_Orientation.hxx>
46 #include <TopExp_Explorer.hxx>
47 #include <TopLoc_Location.hxx>
49 #include <TopoDS_Edge.hxx>
50 #include <TopoDS_Face.hxx>
51 #include <TopoDS_Vertex.hxx>
52 #include <TopoDS_Wire.hxx>
53 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
54 #include <TopTools_IndexedMapOfShape.hxx>
56 static Standard_Boolean IsIssuedFrom(const TopoDS_Edge& E,
57 const TopTools_IndexedMapOfShape& Map,
58 TopoDS_Edge& BasisEdge);
60 static Standard_Boolean IsLineOrCircle(const TopoDS_Edge& E,
61 const TopoDS_Face& F);
64 //=======================================================================
65 //function : ChFi2d_Builder
67 //=======================================================================
69 ChFi2d_Builder::ChFi2d_Builder() : status (ChFi2d_NotPlanar)
73 //=======================================================================
74 //function : ChFi2d_Builder
76 //=======================================================================
78 ChFi2d_Builder::ChFi2d_Builder(const TopoDS_Face& F)
81 status = ChFi2d_NoFace;
85 // syntaxe invalide sur NT
86 // const Handle(Geom_Surface)& surf = BRep_Tool::Surface( F, Loc);
87 // if (surf->IsKind(STANDARD_TYPE(Geom_Plane))) {
88 if ( BRep_Tool::Surface( F, Loc)
89 -> IsKind(STANDARD_TYPE(Geom_Plane)) ) {
90 newFace = refFace = F;
91 newFace.Orientation(TopAbs_FORWARD);
92 BRepLib::BuildCurves3d(newFace);
93 status = ChFi2d_Ready;
95 else status = ChFi2d_NotPlanar;
98 //=======================================================================
101 //=======================================================================
103 void ChFi2d_Builder::Init(const TopoDS_Face& F)
106 status = ChFi2d_NoFace;
113 // syntaxe invalide sur NT
114 // const Handle(Geom_Surface)& surf = BRep_Tool::Surface( F, Loc);
115 // if (surf->IsKind(STANDARD_TYPE(Geom_Plane))) {
116 if ( BRep_Tool::Surface( F, Loc)
117 -> IsKind(STANDARD_TYPE(Geom_Plane)) ) {
118 newFace = refFace = F;
119 newFace.Orientation(TopAbs_FORWARD);
120 status = ChFi2d_Ready;
122 else status = ChFi2d_NotPlanar;
126 //=======================================================================
129 //=======================================================================
131 void ChFi2d_Builder::Init(const TopoDS_Face& RefFace,
132 const TopoDS_Face& ModFace)
134 if (RefFace.IsNull() || ModFace.IsNull()) {
135 status = ChFi2d_NoFace;
142 // syntaxe invalide sur NT
143 // const Handle(Geom_Surface)& surf = BRep_Tool::Surface( RefFace, Loc);
144 // if (!surf->IsKind(STANDARD_TYPE(Geom_Plane))) {
145 if ( ! BRep_Tool::Surface( RefFace, loc)
146 -> IsKind(STANDARD_TYPE(Geom_Plane)) ) {
147 status = ChFi2d_NotPlanar;
153 newFace.Orientation(TopAbs_FORWARD);
154 status = ChFi2d_Ready;
156 // Research in newFace all the edges which not appear in RefFace
157 // The sequence newEdges will contains this edges.
159 TopTools_SequenceOfShape newEdges;
160 TopTools_IndexedMapOfShape refEdgesMap;
161 TopExp::MapShapes(refFace, TopAbs_EDGE, refEdgesMap);
162 TopExp_Explorer ex(newFace, TopAbs_EDGE);
164 const TopoDS_Edge& currentEdge = TopoDS::Edge(ex.Current());
165 if (!refEdgesMap.Contains(currentEdge))
166 newEdges.Append(currentEdge);
170 // update of history, fillets and chamfers fields
171 Standard_Integer i = 1;
172 Standard_Real first, last;
173 TopoDS_Edge basisEdge;
174 while ( i <= newEdges.Length()) {
175 const TopoDS_Edge& currentEdge = TopoDS::Edge(newEdges.Value(i));
176 if (IsIssuedFrom(currentEdge, refEdgesMap, basisEdge))
177 history.Bind(basisEdge, currentEdge);
179 // this edge is a chamfer or a fillet
180 // syntaxe invalide sur NT
181 // const Handle(Geom_Curve)& curve =
182 // BRep_Tool::Curve(currentEdge, loc, first, last);
183 Handle(Geom_Curve) curve =
184 BRep_Tool::Curve(currentEdge, loc, first, last);
185 if (curve->IsKind(STANDARD_TYPE(Geom_Circle))) {
186 fillets.Append(currentEdge);
188 else if (curve->IsKind(STANDARD_TYPE(Geom_Line))) {
189 chamfers.Append(currentEdge);
192 status = ChFi2d_InitialisationError;
195 } // this edge is ...
201 //=======================================================================
202 //function : IsIssuedFrom
203 //purpose : Search in <Map> if <E> has a parent edge. If a parent has
204 // been find, this edge is returned in <BasisEdge>, else <E> is
205 // returned in <BasisEdge>.
206 //=======================================================================
207 Standard_Boolean IsIssuedFrom(const TopoDS_Edge& E,
208 const TopTools_IndexedMapOfShape& Map,
209 TopoDS_Edge& BasisEdge)
211 TopLoc_Location loc1, loc2;
212 Standard_Real f1, L1, f2, L2;
213 // syntaxe invalide sur NT
214 // const Handle(Geom_Curve)& c1 =
215 // BRep_Tool::Curve(E, loc1, f1, L1);
216 Handle(Geom_Curve) c1 = BRep_Tool::Curve(E, loc1, f1, L1);
218 for (Standard_Integer i = 1; i <= Map.Extent(); i++ ) {
219 const TopoDS_Edge& currentEdge = TopoDS::Edge(Map.FindKey(i));
220 // syntaxe invalide sur NT
221 // const Handle(Geom_Curve)& c2 =
222 // BRep_Tool::Curve(currentEdge, loc2, f2, L2);
223 Handle(Geom_Curve) c2 = BRep_Tool::Curve(currentEdge, loc2, f2, L2);
225 (((f1 > f2 && f1 < L2) || (L1 > f2 && L1 < L2) ) ||
226 ( (f1 > L2 && f1 < f2) || (L1 > L2 && L1 < f2) )) ) {
227 BasisEdge = currentEdge;
228 BasisEdge.Orientation(E.Orientation());
229 return Standard_True;
231 } // for (Standard_Integer i ...
233 return Standard_False;
237 //=======================================================================
238 //function : AddFillet
240 //=======================================================================
241 TopoDS_Edge ChFi2d_Builder::AddFillet(const TopoDS_Vertex& V,
242 const Standard_Real Radius)
244 TopoDS_Edge adjEdge1, adjEdge2, basisEdge1, basisEdge2;
245 TopoDS_Edge adjEdge1Mod, adjEdge2Mod, fillet;
246 status = ChFi2d::FindConnectedEdges(newFace, V, adjEdge1, adjEdge2);
247 if (status == ChFi2d_ConnexionError) return fillet;
249 if (IsAFillet(adjEdge1) || IsAChamfer(adjEdge1) ||
250 IsAFillet(adjEdge2) || IsAChamfer(adjEdge2)) {
251 status = ChFi2d_NotAuthorized;
253 } // if (IsAFillet ...
255 if (!IsLineOrCircle(adjEdge1,newFace)
256 || !IsLineOrCircle(adjEdge2,newFace) ) {
257 status = ChFi2d_NotAuthorized;
259 } // if (!IsLineOrCircle ...
261 ComputeFillet(V, adjEdge1, adjEdge2, Radius,
262 adjEdge1Mod, adjEdge2Mod, fillet);
263 if (status == ChFi2d_IsDone
264 || status == ChFi2d_FirstEdgeDegenerated
265 || status == ChFi2d_LastEdgeDegenerated
266 || status == ChFi2d_BothEdgesDegenerated) {
267 BuildNewWire(adjEdge1, adjEdge2, adjEdge1Mod, fillet, adjEdge2Mod);
268 basisEdge1 = BasisEdge(adjEdge1);
269 basisEdge2 = BasisEdge(adjEdge2);
270 UpDateHistory(basisEdge1, basisEdge2,
271 adjEdge1Mod, adjEdge2Mod, fillet, 1);
272 status = ChFi2d_IsDone;
273 return TopoDS::Edge(fillets.Value(fillets.Length()));
278 //=======================================================================
279 //function : ModifyFillet
281 //=======================================================================
283 TopoDS_Edge ChFi2d_Builder::ModifyFillet(const TopoDS_Edge& Fillet,
284 const Standard_Real Radius)
286 TopoDS_Vertex aVertex = RemoveFillet(Fillet);
287 TopoDS_Edge aFillet = AddFillet(aVertex, Radius);
291 //=======================================================================
292 //function : RemoveFillet
294 //=======================================================================
296 TopoDS_Vertex ChFi2d_Builder::RemoveFillet(const TopoDS_Edge& Fillet)
298 TopoDS_Vertex commonVertex;
299 Standard_Integer i = 1;
300 Standard_Integer IsFind = Standard_False;
301 while (i <= fillets.Length()) {
302 const TopoDS_Edge& aFillet = TopoDS::Edge(fillets.Value(i));
303 if (aFillet.IsSame(Fillet)) {
305 IsFind = Standard_True;
310 if (!IsFind) return commonVertex;
313 TopoDS_Vertex firstVertex, lastVertex;
314 TopExp::Vertices(Fillet, firstVertex, lastVertex);
317 TopoDS_Edge adjEdge1, adjEdge2;
318 status = ChFi2d::FindConnectedEdges(newFace, firstVertex,
320 if (status == ChFi2d_ConnexionError) return commonVertex;
322 TopoDS_Edge basisEdge1, basisEdge2, E1, E2;
323 // E1 and E2 are the adjacent edges to Fillet
325 if (adjEdge1.IsSame(Fillet)) E1 = adjEdge2;
327 basisEdge1 = BasisEdge(E1);
328 status = ChFi2d::FindConnectedEdges(newFace, lastVertex,adjEdge1, adjEdge2);
329 if (status == ChFi2d_ConnexionError) return commonVertex;
330 if (adjEdge1.IsSame(Fillet)) E2 = adjEdge2;
332 basisEdge2 = BasisEdge(E2);
333 TopoDS_Vertex connectionE1Fillet, connectionE2Fillet;
334 Standard_Boolean hasConnection =
335 ChFi2d::CommonVertex(basisEdge1, basisEdge2, commonVertex);
336 if (!hasConnection) {
337 status = ChFi2d_ConnexionError;
340 hasConnection = ChFi2d::CommonVertex(E1, Fillet, connectionE1Fillet);
341 if (!hasConnection) {
342 status = ChFi2d_ConnexionError;
345 hasConnection = ChFi2d::CommonVertex(E2, Fillet, connectionE2Fillet);
346 if (!hasConnection) {
347 status = ChFi2d_ConnexionError;
351 // rebuild edges on wire
352 TopoDS_Edge newEdge1, newEdge2;
353 TopoDS_Vertex v, v1, v2;
354 BRepLib_MakeEdge makeEdge;
356 Standard_Real first, last;
358 TopExp::Vertices(E1, firstVertex, lastVertex);
359 TopExp::Vertices(basisEdge1, v1, v2);
360 if (v1.IsSame(commonVertex)) v = v2;
363 if ( firstVertex.IsSame(v) || lastVertex.IsSame(v))
364 // It means the edge support only one fillet. In this case
365 // the new edge must be the basis edge.
366 newEdge1 = basisEdge1;
368 // It means the edge support one fillet on each end.
369 if (firstVertex.IsSame(connectionE1Fillet)) {
370 // syntaxe invalide sur NT
371 // const Handle(Geom_Curve)& curve =
372 // BRep_Tool::Curve(E1, loc, first, last);
373 Handle(Geom_Curve) curve = BRep_Tool::Curve(E1, loc, first, last);
374 makeEdge.Init(curve, commonVertex, lastVertex);
375 newEdge1 = makeEdge.Edge();
376 newEdge1.Orientation(E1.Orientation());
377 newEdge1.Location(E1.Location());
378 } // if (firstVertex ...
379 else if (lastVertex.IsSame(connectionE1Fillet)) {
380 // syntax wrong on NT
381 // const Handle(Geom_Curve)& curve =
382 // BRep_Tool::Curve(E1, loc, first, last);
383 Handle(Geom_Curve) curve = BRep_Tool::Curve(E1, loc, first, last);
384 makeEdge.Init(curve, firstVertex, commonVertex);
385 newEdge1 = makeEdge.Edge();
386 newEdge1.Orientation(E1.Orientation());
387 newEdge1.Location(E1.Location());
388 } // else if (lastVertex ...
391 TopExp::Vertices(basisEdge2, v1, v2);
392 if (v1.IsSame(commonVertex)) v = v2;
395 TopExp::Vertices(E2, firstVertex, lastVertex);
396 if ( firstVertex.IsSame(v) || lastVertex.IsSame(v))
397 // It means the edge support only one fillet. In this case
398 // the new edge must be the basis edge.
399 newEdge2 = basisEdge2;
401 // It means the edge support one fillet on each end.
402 if (firstVertex.IsSame(connectionE2Fillet)) {
403 // syntax wrong on NT
404 // const Handle(Geom_Curve)& curve =
405 // BRep_Tool::Curve(E2, loc, first, last);
406 Handle(Geom_Curve) curve = BRep_Tool::Curve(E2, loc, first, last);
407 makeEdge.Init(curve, commonVertex, lastVertex);
408 newEdge2 = makeEdge.Edge();
409 newEdge2.Orientation(E2.Orientation());
410 newEdge2.Location(E2.Location());
411 } // if (firstVertex ...
412 else if (lastVertex.IsSame(connectionE2Fillet)) {
413 // syntax wrong on NT
414 // const Handle(Geom_Curve)& curve =
415 // BRep_Tool::Curve(E2, loc, first, last);
416 Handle(Geom_Curve) curve = BRep_Tool::Curve(E2, loc, first, last);
417 makeEdge.Init(curve, firstVertex, commonVertex);
418 newEdge2 = makeEdge.Edge();
419 newEdge2.Orientation(E2.Orientation());
420 newEdge2.Location(E2.Location());
421 } // else if (lastVertex ...
424 // rebuild the newFace
425 TopExp_Explorer Ex(newFace, TopAbs_EDGE);
432 const TopoDS_Edge& theEdge = TopoDS::Edge(Ex.Current());
433 if (!theEdge.IsSame(E1) &&
434 !theEdge.IsSame(E2) &&
435 !theEdge.IsSame(Fillet))
436 B.Add(newWire, theEdge);
439 B.Add(newWire, newEdge1);
440 else if (theEdge == E2)
441 B.Add(newWire, newEdge2);
445 BRepAdaptor_Surface Adaptor3dSurface(refFace);
446 BRepLib_MakeFace mFace(Adaptor3dSurface.Plane(), newWire);
450 UpDateHistory(basisEdge1, basisEdge2, newEdge1, newEdge2);
456 //=======================================================================
457 //function : ComputeFillet
459 //=======================================================================
461 void ChFi2d_Builder::ComputeFillet(const TopoDS_Vertex& V,
462 const TopoDS_Edge& E1,
463 const TopoDS_Edge& E2,
464 const Standard_Real Radius,
469 TopoDS_Vertex newExtr1, newExtr2;
470 Standard_Boolean Degen1, Degen2;
471 Fillet = BuildFilletEdge(V, E1, E2, Radius, newExtr1, newExtr2);
472 if ( status != ChFi2d_IsDone) return;
473 TrimE1 = BuildNewEdge(E1, V, newExtr1, Degen1);
474 TrimE2 = BuildNewEdge(E2, V, newExtr2, Degen2);
475 if (Degen1 && Degen2 ) status = ChFi2d_BothEdgesDegenerated;
476 if (Degen1 && !Degen2 ) status = ChFi2d_FirstEdgeDegenerated;
477 if (!Degen1 && Degen2 ) status = ChFi2d_LastEdgeDegenerated;
482 //=======================================================================
483 //function : BuildNewWire
485 //=======================================================================
487 void ChFi2d_Builder::BuildNewWire (const TopoDS_Edge& OldE1,
488 const TopoDS_Edge& OldE2,
489 const TopoDS_Edge& E1,
490 const TopoDS_Edge& Fillet,
491 const TopoDS_Edge& E2)
494 Standard_Boolean aClosedStatus = Standard_True;
496 TopExp_Explorer Ex(refFace, TopAbs_WIRE);
498 const TopoDS_Wire& aWire = TopoDS::Wire(Ex.Current());
499 aClosedStatus = aWire.Closed();
504 Standard_Boolean filletIsAdded = Standard_False;
506 Ex.Init(newFace, TopAbs_EDGE);
512 const TopoDS_Edge& theEdge = TopoDS::Edge(Ex.Current());
513 if (!theEdge.IsSame(OldE1) && !theEdge.IsSame(OldE2)) {
514 B.Add(newWire, theEdge);
517 if (theEdge == OldE1) {
518 if (status != ChFi2d_FirstEdgeDegenerated
519 && status != ChFi2d_BothEdgesDegenerated) {
522 if ( !filletIsAdded) {
523 B.Add(newWire, Fillet);
524 filletIsAdded = Standard_True;
525 } // if ( !filletIsAdded ...
526 } // if (theEdge == ...
528 if (status != ChFi2d_LastEdgeDegenerated
529 && status != ChFi2d_BothEdgesDegenerated) {
532 if ( !filletIsAdded) {
533 B.Add(newWire, Fillet);
534 filletIsAdded = Standard_True;
535 }// if ( !filletIsAdded ...
541 newWire.Closed(aClosedStatus);
542 BRepAdaptor_Surface Adaptor3dSurface(refFace);
543 BRepLib_MakeFace mFace(Adaptor3dSurface.Plane(), newWire);
549 //=======================================================================
550 //function : BuildNewEdge
552 //=======================================================================
554 TopoDS_Edge ChFi2d_Builder::BuildNewEdge(const TopoDS_Edge& E1,
555 const TopoDS_Vertex& OldExtr,
556 const TopoDS_Vertex& NewExtr) const
558 BRepLib_MakeEdge makeEdge;
560 Standard_Real first, last;
561 TopoDS_Vertex firstVertex, lastVertex;
562 TopExp::Vertices(E1, firstVertex, lastVertex);
563 // syntaxe invalide sur NT
564 // const Handle(Geom_Curve)& curve =
565 // BRep_Tool::Curve(E1, first, last);
566 Handle(Geom_Curve) curve = BRep_Tool::Curve(E1, first, last);
567 if (firstVertex.IsSame(OldExtr))
568 makeEdge.Init(curve, NewExtr, lastVertex);
570 makeEdge.Init(curve, firstVertex, NewExtr);
571 TopoDS_Edge anEdge = makeEdge;
572 anEdge.Orientation(E1.Orientation());
573 // anEdge.Location(E1.Location());
578 //=======================================================================
579 //function : BuildNewEdge
580 //purpose : special flag if the new edge is degenerated
581 //=======================================================================
583 TopoDS_Edge ChFi2d_Builder::BuildNewEdge(const TopoDS_Edge& E1,
584 const TopoDS_Vertex& OldExtr,
585 const TopoDS_Vertex& NewExtr,
586 Standard_Boolean& IsDegenerated) const
588 BRepLib_MakeEdge makeEdge;
590 Standard_Real first, last;
591 IsDegenerated = Standard_False;
592 TopoDS_Vertex firstVertex, lastVertex;
593 TopExp::Vertices(E1, firstVertex, lastVertex);
594 gp_Pnt Pnew = BRep_Tool::Pnt(NewExtr);
595 Standard_Boolean PonctualEdge = Standard_False;
596 Standard_Real Tol = Precision::Confusion();
597 // syntax wrong on NT
598 // const Handle(Geom_Curve)& curve =
599 // BRep_Tool::Curve(E1, first, last);
600 Handle(Geom_Curve) curve = BRep_Tool::Curve(E1, first, last);
601 if (firstVertex.IsSame(OldExtr)) {
602 makeEdge.Init(curve, NewExtr, lastVertex);
603 gp_Pnt PV = BRep_Tool::Pnt(lastVertex);
604 PonctualEdge = (Pnew.Distance(PV)<Tol);
607 makeEdge.Init(curve, firstVertex, NewExtr);
608 gp_Pnt PV = BRep_Tool::Pnt(firstVertex);
609 PonctualEdge = (Pnew.Distance(PV)<Tol);
612 BRepLib_EdgeError error = makeEdge.Error();
613 if (error==BRepLib_LineThroughIdenticPoints || PonctualEdge) {
614 IsDegenerated = Standard_True;
619 anEdge.Orientation(E1.Orientation());
620 // anEdge.Location(E1.Location());
626 //=======================================================================
627 //function : UpDateHistory
629 //=======================================================================
630 void ChFi2d_Builder::UpDateHistory(const TopoDS_Edge& E1,
631 const TopoDS_Edge& E2,
632 const TopoDS_Edge& TrimE1,
633 const TopoDS_Edge& TrimE2,
634 const TopoDS_Edge& NewEdge,
635 const Standard_Integer Id)
637 if (Id == 1) // the new edge is a fillet
639 fillets.Append(NewEdge);
641 else // the new edge is a chamfer
643 chamfers.Append(NewEdge);
647 if (status != ChFi2d_FirstEdgeDegenerated
648 && status != ChFi2d_BothEdgesDegenerated)
650 if (!E1.IsSame(TrimE1))
652 history.Bind(E1, TrimE1);
656 if (status != ChFi2d_LastEdgeDegenerated
657 && status != ChFi2d_BothEdgesDegenerated)
659 if (!E2.IsSame(TrimE2))
661 history.Bind(E2, TrimE2);
667 //=======================================================================
668 //function : UpDateHistory
670 //=======================================================================
671 void ChFi2d_Builder::UpDateHistory(const TopoDS_Edge& E1,
672 const TopoDS_Edge& E2,
673 const TopoDS_Edge& TrimE1,
674 const TopoDS_Edge& TrimE2)
678 if (history.IsBound(E1)) history.UnBind(E1);
679 if (!E1.IsSame(TrimE1)) history.Bind(E1, TrimE1);
680 if (history.IsBound(E2)) history.UnBind(E2);
681 if (!E2.IsSame(TrimE2)) history.Bind(E2, TrimE2);
685 //=======================================================================
686 //function : BasisEdge
688 //=======================================================================
689 const TopoDS_Edge& ChFi2d_Builder::BasisEdge(const TopoDS_Edge& E) const
691 TopTools_DataMapIteratorOfDataMapOfShapeShape iterator(history);
693 while (iterator.More()) {
694 anEdge = TopoDS::Edge(iterator.Value());
695 if (anEdge.IsSame(E)) {
696 const TopoDS_Edge& anotherEdge = TopoDS::Edge(iterator.Key());
698 } // if (anEdge.IsSame ...
700 } // while (Iterator.More ...
705 //=======================================================================
706 //function : BuildFilletEdge
708 //=======================================================================
709 TopoDS_Edge ChFi2d_Builder::BuildFilletEdge(const TopoDS_Vertex& V,
710 const TopoDS_Edge& AdjEdge1,
711 const TopoDS_Edge& AdjEdge2,
712 const Standard_Real Radius,
713 TopoDS_Vertex& NewExtr1,
714 TopoDS_Vertex& NewExtr2)
719 TopoDS_Vertex V1 = TopExp::FirstVertex(E1);
720 TopoDS_Vertex V2 = TopExp::LastVertex(E1);
721 TopoDS_Vertex V3 = TopExp::FirstVertex(E2);
722 TopoDS_Vertex V4 = TopExp::LastVertex(E2);
724 //========================================================================
725 // The first arc is found. +
726 //========================================================================
728 TopAbs_Orientation O1;
729 TopAbs_Orientation OE1;
730 OE1 = E1.Orientation();
731 E1.Orientation(TopAbs_FORWARD);
732 E2.Orientation(TopAbs_FORWARD);
733 TopoDS_Shape aLocalShape = E1.EmptyCopied();
734 TopoDS_Edge Ebid1 = TopoDS::Edge(aLocalShape);
735 aLocalShape = E2.EmptyCopied();
736 TopoDS_Edge Ebid2 = TopoDS::Edge(aLocalShape);
737 // TopoDS_Edge Ebid1 = TopoDS::Edge(E1.EmptyCopied());
738 // TopoDS_Edge Ebid2 = TopoDS::Edge(E2.EmptyCopied());
739 Standard_Real param1,param2,param3,param4;
741 //========================================================================
742 // Save non-modified parts of edges concerned. +
743 //========================================================================
746 param1 = BRep_Tool::Parameter(V1,E1);
747 param2 = BRep_Tool::Parameter(V2,E1);
748 O1 = V2.Orientation();
751 param1 = BRep_Tool::Parameter(V2,E1);
752 param2 = BRep_Tool::Parameter(V1,E1);
753 O1 = V1.Orientation();
756 param3 = BRep_Tool::Parameter(V3,E2);
757 param4 = BRep_Tool::Parameter(V4,E2);
760 param3 = BRep_Tool::Parameter(V4,E2);
761 param4 = BRep_Tool::Parameter(V3,E2);
764 //========================================================================
765 // Restore geometric supports. +
766 //========================================================================
768 Handle(Geom2d_Curve) C1,C2;
769 Standard_Real ufirst1,ulast1,ufirst2,ulast2,U1,U2,PU1,PU2,Vv1,Vv2;
770 Standard_Real PPU1,PPU2;
771 C1 = BRep_Tool::CurveOnSurface(E1,newFace,ufirst1,ulast1);
772 C2 = BRep_Tool::CurveOnSurface(E2,newFace,ufirst2,ulast2);
774 //========================================================================
775 // Determination of the face for fillet. +
776 //========================================================================
781 Standard_Boolean Sens1 , Sens2;
783 Handle(Geom2d_Curve) basisC1,basisC2;
784 Handle(Geom2d_TrimmedCurve) T1 = Handle(Geom2d_TrimmedCurve)::DownCast(C1);
786 basisC1 = T1->BasisCurve();
789 Handle(Geom2d_TrimmedCurve) T2 = Handle(Geom2d_TrimmedCurve)::DownCast(C2);
791 basisC2 = T2->BasisCurve();
795 if (basisC1->DynamicType() == STANDARD_TYPE(Geom2d_Circle)) {
796 Handle(Geom2d_Circle) CC1 = Handle(Geom2d_Circle)::DownCast(basisC1);
797 ElCLib::D1(param1,CC1->Circ2d(),p,Ve1);
798 Sens1 = (CC1->Circ2d()).IsDirect();
799 } // if (C1->DynamicType() ...
801 Handle(Geom2d_Line) CC1 = Handle(Geom2d_Line)::DownCast(basisC1);
802 ElCLib::D1(param1,CC1->Lin2d(),p,Ve1);
805 if (basisC2->DynamicType() == STANDARD_TYPE(Geom2d_Circle)) {
806 Handle(Geom2d_Circle) CC2 = Handle(Geom2d_Circle)::DownCast(basisC2);
807 ElCLib::D1(param3,CC2->Circ2d(),p,Ve2);
808 Sens2 = (CC2->Circ2d()).IsDirect();
809 } // if (C2->DynamicType() ...
811 Handle(Geom2d_Line) CC2 = Handle(Geom2d_Line)::DownCast(basisC2);
812 ElCLib::D1(param3,CC2->Lin2d(),p,Ve2);
816 TopoDS_Edge filletEdge;
818 Standard_Real cross = Ve1.Crossed(Ve2);
822 // processing of tangency or downcast point
823 if (Ve1.IsParallel(Ve2,Precision::Angular())) {
824 // Ve1 and Ve2 are parallel : cross at 0
833 if (! Ve4.IsOpposite(Ve3,Precision::Angular())) {
834 // There is a true tangency point and the calculation is stopped
835 status = ChFi2d_TangencyError;
838 // Otherwise this is a downcast point, and the calculation is continued
841 GccEnt_Position Qual1,Qual2;
843 if (param3 > param4 ) {
844 if(Sens1 == Standard_True){
845 Qual1 = GccEnt_enclosed;
848 Qual1 = GccEnt_outside;
852 if(Sens1 == Standard_True){
853 Qual1 = GccEnt_outside;
856 Qual1 = GccEnt_enclosed;
859 if (param1 > param2) {
860 if(Sens2 == Standard_True)
861 Qual2 = GccEnt_outside;
863 Qual2 = GccEnt_enclosed;
866 if(Sens2 == Standard_True)
867 Qual2 = GccEnt_enclosed;
869 Qual2 = GccEnt_outside;
871 } // if (cross < 0 ...
873 if (param3 > param4 ) {
874 if( Sens1 == Standard_True)
875 Qual1 = GccEnt_outside;
877 Qual1 = GccEnt_enclosed;
880 if( Sens1 == Standard_True)
881 Qual1 = GccEnt_enclosed;
883 Qual1 = GccEnt_outside;
885 if (param1 > param2 ) {
886 if( Sens2 == Standard_True)
887 Qual2 = GccEnt_enclosed;
889 Qual2 = GccEnt_outside;
892 if( Sens2 == Standard_True)
893 Qual2 = GccEnt_outside;
895 Qual2 = GccEnt_enclosed;
899 Standard_Real Tol = Precision::Confusion();
900 Geom2dGcc_Circ2d2TanRad Fillet(Geom2dGcc_QualifiedCurve(basisC1,Qual1),
901 Geom2dGcc_QualifiedCurve(basisC2,Qual2),
903 if (!Fillet.IsDone() || Fillet.NbSolutions()==0) {
904 status = ChFi2d_ComputationError;
907 else if (Fillet.NbSolutions() >= 1) {
908 status = ChFi2d_IsDone;
909 Standard_Integer numsol = 1;
910 Standard_Integer nsol = 1;
911 TopoDS_Vertex Vertex1,Vertex2;
914 Standard_Real dist1 = 1.e40;
915 Standard_Boolean inside = Standard_False;
916 while (nsol<=Fillet.NbSolutions()) {
917 Fillet.Tangency1(nsol,PU1,PU2,Ptg1);
918 dist = Ptg1.Distance(p);
919 if (basisC1->DynamicType() == STANDARD_TYPE(Geom2d_Line)) {
920 inside = (PU2<param1 && PU2>param2) || (PU2<param2 && PU2>param1);
921 if ( inside && dist < dist1) {
924 } // if ((((inside && ...
925 } // if (C1->DynamicType( ...
927 Fillet.Tangency2(nsol,PPU1,PPU2,Ptg2);
928 dist = Ptg2.Distance(p);
929 inside = (PPU2<param3 && PPU2>param4) || (PPU2<param4 && PPU2>param3);
930 // case of arc of circle passing on the sewing
931 if ( ( basisC2->DynamicType() == STANDARD_TYPE(Geom2d_Circle) ) &&
932 ( (2*M_PI<param3 && 2*M_PI>param4) || (2*M_PI<param4 && 2*M_PI>param3) ) ) {
934 inside = (param3<PPU2 && PPU2<2*M_PI)
935 || (0<=PPU2 && PPU2<param4-2*M_PI);
937 inside = inside || (param4<PPU2 && PPU2<2*M_PI)
938 || (0<=PPU2 && PPU2<param3-2*M_PI);
940 if ( inside && dist < dist1) {
943 } // if ((((param3 ...
947 gp_Circ2d cir(Fillet.ThisSolution(numsol));
948 Handle(Geom2d_Circle) circle = new Geom2d_Circle(cir);
951 BRepAdaptor_Surface Adaptor3dSurface(refFace);
952 Handle(Geom_Plane) refSurf = new Geom_Plane(Adaptor3dSurface.Plane());
953 Fillet.Tangency1(numsol,U1,U2,Ptg1);
954 Fillet.Tangency2(numsol,Vv1,Vv2,Ptg2);
956 // check the validity of parameters
957 //// modified by jgv, 08.08.2011 for bug 0022695 ////
958 //inside = (U2<param1 && U2>param2) || (U2<param2 && U2>param1);
959 inside = (U2 < param1 && U2 >= param2) || (U2 <= param2 && U2 > param1);
960 /////////////////////////////////////////////////////
961 if ( (basisC1->DynamicType() == STANDARD_TYPE(Geom2d_Circle))
962 && ( (2*M_PI<param1 && 2*M_PI>param2) || (2*M_PI<param2 && 2*M_PI>param1) ) ) {
963 // arc of circle containing the circle origin
964 // case param1<param2
965 inside = (param1<U2 && U2<2*M_PI) || (0<=U2 && U2<param2-2*M_PI);
966 // case param2<param1
967 inside = inside || (param2<U2 && U2<2*M_PI) || (0<=U2 && U2<param1-2*M_PI);
970 status = ChFi2d_ComputationError;
974 //// modified by jgv, 08.08.2011 for bug 0022695 ////
975 //inside = (Vv2<param3 && Vv2>param4) || (Vv2<param4 && Vv2>param3);
976 inside = (Vv2 < param3 && Vv2 >= param4) || (Vv2 <= param4 && Vv2 > param3);
977 /////////////////////////////////////////////////////
978 if ( (basisC2->DynamicType() == STANDARD_TYPE(Geom2d_Circle))
979 && ( (2*M_PI<param3 && 2*M_PI>param4) || (2*M_PI<param4 && 2*M_PI>param3) ) ) {
980 // arc of circle containing the circle origin
982 inside = (param3<Vv2 && Vv2<2*M_PI) || (0<=Vv2 && Vv2<param4-2*M_PI);
984 inside = inside || (param4<Vv2 && Vv2<2*M_PI) || (0<=Vv2 && Vv2<param3-2*M_PI);
987 status = ChFi2d_ComputationError;
991 gp_Pnt p1 = Adaptor3dSurface.Value(Ptg1.X(), Ptg1.Y());
992 gp_Pnt p2 = Adaptor3dSurface.Value(Ptg2.X(), Ptg2.Y());
993 B.MakeVertex(Vertex1, p1,Tol);
995 if (Abs(U2-ufirst1) <= Precision::PConfusion()) {
998 if (Abs(U2-ulast1) <= Precision::PConfusion()) {
1002 B.MakeVertex(Vertex2, p2,Tol);
1004 if (Abs(Vv2-ufirst2) <= Precision::PConfusion()) {
1007 if (Abs(Vv2-ulast2) <= Precision::PConfusion()) {
1011 //=======================================================================
1012 // Update tops of the fillet. +
1013 //=======================================================================
1016 Pntbid = BRep_Tool::Pnt(V);
1017 sommet = gp_Pnt2d(Pntbid.X(),Pntbid.Y());
1022 pntBid = BRep_Tool::Pnt(V2);
1023 somBid = gp_Pnt2d(pntBid.X(),pntBid.Y());
1026 pntBid = BRep_Tool::Pnt(V1);
1027 somBid = gp_Pnt2d(pntBid.X(),pntBid.Y());
1031 ElCLib::D1(U1,cir,Ptg1,vec);
1034 if (basisC1->DynamicType() == STANDARD_TYPE(Geom2d_Circle)) {
1035 Handle(Geom2d_Circle) CC1 = Handle(Geom2d_Circle)::DownCast(basisC1);
1036 gp_Circ2d cir2d(CC1->Circ2d());
1037 Standard_Real par = ElCLib::Parameter(cir2d,Ptg1);
1039 ElCLib::D1(par,cir2d,Pd,vec1);
1040 } // if (C1->DynamicType() ...
1041 else if (basisC1->DynamicType() == STANDARD_TYPE(Geom2d_Line)) {
1042 Handle(Geom2d_Line) CC1 = Handle(Geom2d_Line)::DownCast(basisC1);
1043 gp_Lin2d lin2d(CC1->Lin2d());
1044 Standard_Real par = ElCLib::Parameter(lin2d,sommet);
1045 vec1 = gp_Vec2d(sommet.X()-somBid.X(),sommet.Y()-somBid.Y());
1047 ElCLib::D1(par,lin2d,Pd,vec1);
1050 if (OE1 == TopAbs_REVERSED) {
1053 Standard_Boolean Sense = ( vec1*vec ) > 0.;
1054 if (U1 > Vv1 && U1 > 2.*M_PI) {
1055 ElCLib::AdjustPeriodic(0.,2.*M_PI,Precision::Confusion(),U1,Vv1);
1057 if ( (O1 == TopAbs_FORWARD && OE1 == TopAbs_FORWARD) ||
1058 (O1 == TopAbs_REVERSED && OE1 == TopAbs_REVERSED) ) {
1059 filletEdge = BRepLib_MakeEdge(circle, refSurf,
1060 NewExtr1, NewExtr2, U1, Vv1);
1063 filletEdge = BRepLib_MakeEdge(circle, refSurf,
1064 NewExtr2, NewExtr1, Vv1, U1);
1067 TopAbs_Orientation S1 = filletEdge.Orientation();
1068 if ((O1 == TopAbs_FORWARD && OE1 == TopAbs_FORWARD) ||
1069 (O1 == TopAbs_REVERSED && OE1 == TopAbs_REVERSED) ) {
1070 filletEdge = BRepLib_MakeEdge(circle, refSurf,
1071 NewExtr2, NewExtr1, Vv1, U1);
1074 filletEdge = BRepLib_MakeEdge(circle, refSurf,
1075 NewExtr1, NewExtr2, U1, Vv1);
1077 if (S1 == TopAbs_FORWARD) {
1078 filletEdge.Orientation(TopAbs_REVERSED);
1081 filletEdge.Orientation(TopAbs_FORWARD);
1087 BRepLib::BuildCurves3d(filletEdge);
1089 } // BuildFilletEdge
1092 //=======================================================================
1093 //function : IsAFillet
1095 //=======================================================================
1097 Standard_Boolean ChFi2d_Builder::IsAFillet(const TopoDS_Edge& E) const
1099 Standard_Integer i = 1;
1100 while (i <= fillets.Length()) {
1101 const TopoDS_Edge& currentEdge = TopoDS::Edge(fillets.Value(i));
1102 if (currentEdge.IsSame(E)) return Standard_True;
1105 return Standard_False;
1109 //=======================================================================
1110 //function : IsAChamfer
1112 //=======================================================================
1114 Standard_Boolean ChFi2d_Builder::IsAChamfer(const TopoDS_Edge& E) const
1116 Standard_Integer i = 1;
1117 while (i <= chamfers.Length()) {
1118 const TopoDS_Edge& currentEdge = TopoDS::Edge(chamfers.Value(i));
1119 if (currentEdge.IsSame(E)) return Standard_True;
1122 return Standard_False;
1127 //=======================================================================
1128 //function : IsLineOrCircle
1130 //=======================================================================
1132 Standard_Boolean IsLineOrCircle(const TopoDS_Edge& E,
1133 const TopoDS_Face& F)
1135 Standard_Real first, last;
1136 TopLoc_Location loc;
1137 // syntaxe invalide sur NT
1138 // const Handle(Geom2d_Curve)& C =
1139 // BRep_Tool::CurveOnSurface(E,F,first,last);
1140 Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,first,last);
1141 Handle(Geom2d_Curve) basisC;
1142 Handle(Geom2d_TrimmedCurve) TC = Handle(Geom2d_TrimmedCurve)::DownCast(C);
1144 basisC = TC->BasisCurve();
1148 if ( basisC->DynamicType() == STANDARD_TYPE(Geom2d_Circle)
1149 || basisC->DynamicType() == STANDARD_TYPE(Geom2d_Line) ) {
1150 return Standard_True;
1153 return Standard_False;