0029915: Porting to VC 2017 : Regressions in Modeling Algorithms on VC 2017
[occt.git] / src / ChFi2d / ChFi2d_Builder_0.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// Modified : 08/07/97 : JPI : traitement des edges degeneres comme pour les fillets 2D
18// Modified: Fri Sep 25 09:38:04 1998
7fd59977 19// status = ChFi2d_NotAuthorized si les aretes ne sont pas
20// des droites ou des cercles; fonction IsLineOrCircle
21// (BUC60288)
22
42cf5bc1 23#include <BRep_Builder.hxx>
24#include <BRep_Tool.hxx>
7fd59977 25#include <BRepAdaptor_Curve.hxx>
26#include <BRepAdaptor_Surface.hxx>
27#include <BRepLib_MakeEdge.hxx>
28#include <BRepLib_MakeFace.hxx>
42cf5bc1 29#include <ChFi2d.hxx>
30#include <ChFi2d_Builder.hxx>
7fd59977 31#include <ElCLib.hxx>
42cf5bc1 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>
7fd59977 39#include <Geom_Curve.hxx>
40#include <Geom_Line.hxx>
41#include <Geom_Plane.hxx>
42#include <Geom_Surface.hxx>
7fd59977 43#include <GeomAdaptor_Curve.hxx>
44#include <GeomAPI.hxx>
7fd59977 45#include <gp_Pln.hxx>
46#include <gp_Pnt.hxx>
47#include <gp_Pnt2d.hxx>
42cf5bc1 48#include <IntRes2d_IntersectionPoint.hxx>
7fd59977 49#include <Precision.hxx>
7fd59977 50#include <TopAbs_Orientation.hxx>
51#include <TopExp.hxx>
52#include <TopExp_Explorer.hxx>
53#include <TopLoc_Location.hxx>
7fd59977 54#include <TopoDS.hxx>
55#include <TopoDS_Edge.hxx>
42cf5bc1 56#include <TopoDS_Face.hxx>
7fd59977 57#include <TopoDS_Shape.hxx>
42cf5bc1 58#include <TopoDS_Vertex.hxx>
59#include <TopoDS_Wire.hxx>
7fd59977 60
61gp_Pnt ComputePoint(const TopoDS_Vertex& V,const TopoDS_Edge& E,
62 const Standard_Real D1, Standard_Real& Param1);
63gp_Pnt ComputePoint(const TopoDS_Face& F, const Handle(Geom_Line)& L,
64 const TopoDS_Edge& E, Standard_Real& Param);
65void OrientChamfer(TopoDS_Edge& chamfer,
66 const TopoDS_Edge& E,
67 const TopoDS_Vertex& V);
68
69static Standard_Boolean IsLineOrCircle(const TopoDS_Edge& E,
70 const TopoDS_Face& F);
71
72
73//=======================================================================
74//function : AddChamfer
75//purpose :
76//=======================================================================
77
78TopoDS_Edge ChFi2d_Builder::AddChamfer(const TopoDS_Edge& E1,
79 const TopoDS_Edge& E2,
80 const Standard_Real D1,
81 const Standard_Real D2)
82{
83 TopoDS_Vertex commonVertex;
84 TopoDS_Edge basisEdge1, basisEdge2;
85 TopoDS_Edge E1Mod, E2Mod, chamfer;
86
87 Standard_Boolean hasConnection = ChFi2d::CommonVertex(E1, E2, commonVertex);
88 if (!hasConnection) return chamfer;
89
90 if (IsAFillet(E1) || IsAChamfer(E1) ||
91 IsAFillet(E2) || IsAChamfer(E2)) {
92 status = ChFi2d_NotAuthorized;
93 return chamfer;
94 } // if (IsAChamfer ...
95
96 if (!IsLineOrCircle(E1,newFace)
97 || !IsLineOrCircle(E2,newFace) ) {
98 status = ChFi2d_NotAuthorized;
99 return chamfer;
100 } // if (!IsLineOrCircle ...
101
102 // EE1 and EE2 are copies of E1 and E2 with the good orientation
103 // on <newFace>
104 TopoDS_Edge EE1, EE2;
105 status = ChFi2d::FindConnectedEdges(newFace, commonVertex, EE1, EE2);
106 if (EE1.IsSame(E2)) {
107 TopAbs_Orientation orient = EE1.Orientation();
108 EE1 = EE2;
109 EE2 = E2;
110 EE2.Orientation(orient);
111 }
112
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()));
127 }
128 return chamfer;
129} // AddChamfer
130
131
132//=======================================================================
133//function : AddChamfer
134//purpose :
135//=======================================================================
136
137TopoDS_Edge ChFi2d_Builder::AddChamfer(const TopoDS_Edge& E,
138 const TopoDS_Vertex& V,
139 const Standard_Real D,
140 const Standard_Real Ang)
141{
142 TopoDS_Edge aChamfer, adjEdge1, adjEdge2;
143 status = ChFi2d::FindConnectedEdges(newFace, V, adjEdge1, adjEdge2);
144 if (status == ChFi2d_ConnexionError) return aChamfer;
145
146 // adjEdge1 is a copy of E with the good orientation
147 // on <newFace>
148 if (adjEdge2.IsSame(E)) {
149 TopAbs_Orientation orient = adjEdge2.Orientation();
150 adjEdge2 = adjEdge1;
151 adjEdge1 = E;
152 adjEdge1.Orientation(orient);
153 }
154
155 if (IsAFillet(adjEdge1) || IsAChamfer(adjEdge1) ||
156 IsAFillet(adjEdge2) || IsAChamfer(adjEdge2)) {
157 status = ChFi2d_NotAuthorized;
158 return aChamfer;
159 } // if (IsAChamfer ...
160
161 if (!IsLineOrCircle(adjEdge1,newFace)
606a112a 162 || !IsLineOrCircle(adjEdge2,newFace) ) {
7fd59977 163 status = ChFi2d_NotAuthorized;
164 return aChamfer;
165 } // if (!IsLineOrCircle ...
166
167 TopoDS_Edge E1, E2;
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()));
183 }
184 return aChamfer;
185
186}
187
188
189//=======================================================================
190//function : ComputeChamfer
191//purpose :
192//=======================================================================
193
194void 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,
199 TopoDS_Edge& TrimE1,
200 TopoDS_Edge& TrimE2,
201 TopoDS_Edge& Chamfer)
202{
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);
214} // ComputeChamfer
215
216
217//=======================================================================
218//function : ComputeChamfer
219//purpose :
220//=======================================================================
221
222void 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,
227 TopoDS_Edge& TrimE1,
228 TopoDS_Edge& TrimE2,
229 TopoDS_Edge& Chamfer)
230{
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);
242} // ComputeChamfer
243
244
245//=======================================================================
246//function : ModifyFillet
247//purpose :
248//=======================================================================
249
250TopoDS_Edge ChFi2d_Builder::ModifyChamfer(const TopoDS_Edge& Chamfer,
35e08fe8 251 const TopoDS_Edge& /*E1*/,
7fd59977 252 const TopoDS_Edge& E2,
253 const Standard_Real D1,
254 const Standard_Real D2)
255{
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;
261
262 // adjEdge1 and adjEdge2 are copies of E1 and E2 with the good orientation
263 // on <newFace>
264 if (adjEdge1.IsSame(E2)) {
265 TopAbs_Orientation orient = adjEdge1.Orientation();
266 adjEdge1 = adjEdge2;
267 adjEdge2 = E2;
268 adjEdge2.Orientation(orient);
269 }
270
271 aChamfer = AddChamfer(adjEdge1, adjEdge2, D1, D2);
272 return aChamfer;
273} // ModifyChamfer
274
275
276//=======================================================================
277//function : ModifyFillet
278//purpose :
279//=======================================================================
280
281TopoDS_Edge ChFi2d_Builder::ModifyChamfer(const TopoDS_Edge& Chamfer,
282 const TopoDS_Edge& E,
283 const Standard_Real D,
284 const Standard_Real Ang)
285{
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;
291
292 if (adjEdge1.IsSame(E))
293 aChamfer = AddChamfer(adjEdge1, aVertex, D, Ang);
294 else aChamfer = AddChamfer(adjEdge2, aVertex, D, Ang);
295 return aChamfer;
296} // ModifyChamfer
297
298
299//=======================================================================
300//function : RemoveChamfer
301//purpose :
302//=======================================================================
303
304TopoDS_Vertex ChFi2d_Builder::RemoveChamfer(const TopoDS_Edge& Chamfer)
305{
306 TopoDS_Vertex commonVertex;
307
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)) {
313 chamfers.Remove(i);
314 IsFind = Standard_True;
315 break;
316 }
317 i++;
318 }
319 if (!IsFind) return commonVertex;
320
321 TopoDS_Vertex firstVertex, lastVertex;
322 TopExp::Vertices(Chamfer, firstVertex, lastVertex);
323
324
325 TopoDS_Edge adjEdge1, adjEdge2;
326 status = ChFi2d::FindConnectedEdges(newFace, firstVertex,
327 adjEdge1, adjEdge2);
328 if (status == ChFi2d_ConnexionError) return commonVertex;
329
330 TopoDS_Edge basisEdge1, basisEdge2, E1, E2;
331 // E1 and E2 are the adjacentes edges to Chamfer
332
333 if (adjEdge1.IsSame(Chamfer)) E1 = adjEdge2;
334 else E1 = adjEdge1;
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;
339 else E2 = adjEdge1;
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;
346 return commonVertex;
347 }
348 hasConnection = ChFi2d::CommonVertex(E1, Chamfer, connectionE1Chamfer);
349 if (!hasConnection) {
350 status = ChFi2d_ConnexionError;
351 return commonVertex;
352 }
353 hasConnection = ChFi2d::CommonVertex(E2, Chamfer, connectionE2Chamfer);
354 if (!hasConnection) {
355 status = ChFi2d_ConnexionError;
356 return commonVertex;
357 }
358
359 // rebuild edges on wire
360 TopoDS_Edge newEdge1, newEdge2;
361 TopoDS_Vertex v, v1, v2;
362 BRepLib_MakeEdge makeEdge;
363 TopLoc_Location loc;
364 Standard_Real first, last;
365
366 TopExp::Vertices(E1, firstVertex, lastVertex);
367 TopExp::Vertices(basisEdge1, v1, v2);
368 if (v1.IsSame(commonVertex)) v = v2;
369 else v = v1;
370
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;
375 else {
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 ...
397 } // else ...
398
399 TopExp::Vertices(basisEdge2, v1, v2);
400 if (v1.IsSame(commonVertex)) v = v2;
401 else v = v1;
402
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;
408 else {
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 ...
430 } // else ...
431
432 // rebuild the newFace
433 TopExp_Explorer Ex(newFace, TopAbs_EDGE);
434 TopoDS_Wire newWire;
435
436 BRep_Builder B;
437 B.MakeWire(newWire);
438
439 while (Ex.More()) {
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);
445 else {
446 if (theEdge == E1)
447 B.Add(newWire, newEdge1);
448 else if (theEdge == E2)
449 B.Add(newWire, newEdge2);
450 } // else
451 Ex.Next();
452 } // while ...
453
454 BRepAdaptor_Surface Adaptor3dSurface(refFace);
455 BRepLib_MakeFace mFace(Adaptor3dSurface.Plane(), newWire);
456 newFace.Nullify();
457 newFace = mFace;
458
459 UpDateHistory(basisEdge1, basisEdge2, newEdge1, newEdge2);
460
461 return commonVertex;
462} // RemoveChamfer
463
464
465//=======================================================================
466//function : BuildChamferEdge
467//purpose :
468//=======================================================================
469TopoDS_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)
476{
477 TopoDS_Edge chamfer;
478 if ( D1 <= 0 || D2 <= 0) {
479 status = ChFi2d_ParametersError;
480 return chamfer;
481 } // if ( D1 <=0 ...
482
483 Standard_Real param1, param2;
484 gp_Pnt p1 = ComputePoint(V, AdjEdge1, D1, param1);
485 gp_Pnt p2 = ComputePoint(V, AdjEdge2, D2, param2);
486
487 Standard_Real tol = Precision::Confusion();
488 BRep_Builder B;
489 B.MakeVertex(NewExtr1, p1, tol);
490 B.MakeVertex(NewExtr2, p2, tol);
491 NewExtr1.Orientation(TopAbs_FORWARD);
492 NewExtr2.Orientation(TopAbs_REVERSED);
493
494 // chamfer edge construction
495 TopLoc_Location loc;
496 const Handle(Geom_Surface) refSurf = BRep_Tool::Surface(refFace, loc);
497 gp_Vec myVec( p1, p2);
498 gp_Dir myDir(myVec);
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);
508
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());
514
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);
521
522 status = ChFi2d_IsDone;
523 return chamfer;
524} // BuildChamferEdge
525
526
527//=======================================================================
528//function : BuildFilletEdge
529//purpose :
530//=======================================================================
531TopoDS_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)
538{
539 TopoDS_Edge chamfer;
540 if ( D <= 0 || Ang <= 0) {
541 status = ChFi2d_ParametersError;
542 return chamfer;
543 } // if ( D <= 0 ...
544
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);
549
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();
555
556 gp_Pnt aPoint;
557 gp_Vec tan;
558 c.D1(first, aPoint, tan);
559 if (aPoint.Distance(p) > Precision::Confusion()) {
560 c.D1(last, aPoint, tan);
561 }
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;
569
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);
575 BRep_Builder B1;
576 B1.MakeEdge(chamfer, newLine, Precision::Confusion());
577 gp_Pnt p2 = ComputePoint(refFace, newLine, AdjEdge2, param2);
578
579
580 Standard_Real tol = Precision::Confusion();
581 BRep_Builder B;
582 B.MakeVertex(NewExtr1, p1, tol);
583 B.MakeVertex(NewExtr2, p2, tol);
584 NewExtr1.Orientation(TopAbs_FORWARD);
585 NewExtr2.Orientation(TopAbs_REVERSED);
586
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);
596
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());
602
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);
609
610 status = ChFi2d_IsDone;
611 return chamfer;
612}
613
614
615//=======================================================================
616//function : ComputePoint
617//purpose :
618//=======================================================================
619
620gp_Pnt ComputePoint(const TopoDS_Vertex& V,const TopoDS_Edge& E,
621 const Standard_Real D, Standard_Real& Param)
622{
623 // geometric support
624 BRepAdaptor_Curve c(E);
625 Standard_Real first, last;
626 first = c.FirstParameter();
627 last = c.LastParameter();
628
629 gp_Pnt thePoint;
630 if (c.GetType() == GeomAbs_Line) {
631 gp_Pnt p1, p2;
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);
637 myVec.Normalize();
638 myVec *= D;
639 if (v2.IsSame(V)) {
640 myVec *= -1; // change the sense of myVec
641 thePoint = p2.Translated(myVec);
642 } // if (v2 ...
643 else thePoint = p1.Translated(myVec);
644
645 Param = ElCLib::Parameter(c.Line(), thePoint);
646 //szv:OCC20823-begin
647 c.D0(Param, thePoint);
648 //szv:OCC20823-end
649 return thePoint;
650 } // if (C->IsKind(TYPE ...
651
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;
658 if (V.IsSame(v1)) {
659 param1 = BRep_Tool::Parameter(v1,E);
660 param2 = BRep_Tool::Parameter(v2,E);
661 }
662 else {
663 param1 = BRep_Tool::Parameter(v2,E);
664 param2 = BRep_Tool::Parameter(v1,E);
665 }
666 Standard_Real deltaAlpha = D/radius;
667 if (param1 > param2) Param = param1 - deltaAlpha;
668 else Param = param1 + deltaAlpha;
669 c.D0(Param, thePoint);
670 return thePoint;
671 } // if (C->IsKind(TYPE ...
672
673 else {
674 // in all other case than lines and circles.
675 gp_Pnt p;
676 TopoDS_Vertex v1, v2;
677 TopExp::Vertices(E, v1, v2);
678 if (V.IsSame(v1)) {
679 p = BRep_Tool::Pnt(v1);
680 }
681 else {
682 p = BRep_Tool::Pnt(v2);
683 }
684
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();
689 }
690 else {
691 GCPnts_AbscissaPoint computePoint(cc, D, last);
692 Param = computePoint.Parameter();
693 }
694 thePoint = cc.Value(Param);
695 return thePoint;
696 } // else ...
7fd59977 697} // ComputePoint
698
699
700
701//=======================================================================
702//function : ComputePoint
703//purpose :
704//=======================================================================
705
706gp_Pnt ComputePoint(const TopoDS_Face& F,
707 const Handle(Geom_Line)& L,
708 const TopoDS_Edge& E,
709 Standard_Real& Param)
710{
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;
723 gp_Pnt2d p2d;
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) {
729 p2d = iP.Value();
730 paramOnLine = iP.ParamOnFirst();
731 Param = iP.ParamOnSecond();
732 } // if (iP.ParamOnFirst ...
733 i++;
734 } // while ( i <= ...
735 } // if (Intersection.IsDone ...
736
737 gp_Pnt thePoint = Adaptor3dSurface.Value(p2d.X(), p2d.Y());
738 return thePoint;
739} // ComputePoint
740
741//=======================================================================
742//function : OrientChamfer
743//purpose :
744//=======================================================================
745
746void OrientChamfer(TopoDS_Edge& chamfer,
747 const TopoDS_Edge& E,
748 const TopoDS_Vertex& V)
749{
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();
755
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);
760} // OrientChamfer
761
762
763//=======================================================================
764//function : IsLineOrCircle
765//purpose :
766//=======================================================================
767
768Standard_Boolean IsLineOrCircle(const TopoDS_Edge& E,
769 const TopoDS_Face& F)
770{
771 Standard_Real first, last;
772 TopLoc_Location loc;
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);
779 if (!TC.IsNull())
a9dde4a3 780 basisC = TC->BasisCurve();
7fd59977 781 else
a9dde4a3 782 basisC = C;
7fd59977 783
784 if ( basisC->DynamicType() == STANDARD_TYPE(Geom2d_Circle)
785 || basisC->DynamicType() == STANDARD_TYPE(Geom2d_Line) ) {
786 return Standard_True;
787 }
788 else {
789 return Standard_False;
790 } // else ...
791} // IsLineOrCircle