1 // File: ChFi2d_Builder.cxx
2 // Created: Fri Jul 7 16:39:57 1995
3 // Author: Philippe DERVIEUX
5 // Modified: Tue Oct 15 10:12:02 1996
6 // Author: Joelle CHAUVET
8 // correction in BuildFilletEdge (PRO3529 : computation of dist)
9 // Modified: Tue Oct 22 09:23:11 1996
10 // Author: Joelle CHAUVET
12 // correction in BuildFilletEdge (PRO5827 : computation of vec1)
13 // Modified: Tue Oct 22 09:23:11 1996
14 // Author: Joelle CHAUVET
16 // new status in ComputeFillet for degenerated edges (PRO4896)
17 // Modified: Thu Dec 5 16:25:44 1996
18 // Author: Joelle CHAUVET
20 // correction in BuildFilletEdge (PRO4896 : NewExtr1, NewExtr2)
21 // Modified: Tue Apr 22 16:25:44 1996
22 // Author: Joelle CHAUVET
24 // correction in BuildFilletEdge (ID140047 : inside)
25 // Modified: Fri Oct 24 10:47:52 1997
26 // Author: Joelle CHAUVET
28 // distinction point de tangence --> on arrete
29 // point de rebroussement --> on continue
30 // (PRO10404 : Ve3, Ve4)
31 // Modified: Tue Oct 28 11:55:53 1997
32 // Author: Joelle CHAUVET
34 // construction de filletEdge avec les parametres U1 et Vv1
35 // au lieu des vertex (PRO10434)
36 // Modified: Tue Apr 7 14:35:58 1998
37 // Author: Joelle CHAUVET
39 // construction de filletEdge avec les parametres U1 et Vv1
40 // ET les vertex NewExtr1, NewExtr2 sinon pb sur qq aretes
41 // degenerees (GER60069 + controle de PRO10434)
42 // Modified: Mon Jun 22 13:32:25 1998
43 // Author: Joelle CHAUVET
45 // verification de la validite des parametres (PRO13078 partiel)
46 // Modified: Fri Sep 25 09:38:04 1998
47 // Author: Joelle CHAUVET
49 // status = ChFi2d_NotAuthorized si les aretes ne sont pas
50 // des droites ou des cercles; fonction IsLineOrCircle
56 #include <ChFi2d_Builder.ixx>
58 #include <BRepAdaptor_Surface.hxx>
59 #include <BRepLib.hxx>
60 #include <BRepLib_MakeEdge.hxx>
61 #include <BRepLib_MakeFace.hxx>
63 #include <BRep_Builder.hxx>
64 #include <BRep_Tool.hxx>
68 #include <GccEnt_Position.hxx>
70 #include <Geom_Circle.hxx>
71 #include <Geom_Curve.hxx>
72 #include <Geom_Line.hxx>
73 #include <Geom_Plane.hxx>
74 #include <Geom_Surface.hxx>
77 #include <Geom2d_TrimmedCurve.hxx>
78 #include <Geom2d_Circle.hxx>
79 #include <Geom2d_Curve.hxx>
80 #include <Geom2d_Line.hxx>
82 #include <Geom2dInt_GInter.hxx>
83 #include <Geom2dGcc_Circ2d2TanRad.hxx>
84 #include <Geom2dGcc_QualifiedCurve.hxx>
86 #include <IntRes2d_IntersectionPoint.hxx>
90 #include <gp_Pnt2d.hxx>
91 #include <gp_Circ2d.hxx>
92 #include <gp_Vec2d.hxx>
94 #include <Precision.hxx>
96 #include <TopAbs_Orientation.hxx>
98 #include <TopExp_Explorer.hxx>
99 #include <TopLoc_Location.hxx>
100 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
101 #include <TopTools_ListIteratorOfListOfShape.hxx>
102 #include <TopTools_IndexedMapOfShape.hxx>
104 #include <TopoDS.hxx>
105 #include <TopoDS_Edge.hxx>
106 #include <TopoDS_Wire.hxx>
108 static Standard_Boolean IsIssuedFrom(const TopoDS_Edge& E,
109 const TopTools_IndexedMapOfShape& Map,
110 TopoDS_Edge& BasisEdge);
112 static Standard_Boolean IsLineOrCircle(const TopoDS_Edge& E,
113 const TopoDS_Face& F);
116 //=======================================================================
117 //function : ChFi2d_Builder
119 //=======================================================================
121 ChFi2d_Builder::ChFi2d_Builder()
125 //=======================================================================
126 //function : ChFi2d_Builder
128 //=======================================================================
130 ChFi2d_Builder::ChFi2d_Builder(const TopoDS_Face& F)
133 status = ChFi2d_NoFace;
137 // syntaxe invalide sur NT
138 // const Handle(Geom_Surface)& surf = BRep_Tool::Surface( F, Loc);
139 // if (surf->IsKind(STANDARD_TYPE(Geom_Plane))) {
140 if ( BRep_Tool::Surface( F, Loc)
141 -> IsKind(STANDARD_TYPE(Geom_Plane)) ) {
142 newFace = refFace = F;
143 newFace.Orientation(TopAbs_FORWARD);
144 BRepLib::BuildCurves3d(newFace);
145 status = ChFi2d_Ready;
147 else status = ChFi2d_NotPlanar;
150 //=======================================================================
153 //=======================================================================
155 void ChFi2d_Builder::Init(const TopoDS_Face& F)
158 status = ChFi2d_NoFace;
165 // syntaxe invalide sur NT
166 // const Handle(Geom_Surface)& surf = BRep_Tool::Surface( F, Loc);
167 // if (surf->IsKind(STANDARD_TYPE(Geom_Plane))) {
168 if ( BRep_Tool::Surface( F, Loc)
169 -> IsKind(STANDARD_TYPE(Geom_Plane)) ) {
170 newFace = refFace = F;
171 newFace.Orientation(TopAbs_FORWARD);
172 status = ChFi2d_Ready;
174 else status = ChFi2d_NotPlanar;
178 //=======================================================================
181 //=======================================================================
183 void ChFi2d_Builder::Init(const TopoDS_Face& RefFace,
184 const TopoDS_Face& ModFace)
186 if (RefFace.IsNull() || ModFace.IsNull()) {
187 status = ChFi2d_NoFace;
194 // syntaxe invalide sur NT
195 // const Handle(Geom_Surface)& surf = BRep_Tool::Surface( RefFace, Loc);
196 // if (!surf->IsKind(STANDARD_TYPE(Geom_Plane))) {
197 if ( ! BRep_Tool::Surface( RefFace, loc)
198 -> IsKind(STANDARD_TYPE(Geom_Plane)) ) {
199 status = ChFi2d_NotPlanar;
205 newFace.Orientation(TopAbs_FORWARD);
206 status = ChFi2d_Ready;
208 // Research in newFace all the edges which not appear in RefFace
209 // The sequence newEdges will contains this edges.
211 TopTools_SequenceOfShape newEdges;
212 TopTools_IndexedMapOfShape refEdgesMap;
213 TopExp::MapShapes(refFace, TopAbs_EDGE, refEdgesMap);
214 TopExp_Explorer ex(newFace, TopAbs_EDGE);
216 const TopoDS_Edge& currentEdge = TopoDS::Edge(ex.Current());
217 if (!refEdgesMap.Contains(currentEdge))
218 newEdges.Append(currentEdge);
222 // update of history, fillets and chamfers fields
223 Standard_Integer i = 1;
224 Standard_Real first, last;
225 TopoDS_Edge basisEdge;
226 while ( i <= newEdges.Length()) {
227 const TopoDS_Edge& currentEdge = TopoDS::Edge(newEdges.Value(i));
228 if (IsIssuedFrom(currentEdge, refEdgesMap, basisEdge))
229 history.Bind(basisEdge, currentEdge);
231 // this edge is a chamfer or a fillet
232 // syntaxe invalide sur NT
233 // const Handle(Geom_Curve)& curve =
234 // BRep_Tool::Curve(currentEdge, loc, first, last);
235 Handle(Geom_Curve) curve =
236 BRep_Tool::Curve(currentEdge, loc, first, last);
237 if (curve->IsKind(STANDARD_TYPE(Geom_Circle))) {
238 fillets.Append(currentEdge);
240 else if (curve->IsKind(STANDARD_TYPE(Geom_Line))) {
241 chamfers.Append(currentEdge);
244 status = ChFi2d_InitialisationError;
247 } // this edge is ...
253 //=======================================================================
254 //function : IsIssuedFrom
255 //purpose : Search in <Map> if <E> has a parent edge. If a parent has
256 // been find, this edge is returned in <BasisEdge>, else <E> is
257 // returned in <BasisEdge>.
258 //=======================================================================
259 Standard_Boolean IsIssuedFrom(const TopoDS_Edge& E,
260 const TopTools_IndexedMapOfShape& Map,
261 TopoDS_Edge& BasisEdge)
263 TopLoc_Location loc1, loc2;
264 Standard_Real f1, L1, f2, L2;
265 // syntaxe invalide sur NT
266 // const Handle(Geom_Curve)& c1 =
267 // BRep_Tool::Curve(E, loc1, f1, L1);
268 Handle(Geom_Curve) c1 = BRep_Tool::Curve(E, loc1, f1, L1);
270 for (Standard_Integer i = 1; i <= Map.Extent(); i++ ) {
271 const TopoDS_Edge& currentEdge = TopoDS::Edge(Map.FindKey(i));
272 // syntaxe invalide sur NT
273 // const Handle(Geom_Curve)& c2 =
274 // BRep_Tool::Curve(currentEdge, loc2, f2, L2);
275 Handle(Geom_Curve) c2 = BRep_Tool::Curve(currentEdge, loc2, f2, L2);
277 (((f1 > f2 && f1 < L2) || (L1 > f2 && L1 < L2) ) ||
278 ( (f1 > L2 && f1 < f2) || (L1 > L2 && L1 < f2) )) ) {
279 BasisEdge = currentEdge;
280 BasisEdge.Orientation(E.Orientation());
281 return Standard_True;
283 } // for (Standard_Integer i ...
285 return Standard_False;
289 //=======================================================================
290 //function : AddFillet
292 //=======================================================================
293 TopoDS_Edge ChFi2d_Builder::AddFillet(const TopoDS_Vertex& V,
294 const Standard_Real Radius)
296 TopoDS_Edge adjEdge1, adjEdge2, basisEdge1, basisEdge2;
297 TopoDS_Edge adjEdge1Mod, adjEdge2Mod, fillet;
298 status = ChFi2d::FindConnectedEdges(newFace, V, adjEdge1, adjEdge2);
299 if (status == ChFi2d_ConnexionError) return fillet;
301 if (IsAFillet(adjEdge1) || IsAChamfer(adjEdge1) ||
302 IsAFillet(adjEdge2) || IsAChamfer(adjEdge2)) {
303 status = ChFi2d_NotAuthorized;
305 } // if (IsAFillet ...
307 if (!IsLineOrCircle(adjEdge1,newFace)
308 || !IsLineOrCircle(adjEdge2,newFace) ) {
309 status = ChFi2d_NotAuthorized;
311 } // if (!IsLineOrCircle ...
313 ComputeFillet(V, adjEdge1, adjEdge2, Radius,
314 adjEdge1Mod, adjEdge2Mod, fillet);
315 if (status == ChFi2d_IsDone
316 || status == ChFi2d_FirstEdgeDegenerated
317 || status == ChFi2d_LastEdgeDegenerated
318 || status == ChFi2d_BothEdgesDegenerated) {
319 BuildNewWire(adjEdge1, adjEdge2, adjEdge1Mod, fillet, adjEdge2Mod);
320 basisEdge1 = BasisEdge(adjEdge1);
321 basisEdge2 = BasisEdge(adjEdge2);
322 UpDateHistory(basisEdge1, basisEdge2,
323 adjEdge1Mod, adjEdge2Mod, fillet, 1);
324 status = ChFi2d_IsDone;
325 return TopoDS::Edge(fillets.Value(fillets.Length()));
330 //=======================================================================
331 //function : ModifyFillet
333 //=======================================================================
335 TopoDS_Edge ChFi2d_Builder::ModifyFillet(const TopoDS_Edge& Fillet,
336 const Standard_Real Radius)
338 TopoDS_Vertex aVertex = RemoveFillet(Fillet);
339 TopoDS_Edge aFillet = AddFillet(aVertex, Radius);
343 //=======================================================================
344 //function : RemoveFillet
346 //=======================================================================
348 TopoDS_Vertex ChFi2d_Builder::RemoveFillet(const TopoDS_Edge& Fillet)
350 TopoDS_Vertex commonVertex;
351 Standard_Integer i = 1;
352 Standard_Integer IsFind = Standard_False;
353 while (i <= fillets.Length()) {
354 const TopoDS_Edge& aFillet = TopoDS::Edge(fillets.Value(i));
355 if (aFillet.IsSame(Fillet)) {
357 IsFind = Standard_True;
362 if (!IsFind) return commonVertex;
365 TopoDS_Vertex firstVertex, lastVertex;
366 TopExp::Vertices(Fillet, firstVertex, lastVertex);
369 TopoDS_Edge adjEdge1, adjEdge2;
370 status = ChFi2d::FindConnectedEdges(newFace, firstVertex,
372 if (status == ChFi2d_ConnexionError) return commonVertex;
374 TopoDS_Edge basisEdge1, basisEdge2, E1, E2;
375 // E1 and E2 are the adjacent edges to Fillet
377 if (adjEdge1.IsSame(Fillet)) E1 = adjEdge2;
379 basisEdge1 = BasisEdge(E1);
380 status = ChFi2d::FindConnectedEdges(newFace, lastVertex,adjEdge1, adjEdge2);
381 if (status == ChFi2d_ConnexionError) return commonVertex;
382 if (adjEdge1.IsSame(Fillet)) E2 = adjEdge2;
384 basisEdge2 = BasisEdge(E2);
385 TopoDS_Vertex connectionE1Fillet, connectionE2Fillet;
386 Standard_Boolean hasConnection =
387 ChFi2d::CommonVertex(basisEdge1, basisEdge2, commonVertex);
388 if (!hasConnection) {
389 status = ChFi2d_ConnexionError;
392 hasConnection = ChFi2d::CommonVertex(E1, Fillet, connectionE1Fillet);
393 if (!hasConnection) {
394 status = ChFi2d_ConnexionError;
397 hasConnection = ChFi2d::CommonVertex(E2, Fillet, connectionE2Fillet);
398 if (!hasConnection) {
399 status = ChFi2d_ConnexionError;
403 // rebuild edges on wire
404 TopoDS_Edge newEdge1, newEdge2;
405 TopoDS_Vertex v, v1, v2;
406 BRepLib_MakeEdge makeEdge;
408 Standard_Real first, last;
410 TopExp::Vertices(E1, firstVertex, lastVertex);
411 TopExp::Vertices(basisEdge1, v1, v2);
412 if (v1.IsSame(commonVertex)) v = v2;
415 if ( firstVertex.IsSame(v) || lastVertex.IsSame(v))
416 // It means the edge support only one fillet. In this case
417 // the new edge must be the basis edge.
418 newEdge1 = basisEdge1;
420 // It means the edge support one fillet on each end.
421 if (firstVertex.IsSame(connectionE1Fillet)) {
422 // syntaxe invalide sur NT
423 // const Handle(Geom_Curve)& curve =
424 // BRep_Tool::Curve(E1, loc, first, last);
425 Handle(Geom_Curve) curve = BRep_Tool::Curve(E1, loc, first, last);
426 makeEdge.Init(curve, commonVertex, lastVertex);
427 newEdge1 = makeEdge.Edge();
428 newEdge1.Orientation(E1.Orientation());
429 newEdge1.Location(E1.Location());
430 } // if (firstVertex ...
431 else if (lastVertex.IsSame(connectionE1Fillet)) {
432 // syntax wrong on NT
433 // const Handle(Geom_Curve)& curve =
434 // BRep_Tool::Curve(E1, loc, first, last);
435 Handle(Geom_Curve) curve = BRep_Tool::Curve(E1, loc, first, last);
436 makeEdge.Init(curve, firstVertex, commonVertex);
437 newEdge1 = makeEdge.Edge();
438 newEdge1.Orientation(E1.Orientation());
439 newEdge1.Location(E1.Location());
440 } // else if (lastVertex ...
443 TopExp::Vertices(basisEdge2, v1, v2);
444 if (v1.IsSame(commonVertex)) v = v2;
447 TopExp::Vertices(E2, firstVertex, lastVertex);
448 if ( firstVertex.IsSame(v) || lastVertex.IsSame(v))
449 // It means the edge support only one fillet. In this case
450 // the new edge must be the basis edge.
451 newEdge2 = basisEdge2;
453 // It means the edge support one fillet on each end.
454 if (firstVertex.IsSame(connectionE2Fillet)) {
455 // syntax wrong on NT
456 // const Handle(Geom_Curve)& curve =
457 // BRep_Tool::Curve(E2, loc, first, last);
458 Handle(Geom_Curve) curve = BRep_Tool::Curve(E2, loc, first, last);
459 makeEdge.Init(curve, commonVertex, lastVertex);
460 newEdge2 = makeEdge.Edge();
461 newEdge2.Orientation(E2.Orientation());
462 newEdge2.Location(E2.Location());
463 } // if (firstVertex ...
464 else if (lastVertex.IsSame(connectionE2Fillet)) {
465 // syntax wrong on NT
466 // const Handle(Geom_Curve)& curve =
467 // BRep_Tool::Curve(E2, loc, first, last);
468 Handle(Geom_Curve) curve = BRep_Tool::Curve(E2, loc, first, last);
469 makeEdge.Init(curve, firstVertex, commonVertex);
470 newEdge2 = makeEdge.Edge();
471 newEdge2.Orientation(E2.Orientation());
472 newEdge2.Location(E2.Location());
473 } // else if (lastVertex ...
476 // rebuild the newFace
477 TopExp_Explorer Ex(newFace, TopAbs_EDGE);
484 const TopoDS_Edge& theEdge = TopoDS::Edge(Ex.Current());
485 if (!theEdge.IsSame(E1) &&
486 !theEdge.IsSame(E2) &&
487 !theEdge.IsSame(Fillet))
488 B.Add(newWire, theEdge);
491 B.Add(newWire, newEdge1);
492 else if (theEdge == E2)
493 B.Add(newWire, newEdge2);
497 BRepAdaptor_Surface Adaptor3dSurface(refFace);
498 BRepLib_MakeFace mFace(Adaptor3dSurface.Plane(), newWire);
502 UpDateHistory(basisEdge1, basisEdge2, newEdge1, newEdge2);
508 //=======================================================================
509 //function : ComputeFillet
511 //=======================================================================
513 void ChFi2d_Builder::ComputeFillet(const TopoDS_Vertex& V,
514 const TopoDS_Edge& E1,
515 const TopoDS_Edge& E2,
516 const Standard_Real Radius,
521 TopoDS_Vertex newExtr1, newExtr2;
522 Standard_Boolean Degen1, Degen2;
523 Fillet = BuildFilletEdge(V, E1, E2, Radius, newExtr1, newExtr2);
524 if ( status != ChFi2d_IsDone) return;
525 TrimE1 = BuildNewEdge(E1, V, newExtr1, Degen1);
526 TrimE2 = BuildNewEdge(E2, V, newExtr2, Degen2);
527 if (Degen1 && Degen2 ) status = ChFi2d_BothEdgesDegenerated;
528 if (Degen1 && !Degen2 ) status = ChFi2d_FirstEdgeDegenerated;
529 if (!Degen1 && Degen2 ) status = ChFi2d_LastEdgeDegenerated;
534 //=======================================================================
535 //function : BuildNewWire
537 //=======================================================================
539 void ChFi2d_Builder::BuildNewWire (const TopoDS_Edge& OldE1,
540 const TopoDS_Edge& OldE2,
541 const TopoDS_Edge& E1,
542 const TopoDS_Edge& Fillet,
543 const TopoDS_Edge& E2)
546 Standard_Boolean aClosedStatus = Standard_True;
548 TopExp_Explorer Ex(refFace, TopAbs_WIRE);
550 const TopoDS_Wire& aWire = TopoDS::Wire(Ex.Current());
551 aClosedStatus = aWire.Closed();
556 Standard_Boolean filletIsAdded = Standard_False;
558 Ex.Init(newFace, TopAbs_EDGE);
564 const TopoDS_Edge& theEdge = TopoDS::Edge(Ex.Current());
565 if (!theEdge.IsSame(OldE1) && !theEdge.IsSame(OldE2)) {
566 B.Add(newWire, theEdge);
569 if (theEdge == OldE1) {
570 if (status != ChFi2d_FirstEdgeDegenerated
571 && status != ChFi2d_BothEdgesDegenerated) {
574 if ( !filletIsAdded) {
575 B.Add(newWire, Fillet);
576 filletIsAdded = Standard_True;
577 } // if ( !filletIsAdded ...
578 } // if (theEdge == ...
580 if (status != ChFi2d_LastEdgeDegenerated
581 && status != ChFi2d_BothEdgesDegenerated) {
584 if ( !filletIsAdded) {
585 B.Add(newWire, Fillet);
586 filletIsAdded = Standard_True;
587 }// if ( !filletIsAdded ...
593 newWire.Closed(aClosedStatus);
594 BRepAdaptor_Surface Adaptor3dSurface(refFace);
595 BRepLib_MakeFace mFace(Adaptor3dSurface.Plane(), newWire);
601 //=======================================================================
602 //function : BuildNewEdge
604 //=======================================================================
606 TopoDS_Edge ChFi2d_Builder::BuildNewEdge(const TopoDS_Edge& E1,
607 const TopoDS_Vertex& OldExtr,
608 const TopoDS_Vertex& NewExtr) const
610 BRepLib_MakeEdge makeEdge;
612 Standard_Real first, last;
613 TopoDS_Vertex firstVertex, lastVertex;
614 TopExp::Vertices(E1, firstVertex, lastVertex);
615 // syntaxe invalide sur NT
616 // const Handle(Geom_Curve)& curve =
617 // BRep_Tool::Curve(E1, first, last);
618 Handle(Geom_Curve) curve = BRep_Tool::Curve(E1, first, last);
619 if (firstVertex.IsSame(OldExtr))
620 makeEdge.Init(curve, NewExtr, lastVertex);
622 makeEdge.Init(curve, firstVertex, NewExtr);
623 TopoDS_Edge anEdge = makeEdge;
624 anEdge.Orientation(E1.Orientation());
625 // anEdge.Location(E1.Location());
627 BRepLib_EdgeError error =
634 //=======================================================================
635 //function : BuildNewEdge
636 //purpose : special flag if the new edge is degenerated
637 //=======================================================================
639 TopoDS_Edge ChFi2d_Builder::BuildNewEdge(const TopoDS_Edge& E1,
640 const TopoDS_Vertex& OldExtr,
641 const TopoDS_Vertex& NewExtr,
642 Standard_Boolean& IsDegenerated) const
644 BRepLib_MakeEdge makeEdge;
646 Standard_Real first, last;
647 IsDegenerated = Standard_False;
648 TopoDS_Vertex firstVertex, lastVertex;
649 TopExp::Vertices(E1, firstVertex, lastVertex);
650 gp_Pnt Pnew = BRep_Tool::Pnt(NewExtr);
651 Standard_Boolean PonctualEdge = Standard_False;
652 Standard_Real Tol = Precision::Confusion();
653 // syntax wrong on NT
654 // const Handle(Geom_Curve)& curve =
655 // BRep_Tool::Curve(E1, first, last);
656 Handle(Geom_Curve) curve = BRep_Tool::Curve(E1, first, last);
657 if (firstVertex.IsSame(OldExtr)) {
658 makeEdge.Init(curve, NewExtr, lastVertex);
659 gp_Pnt PV = BRep_Tool::Pnt(lastVertex);
660 PonctualEdge = (Pnew.Distance(PV)<Tol);
663 makeEdge.Init(curve, firstVertex, NewExtr);
664 gp_Pnt PV = BRep_Tool::Pnt(firstVertex);
665 PonctualEdge = (Pnew.Distance(PV)<Tol);
668 BRepLib_EdgeError error = makeEdge.Error();
669 if (error==BRepLib_LineThroughIdenticPoints || PonctualEdge) {
670 IsDegenerated = Standard_True;
675 anEdge.Orientation(E1.Orientation());
676 // anEdge.Location(E1.Location());
682 //=======================================================================
683 //function : UpDateHistory
685 //=======================================================================
686 void ChFi2d_Builder::UpDateHistory(const TopoDS_Edge& E1,
687 const TopoDS_Edge& E2,
688 const TopoDS_Edge& TrimE1,
689 const TopoDS_Edge& TrimE2,
690 const TopoDS_Edge& NewEdge,
691 const Standard_Integer Id)
693 if (Id == 1) // the new edge is a fillet
694 fillets.Append(NewEdge);
695 else // the new edge is a chamfer
696 chamfers.Append(NewEdge);
697 if (history.IsBound(E1)) history.UnBind(E1);
698 if ( status != ChFi2d_FirstEdgeDegenerated
699 && status != ChFi2d_BothEdgesDegenerated) {
700 if (!E1.IsSame(TrimE1)) history.Bind(E1, TrimE1);
702 if (history.IsBound(E2)) history.UnBind(E2);
703 if ( status != ChFi2d_LastEdgeDegenerated
704 && status != ChFi2d_BothEdgesDegenerated) {
705 if (!E2.IsSame(TrimE2)) history.Bind(E2, TrimE2);
710 //=======================================================================
711 //function : UpDateHistory
713 //=======================================================================
714 void ChFi2d_Builder::UpDateHistory(const TopoDS_Edge& E1,
715 const TopoDS_Edge& E2,
716 const TopoDS_Edge& TrimE1,
717 const TopoDS_Edge& TrimE2)
721 if (history.IsBound(E1)) history.UnBind(E1);
722 if (!E1.IsSame(TrimE1)) history.Bind(E1, TrimE1);
723 if (history.IsBound(E2)) history.UnBind(E2);
724 if (!E2.IsSame(TrimE2)) history.Bind(E2, TrimE2);
728 //=======================================================================
729 //function : BasisEdge
731 //=======================================================================
732 const TopoDS_Edge& ChFi2d_Builder::BasisEdge(const TopoDS_Edge& E) const
734 TopTools_DataMapIteratorOfDataMapOfShapeShape iterator(history);
736 while (iterator.More()) {
737 anEdge = TopoDS::Edge(iterator.Value());
738 if (anEdge.IsSame(E)) {
739 const TopoDS_Edge& anotherEdge = TopoDS::Edge(iterator.Key());
741 } // if (anEdge.IsSame ...
743 } // while (Iterator.More ...
748 //=======================================================================
749 //function : BuildFilletEdge
751 //=======================================================================
752 TopoDS_Edge ChFi2d_Builder::BuildFilletEdge(const TopoDS_Vertex& V,
753 const TopoDS_Edge& AdjEdge1,
754 const TopoDS_Edge& AdjEdge2,
755 const Standard_Real Radius,
756 TopoDS_Vertex& NewExtr1,
757 TopoDS_Vertex& NewExtr2)
762 TopoDS_Vertex V1 = TopExp::FirstVertex(E1);
763 TopoDS_Vertex V2 = TopExp::LastVertex(E1);
764 TopoDS_Vertex V3 = TopExp::FirstVertex(E2);
765 TopoDS_Vertex V4 = TopExp::LastVertex(E2);
767 //========================================================================
768 // The first arc is found. +
769 //========================================================================
771 TopAbs_Orientation O1,O2;
772 TopAbs_Orientation OE1,OE2;
773 OE1 = E1.Orientation();
774 OE2 = E2.Orientation();
775 E1.Orientation(TopAbs_FORWARD);
776 E2.Orientation(TopAbs_FORWARD);
777 TopoDS_Shape aLocalShape = E1.EmptyCopied();
778 TopoDS_Edge Ebid1 = TopoDS::Edge(aLocalShape);
779 aLocalShape = E2.EmptyCopied();
780 TopoDS_Edge Ebid2 = TopoDS::Edge(aLocalShape);
781 // TopoDS_Edge Ebid1 = TopoDS::Edge(E1.EmptyCopied());
782 // TopoDS_Edge Ebid2 = TopoDS::Edge(E2.EmptyCopied());
783 Standard_Real param1,param2,param3,param4;
785 //========================================================================
786 // Save non-modified parts of edges concerned. +
787 //========================================================================
790 param1 = BRep_Tool::Parameter(V1,E1);
791 param2 = BRep_Tool::Parameter(V2,E1);
792 O1 = V2.Orientation();
795 param1 = BRep_Tool::Parameter(V2,E1);
796 param2 = BRep_Tool::Parameter(V1,E1);
797 O1 = V1.Orientation();
800 param3 = BRep_Tool::Parameter(V3,E2);
801 param4 = BRep_Tool::Parameter(V4,E2);
802 O2 = V4.Orientation();
805 param3 = BRep_Tool::Parameter(V4,E2);
806 param4 = BRep_Tool::Parameter(V3,E2);
807 O2 = V3.Orientation();
810 //========================================================================
811 // Restore geometric supports. +
812 //========================================================================
814 Handle(Geom2d_Curve) C1,C2;
815 Standard_Real ufirst1,ulast1,ufirst2,ulast2,U1,U2,PU1,PU2,Vv1,Vv2;
816 Standard_Real PPU1,PPU2;
817 C1 = BRep_Tool::CurveOnSurface(E1,newFace,ufirst1,ulast1);
818 C2 = BRep_Tool::CurveOnSurface(E2,newFace,ufirst2,ulast2);
820 //========================================================================
821 // Determination of the face for fillet. +
822 //========================================================================
827 Standard_Boolean Sens1 , Sens2;
829 Handle(Geom2d_Curve) basisC1,basisC2;
830 Handle(Geom2d_TrimmedCurve) T1 = Handle(Geom2d_TrimmedCurve)::DownCast(C1);
832 basisC1 = Handle(Geom2d_Curve)::DownCast(T1->BasisCurve());
834 basisC1 = Handle(Geom2d_Curve)::DownCast(C1);
835 Handle(Geom2d_TrimmedCurve) T2 = Handle(Geom2d_TrimmedCurve)::DownCast(C2);
837 basisC2 = Handle(Geom2d_Curve)::DownCast(T2->BasisCurve());
839 basisC2 = Handle(Geom2d_Curve)::DownCast(C2);
841 if (basisC1->DynamicType() == STANDARD_TYPE(Geom2d_Circle)) {
842 Handle(Geom2d_Circle) CC1 = Handle(Geom2d_Circle)::DownCast(basisC1);
843 ElCLib::D1(param1,CC1->Circ2d(),p,Ve1);
844 Sens1 = (CC1->Circ2d()).IsDirect();
845 } // if (C1->DynamicType() ...
847 Handle(Geom2d_Line) CC1 = Handle(Geom2d_Line)::DownCast(basisC1);
848 ElCLib::D1(param1,CC1->Lin2d(),p,Ve1);
851 if (basisC2->DynamicType() == STANDARD_TYPE(Geom2d_Circle)) {
852 Handle(Geom2d_Circle) CC2 = Handle(Geom2d_Circle)::DownCast(basisC2);
853 ElCLib::D1(param3,CC2->Circ2d(),p,Ve2);
854 Sens2 = (CC2->Circ2d()).IsDirect();
855 } // if if (C2->DynamicType() ...
857 Handle(Geom2d_Line) CC2 = Handle(Geom2d_Line)::DownCast(basisC2);
858 ElCLib::D1(param3,CC2->Lin2d(),p,Ve2);
862 TopoDS_Edge filletEdge;
864 Standard_Real cross = Ve1.Crossed(Ve2);
868 // processing of tangency or downcast point
869 if (Ve1.IsParallel(Ve2,Precision::Angular())) {
870 // Ve1 and Ve2 are parallel : cross at 0
879 if (! Ve4.IsOpposite(Ve3,Precision::Angular())) {
880 // There is a true tangency point and the calculation is stopped
881 status = ChFi2d_TangencyError;
884 // Otherwise this is a downcast point, and the calculation is continued
887 GccEnt_Position Qual1,Qual2;
889 if (param3 > param4 ) {
890 if(Sens1 == Standard_True){
891 Qual1 = GccEnt_enclosed;
894 Qual1 = GccEnt_outside;
898 if(Sens1 == Standard_True){
899 Qual1 = GccEnt_outside;
902 Qual1 = GccEnt_enclosed;
905 if (param1 > param2) {
906 if(Sens2 == Standard_True)
907 Qual2 = GccEnt_outside;
909 Qual2 = GccEnt_enclosed;
912 if(Sens2 == Standard_True)
913 Qual2 = GccEnt_enclosed;
915 Qual2 = GccEnt_outside;
917 } // if (cross < 0 ...
919 if (param3 > param4 ) {
920 if( Sens1 == Standard_True)
921 Qual1 = GccEnt_outside;
923 Qual1 = GccEnt_enclosed;
926 if( Sens1 == Standard_True)
927 Qual1 = GccEnt_enclosed;
929 Qual1 = GccEnt_outside;
931 if (param1 > param2 ) {
932 if( Sens2 == Standard_True)
933 Qual2 = GccEnt_enclosed;
935 Qual2 = GccEnt_outside;
938 if( Sens2 == Standard_True)
939 Qual2 = GccEnt_outside;
941 Qual2 = GccEnt_enclosed;
945 Standard_Real Tol = Precision::Confusion();
946 Geom2dGcc_Circ2d2TanRad Fillet(Geom2dGcc_QualifiedCurve(basisC1,Qual1),
947 Geom2dGcc_QualifiedCurve(basisC2,Qual2),
949 if (!Fillet.IsDone() || Fillet.NbSolutions()==0) {
950 status = ChFi2d_ComputationError;
953 else if (Fillet.NbSolutions() >= 1) {
954 status = ChFi2d_IsDone;
955 Standard_Integer numsol = 1;
956 Standard_Integer nsol = 1;
957 TopoDS_Vertex Vertex1,Vertex2;
960 Standard_Real dist1 = 1.e40;
961 Standard_Boolean inside = Standard_False;
962 while (nsol<=Fillet.NbSolutions()) {
963 Fillet.Tangency1(nsol,PU1,PU2,Ptg1);
964 dist = Ptg1.Distance(p);
965 if (basisC1->DynamicType() == STANDARD_TYPE(Geom2d_Line)) {
966 inside = (PU2<param1 && PU2>param2) || (PU2<param2 && PU2>param1);
967 if ( inside && dist < dist1) {
970 } // if ((((inside && ...
971 } // if (C1->DynamicType( ...
973 Fillet.Tangency2(nsol,PPU1,PPU2,Ptg2);
974 dist = Ptg2.Distance(p);
975 inside = (PPU2<param3 && PPU2>param4) || (PPU2<param4 && PPU2>param3);
976 // case of arc of circle passing on the sewing
977 if ( ( basisC2->DynamicType() == STANDARD_TYPE(Geom2d_Circle) ) &&
978 ( (2*PI<param3 && 2*PI>param4) || (2*PI<param4 && 2*PI>param3) ) ) {
980 inside = (param3<PPU2 && PPU2<2*PI)
981 || (0<=PPU2 && PPU2<param4-2*PI);
983 inside = inside || (param4<PPU2 && PPU2<2*PI)
984 || (0<=PPU2 && PPU2<param3-2*PI);
986 if ( inside && dist < dist1) {
989 } // if ((((param3 ...
993 gp_Circ2d cir(Fillet.ThisSolution(numsol));
994 Handle(Geom2d_Circle) circle = new Geom2d_Circle(cir);
997 BRepAdaptor_Surface Adaptor3dSurface(refFace);
998 Handle(Geom_Plane) refSurf = new Geom_Plane(Adaptor3dSurface.Plane());
999 Fillet.Tangency1(numsol,U1,U2,Ptg1);
1000 Fillet.Tangency2(numsol,Vv1,Vv2,Ptg2);
1002 // check the validity of parameters
1003 //// modified by jgv, 08.08.2011 for bug 0022695 ////
1004 //inside = (U2<param1 && U2>param2) || (U2<param2 && U2>param1);
1005 inside = (U2 < param1 && U2 >= param2) || (U2 <= param2 && U2 > param1);
1006 /////////////////////////////////////////////////////
1007 if ( (basisC1->DynamicType() == STANDARD_TYPE(Geom2d_Circle))
1008 && ( (2*PI<param1 && 2*PI>param2) || (2*PI<param2 && 2*PI>param1) ) ) {
1009 // arc of circle containing the circle origin
1010 // case param1<param2
1011 inside = (param1<U2 && U2<2*PI) || (0<=U2 && U2<param2-2*PI);
1012 // case param2<param1
1013 inside = inside || (param2<U2 && U2<2*PI) || (0<=U2 && U2<param1-2*PI);
1016 status = ChFi2d_ComputationError;
1020 //// modified by jgv, 08.08.2011 for bug 0022695 ////
1021 //inside = (Vv2<param3 && Vv2>param4) || (Vv2<param4 && Vv2>param3);
1022 inside = (Vv2 < param3 && Vv2 >= param4) || (Vv2 <= param4 && Vv2 > param3);
1023 /////////////////////////////////////////////////////
1024 if ( (basisC2->DynamicType() == STANDARD_TYPE(Geom2d_Circle))
1025 && ( (2*PI<param3 && 2*PI>param4) || (2*PI<param4 && 2*PI>param3) ) ) {
1026 // arc of circle containing the circle origin
1027 // cas param3<param4
1028 inside = (param3<Vv2 && Vv2<2*PI) || (0<=Vv2 && Vv2<param4-2*PI);
1029 // cas param4<param3
1030 inside = inside || (param4<Vv2 && Vv2<2*PI) || (0<=Vv2 && Vv2<param3-2*PI);
1033 status = ChFi2d_ComputationError;
1037 gp_Pnt p1 = Adaptor3dSurface.Value(Ptg1.X(), Ptg1.Y());
1038 gp_Pnt p2 = Adaptor3dSurface.Value(Ptg2.X(), Ptg2.Y());
1039 B.MakeVertex(Vertex1, p1,Tol);
1041 if (Abs(U2-ufirst1) <= Precision::PConfusion()) {
1044 if (Abs(U2-ulast1) <= Precision::PConfusion()) {
1048 B.MakeVertex(Vertex2, p2,Tol);
1050 if (Abs(Vv2-ufirst2) <= Precision::PConfusion()) {
1053 if (Abs(Vv2-ulast2) <= Precision::PConfusion()) {
1057 //=======================================================================
1058 // Update tops of the fillet. +
1059 //=======================================================================
1062 Pntbid = BRep_Tool::Pnt(V);
1063 sommet = gp_Pnt2d(Pntbid.X(),Pntbid.Y());
1068 pntBid = BRep_Tool::Pnt(V2);
1069 somBid = gp_Pnt2d(pntBid.X(),pntBid.Y());
1072 pntBid = BRep_Tool::Pnt(V1);
1073 somBid = gp_Pnt2d(pntBid.X(),pntBid.Y());
1077 ElCLib::D1(U1,cir,Ptg1,vec);
1080 if (basisC1->DynamicType() == STANDARD_TYPE(Geom2d_Circle)) {
1081 Handle(Geom2d_Circle) CC1 = Handle(Geom2d_Circle)::DownCast(basisC1);
1082 gp_Circ2d cir2d(CC1->Circ2d());
1083 Standard_Real par = ElCLib::Parameter(cir2d,Ptg1);
1085 ElCLib::D1(par,cir2d,Pd,vec1);
1086 } // if (C1->DynamicType() ...
1087 else if (basisC1->DynamicType() == STANDARD_TYPE(Geom2d_Line)) {
1088 Handle(Geom2d_Line) CC1 = Handle(Geom2d_Line)::DownCast(basisC1);
1089 gp_Lin2d lin2d(CC1->Lin2d());
1090 Standard_Real par = ElCLib::Parameter(lin2d,sommet);
1091 vec1 = gp_Vec2d(sommet.X()-somBid.X(),sommet.Y()-somBid.Y());
1093 ElCLib::D1(par,lin2d,Pd,vec1);
1096 if (OE1 == TopAbs_REVERSED) {
1099 Standard_Real cross = vec1*vec;
1100 Standard_Boolean Sense = cross > 0.;
1101 if (U1 > Vv1 && U1 > 2.*PI) {
1102 ElCLib::AdjustPeriodic(0.,2.*PI,Precision::Confusion(),U1,Vv1);
1104 if (O1 == TopAbs_FORWARD && OE1 == TopAbs_FORWARD ||
1105 O1 == TopAbs_REVERSED && OE1 == TopAbs_REVERSED ) {
1106 filletEdge = BRepLib_MakeEdge(circle, refSurf,
1107 NewExtr1, NewExtr2, U1, Vv1);
1110 filletEdge = BRepLib_MakeEdge(circle, refSurf,
1111 NewExtr2, NewExtr1, Vv1, U1);
1114 TopAbs_Orientation S1 = filletEdge.Orientation();
1115 if (O1 == TopAbs_FORWARD && OE1 == TopAbs_FORWARD ||
1116 O1 == TopAbs_REVERSED && OE1 == TopAbs_REVERSED ) {
1117 filletEdge = BRepLib_MakeEdge(circle, refSurf,
1118 NewExtr2, NewExtr1, Vv1, U1);
1121 filletEdge = BRepLib_MakeEdge(circle, refSurf,
1122 NewExtr1, NewExtr2, U1, Vv1);
1124 if (S1 == TopAbs_FORWARD) {
1125 filletEdge.Orientation(TopAbs_REVERSED);
1128 filletEdge.Orientation(TopAbs_FORWARD);
1134 BRepLib::BuildCurves3d(filletEdge);
1136 } // BuildFilletEdge
1139 //=======================================================================
1140 //function : IsAFillet
1142 //=======================================================================
1144 Standard_Boolean ChFi2d_Builder::IsAFillet(const TopoDS_Edge& E) const
1146 Standard_Integer i = 1;
1147 while (i <= fillets.Length()) {
1148 const TopoDS_Edge& currentEdge = TopoDS::Edge(fillets.Value(i));
1149 if (currentEdge.IsSame(E)) return Standard_True;
1152 return Standard_False;
1156 //=======================================================================
1157 //function : IsAChamfer
1159 //=======================================================================
1161 Standard_Boolean ChFi2d_Builder::IsAChamfer(const TopoDS_Edge& E) const
1163 Standard_Integer i = 1;
1164 while (i <= chamfers.Length()) {
1165 const TopoDS_Edge& currentEdge = TopoDS::Edge(chamfers.Value(i));
1166 if (currentEdge.IsSame(E)) return Standard_True;
1169 return Standard_False;
1174 //=======================================================================
1175 //function : IsLineOrCircle
1177 //=======================================================================
1179 Standard_Boolean IsLineOrCircle(const TopoDS_Edge& E,
1180 const TopoDS_Face& F)
1182 Standard_Real first, last;
1183 TopLoc_Location loc;
1184 // syntaxe invalide sur NT
1185 // const Handle(Geom2d_Curve)& C =
1186 // BRep_Tool::CurveOnSurface(E,F,first,last);
1187 Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,first,last);
1188 Handle(Geom2d_Curve) basisC;
1189 Handle(Geom2d_TrimmedCurve) TC = Handle(Geom2d_TrimmedCurve)::DownCast(C);
1191 basisC = Handle(Geom2d_Curve)::DownCast(TC->BasisCurve());
1193 basisC = Handle(Geom2d_Curve)::DownCast(C);
1195 if ( basisC->DynamicType() == STANDARD_TYPE(Geom2d_Circle)
1196 || basisC->DynamicType() == STANDARD_TYPE(Geom2d_Line) ) {
1197 return Standard_True;
1200 return Standard_False;