0023311: Duplicated check in if-clause in ChFi2d_Builder_0.cxx
[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
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
7fd59977 21// Modified : 08/07/97 : JPI : traitement des edges degeneres comme pour les fillets 2D
22// Modified: Fri Sep 25 09:38:04 1998
7fd59977 23// status = ChFi2d_NotAuthorized si les aretes ne sont pas
24// des droites ou des cercles; fonction IsLineOrCircle
25// (BUC60288)
26
27#include <ChFi2d.hxx>
28#include <ChFi2d_Builder.ixx>
29
30#include <BRepAdaptor_Curve.hxx>
31#include <BRepAdaptor_Surface.hxx>
32#include <BRepLib_MakeEdge.hxx>
33#include <BRepLib_MakeFace.hxx>
34
35#include <BRep_Builder.hxx>
36#include <BRep_Tool.hxx>
37
38#include <ElCLib.hxx>
39#include <Geom_Curve.hxx>
40#include <Geom_Line.hxx>
41#include <Geom_Plane.hxx>
42#include <Geom_Surface.hxx>
43
44#include <GeomAdaptor_Curve.hxx>
45#include <GeomAPI.hxx>
46#include <GCPnts_AbscissaPoint.hxx>
47
48#include <Geom2dAdaptor_Curve.hxx>
49#include <Geom2d_TrimmedCurve.hxx>
50#include <Geom2d_Circle.hxx>
51#include <Geom2d_Curve.hxx>
52#include <Geom2d_Line.hxx>
53#include <Geom2dInt_GInter.hxx>
54
55#include <IntRes2d_IntersectionPoint.hxx>
56
57#include <gp_Pln.hxx>
58#include <gp_Pnt.hxx>
59#include <gp_Pnt2d.hxx>
60
61#include <Precision.hxx>
62
63#include <TopAbs_Orientation.hxx>
64#include <TopExp.hxx>
65#include <TopExp_Explorer.hxx>
66#include <TopLoc_Location.hxx>
67
68#include <TopoDS.hxx>
69#include <TopoDS_Edge.hxx>
70#include <TopoDS_Wire.hxx>
71#include <TopoDS_Shape.hxx>
72
73
74gp_Pnt ComputePoint(const TopoDS_Vertex& V,const TopoDS_Edge& E,
75 const Standard_Real D1, Standard_Real& Param1);
76gp_Pnt ComputePoint(const TopoDS_Face& F, const Handle(Geom_Line)& L,
77 const TopoDS_Edge& E, Standard_Real& Param);
78void OrientChamfer(TopoDS_Edge& chamfer,
79 const TopoDS_Edge& E,
80 const TopoDS_Vertex& V);
81
82static Standard_Boolean IsLineOrCircle(const TopoDS_Edge& E,
83 const TopoDS_Face& F);
84
85
86//=======================================================================
87//function : AddChamfer
88//purpose :
89//=======================================================================
90
91TopoDS_Edge ChFi2d_Builder::AddChamfer(const TopoDS_Edge& E1,
92 const TopoDS_Edge& E2,
93 const Standard_Real D1,
94 const Standard_Real D2)
95{
96 TopoDS_Vertex commonVertex;
97 TopoDS_Edge basisEdge1, basisEdge2;
98 TopoDS_Edge E1Mod, E2Mod, chamfer;
99
100 Standard_Boolean hasConnection = ChFi2d::CommonVertex(E1, E2, commonVertex);
101 if (!hasConnection) return chamfer;
102
103 if (IsAFillet(E1) || IsAChamfer(E1) ||
104 IsAFillet(E2) || IsAChamfer(E2)) {
105 status = ChFi2d_NotAuthorized;
106 return chamfer;
107 } // if (IsAChamfer ...
108
109 if (!IsLineOrCircle(E1,newFace)
110 || !IsLineOrCircle(E2,newFace) ) {
111 status = ChFi2d_NotAuthorized;
112 return chamfer;
113 } // if (!IsLineOrCircle ...
114
115 // EE1 and EE2 are copies of E1 and E2 with the good orientation
116 // on <newFace>
117 TopoDS_Edge EE1, EE2;
118 status = ChFi2d::FindConnectedEdges(newFace, commonVertex, EE1, EE2);
119 if (EE1.IsSame(E2)) {
120 TopAbs_Orientation orient = EE1.Orientation();
121 EE1 = EE2;
122 EE2 = E2;
123 EE2.Orientation(orient);
124 }
125
126 ComputeChamfer(commonVertex, EE1, EE2, D1, D2,
127 E1Mod, E2Mod, chamfer);
128 if (status == ChFi2d_IsDone
129 || status == ChFi2d_FirstEdgeDegenerated
130 || status == ChFi2d_LastEdgeDegenerated
131 || status == ChFi2d_BothEdgesDegenerated) {
132// if (status == ChFi2d_IsDone) {
133 BuildNewWire(EE1, EE2, E1Mod, chamfer, E2Mod);
134 basisEdge1 = BasisEdge(EE1);
135 basisEdge2 = BasisEdge(EE2);
136 UpDateHistory(basisEdge1, basisEdge2,
137 E1Mod, E2Mod, chamfer, 2);
138 status = ChFi2d_IsDone;
139 return TopoDS::Edge(chamfers.Value(chamfers.Length()));
140 }
141 return chamfer;
142} // AddChamfer
143
144
145//=======================================================================
146//function : AddChamfer
147//purpose :
148//=======================================================================
149
150TopoDS_Edge ChFi2d_Builder::AddChamfer(const TopoDS_Edge& E,
151 const TopoDS_Vertex& V,
152 const Standard_Real D,
153 const Standard_Real Ang)
154{
155 TopoDS_Edge aChamfer, adjEdge1, adjEdge2;
156 status = ChFi2d::FindConnectedEdges(newFace, V, adjEdge1, adjEdge2);
157 if (status == ChFi2d_ConnexionError) return aChamfer;
158
159 // adjEdge1 is a copy of E with the good orientation
160 // on <newFace>
161 if (adjEdge2.IsSame(E)) {
162 TopAbs_Orientation orient = adjEdge2.Orientation();
163 adjEdge2 = adjEdge1;
164 adjEdge1 = E;
165 adjEdge1.Orientation(orient);
166 }
167
168 if (IsAFillet(adjEdge1) || IsAChamfer(adjEdge1) ||
169 IsAFillet(adjEdge2) || IsAChamfer(adjEdge2)) {
170 status = ChFi2d_NotAuthorized;
171 return aChamfer;
172 } // if (IsAChamfer ...
173
174 if (!IsLineOrCircle(adjEdge1,newFace)
606a112a 175 || !IsLineOrCircle(adjEdge2,newFace) ) {
7fd59977 176 status = ChFi2d_NotAuthorized;
177 return aChamfer;
178 } // if (!IsLineOrCircle ...
179
180 TopoDS_Edge E1, E2;
181 ComputeChamfer(V, adjEdge1, D, Ang,
182 adjEdge2, E1, E2, aChamfer);
183 TopoDS_Edge basisEdge1, basisEdge2;
184 if (status == ChFi2d_IsDone
185 || status == ChFi2d_FirstEdgeDegenerated
186 || status == ChFi2d_LastEdgeDegenerated
187 || status == ChFi2d_BothEdgesDegenerated) {
188// if (status == ChFi2d_IsDone) {
189 BuildNewWire(adjEdge1, adjEdge2, E1, aChamfer, E2);
190 basisEdge1 = BasisEdge(adjEdge1);
191 basisEdge2 = BasisEdge(adjEdge2);
192 UpDateHistory(basisEdge1, basisEdge2,
193 E1, E2, aChamfer, 2);
194 status = ChFi2d_IsDone;
195 return TopoDS::Edge(chamfers.Value(chamfers.Length()));
196 }
197 return aChamfer;
198
199}
200
201
202//=======================================================================
203//function : ComputeChamfer
204//purpose :
205//=======================================================================
206
207void ChFi2d_Builder::ComputeChamfer(const TopoDS_Vertex& V,
208 const TopoDS_Edge& E1,
209 const TopoDS_Edge& E2,
210 const Standard_Real D1,
211 const Standard_Real D2,
212 TopoDS_Edge& TrimE1,
213 TopoDS_Edge& TrimE2,
214 TopoDS_Edge& Chamfer)
215{
216 TopoDS_Vertex newExtr1, newExtr2;
217 Standard_Boolean Degen1, Degen2;
218 Chamfer = BuildChamferEdge(V, E1, E2, D1, D2, newExtr1, newExtr2);
219 if ( status != ChFi2d_IsDone) return;
220 TrimE1 = BuildNewEdge(E1, V, newExtr1, Degen1);
221 TrimE2 = BuildNewEdge(E2, V, newExtr2, Degen2);
222 if (Degen1 && Degen2 ) status = ChFi2d_BothEdgesDegenerated;
223 if (Degen1 && !Degen2 ) status = ChFi2d_FirstEdgeDegenerated;
224 if (!Degen1 && Degen2 ) status = ChFi2d_LastEdgeDegenerated;
225// TrimE1 = BuildNewEdge(E1, V, newExtr1);
226// TrimE2 = BuildNewEdge(E2, V, newExtr2);
227} // ComputeChamfer
228
229
230//=======================================================================
231//function : ComputeChamfer
232//purpose :
233//=======================================================================
234
235void ChFi2d_Builder::ComputeChamfer(const TopoDS_Vertex& V,
236 const TopoDS_Edge& E1,
237 const Standard_Real D,
238 const Standard_Real Ang,
239 const TopoDS_Edge& E2,
240 TopoDS_Edge& TrimE1,
241 TopoDS_Edge& TrimE2,
242 TopoDS_Edge& Chamfer)
243{
244 TopoDS_Vertex newExtr1, newExtr2;
245 Standard_Boolean Degen1, Degen2;
246 Chamfer = BuildChamferEdge(V, E1, D, Ang, E2, newExtr1, newExtr2);
247 if ( status != ChFi2d_IsDone) return;
248 TrimE1 = BuildNewEdge(E1, V, newExtr1, Degen1);
249 TrimE2 = BuildNewEdge(E2, V, newExtr2, Degen2);
250 if (Degen1 && Degen2 ) status = ChFi2d_BothEdgesDegenerated;
251 if (Degen1 && !Degen2 ) status = ChFi2d_FirstEdgeDegenerated;
252 if (!Degen1 && Degen2 ) status = ChFi2d_LastEdgeDegenerated;
253// TrimE1 = BuildNewEdge(E1, V, newExtr1);
254// TrimE2 = BuildNewEdge(E2, V, newExtr2);
255} // ComputeChamfer
256
257
258//=======================================================================
259//function : ModifyFillet
260//purpose :
261//=======================================================================
262
263TopoDS_Edge ChFi2d_Builder::ModifyChamfer(const TopoDS_Edge& Chamfer,
264 const TopoDS_Edge& E1,
265 const TopoDS_Edge& E2,
266 const Standard_Real D1,
267 const Standard_Real D2)
268{
269 TopoDS_Vertex aVertex = RemoveChamfer(Chamfer);
270 TopoDS_Edge adjEdge1, adjEdge2;
271 status = ChFi2d::FindConnectedEdges(newFace, aVertex, adjEdge1, adjEdge2);
272 TopoDS_Edge aChamfer;
273 if (status == ChFi2d_ConnexionError) return aChamfer;
274
275 // adjEdge1 and adjEdge2 are copies of E1 and E2 with the good orientation
276 // on <newFace>
277 if (adjEdge1.IsSame(E2)) {
278 TopAbs_Orientation orient = adjEdge1.Orientation();
279 adjEdge1 = adjEdge2;
280 adjEdge2 = E2;
281 adjEdge2.Orientation(orient);
282 }
283
284 aChamfer = AddChamfer(adjEdge1, adjEdge2, D1, D2);
285 return aChamfer;
286} // ModifyChamfer
287
288
289//=======================================================================
290//function : ModifyFillet
291//purpose :
292//=======================================================================
293
294TopoDS_Edge ChFi2d_Builder::ModifyChamfer(const TopoDS_Edge& Chamfer,
295 const TopoDS_Edge& E,
296 const Standard_Real D,
297 const Standard_Real Ang)
298{
299 TopoDS_Vertex aVertex = RemoveChamfer(Chamfer);
300 TopoDS_Edge adjEdge1, adjEdge2;
301 status = ChFi2d::FindConnectedEdges(newFace, aVertex, adjEdge1, adjEdge2);
302 TopoDS_Edge aChamfer;
303 if (status == ChFi2d_ConnexionError) return aChamfer;
304
305 if (adjEdge1.IsSame(E))
306 aChamfer = AddChamfer(adjEdge1, aVertex, D, Ang);
307 else aChamfer = AddChamfer(adjEdge2, aVertex, D, Ang);
308 return aChamfer;
309} // ModifyChamfer
310
311
312//=======================================================================
313//function : RemoveChamfer
314//purpose :
315//=======================================================================
316
317TopoDS_Vertex ChFi2d_Builder::RemoveChamfer(const TopoDS_Edge& Chamfer)
318{
319 TopoDS_Vertex commonVertex;
320
321 Standard_Integer i = 1;
322 Standard_Integer IsFind = Standard_False;
323 while (i <= chamfers.Length()) {
324 const TopoDS_Edge& aChamfer = TopoDS::Edge(chamfers.Value(i));
325 if (aChamfer.IsSame(Chamfer)) {
326 chamfers.Remove(i);
327 IsFind = Standard_True;
328 break;
329 }
330 i++;
331 }
332 if (!IsFind) return commonVertex;
333
334 TopoDS_Vertex firstVertex, lastVertex;
335 TopExp::Vertices(Chamfer, firstVertex, lastVertex);
336
337
338 TopoDS_Edge adjEdge1, adjEdge2;
339 status = ChFi2d::FindConnectedEdges(newFace, firstVertex,
340 adjEdge1, adjEdge2);
341 if (status == ChFi2d_ConnexionError) return commonVertex;
342
343 TopoDS_Edge basisEdge1, basisEdge2, E1, E2;
344 // E1 and E2 are the adjacentes edges to Chamfer
345
346 if (adjEdge1.IsSame(Chamfer)) E1 = adjEdge2;
347 else E1 = adjEdge1;
348 basisEdge1 = BasisEdge(E1);
349 status = ChFi2d::FindConnectedEdges(newFace, lastVertex,adjEdge1, adjEdge2);
350 if (status == ChFi2d_ConnexionError) return commonVertex;
351 if (adjEdge1.IsSame(Chamfer)) E2 = adjEdge2;
352 else E2 = adjEdge1;
353 basisEdge2 = BasisEdge(E2);
354 TopoDS_Vertex connectionE1Chamfer, connectionE2Chamfer;
355 Standard_Boolean hasConnection =
356 ChFi2d::CommonVertex(basisEdge1, basisEdge2, commonVertex);
357 if (!hasConnection) {
358 status = ChFi2d_ConnexionError;
359 return commonVertex;
360 }
361 hasConnection = ChFi2d::CommonVertex(E1, Chamfer, connectionE1Chamfer);
362 if (!hasConnection) {
363 status = ChFi2d_ConnexionError;
364 return commonVertex;
365 }
366 hasConnection = ChFi2d::CommonVertex(E2, Chamfer, connectionE2Chamfer);
367 if (!hasConnection) {
368 status = ChFi2d_ConnexionError;
369 return commonVertex;
370 }
371
372 // rebuild edges on wire
373 TopoDS_Edge newEdge1, newEdge2;
374 TopoDS_Vertex v, v1, v2;
375 BRepLib_MakeEdge makeEdge;
376 TopLoc_Location loc;
377 Standard_Real first, last;
378
379 TopExp::Vertices(E1, firstVertex, lastVertex);
380 TopExp::Vertices(basisEdge1, v1, v2);
381 if (v1.IsSame(commonVertex)) v = v2;
382 else v = v1;
383
384 if ( firstVertex.IsSame(v) || lastVertex.IsSame(v))
385 // It means the edge support only one fillet. In this case
386 // the new edge must be the basis edge.
387 newEdge1 = basisEdge1;
388 else {
389 // It means the edge support one fillet on each end.
390 if (firstVertex.IsSame(connectionE1Chamfer)) {
391// syntaxe invalide sur NT
392// const Handle(Geom_Curve)& curve =
393// BRep_Tool::Curve(E1, loc, first, last);
394 Handle(Geom_Curve) curve = BRep_Tool::Curve(E1, loc, first, last);
395 makeEdge.Init(curve, commonVertex, lastVertex);
396 newEdge1 = makeEdge.Edge();
397 newEdge1.Orientation(basisEdge1.Orientation());
398 newEdge1.Location(basisEdge1.Location());
399 } // if (firstVertex ...
400 else if (lastVertex.IsSame(connectionE1Chamfer)) {
401// syntaxe invalide sur NT
402// const Handle(Geom_Curve)& curve =
403// BRep_Tool::Curve(E1, loc, first, last);
404 Handle(Geom_Curve) curve = BRep_Tool::Curve(E1, loc, first, last);
405 makeEdge.Init(curve, firstVertex, commonVertex);
406 newEdge1 = makeEdge.Edge();
407 newEdge1.Orientation(basisEdge1.Orientation());
408 newEdge1.Location(basisEdge1.Location());
409 } // else if (lastVertex ...
410 } // else ...
411
412 TopExp::Vertices(basisEdge2, v1, v2);
413 if (v1.IsSame(commonVertex)) v = v2;
414 else v = v1;
415
416 TopExp::Vertices(E2, firstVertex, lastVertex);
417 if ( firstVertex.IsSame(v) || lastVertex.IsSame(v))
418 // It means the edge support only one fillet. In this case
419 // the new edge must be the basis edge.
420 newEdge2 = basisEdge2;
421 else {
422 // It means the edge support one fillet on each end.
423 if (firstVertex.IsSame(connectionE2Chamfer)) {
424// syntaxe invalide sur NT
425// const Handle(Geom_Curve)& curve =
426// BRep_Tool::Curve(E2, loc, first, last);
427 Handle(Geom_Curve) curve = BRep_Tool::Curve(E2, loc, first, last);
428 makeEdge.Init(curve, commonVertex, lastVertex);
429 newEdge2 = makeEdge.Edge();
430 newEdge2.Orientation(basisEdge2.Orientation());
431 newEdge2.Location(basisEdge2.Location());
432 } // if (firstVertex ...
433 else if (lastVertex.IsSame(connectionE2Chamfer)) {
434// syntaxe invalide sur NT
435// const Handle(Geom_Curve)& curve =
436// BRep_Tool::Curve(E2, loc, first, last);
437 Handle(Geom_Curve) curve = BRep_Tool::Curve(E2, loc, first, last);
438 makeEdge.Init(curve, firstVertex, commonVertex);
439 newEdge2 = makeEdge.Edge();
440 newEdge2.Orientation(basisEdge2.Orientation());
441 newEdge2.Location(basisEdge2.Location());
442 } // else if (lastVertex ...
443 } // else ...
444
445 // rebuild the newFace
446 TopExp_Explorer Ex(newFace, TopAbs_EDGE);
447 TopoDS_Wire newWire;
448
449 BRep_Builder B;
450 B.MakeWire(newWire);
451
452 while (Ex.More()) {
453 const TopoDS_Edge& theEdge = TopoDS::Edge(Ex.Current());
454 if (!theEdge.IsSame(E1) &&
455 !theEdge.IsSame(E2) &&
456 !theEdge.IsSame(Chamfer) )
457 B.Add(newWire, theEdge);
458 else {
459 if (theEdge == E1)
460 B.Add(newWire, newEdge1);
461 else if (theEdge == E2)
462 B.Add(newWire, newEdge2);
463 } // else
464 Ex.Next();
465 } // while ...
466
467 BRepAdaptor_Surface Adaptor3dSurface(refFace);
468 BRepLib_MakeFace mFace(Adaptor3dSurface.Plane(), newWire);
469 newFace.Nullify();
470 newFace = mFace;
471
472 UpDateHistory(basisEdge1, basisEdge2, newEdge1, newEdge2);
473
474 return commonVertex;
475} // RemoveChamfer
476
477
478//=======================================================================
479//function : BuildChamferEdge
480//purpose :
481//=======================================================================
482TopoDS_Edge ChFi2d_Builder::BuildChamferEdge(const TopoDS_Vertex& V,
483 const TopoDS_Edge& AdjEdge1,
484 const TopoDS_Edge& AdjEdge2,
485 const Standard_Real D1,
486 const Standard_Real D2,
487 TopoDS_Vertex& NewExtr1,
488 TopoDS_Vertex& NewExtr2)
489{
490 TopoDS_Edge chamfer;
491 if ( D1 <= 0 || D2 <= 0) {
492 status = ChFi2d_ParametersError;
493 return chamfer;
494 } // if ( D1 <=0 ...
495
496 Standard_Real param1, param2;
497 gp_Pnt p1 = ComputePoint(V, AdjEdge1, D1, param1);
498 gp_Pnt p2 = ComputePoint(V, AdjEdge2, D2, param2);
499
500 Standard_Real tol = Precision::Confusion();
501 BRep_Builder B;
502 B.MakeVertex(NewExtr1, p1, tol);
503 B.MakeVertex(NewExtr2, p2, tol);
504 NewExtr1.Orientation(TopAbs_FORWARD);
505 NewExtr2.Orientation(TopAbs_REVERSED);
506
507 // chamfer edge construction
508 TopLoc_Location loc;
509 const Handle(Geom_Surface) refSurf = BRep_Tool::Surface(refFace, loc);
510 gp_Vec myVec( p1, p2);
511 gp_Dir myDir(myVec);
512 Handle(Geom_Line) newLine = new Geom_Line( p1, myDir);
513 Standard_Real param = ElCLib::Parameter(newLine->Lin(), p2);
514 B.MakeEdge(chamfer, newLine, tol);
515 B.Range(chamfer,0., param);
516 B.Add(chamfer, NewExtr1);
517 B.UpdateVertex(NewExtr1,0., chamfer, tol);
518 B.Add(chamfer, NewExtr2);
519 B.UpdateVertex(NewExtr2,param, chamfer, tol);
520 OrientChamfer(chamfer, AdjEdge1, V);
521
522 // set the orientation of NewExtr1 and NewExtr2 for the adjacent edges
523 TopoDS_Vertex V1 = TopExp::FirstVertex(AdjEdge1);
524 TopoDS_Vertex V2 = TopExp::LastVertex(AdjEdge1);
525 if (V1.IsSame(V)) NewExtr1.Orientation(V1.Orientation());
526 else NewExtr1.Orientation(V2.Orientation());
527
528 V1 = TopExp::FirstVertex(AdjEdge2);
529 V2 = TopExp::LastVertex(AdjEdge2);
530 if (V1.IsSame(V)) NewExtr2.Orientation(V1.Orientation());
531 else NewExtr2.Orientation(V2.Orientation());
532 B.UpdateVertex(NewExtr1, param1, AdjEdge1, tol);
533 B.UpdateVertex(NewExtr2, param2, AdjEdge2, tol);
534
535 status = ChFi2d_IsDone;
536 return chamfer;
537} // BuildChamferEdge
538
539
540//=======================================================================
541//function : BuildFilletEdge
542//purpose :
543//=======================================================================
544TopoDS_Edge ChFi2d_Builder::BuildChamferEdge(const TopoDS_Vertex& V,
545 const TopoDS_Edge& AdjEdge1,
546 const Standard_Real D,
547 const Standard_Real Ang,
548 const TopoDS_Edge& AdjEdge2,
549 TopoDS_Vertex& NewExtr1,
550 TopoDS_Vertex& NewExtr2)
551{
552 TopoDS_Edge chamfer;
553 if ( D <= 0 || Ang <= 0) {
554 status = ChFi2d_ParametersError;
555 return chamfer;
556 } // if ( D <= 0 ...
557
558 Standard_Real param1, param2;
559 gp_Pnt p1 = ComputePoint(V, AdjEdge1, D, param1);
560 gp_Pnt p = BRep_Tool::Pnt(V);
561 gp_Vec myVec( p1, p);
562
563 // compute the tangent vector on AdjEdge2 at the vertex V.
564 BRepAdaptor_Curve c(AdjEdge2, refFace);
565 Standard_Real first, last;
566 first = c.FirstParameter();
567 last = c.LastParameter();
568
569 gp_Pnt aPoint;
570 gp_Vec tan;
571 c.D1(first, aPoint, tan);
572 if (aPoint.Distance(p) > Precision::Confusion()) {
573 c.D1(last, aPoint, tan);
574 }
575 // tangent orientation
576 TopoDS_Vertex v1, v2;
577 TopExp::Vertices(AdjEdge2, v1, v2);
578 TopAbs_Orientation orient;
579 if (v1.IsSame(V)) orient = v1.Orientation();
580 else orient = v2.Orientation();
581 if (orient == TopAbs_REVERSED) tan *= -1;
582
583 // compute the chamfer geometric support
584 gp_Ax1 RotAxe(p1, tan^myVec);
585 gp_Vec vecLin = myVec.Rotated(RotAxe, -Ang);
586 gp_Dir myDir(vecLin);
587 Handle(Geom_Line) newLine = new Geom_Line( p1, myDir);
588 BRep_Builder B1;
589 B1.MakeEdge(chamfer, newLine, Precision::Confusion());
590 gp_Pnt p2 = ComputePoint(refFace, newLine, AdjEdge2, param2);
591
592
593 Standard_Real tol = Precision::Confusion();
594 BRep_Builder B;
595 B.MakeVertex(NewExtr1, p1, tol);
596 B.MakeVertex(NewExtr2, p2, tol);
597 NewExtr1.Orientation(TopAbs_FORWARD);
598 NewExtr2.Orientation(TopAbs_REVERSED);
599
600 // chamfer edge construction
601 Standard_Real param = ElCLib::Parameter(newLine->Lin(), p2);
602 B.MakeEdge(chamfer, newLine, tol);
603 B.Range(chamfer,0., param);
604 B.Add(chamfer, NewExtr1);
605 B.UpdateVertex(NewExtr1,0., chamfer, tol);
606 B.Add(chamfer, NewExtr2);
607 B.UpdateVertex(NewExtr2,param, chamfer, tol);
608 OrientChamfer(chamfer, AdjEdge1, V);
609
610 // set the orientation of NewExtr1 and NewExtr2 for the adjacent edges
611 TopoDS_Vertex V1 = TopExp::FirstVertex(AdjEdge1);
612 TopoDS_Vertex V2 = TopExp::LastVertex(AdjEdge1);
613 if (V1.IsSame(V)) NewExtr1.Orientation(V1.Orientation());
614 else NewExtr1.Orientation(V2.Orientation());
615
616 V1 = TopExp::FirstVertex(AdjEdge2);
617 V2 = TopExp::LastVertex(AdjEdge2);
618 if (V1.IsSame(V)) NewExtr2.Orientation(V1.Orientation());
619 else NewExtr2.Orientation(V2.Orientation());
620 B.UpdateVertex(NewExtr1, param1, AdjEdge1, tol);
621 B.UpdateVertex(NewExtr2, param2, AdjEdge2, tol);
622
623 status = ChFi2d_IsDone;
624 return chamfer;
625}
626
627
628//=======================================================================
629//function : ComputePoint
630//purpose :
631//=======================================================================
632
633gp_Pnt ComputePoint(const TopoDS_Vertex& V,const TopoDS_Edge& E,
634 const Standard_Real D, Standard_Real& Param)
635{
636 // geometric support
637 BRepAdaptor_Curve c(E);
638 Standard_Real first, last;
639 first = c.FirstParameter();
640 last = c.LastParameter();
641
642 gp_Pnt thePoint;
643 if (c.GetType() == GeomAbs_Line) {
644 gp_Pnt p1, p2;
645 TopoDS_Vertex v1, v2;
646 TopExp::Vertices(E, v1, v2);
647 p1 = BRep_Tool::Pnt(v1);
648 p2 = BRep_Tool::Pnt(v2);
649 gp_Vec myVec( p1, p2);
650 myVec.Normalize();
651 myVec *= D;
652 if (v2.IsSame(V)) {
653 myVec *= -1; // change the sense of myVec
654 thePoint = p2.Translated(myVec);
655 } // if (v2 ...
656 else thePoint = p1.Translated(myVec);
657
658 Param = ElCLib::Parameter(c.Line(), thePoint);
659 //szv:OCC20823-begin
660 c.D0(Param, thePoint);
661 //szv:OCC20823-end
662 return thePoint;
663 } // if (C->IsKind(TYPE ...
664
665 if (c.GetType() == GeomAbs_Circle) {
666 gp_Circ cir = c.Circle();
667 Standard_Real radius = cir.Radius();
668 TopoDS_Vertex v1, v2;
669 TopExp::Vertices(E, v1, v2);
670 Standard_Real param1,param2;
671 if (V.IsSame(v1)) {
672 param1 = BRep_Tool::Parameter(v1,E);
673 param2 = BRep_Tool::Parameter(v2,E);
674 }
675 else {
676 param1 = BRep_Tool::Parameter(v2,E);
677 param2 = BRep_Tool::Parameter(v1,E);
678 }
679 Standard_Real deltaAlpha = D/radius;
680 if (param1 > param2) Param = param1 - deltaAlpha;
681 else Param = param1 + deltaAlpha;
682 c.D0(Param, thePoint);
683 return thePoint;
684 } // if (C->IsKind(TYPE ...
685
686 else {
687 // in all other case than lines and circles.
688 gp_Pnt p;
689 TopoDS_Vertex v1, v2;
690 TopExp::Vertices(E, v1, v2);
691 if (V.IsSame(v1)) {
692 p = BRep_Tool::Pnt(v1);
693 }
694 else {
695 p = BRep_Tool::Pnt(v2);
696 }
697
698 GeomAdaptor_Curve cc = c.Curve();
699 if (p.Distance(c.Value(first)) <= Precision::Confusion()) {
700 GCPnts_AbscissaPoint computePoint(cc, D, first);
701 Param = computePoint.Parameter();
702 }
703 else {
704 GCPnts_AbscissaPoint computePoint(cc, D, last);
705 Param = computePoint.Parameter();
706 }
707 thePoint = cc.Value(Param);
708 return thePoint;
709 } // else ...
710 return thePoint;
711} // ComputePoint
712
713
714
715//=======================================================================
716//function : ComputePoint
717//purpose :
718//=======================================================================
719
720gp_Pnt ComputePoint(const TopoDS_Face& F,
721 const Handle(Geom_Line)& L,
722 const TopoDS_Edge& E,
723 Standard_Real& Param)
724{
725 BRepAdaptor_Surface Adaptor3dSurface(F);
726 Handle(Geom_Plane) refSurf = new Geom_Plane(Adaptor3dSurface.Plane());
727 Handle(Geom2d_Curve) lin2d = GeomAPI::To2d(L, refSurf->Pln());
728 Handle(Geom2d_Curve) c2d;
729 Standard_Real first, last;
730 c2d = BRep_Tool::CurveOnSurface(E, F, first, last);
731 Geom2dAdaptor_Curve adaptorL(lin2d);
732 Geom2dAdaptor_Curve adaptorC(c2d);
733 Geom2dInt_GInter Intersection(adaptorL, adaptorC,
734 Precision::PIntersection(),
735 Precision::PIntersection());
736 Standard_Real paramOnLine = 1E300;
737 gp_Pnt2d p2d;
738 if (Intersection.IsDone()) {
739 Standard_Integer i = 1;
740 while ( i <= Intersection.NbPoints()) {
741 IntRes2d_IntersectionPoint iP = Intersection.Point(i);
742 if (iP.ParamOnFirst() < paramOnLine) {
743 p2d = iP.Value();
744 paramOnLine = iP.ParamOnFirst();
745 Param = iP.ParamOnSecond();
746 } // if (iP.ParamOnFirst ...
747 i++;
748 } // while ( i <= ...
749 } // if (Intersection.IsDone ...
750
751 gp_Pnt thePoint = Adaptor3dSurface.Value(p2d.X(), p2d.Y());
752 return thePoint;
753} // ComputePoint
754
755//=======================================================================
756//function : OrientChamfer
757//purpose :
758//=======================================================================
759
760void OrientChamfer(TopoDS_Edge& chamfer,
761 const TopoDS_Edge& E,
762 const TopoDS_Vertex& V)
763{
764 TopAbs_Orientation vOrient, orient = E.Orientation();
765 TopoDS_Vertex v1, v2;
766 TopExp::Vertices(E, v1, v2);
767 if (v1.IsSame(V)) vOrient = v2.Orientation();
768 else vOrient = v1.Orientation();
769
770 if ((orient == TopAbs_FORWARD && vOrient == TopAbs_FORWARD) ||
771 (orient == TopAbs_REVERSED && vOrient == TopAbs_REVERSED))
772 chamfer.Orientation(TopAbs_FORWARD);
773 else chamfer.Orientation(TopAbs_REVERSED);
774} // OrientChamfer
775
776
777//=======================================================================
778//function : IsLineOrCircle
779//purpose :
780//=======================================================================
781
782Standard_Boolean IsLineOrCircle(const TopoDS_Edge& E,
783 const TopoDS_Face& F)
784{
785 Standard_Real first, last;
786 TopLoc_Location loc;
787// syntaxe invalide sur NT
788// const Handle(Geom2d_Curve)& C =
789// BRep_Tool::CurveOnSurface(E,F,first,last);
790 Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,first,last);
791 Handle(Geom2d_Curve) basisC;
792 Handle(Geom2d_TrimmedCurve) TC = Handle(Geom2d_TrimmedCurve)::DownCast(C);
793 if (!TC.IsNull())
794 basisC = Handle(Geom2d_Curve)::DownCast(TC->BasisCurve());
795 else
796 basisC = Handle(Geom2d_Curve)::DownCast(C);
797
798 if ( basisC->DynamicType() == STANDARD_TYPE(Geom2d_Circle)
799 || basisC->DynamicType() == STANDARD_TYPE(Geom2d_Line) ) {
800 return Standard_True;
801 }
802 else {
803 return Standard_False;
804 } // else ...
805} // IsLineOrCircle