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.
17 // Modified : 08/07/97 : JPI : traitement des edges degeneres comme pour les fillets 2D
18 // Modified: Fri Sep 25 09:38:04 1998
19 // status = ChFi2d_NotAuthorized si les aretes ne sont pas
20 // des droites ou des cercles; fonction IsLineOrCircle
23 #include <BRep_Builder.hxx>
24 #include <BRep_Tool.hxx>
25 #include <BRepAdaptor_Curve.hxx>
26 #include <BRepAdaptor_Surface.hxx>
27 #include <BRepLib_MakeEdge.hxx>
28 #include <BRepLib_MakeFace.hxx>
30 #include <ChFi2d_Builder.hxx>
32 #include <GCPnts_AbscissaPoint.hxx>
33 #include <Geom2d_Circle.hxx>
34 #include <Geom2d_Curve.hxx>
35 #include <Geom2d_Line.hxx>
36 #include <Geom2d_TrimmedCurve.hxx>
37 #include <Geom2dAdaptor_Curve.hxx>
38 #include <Geom2dInt_GInter.hxx>
39 #include <Geom_Curve.hxx>
40 #include <Geom_Line.hxx>
41 #include <Geom_Plane.hxx>
42 #include <Geom_Surface.hxx>
43 #include <GeomAdaptor_Curve.hxx>
44 #include <GeomAPI.hxx>
47 #include <gp_Pnt2d.hxx>
48 #include <IntRes2d_IntersectionPoint.hxx>
49 #include <Precision.hxx>
50 #include <TopAbs_Orientation.hxx>
52 #include <TopExp_Explorer.hxx>
53 #include <TopLoc_Location.hxx>
55 #include <TopoDS_Edge.hxx>
56 #include <TopoDS_Face.hxx>
57 #include <TopoDS_Shape.hxx>
58 #include <TopoDS_Vertex.hxx>
59 #include <TopoDS_Wire.hxx>
61 gp_Pnt ComputePoint(const TopoDS_Vertex& V,const TopoDS_Edge& E,
62 const Standard_Real D1, Standard_Real& Param1);
63 gp_Pnt ComputePoint(const TopoDS_Face& F, const Handle(Geom_Line)& L,
64 const TopoDS_Edge& E, Standard_Real& Param);
65 void OrientChamfer(TopoDS_Edge& chamfer,
67 const TopoDS_Vertex& V);
69 static Standard_Boolean IsLineOrCircle(const TopoDS_Edge& E,
70 const TopoDS_Face& F);
73 //=======================================================================
74 //function : AddChamfer
76 //=======================================================================
78 TopoDS_Edge ChFi2d_Builder::AddChamfer(const TopoDS_Edge& E1,
79 const TopoDS_Edge& E2,
80 const Standard_Real D1,
81 const Standard_Real D2)
83 TopoDS_Vertex commonVertex;
84 TopoDS_Edge basisEdge1, basisEdge2;
85 TopoDS_Edge E1Mod, E2Mod, chamfer;
87 Standard_Boolean hasConnection = ChFi2d::CommonVertex(E1, E2, commonVertex);
88 if (!hasConnection) return chamfer;
90 if (IsAFillet(E1) || IsAChamfer(E1) ||
91 IsAFillet(E2) || IsAChamfer(E2)) {
92 status = ChFi2d_NotAuthorized;
94 } // if (IsAChamfer ...
96 if (!IsLineOrCircle(E1,newFace)
97 || !IsLineOrCircle(E2,newFace) ) {
98 status = ChFi2d_NotAuthorized;
100 } // if (!IsLineOrCircle ...
102 // EE1 and EE2 are copies of E1 and E2 with the good orientation
104 TopoDS_Edge EE1, EE2;
105 status = ChFi2d::FindConnectedEdges(newFace, commonVertex, EE1, EE2);
106 if (EE1.IsSame(E2)) {
107 TopAbs_Orientation orient = EE1.Orientation();
110 EE2.Orientation(orient);
113 ComputeChamfer(commonVertex, EE1, EE2, D1, D2,
114 E1Mod, E2Mod, chamfer);
115 if (status == ChFi2d_IsDone
116 || status == ChFi2d_FirstEdgeDegenerated
117 || status == ChFi2d_LastEdgeDegenerated
118 || status == ChFi2d_BothEdgesDegenerated) {
119 // if (status == ChFi2d_IsDone) {
120 BuildNewWire(EE1, EE2, E1Mod, chamfer, E2Mod);
121 basisEdge1 = BasisEdge(EE1);
122 basisEdge2 = BasisEdge(EE2);
123 UpDateHistory(basisEdge1, basisEdge2,
124 E1Mod, E2Mod, chamfer, 2);
125 status = ChFi2d_IsDone;
126 return TopoDS::Edge(chamfers.Value(chamfers.Length()));
132 //=======================================================================
133 //function : AddChamfer
135 //=======================================================================
137 TopoDS_Edge ChFi2d_Builder::AddChamfer(const TopoDS_Edge& E,
138 const TopoDS_Vertex& V,
139 const Standard_Real D,
140 const Standard_Real Ang)
142 TopoDS_Edge aChamfer, adjEdge1, adjEdge2;
143 status = ChFi2d::FindConnectedEdges(newFace, V, adjEdge1, adjEdge2);
144 if (status == ChFi2d_ConnexionError) return aChamfer;
146 // adjEdge1 is a copy of E with the good orientation
148 if (adjEdge2.IsSame(E)) {
149 TopAbs_Orientation orient = adjEdge2.Orientation();
152 adjEdge1.Orientation(orient);
155 if (IsAFillet(adjEdge1) || IsAChamfer(adjEdge1) ||
156 IsAFillet(adjEdge2) || IsAChamfer(adjEdge2)) {
157 status = ChFi2d_NotAuthorized;
159 } // if (IsAChamfer ...
161 if (!IsLineOrCircle(adjEdge1,newFace)
162 || !IsLineOrCircle(adjEdge2,newFace) ) {
163 status = ChFi2d_NotAuthorized;
165 } // if (!IsLineOrCircle ...
168 ComputeChamfer(V, adjEdge1, D, Ang,
169 adjEdge2, E1, E2, aChamfer);
170 TopoDS_Edge basisEdge1, basisEdge2;
171 if (status == ChFi2d_IsDone
172 || status == ChFi2d_FirstEdgeDegenerated
173 || status == ChFi2d_LastEdgeDegenerated
174 || status == ChFi2d_BothEdgesDegenerated) {
175 // if (status == ChFi2d_IsDone) {
176 BuildNewWire(adjEdge1, adjEdge2, E1, aChamfer, E2);
177 basisEdge1 = BasisEdge(adjEdge1);
178 basisEdge2 = BasisEdge(adjEdge2);
179 UpDateHistory(basisEdge1, basisEdge2,
180 E1, E2, aChamfer, 2);
181 status = ChFi2d_IsDone;
182 return TopoDS::Edge(chamfers.Value(chamfers.Length()));
189 //=======================================================================
190 //function : ComputeChamfer
192 //=======================================================================
194 void ChFi2d_Builder::ComputeChamfer(const TopoDS_Vertex& V,
195 const TopoDS_Edge& E1,
196 const TopoDS_Edge& E2,
197 const Standard_Real D1,
198 const Standard_Real D2,
201 TopoDS_Edge& Chamfer)
203 TopoDS_Vertex newExtr1, newExtr2;
204 Standard_Boolean Degen1, Degen2;
205 Chamfer = BuildChamferEdge(V, E1, E2, D1, D2, newExtr1, newExtr2);
206 if ( status != ChFi2d_IsDone) return;
207 TrimE1 = BuildNewEdge(E1, V, newExtr1, Degen1);
208 TrimE2 = BuildNewEdge(E2, V, newExtr2, Degen2);
209 if (Degen1 && Degen2 ) status = ChFi2d_BothEdgesDegenerated;
210 if (Degen1 && !Degen2 ) status = ChFi2d_FirstEdgeDegenerated;
211 if (!Degen1 && Degen2 ) status = ChFi2d_LastEdgeDegenerated;
212 // TrimE1 = BuildNewEdge(E1, V, newExtr1);
213 // TrimE2 = BuildNewEdge(E2, V, newExtr2);
217 //=======================================================================
218 //function : ComputeChamfer
220 //=======================================================================
222 void ChFi2d_Builder::ComputeChamfer(const TopoDS_Vertex& V,
223 const TopoDS_Edge& E1,
224 const Standard_Real D,
225 const Standard_Real Ang,
226 const TopoDS_Edge& E2,
229 TopoDS_Edge& Chamfer)
231 TopoDS_Vertex newExtr1, newExtr2;
232 Standard_Boolean Degen1, Degen2;
233 Chamfer = BuildChamferEdge(V, E1, D, Ang, E2, newExtr1, newExtr2);
234 if ( status != ChFi2d_IsDone) return;
235 TrimE1 = BuildNewEdge(E1, V, newExtr1, Degen1);
236 TrimE2 = BuildNewEdge(E2, V, newExtr2, Degen2);
237 if (Degen1 && Degen2 ) status = ChFi2d_BothEdgesDegenerated;
238 if (Degen1 && !Degen2 ) status = ChFi2d_FirstEdgeDegenerated;
239 if (!Degen1 && Degen2 ) status = ChFi2d_LastEdgeDegenerated;
240 // TrimE1 = BuildNewEdge(E1, V, newExtr1);
241 // TrimE2 = BuildNewEdge(E2, V, newExtr2);
245 //=======================================================================
246 //function : ModifyFillet
248 //=======================================================================
250 TopoDS_Edge ChFi2d_Builder::ModifyChamfer(const TopoDS_Edge& Chamfer,
251 const TopoDS_Edge& /*E1*/,
252 const TopoDS_Edge& E2,
253 const Standard_Real D1,
254 const Standard_Real D2)
256 TopoDS_Vertex aVertex = RemoveChamfer(Chamfer);
257 TopoDS_Edge adjEdge1, adjEdge2;
258 status = ChFi2d::FindConnectedEdges(newFace, aVertex, adjEdge1, adjEdge2);
259 TopoDS_Edge aChamfer;
260 if (status == ChFi2d_ConnexionError) return aChamfer;
262 // adjEdge1 and adjEdge2 are copies of E1 and E2 with the good orientation
264 if (adjEdge1.IsSame(E2)) {
265 TopAbs_Orientation orient = adjEdge1.Orientation();
268 adjEdge2.Orientation(orient);
271 aChamfer = AddChamfer(adjEdge1, adjEdge2, D1, D2);
276 //=======================================================================
277 //function : ModifyFillet
279 //=======================================================================
281 TopoDS_Edge ChFi2d_Builder::ModifyChamfer(const TopoDS_Edge& Chamfer,
282 const TopoDS_Edge& E,
283 const Standard_Real D,
284 const Standard_Real Ang)
286 TopoDS_Vertex aVertex = RemoveChamfer(Chamfer);
287 TopoDS_Edge adjEdge1, adjEdge2;
288 status = ChFi2d::FindConnectedEdges(newFace, aVertex, adjEdge1, adjEdge2);
289 TopoDS_Edge aChamfer;
290 if (status == ChFi2d_ConnexionError) return aChamfer;
292 if (adjEdge1.IsSame(E))
293 aChamfer = AddChamfer(adjEdge1, aVertex, D, Ang);
294 else aChamfer = AddChamfer(adjEdge2, aVertex, D, Ang);
299 //=======================================================================
300 //function : RemoveChamfer
302 //=======================================================================
304 TopoDS_Vertex ChFi2d_Builder::RemoveChamfer(const TopoDS_Edge& Chamfer)
306 TopoDS_Vertex commonVertex;
308 Standard_Integer i = 1;
309 Standard_Integer IsFind = Standard_False;
310 while (i <= chamfers.Length()) {
311 const TopoDS_Edge& aChamfer = TopoDS::Edge(chamfers.Value(i));
312 if (aChamfer.IsSame(Chamfer)) {
314 IsFind = Standard_True;
319 if (!IsFind) return commonVertex;
321 TopoDS_Vertex firstVertex, lastVertex;
322 TopExp::Vertices(Chamfer, firstVertex, lastVertex);
325 TopoDS_Edge adjEdge1, adjEdge2;
326 status = ChFi2d::FindConnectedEdges(newFace, firstVertex,
328 if (status == ChFi2d_ConnexionError) return commonVertex;
330 TopoDS_Edge basisEdge1, basisEdge2, E1, E2;
331 // E1 and E2 are the adjacentes edges to Chamfer
333 if (adjEdge1.IsSame(Chamfer)) E1 = adjEdge2;
335 basisEdge1 = BasisEdge(E1);
336 status = ChFi2d::FindConnectedEdges(newFace, lastVertex,adjEdge1, adjEdge2);
337 if (status == ChFi2d_ConnexionError) return commonVertex;
338 if (adjEdge1.IsSame(Chamfer)) E2 = adjEdge2;
340 basisEdge2 = BasisEdge(E2);
341 TopoDS_Vertex connectionE1Chamfer, connectionE2Chamfer;
342 Standard_Boolean hasConnection =
343 ChFi2d::CommonVertex(basisEdge1, basisEdge2, commonVertex);
344 if (!hasConnection) {
345 status = ChFi2d_ConnexionError;
348 hasConnection = ChFi2d::CommonVertex(E1, Chamfer, connectionE1Chamfer);
349 if (!hasConnection) {
350 status = ChFi2d_ConnexionError;
353 hasConnection = ChFi2d::CommonVertex(E2, Chamfer, connectionE2Chamfer);
354 if (!hasConnection) {
355 status = ChFi2d_ConnexionError;
359 // rebuild edges on wire
360 TopoDS_Edge newEdge1, newEdge2;
361 TopoDS_Vertex v, v1, v2;
362 BRepLib_MakeEdge makeEdge;
364 Standard_Real first, last;
366 TopExp::Vertices(E1, firstVertex, lastVertex);
367 TopExp::Vertices(basisEdge1, v1, v2);
368 if (v1.IsSame(commonVertex)) v = v2;
371 if ( firstVertex.IsSame(v) || lastVertex.IsSame(v))
372 // It means the edge support only one fillet. In this case
373 // the new edge must be the basis edge.
374 newEdge1 = basisEdge1;
376 // It means the edge support one fillet on each end.
377 if (firstVertex.IsSame(connectionE1Chamfer)) {
378 // syntaxe invalide sur NT
379 // const Handle(Geom_Curve)& curve =
380 // BRep_Tool::Curve(E1, loc, first, last);
381 Handle(Geom_Curve) curve = BRep_Tool::Curve(E1, loc, first, last);
382 makeEdge.Init(curve, commonVertex, lastVertex);
383 newEdge1 = makeEdge.Edge();
384 newEdge1.Orientation(basisEdge1.Orientation());
385 newEdge1.Location(basisEdge1.Location());
386 } // if (firstVertex ...
387 else if (lastVertex.IsSame(connectionE1Chamfer)) {
388 // syntaxe invalide sur NT
389 // const Handle(Geom_Curve)& curve =
390 // BRep_Tool::Curve(E1, loc, first, last);
391 Handle(Geom_Curve) curve = BRep_Tool::Curve(E1, loc, first, last);
392 makeEdge.Init(curve, firstVertex, commonVertex);
393 newEdge1 = makeEdge.Edge();
394 newEdge1.Orientation(basisEdge1.Orientation());
395 newEdge1.Location(basisEdge1.Location());
396 } // else if (lastVertex ...
399 TopExp::Vertices(basisEdge2, v1, v2);
400 if (v1.IsSame(commonVertex)) v = v2;
403 TopExp::Vertices(E2, firstVertex, lastVertex);
404 if ( firstVertex.IsSame(v) || lastVertex.IsSame(v))
405 // It means the edge support only one fillet. In this case
406 // the new edge must be the basis edge.
407 newEdge2 = basisEdge2;
409 // It means the edge support one fillet on each end.
410 if (firstVertex.IsSame(connectionE2Chamfer)) {
411 // syntaxe invalide sur NT
412 // const Handle(Geom_Curve)& curve =
413 // BRep_Tool::Curve(E2, loc, first, last);
414 Handle(Geom_Curve) curve = BRep_Tool::Curve(E2, loc, first, last);
415 makeEdge.Init(curve, commonVertex, lastVertex);
416 newEdge2 = makeEdge.Edge();
417 newEdge2.Orientation(basisEdge2.Orientation());
418 newEdge2.Location(basisEdge2.Location());
419 } // if (firstVertex ...
420 else if (lastVertex.IsSame(connectionE2Chamfer)) {
421 // syntaxe invalide sur NT
422 // const Handle(Geom_Curve)& curve =
423 // BRep_Tool::Curve(E2, loc, first, last);
424 Handle(Geom_Curve) curve = BRep_Tool::Curve(E2, loc, first, last);
425 makeEdge.Init(curve, firstVertex, commonVertex);
426 newEdge2 = makeEdge.Edge();
427 newEdge2.Orientation(basisEdge2.Orientation());
428 newEdge2.Location(basisEdge2.Location());
429 } // else if (lastVertex ...
432 // rebuild the newFace
433 TopExp_Explorer Ex(newFace, TopAbs_EDGE);
440 const TopoDS_Edge& theEdge = TopoDS::Edge(Ex.Current());
441 if (!theEdge.IsSame(E1) &&
442 !theEdge.IsSame(E2) &&
443 !theEdge.IsSame(Chamfer) )
444 B.Add(newWire, theEdge);
447 B.Add(newWire, newEdge1);
448 else if (theEdge == E2)
449 B.Add(newWire, newEdge2);
454 BRepAdaptor_Surface Adaptor3dSurface(refFace);
455 BRepLib_MakeFace mFace(Adaptor3dSurface.Plane(), newWire);
459 UpDateHistory(basisEdge1, basisEdge2, newEdge1, newEdge2);
465 //=======================================================================
466 //function : BuildChamferEdge
468 //=======================================================================
469 TopoDS_Edge ChFi2d_Builder::BuildChamferEdge(const TopoDS_Vertex& V,
470 const TopoDS_Edge& AdjEdge1,
471 const TopoDS_Edge& AdjEdge2,
472 const Standard_Real D1,
473 const Standard_Real D2,
474 TopoDS_Vertex& NewExtr1,
475 TopoDS_Vertex& NewExtr2)
478 if ( D1 <= 0 || D2 <= 0) {
479 status = ChFi2d_ParametersError;
483 Standard_Real param1, param2;
484 gp_Pnt p1 = ComputePoint(V, AdjEdge1, D1, param1);
485 gp_Pnt p2 = ComputePoint(V, AdjEdge2, D2, param2);
487 Standard_Real tol = Precision::Confusion();
489 B.MakeVertex(NewExtr1, p1, tol);
490 B.MakeVertex(NewExtr2, p2, tol);
491 NewExtr1.Orientation(TopAbs_FORWARD);
492 NewExtr2.Orientation(TopAbs_REVERSED);
494 // chamfer edge construction
496 const Handle(Geom_Surface) refSurf = BRep_Tool::Surface(refFace, loc);
497 gp_Vec myVec( p1, p2);
499 Handle(Geom_Line) newLine = new Geom_Line( p1, myDir);
500 Standard_Real param = ElCLib::Parameter(newLine->Lin(), p2);
501 B.MakeEdge(chamfer, newLine, tol);
502 B.Range(chamfer,0., param);
503 B.Add(chamfer, NewExtr1);
504 B.UpdateVertex(NewExtr1,0., chamfer, tol);
505 B.Add(chamfer, NewExtr2);
506 B.UpdateVertex(NewExtr2,param, chamfer, tol);
507 OrientChamfer(chamfer, AdjEdge1, V);
509 // set the orientation of NewExtr1 and NewExtr2 for the adjacent edges
510 TopoDS_Vertex V1 = TopExp::FirstVertex(AdjEdge1);
511 TopoDS_Vertex V2 = TopExp::LastVertex(AdjEdge1);
512 if (V1.IsSame(V)) NewExtr1.Orientation(V1.Orientation());
513 else NewExtr1.Orientation(V2.Orientation());
515 V1 = TopExp::FirstVertex(AdjEdge2);
516 V2 = TopExp::LastVertex(AdjEdge2);
517 if (V1.IsSame(V)) NewExtr2.Orientation(V1.Orientation());
518 else NewExtr2.Orientation(V2.Orientation());
519 B.UpdateVertex(NewExtr1, param1, AdjEdge1, tol);
520 B.UpdateVertex(NewExtr2, param2, AdjEdge2, tol);
522 status = ChFi2d_IsDone;
524 } // BuildChamferEdge
527 //=======================================================================
528 //function : BuildFilletEdge
530 //=======================================================================
531 TopoDS_Edge ChFi2d_Builder::BuildChamferEdge(const TopoDS_Vertex& V,
532 const TopoDS_Edge& AdjEdge1,
533 const Standard_Real D,
534 const Standard_Real Ang,
535 const TopoDS_Edge& AdjEdge2,
536 TopoDS_Vertex& NewExtr1,
537 TopoDS_Vertex& NewExtr2)
540 if ( D <= 0 || Ang <= 0) {
541 status = ChFi2d_ParametersError;
545 Standard_Real param1, param2;
546 gp_Pnt p1 = ComputePoint(V, AdjEdge1, D, param1);
547 gp_Pnt p = BRep_Tool::Pnt(V);
548 gp_Vec myVec( p1, p);
550 // compute the tangent vector on AdjEdge2 at the vertex V.
551 BRepAdaptor_Curve c(AdjEdge2, refFace);
552 Standard_Real first, last;
553 first = c.FirstParameter();
554 last = c.LastParameter();
558 c.D1(first, aPoint, tan);
559 if (aPoint.Distance(p) > Precision::Confusion()) {
560 c.D1(last, aPoint, tan);
562 // tangent orientation
563 TopoDS_Vertex v1, v2;
564 TopExp::Vertices(AdjEdge2, v1, v2);
565 TopAbs_Orientation orient;
566 if (v1.IsSame(V)) orient = v1.Orientation();
567 else orient = v2.Orientation();
568 if (orient == TopAbs_REVERSED) tan *= -1;
570 // compute the chamfer geometric support
571 gp_Ax1 RotAxe(p1, tan^myVec);
572 gp_Vec vecLin = myVec.Rotated(RotAxe, -Ang);
573 gp_Dir myDir(vecLin);
574 Handle(Geom_Line) newLine = new Geom_Line( p1, myDir);
576 B1.MakeEdge(chamfer, newLine, Precision::Confusion());
577 gp_Pnt p2 = ComputePoint(refFace, newLine, AdjEdge2, param2);
580 Standard_Real tol = Precision::Confusion();
582 B.MakeVertex(NewExtr1, p1, tol);
583 B.MakeVertex(NewExtr2, p2, tol);
584 NewExtr1.Orientation(TopAbs_FORWARD);
585 NewExtr2.Orientation(TopAbs_REVERSED);
587 // chamfer edge construction
588 Standard_Real param = ElCLib::Parameter(newLine->Lin(), p2);
589 B.MakeEdge(chamfer, newLine, tol);
590 B.Range(chamfer,0., param);
591 B.Add(chamfer, NewExtr1);
592 B.UpdateVertex(NewExtr1,0., chamfer, tol);
593 B.Add(chamfer, NewExtr2);
594 B.UpdateVertex(NewExtr2,param, chamfer, tol);
595 OrientChamfer(chamfer, AdjEdge1, V);
597 // set the orientation of NewExtr1 and NewExtr2 for the adjacent edges
598 TopoDS_Vertex V1 = TopExp::FirstVertex(AdjEdge1);
599 TopoDS_Vertex V2 = TopExp::LastVertex(AdjEdge1);
600 if (V1.IsSame(V)) NewExtr1.Orientation(V1.Orientation());
601 else NewExtr1.Orientation(V2.Orientation());
603 V1 = TopExp::FirstVertex(AdjEdge2);
604 V2 = TopExp::LastVertex(AdjEdge2);
605 if (V1.IsSame(V)) NewExtr2.Orientation(V1.Orientation());
606 else NewExtr2.Orientation(V2.Orientation());
607 B.UpdateVertex(NewExtr1, param1, AdjEdge1, tol);
608 B.UpdateVertex(NewExtr2, param2, AdjEdge2, tol);
610 status = ChFi2d_IsDone;
615 //=======================================================================
616 //function : ComputePoint
618 //=======================================================================
620 gp_Pnt ComputePoint(const TopoDS_Vertex& V,const TopoDS_Edge& E,
621 const Standard_Real D, Standard_Real& Param)
624 BRepAdaptor_Curve c(E);
625 Standard_Real first, last;
626 first = c.FirstParameter();
627 last = c.LastParameter();
630 if (c.GetType() == GeomAbs_Line) {
632 TopoDS_Vertex v1, v2;
633 TopExp::Vertices(E, v1, v2);
634 p1 = BRep_Tool::Pnt(v1);
635 p2 = BRep_Tool::Pnt(v2);
636 gp_Vec myVec( p1, p2);
640 myVec *= -1; // change the sense of myVec
641 thePoint = p2.Translated(myVec);
643 else thePoint = p1.Translated(myVec);
645 Param = ElCLib::Parameter(c.Line(), thePoint);
647 c.D0(Param, thePoint);
650 } // if (C->IsKind(TYPE ...
652 if (c.GetType() == GeomAbs_Circle) {
653 gp_Circ cir = c.Circle();
654 Standard_Real radius = cir.Radius();
655 TopoDS_Vertex v1, v2;
656 TopExp::Vertices(E, v1, v2);
657 Standard_Real param1,param2;
659 param1 = BRep_Tool::Parameter(v1,E);
660 param2 = BRep_Tool::Parameter(v2,E);
663 param1 = BRep_Tool::Parameter(v2,E);
664 param2 = BRep_Tool::Parameter(v1,E);
666 Standard_Real deltaAlpha = D/radius;
667 if (param1 > param2) Param = param1 - deltaAlpha;
668 else Param = param1 + deltaAlpha;
669 c.D0(Param, thePoint);
671 } // if (C->IsKind(TYPE ...
674 // in all other case than lines and circles.
676 TopoDS_Vertex v1, v2;
677 TopExp::Vertices(E, v1, v2);
679 p = BRep_Tool::Pnt(v1);
682 p = BRep_Tool::Pnt(v2);
685 GeomAdaptor_Curve cc = c.Curve();
686 if (p.Distance(c.Value(first)) <= Precision::Confusion()) {
687 GCPnts_AbscissaPoint computePoint(cc, D, first);
688 Param = computePoint.Parameter();
691 GCPnts_AbscissaPoint computePoint(cc, D, last);
692 Param = computePoint.Parameter();
694 thePoint = cc.Value(Param);
701 //=======================================================================
702 //function : ComputePoint
704 //=======================================================================
706 gp_Pnt ComputePoint(const TopoDS_Face& F,
707 const Handle(Geom_Line)& L,
708 const TopoDS_Edge& E,
709 Standard_Real& Param)
711 BRepAdaptor_Surface Adaptor3dSurface(F);
712 Handle(Geom_Plane) refSurf = new Geom_Plane(Adaptor3dSurface.Plane());
713 Handle(Geom2d_Curve) lin2d = GeomAPI::To2d(L, refSurf->Pln());
714 Handle(Geom2d_Curve) c2d;
715 Standard_Real first, last;
716 c2d = BRep_Tool::CurveOnSurface(E, F, first, last);
717 Geom2dAdaptor_Curve adaptorL(lin2d);
718 Geom2dAdaptor_Curve adaptorC(c2d);
719 Geom2dInt_GInter Intersection(adaptorL, adaptorC,
720 Precision::PIntersection(),
721 Precision::PIntersection());
722 Standard_Real paramOnLine = 1E300;
724 if (Intersection.IsDone()) {
725 Standard_Integer i = 1;
726 while ( i <= Intersection.NbPoints()) {
727 IntRes2d_IntersectionPoint iP = Intersection.Point(i);
728 if (iP.ParamOnFirst() < paramOnLine) {
730 paramOnLine = iP.ParamOnFirst();
731 Param = iP.ParamOnSecond();
732 } // if (iP.ParamOnFirst ...
734 } // while ( i <= ...
735 } // if (Intersection.IsDone ...
737 gp_Pnt thePoint = Adaptor3dSurface.Value(p2d.X(), p2d.Y());
741 //=======================================================================
742 //function : OrientChamfer
744 //=======================================================================
746 void OrientChamfer(TopoDS_Edge& chamfer,
747 const TopoDS_Edge& E,
748 const TopoDS_Vertex& V)
750 TopAbs_Orientation vOrient, orient = E.Orientation();
751 TopoDS_Vertex v1, v2;
752 TopExp::Vertices(E, v1, v2);
753 if (v1.IsSame(V)) vOrient = v2.Orientation();
754 else vOrient = v1.Orientation();
756 if ((orient == TopAbs_FORWARD && vOrient == TopAbs_FORWARD) ||
757 (orient == TopAbs_REVERSED && vOrient == TopAbs_REVERSED))
758 chamfer.Orientation(TopAbs_FORWARD);
759 else chamfer.Orientation(TopAbs_REVERSED);
763 //=======================================================================
764 //function : IsLineOrCircle
766 //=======================================================================
768 Standard_Boolean IsLineOrCircle(const TopoDS_Edge& E,
769 const TopoDS_Face& F)
771 Standard_Real first, last;
773 // syntaxe invalide sur NT
774 // const Handle(Geom2d_Curve)& C =
775 // BRep_Tool::CurveOnSurface(E,F,first,last);
776 Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,first,last);
777 Handle(Geom2d_Curve) basisC;
778 Handle(Geom2d_TrimmedCurve) TC = Handle(Geom2d_TrimmedCurve)::DownCast(C);
780 basisC = TC->BasisCurve();
784 if ( basisC->DynamicType() == STANDARD_TYPE(Geom2d_Circle)
785 || basisC->DynamicType() == STANDARD_TYPE(Geom2d_Line) ) {
786 return Standard_True;
789 return Standard_False;