Commit | Line | Data |
---|---|---|
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 | // |
973c2be1 | 8 | // This library is free software; you can redistribute it and / or modify it |
9 | // under the terms of the GNU Lesser General Public 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. | |
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: Tue Oct 15 10:12:02 1996 |
7fd59977 | 18 | // correction in BuildFilletEdge (PRO3529 : computation of dist) |
19 | // Modified: Tue Oct 22 09:23:11 1996 | |
7fd59977 | 20 | // correction in BuildFilletEdge (PRO5827 : computation of vec1) |
21 | // Modified: Tue Oct 22 09:23:11 1996 | |
7fd59977 | 22 | // new status in ComputeFillet for degenerated edges (PRO4896) |
23 | // Modified: Thu Dec 5 16:25:44 1996 | |
7fd59977 | 24 | // correction in BuildFilletEdge (PRO4896 : NewExtr1, NewExtr2) |
25 | // Modified: Tue Apr 22 16:25:44 1996 | |
7fd59977 | 26 | // correction in BuildFilletEdge (ID140047 : inside) |
27 | // Modified: Fri Oct 24 10:47:52 1997 | |
7fd59977 | 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 | |
7fd59977 | 32 | // construction de filletEdge avec les parametres U1 et Vv1 |
33 | // au lieu des vertex (PRO10434) | |
34 | // Modified: Tue Apr 7 14:35:58 1998 | |
7fd59977 | 35 | // construction de filletEdge avec les parametres U1 et Vv1 |
36 | // ET les vertex NewExtr1, NewExtr2 sinon pb sur qq aretes | |
37 | // degenerees (GER60069 + controle de PRO10434) | |
38 | // Modified: Mon Jun 22 13:32:25 1998 | |
7fd59977 | 39 | // verification de la validite des parametres (PRO13078 partiel) |
40 | // Modified: Fri Sep 25 09:38:04 1998 | |
7fd59977 | 41 | // status = ChFi2d_NotAuthorized si les aretes ne sont pas |
42 | // des droites ou des cercles; fonction IsLineOrCircle | |
43 | // (BUC60288) | |
44 | ||
45 | ||
46 | ||
47 | #include <ChFi2d.hxx> | |
48 | #include <ChFi2d_Builder.ixx> | |
49 | ||
50 | #include <BRepAdaptor_Surface.hxx> | |
51 | #include <BRepLib.hxx> | |
52 | #include <BRepLib_MakeEdge.hxx> | |
53 | #include <BRepLib_MakeFace.hxx> | |
54 | ||
55 | #include <BRep_Builder.hxx> | |
56 | #include <BRep_Tool.hxx> | |
57 | ||
58 | #include <ElCLib.hxx> | |
59 | ||
60 | #include <GccEnt_Position.hxx> | |
61 | ||
62 | #include <Geom_Circle.hxx> | |
63 | #include <Geom_Curve.hxx> | |
64 | #include <Geom_Line.hxx> | |
65 | #include <Geom_Plane.hxx> | |
66 | #include <Geom_Surface.hxx> | |
67 | ||
68 | ||
69 | #include <Geom2d_TrimmedCurve.hxx> | |
70 | #include <Geom2d_Circle.hxx> | |
71 | #include <Geom2d_Curve.hxx> | |
72 | #include <Geom2d_Line.hxx> | |
73 | ||
74 | #include <Geom2dInt_GInter.hxx> | |
75 | #include <Geom2dGcc_Circ2d2TanRad.hxx> | |
76 | #include <Geom2dGcc_QualifiedCurve.hxx> | |
77 | ||
78 | #include <IntRes2d_IntersectionPoint.hxx> | |
79 | ||
80 | #include <gp_Pln.hxx> | |
81 | #include <gp_Pnt.hxx> | |
82 | #include <gp_Pnt2d.hxx> | |
83 | #include <gp_Circ2d.hxx> | |
84 | #include <gp_Vec2d.hxx> | |
85 | ||
86 | #include <Precision.hxx> | |
87 | ||
88 | #include <TopAbs_Orientation.hxx> | |
89 | #include <TopExp.hxx> | |
90 | #include <TopExp_Explorer.hxx> | |
91 | #include <TopLoc_Location.hxx> | |
92 | #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx> | |
93 | #include <TopTools_ListIteratorOfListOfShape.hxx> | |
94 | #include <TopTools_IndexedMapOfShape.hxx> | |
95 | ||
96 | #include <TopoDS.hxx> | |
97 | #include <TopoDS_Edge.hxx> | |
98 | #include <TopoDS_Wire.hxx> | |
99 | ||
100 | static Standard_Boolean IsIssuedFrom(const TopoDS_Edge& E, | |
101 | const TopTools_IndexedMapOfShape& Map, | |
102 | TopoDS_Edge& BasisEdge); | |
103 | ||
104 | static Standard_Boolean IsLineOrCircle(const TopoDS_Edge& E, | |
105 | const TopoDS_Face& F); | |
106 | ||
107 | ||
108 | //======================================================================= | |
109 | //function : ChFi2d_Builder | |
110 | //purpose : | |
111 | //======================================================================= | |
112 | ||
113 | ChFi2d_Builder::ChFi2d_Builder() | |
114 | { | |
115 | } | |
116 | ||
117 | //======================================================================= | |
118 | //function : ChFi2d_Builder | |
119 | //purpose : | |
120 | //======================================================================= | |
121 | ||
122 | ChFi2d_Builder::ChFi2d_Builder(const TopoDS_Face& F) | |
123 | { | |
124 | if (F.IsNull()) { | |
125 | status = ChFi2d_NoFace; | |
126 | return; | |
127 | } | |
128 | TopLoc_Location Loc; | |
129 | // syntaxe invalide sur NT | |
130 | // const Handle(Geom_Surface)& surf = BRep_Tool::Surface( F, Loc); | |
131 | // if (surf->IsKind(STANDARD_TYPE(Geom_Plane))) { | |
132 | if ( BRep_Tool::Surface( F, Loc) | |
133 | -> IsKind(STANDARD_TYPE(Geom_Plane)) ) { | |
134 | newFace = refFace = F; | |
135 | newFace.Orientation(TopAbs_FORWARD); | |
136 | BRepLib::BuildCurves3d(newFace); | |
137 | status = ChFi2d_Ready; | |
138 | } | |
139 | else status = ChFi2d_NotPlanar; | |
140 | } // ChFi2d_Builder | |
141 | ||
142 | //======================================================================= | |
143 | //function : Init | |
144 | //purpose : | |
145 | //======================================================================= | |
146 | ||
147 | void ChFi2d_Builder::Init(const TopoDS_Face& F) | |
148 | { | |
149 | if (F.IsNull()) { | |
150 | status = ChFi2d_NoFace; | |
151 | return; | |
152 | } | |
153 | fillets.Clear(); | |
154 | chamfers.Clear(); | |
155 | history.Clear(); | |
156 | TopLoc_Location Loc; | |
157 | // syntaxe invalide sur NT | |
158 | // const Handle(Geom_Surface)& surf = BRep_Tool::Surface( F, Loc); | |
159 | // if (surf->IsKind(STANDARD_TYPE(Geom_Plane))) { | |
160 | if ( BRep_Tool::Surface( F, Loc) | |
161 | -> IsKind(STANDARD_TYPE(Geom_Plane)) ) { | |
162 | newFace = refFace = F; | |
163 | newFace.Orientation(TopAbs_FORWARD); | |
164 | status = ChFi2d_Ready; | |
165 | } | |
166 | else status = ChFi2d_NotPlanar; | |
167 | } // Init | |
168 | ||
169 | ||
170 | //======================================================================= | |
171 | //function : Init | |
172 | //purpose : | |
173 | //======================================================================= | |
174 | ||
175 | void ChFi2d_Builder::Init(const TopoDS_Face& RefFace, | |
176 | const TopoDS_Face& ModFace) | |
177 | { | |
178 | if (RefFace.IsNull() || ModFace.IsNull()) { | |
179 | status = ChFi2d_NoFace; | |
180 | return; | |
181 | } | |
182 | fillets.Clear(); | |
183 | chamfers.Clear(); | |
184 | history.Clear(); | |
185 | TopLoc_Location loc; | |
186 | // syntaxe invalide sur NT | |
187 | // const Handle(Geom_Surface)& surf = BRep_Tool::Surface( RefFace, Loc); | |
188 | // if (!surf->IsKind(STANDARD_TYPE(Geom_Plane))) { | |
189 | if ( ! BRep_Tool::Surface( RefFace, loc) | |
190 | -> IsKind(STANDARD_TYPE(Geom_Plane)) ) { | |
191 | status = ChFi2d_NotPlanar; | |
192 | return; | |
193 | } | |
194 | ||
195 | refFace = RefFace; | |
196 | newFace = ModFace; | |
197 | newFace.Orientation(TopAbs_FORWARD); | |
198 | status = ChFi2d_Ready; | |
199 | ||
200 | // Research in newFace all the edges which not appear in RefFace | |
201 | // The sequence newEdges will contains this edges. | |
202 | ||
203 | TopTools_SequenceOfShape newEdges; | |
204 | TopTools_IndexedMapOfShape refEdgesMap; | |
205 | TopExp::MapShapes(refFace, TopAbs_EDGE, refEdgesMap); | |
206 | TopExp_Explorer ex(newFace, TopAbs_EDGE); | |
207 | while (ex.More()){ | |
208 | const TopoDS_Edge& currentEdge = TopoDS::Edge(ex.Current()); | |
209 | if (!refEdgesMap.Contains(currentEdge)) | |
210 | newEdges.Append(currentEdge); | |
211 | ex.Next(); | |
212 | } // while (ex ... | |
213 | ||
214 | // update of history, fillets and chamfers fields | |
215 | Standard_Integer i = 1; | |
216 | Standard_Real first, last; | |
217 | TopoDS_Edge basisEdge; | |
218 | while ( i <= newEdges.Length()) { | |
219 | const TopoDS_Edge& currentEdge = TopoDS::Edge(newEdges.Value(i)); | |
220 | if (IsIssuedFrom(currentEdge, refEdgesMap, basisEdge)) | |
221 | history.Bind(basisEdge, currentEdge); | |
222 | else { | |
223 | // this edge is a chamfer or a fillet | |
224 | // syntaxe invalide sur NT | |
225 | // const Handle(Geom_Curve)& curve = | |
226 | // BRep_Tool::Curve(currentEdge, loc, first, last); | |
227 | Handle(Geom_Curve) curve = | |
228 | BRep_Tool::Curve(currentEdge, loc, first, last); | |
229 | if (curve->IsKind(STANDARD_TYPE(Geom_Circle))) { | |
230 | fillets.Append(currentEdge); | |
231 | } | |
232 | else if (curve->IsKind(STANDARD_TYPE(Geom_Line))) { | |
233 | chamfers.Append(currentEdge); | |
234 | } | |
235 | else { | |
236 | status = ChFi2d_InitialisationError; | |
237 | return; | |
238 | } // else ... | |
239 | } // this edge is ... | |
240 | i++; | |
241 | } // while ... | |
242 | } // Init | |
243 | ||
244 | ||
245 | //======================================================================= | |
246 | //function : IsIssuedFrom | |
247 | //purpose : Search in <Map> if <E> has a parent edge. If a parent has | |
248 | // been find, this edge is returned in <BasisEdge>, else <E> is | |
249 | // returned in <BasisEdge>. | |
250 | //======================================================================= | |
251 | Standard_Boolean IsIssuedFrom(const TopoDS_Edge& E, | |
252 | const TopTools_IndexedMapOfShape& Map, | |
253 | TopoDS_Edge& BasisEdge) | |
254 | { | |
255 | TopLoc_Location loc1, loc2; | |
256 | Standard_Real f1, L1, f2, L2; | |
257 | // syntaxe invalide sur NT | |
258 | // const Handle(Geom_Curve)& c1 = | |
259 | // BRep_Tool::Curve(E, loc1, f1, L1); | |
260 | Handle(Geom_Curve) c1 = BRep_Tool::Curve(E, loc1, f1, L1); | |
261 | ||
262 | for (Standard_Integer i = 1; i <= Map.Extent(); i++ ) { | |
263 | const TopoDS_Edge& currentEdge = TopoDS::Edge(Map.FindKey(i)); | |
264 | // syntaxe invalide sur NT | |
265 | // const Handle(Geom_Curve)& c2 = | |
266 | // BRep_Tool::Curve(currentEdge, loc2, f2, L2); | |
267 | Handle(Geom_Curve) c2 = BRep_Tool::Curve(currentEdge, loc2, f2, L2); | |
268 | if (c1 == c2 && | |
269 | (((f1 > f2 && f1 < L2) || (L1 > f2 && L1 < L2) ) || | |
270 | ( (f1 > L2 && f1 < f2) || (L1 > L2 && L1 < f2) )) ) { | |
271 | BasisEdge = currentEdge; | |
272 | BasisEdge.Orientation(E.Orientation()); | |
273 | return Standard_True; | |
274 | } // if (c1 == c2 | |
275 | } // for (Standard_Integer i ... | |
276 | ||
277 | return Standard_False; | |
278 | } // IsIssuedFrom | |
279 | ||
280 | ||
281 | //======================================================================= | |
282 | //function : AddFillet | |
283 | //purpose : | |
284 | //======================================================================= | |
285 | TopoDS_Edge ChFi2d_Builder::AddFillet(const TopoDS_Vertex& V, | |
286 | const Standard_Real Radius) | |
287 | { | |
288 | TopoDS_Edge adjEdge1, adjEdge2, basisEdge1, basisEdge2; | |
289 | TopoDS_Edge adjEdge1Mod, adjEdge2Mod, fillet; | |
290 | status = ChFi2d::FindConnectedEdges(newFace, V, adjEdge1, adjEdge2); | |
291 | if (status == ChFi2d_ConnexionError) return fillet; | |
292 | ||
293 | if (IsAFillet(adjEdge1) || IsAChamfer(adjEdge1) || | |
294 | IsAFillet(adjEdge2) || IsAChamfer(adjEdge2)) { | |
295 | status = ChFi2d_NotAuthorized; | |
296 | return fillet; | |
297 | } // if (IsAFillet ... | |
298 | ||
299 | if (!IsLineOrCircle(adjEdge1,newFace) | |
300 | || !IsLineOrCircle(adjEdge2,newFace) ) { | |
301 | status = ChFi2d_NotAuthorized; | |
302 | return fillet; | |
303 | } // if (!IsLineOrCircle ... | |
304 | ||
305 | ComputeFillet(V, adjEdge1, adjEdge2, Radius, | |
306 | adjEdge1Mod, adjEdge2Mod, fillet); | |
307 | if (status == ChFi2d_IsDone | |
308 | || status == ChFi2d_FirstEdgeDegenerated | |
309 | || status == ChFi2d_LastEdgeDegenerated | |
310 | || status == ChFi2d_BothEdgesDegenerated) { | |
311 | BuildNewWire(adjEdge1, adjEdge2, adjEdge1Mod, fillet, adjEdge2Mod); | |
312 | basisEdge1 = BasisEdge(adjEdge1); | |
313 | basisEdge2 = BasisEdge(adjEdge2); | |
314 | UpDateHistory(basisEdge1, basisEdge2, | |
315 | adjEdge1Mod, adjEdge2Mod, fillet, 1); | |
316 | status = ChFi2d_IsDone; | |
317 | return TopoDS::Edge(fillets.Value(fillets.Length())); | |
318 | } | |
319 | return fillet; | |
320 | } // AddFillet | |
321 | ||
322 | //======================================================================= | |
323 | //function : ModifyFillet | |
324 | //purpose : | |
325 | //======================================================================= | |
326 | ||
327 | TopoDS_Edge ChFi2d_Builder::ModifyFillet(const TopoDS_Edge& Fillet, | |
328 | const Standard_Real Radius) | |
329 | { | |
330 | TopoDS_Vertex aVertex = RemoveFillet(Fillet); | |
331 | TopoDS_Edge aFillet = AddFillet(aVertex, Radius); | |
332 | return aFillet; | |
333 | } // ModifyFillet | |
334 | ||
335 | //======================================================================= | |
336 | //function : RemoveFillet | |
337 | //purpose : | |
338 | //======================================================================= | |
339 | ||
340 | TopoDS_Vertex ChFi2d_Builder::RemoveFillet(const TopoDS_Edge& Fillet) | |
341 | { | |
342 | TopoDS_Vertex commonVertex; | |
343 | Standard_Integer i = 1; | |
344 | Standard_Integer IsFind = Standard_False; | |
345 | while (i <= fillets.Length()) { | |
346 | const TopoDS_Edge& aFillet = TopoDS::Edge(fillets.Value(i)); | |
347 | if (aFillet.IsSame(Fillet)) { | |
348 | fillets.Remove(i); | |
349 | IsFind = Standard_True; | |
350 | break; | |
351 | } | |
352 | i++; | |
353 | } | |
354 | if (!IsFind) return commonVertex; | |
355 | ||
356 | ||
357 | TopoDS_Vertex firstVertex, lastVertex; | |
358 | TopExp::Vertices(Fillet, firstVertex, lastVertex); | |
359 | ||
360 | ||
361 | TopoDS_Edge adjEdge1, adjEdge2; | |
362 | status = ChFi2d::FindConnectedEdges(newFace, firstVertex, | |
363 | adjEdge1, adjEdge2); | |
364 | if (status == ChFi2d_ConnexionError) return commonVertex; | |
365 | ||
366 | TopoDS_Edge basisEdge1, basisEdge2, E1, E2; | |
81bba717 | 367 | // E1 and E2 are the adjacent edges to Fillet |
7fd59977 | 368 | |
369 | if (adjEdge1.IsSame(Fillet)) E1 = adjEdge2; | |
370 | else E1 = adjEdge1; | |
371 | basisEdge1 = BasisEdge(E1); | |
372 | status = ChFi2d::FindConnectedEdges(newFace, lastVertex,adjEdge1, adjEdge2); | |
373 | if (status == ChFi2d_ConnexionError) return commonVertex; | |
374 | if (adjEdge1.IsSame(Fillet)) E2 = adjEdge2; | |
375 | else E2 = adjEdge1; | |
376 | basisEdge2 = BasisEdge(E2); | |
377 | TopoDS_Vertex connectionE1Fillet, connectionE2Fillet; | |
378 | Standard_Boolean hasConnection = | |
379 | ChFi2d::CommonVertex(basisEdge1, basisEdge2, commonVertex); | |
380 | if (!hasConnection) { | |
381 | status = ChFi2d_ConnexionError; | |
382 | return commonVertex; | |
383 | } | |
384 | hasConnection = ChFi2d::CommonVertex(E1, Fillet, connectionE1Fillet); | |
385 | if (!hasConnection) { | |
386 | status = ChFi2d_ConnexionError; | |
387 | return commonVertex; | |
388 | } | |
389 | hasConnection = ChFi2d::CommonVertex(E2, Fillet, connectionE2Fillet); | |
390 | if (!hasConnection) { | |
391 | status = ChFi2d_ConnexionError; | |
392 | return commonVertex; | |
393 | } | |
394 | ||
395 | // rebuild edges on wire | |
396 | TopoDS_Edge newEdge1, newEdge2; | |
397 | TopoDS_Vertex v, v1, v2; | |
398 | BRepLib_MakeEdge makeEdge; | |
399 | TopLoc_Location loc; | |
400 | Standard_Real first, last; | |
401 | ||
402 | TopExp::Vertices(E1, firstVertex, lastVertex); | |
403 | TopExp::Vertices(basisEdge1, v1, v2); | |
404 | if (v1.IsSame(commonVertex)) v = v2; | |
405 | else v = v1; | |
406 | ||
407 | if ( firstVertex.IsSame(v) || lastVertex.IsSame(v)) | |
408 | // It means the edge support only one fillet. In this case | |
409 | // the new edge must be the basis edge. | |
410 | newEdge1 = basisEdge1; | |
411 | else { | |
412 | // It means the edge support one fillet on each end. | |
413 | if (firstVertex.IsSame(connectionE1Fillet)) { | |
414 | // syntaxe invalide sur NT | |
415 | // const Handle(Geom_Curve)& curve = | |
416 | // BRep_Tool::Curve(E1, loc, first, last); | |
417 | Handle(Geom_Curve) curve = BRep_Tool::Curve(E1, loc, first, last); | |
418 | makeEdge.Init(curve, commonVertex, lastVertex); | |
419 | newEdge1 = makeEdge.Edge(); | |
420 | newEdge1.Orientation(E1.Orientation()); | |
421 | newEdge1.Location(E1.Location()); | |
422 | } // if (firstVertex ... | |
423 | else if (lastVertex.IsSame(connectionE1Fillet)) { | |
81bba717 | 424 | // syntax wrong on NT |
7fd59977 | 425 | // const Handle(Geom_Curve)& curve = |
426 | // BRep_Tool::Curve(E1, loc, first, last); | |
427 | Handle(Geom_Curve) curve = BRep_Tool::Curve(E1, loc, first, last); | |
428 | makeEdge.Init(curve, firstVertex, commonVertex); | |
429 | newEdge1 = makeEdge.Edge(); | |
430 | newEdge1.Orientation(E1.Orientation()); | |
431 | newEdge1.Location(E1.Location()); | |
432 | } // else if (lastVertex ... | |
433 | } // else ... | |
434 | ||
435 | TopExp::Vertices(basisEdge2, v1, v2); | |
436 | if (v1.IsSame(commonVertex)) v = v2; | |
437 | else v = v1; | |
438 | ||
439 | TopExp::Vertices(E2, firstVertex, lastVertex); | |
440 | if ( firstVertex.IsSame(v) || lastVertex.IsSame(v)) | |
441 | // It means the edge support only one fillet. In this case | |
442 | // the new edge must be the basis edge. | |
443 | newEdge2 = basisEdge2; | |
444 | else { | |
445 | // It means the edge support one fillet on each end. | |
446 | if (firstVertex.IsSame(connectionE2Fillet)) { | |
81bba717 | 447 | // syntax wrong on NT |
7fd59977 | 448 | // const Handle(Geom_Curve)& curve = |
449 | // BRep_Tool::Curve(E2, loc, first, last); | |
450 | Handle(Geom_Curve) curve = BRep_Tool::Curve(E2, loc, first, last); | |
451 | makeEdge.Init(curve, commonVertex, lastVertex); | |
452 | newEdge2 = makeEdge.Edge(); | |
453 | newEdge2.Orientation(E2.Orientation()); | |
454 | newEdge2.Location(E2.Location()); | |
455 | } // if (firstVertex ... | |
456 | else if (lastVertex.IsSame(connectionE2Fillet)) { | |
81bba717 | 457 | // syntax wrong on NT |
7fd59977 | 458 | // const Handle(Geom_Curve)& curve = |
459 | // BRep_Tool::Curve(E2, loc, first, last); | |
460 | Handle(Geom_Curve) curve = BRep_Tool::Curve(E2, loc, first, last); | |
461 | makeEdge.Init(curve, firstVertex, commonVertex); | |
462 | newEdge2 = makeEdge.Edge(); | |
463 | newEdge2.Orientation(E2.Orientation()); | |
464 | newEdge2.Location(E2.Location()); | |
465 | } // else if (lastVertex ... | |
466 | } // else ... | |
467 | ||
468 | // rebuild the newFace | |
469 | TopExp_Explorer Ex(newFace, TopAbs_EDGE); | |
470 | TopoDS_Wire newWire; | |
471 | ||
472 | BRep_Builder B; | |
473 | B.MakeWire(newWire); | |
474 | ||
475 | while (Ex.More()) { | |
476 | const TopoDS_Edge& theEdge = TopoDS::Edge(Ex.Current()); | |
477 | if (!theEdge.IsSame(E1) && | |
478 | !theEdge.IsSame(E2) && | |
479 | !theEdge.IsSame(Fillet)) | |
480 | B.Add(newWire, theEdge); | |
481 | else { | |
482 | if (theEdge == E1) | |
483 | B.Add(newWire, newEdge1); | |
484 | else if (theEdge == E2) | |
485 | B.Add(newWire, newEdge2); | |
486 | } // else | |
487 | Ex.Next(); | |
488 | } // while ... | |
489 | BRepAdaptor_Surface Adaptor3dSurface(refFace); | |
490 | BRepLib_MakeFace mFace(Adaptor3dSurface.Plane(), newWire); | |
491 | newFace.Nullify(); | |
492 | newFace = mFace; | |
493 | ||
494 | UpDateHistory(basisEdge1, basisEdge2, newEdge1, newEdge2); | |
495 | ||
496 | return commonVertex; | |
497 | } // RemoveFillet | |
498 | ||
499 | ||
500 | //======================================================================= | |
501 | //function : ComputeFillet | |
502 | //purpose : | |
503 | //======================================================================= | |
504 | ||
505 | void ChFi2d_Builder::ComputeFillet(const TopoDS_Vertex& V, | |
506 | const TopoDS_Edge& E1, | |
507 | const TopoDS_Edge& E2, | |
508 | const Standard_Real Radius, | |
509 | TopoDS_Edge& TrimE1, | |
510 | TopoDS_Edge& TrimE2, | |
511 | TopoDS_Edge& Fillet) | |
512 | { | |
513 | TopoDS_Vertex newExtr1, newExtr2; | |
514 | Standard_Boolean Degen1, Degen2; | |
515 | Fillet = BuildFilletEdge(V, E1, E2, Radius, newExtr1, newExtr2); | |
516 | if ( status != ChFi2d_IsDone) return; | |
517 | TrimE1 = BuildNewEdge(E1, V, newExtr1, Degen1); | |
518 | TrimE2 = BuildNewEdge(E2, V, newExtr2, Degen2); | |
519 | if (Degen1 && Degen2 ) status = ChFi2d_BothEdgesDegenerated; | |
520 | if (Degen1 && !Degen2 ) status = ChFi2d_FirstEdgeDegenerated; | |
521 | if (!Degen1 && Degen2 ) status = ChFi2d_LastEdgeDegenerated; | |
522 | } // ComputeFillet | |
523 | ||
524 | ||
525 | ||
526 | //======================================================================= | |
527 | //function : BuildNewWire | |
528 | //purpose : | |
529 | //======================================================================= | |
530 | ||
531 | void ChFi2d_Builder::BuildNewWire (const TopoDS_Edge& OldE1, | |
532 | const TopoDS_Edge& OldE2, | |
533 | const TopoDS_Edge& E1, | |
534 | const TopoDS_Edge& Fillet, | |
535 | const TopoDS_Edge& E2) | |
536 | { | |
537 | ||
538 | Standard_Boolean aClosedStatus = Standard_True; | |
539 | ||
540 | TopExp_Explorer Ex(refFace, TopAbs_WIRE); | |
541 | while (Ex.More()) { | |
542 | const TopoDS_Wire& aWire = TopoDS::Wire(Ex.Current()); | |
543 | aClosedStatus = aWire.Closed(); | |
544 | break; | |
545 | } | |
546 | ||
547 | ||
548 | Standard_Boolean filletIsAdded = Standard_False; | |
549 | ||
550 | Ex.Init(newFace, TopAbs_EDGE); | |
551 | TopoDS_Wire newWire; | |
552 | BRep_Builder B; | |
553 | B.MakeWire(newWire); | |
554 | ||
555 | while (Ex.More()) { | |
556 | const TopoDS_Edge& theEdge = TopoDS::Edge(Ex.Current()); | |
557 | if (!theEdge.IsSame(OldE1) && !theEdge.IsSame(OldE2)) { | |
558 | B.Add(newWire, theEdge); | |
559 | } | |
560 | else { | |
561 | if (theEdge == OldE1) { | |
562 | if (status != ChFi2d_FirstEdgeDegenerated | |
563 | && status != ChFi2d_BothEdgesDegenerated) { | |
564 | B.Add(newWire, E1); | |
565 | } | |
566 | if ( !filletIsAdded) { | |
567 | B.Add(newWire, Fillet); | |
568 | filletIsAdded = Standard_True; | |
569 | } // if ( !filletIsAdded ... | |
570 | } // if (theEdge == ... | |
571 | else { | |
572 | if (status != ChFi2d_LastEdgeDegenerated | |
573 | && status != ChFi2d_BothEdgesDegenerated) { | |
574 | B.Add(newWire, E2); | |
575 | } | |
576 | if ( !filletIsAdded) { | |
577 | B.Add(newWire, Fillet); | |
578 | filletIsAdded = Standard_True; | |
579 | }// if ( !filletIsAdded ... | |
580 | } // else ... | |
581 | } // else ... | |
582 | Ex.Next(); | |
583 | } // while ... | |
584 | ||
585 | newWire.Closed(aClosedStatus); | |
586 | BRepAdaptor_Surface Adaptor3dSurface(refFace); | |
587 | BRepLib_MakeFace mFace(Adaptor3dSurface.Plane(), newWire); | |
588 | newFace = mFace; | |
589 | ||
590 | } // BuildNewWire | |
591 | ||
592 | ||
593 | //======================================================================= | |
594 | //function : BuildNewEdge | |
595 | //purpose : | |
596 | //======================================================================= | |
597 | ||
598 | TopoDS_Edge ChFi2d_Builder::BuildNewEdge(const TopoDS_Edge& E1, | |
599 | const TopoDS_Vertex& OldExtr, | |
600 | const TopoDS_Vertex& NewExtr) const | |
601 | { | |
602 | BRepLib_MakeEdge makeEdge; | |
603 | TopLoc_Location loc; | |
604 | Standard_Real first, last; | |
605 | TopoDS_Vertex firstVertex, lastVertex; | |
606 | TopExp::Vertices(E1, firstVertex, lastVertex); | |
607 | // syntaxe invalide sur NT | |
608 | // const Handle(Geom_Curve)& curve = | |
609 | // BRep_Tool::Curve(E1, first, last); | |
610 | Handle(Geom_Curve) curve = BRep_Tool::Curve(E1, first, last); | |
611 | if (firstVertex.IsSame(OldExtr)) | |
612 | makeEdge.Init(curve, NewExtr, lastVertex); | |
613 | else | |
614 | makeEdge.Init(curve, firstVertex, NewExtr); | |
615 | TopoDS_Edge anEdge = makeEdge; | |
616 | anEdge.Orientation(E1.Orientation()); | |
617 | // anEdge.Location(E1.Location()); | |
7fd59977 | 618 | return anEdge; |
619 | } | |
620 | ||
621 | ||
622 | //======================================================================= | |
623 | //function : BuildNewEdge | |
624 | //purpose : special flag if the new edge is degenerated | |
625 | //======================================================================= | |
626 | ||
627 | TopoDS_Edge ChFi2d_Builder::BuildNewEdge(const TopoDS_Edge& E1, | |
628 | const TopoDS_Vertex& OldExtr, | |
629 | const TopoDS_Vertex& NewExtr, | |
630 | Standard_Boolean& IsDegenerated) const | |
631 | { | |
632 | BRepLib_MakeEdge makeEdge; | |
633 | TopLoc_Location loc; | |
634 | Standard_Real first, last; | |
635 | IsDegenerated = Standard_False; | |
636 | TopoDS_Vertex firstVertex, lastVertex; | |
637 | TopExp::Vertices(E1, firstVertex, lastVertex); | |
638 | gp_Pnt Pnew = BRep_Tool::Pnt(NewExtr); | |
639 | Standard_Boolean PonctualEdge = Standard_False; | |
640 | Standard_Real Tol = Precision::Confusion(); | |
81bba717 | 641 | // syntax wrong on NT |
7fd59977 | 642 | // const Handle(Geom_Curve)& curve = |
643 | // BRep_Tool::Curve(E1, first, last); | |
644 | Handle(Geom_Curve) curve = BRep_Tool::Curve(E1, first, last); | |
645 | if (firstVertex.IsSame(OldExtr)) { | |
646 | makeEdge.Init(curve, NewExtr, lastVertex); | |
647 | gp_Pnt PV = BRep_Tool::Pnt(lastVertex); | |
648 | PonctualEdge = (Pnew.Distance(PV)<Tol); | |
649 | } | |
650 | else { | |
651 | makeEdge.Init(curve, firstVertex, NewExtr); | |
652 | gp_Pnt PV = BRep_Tool::Pnt(firstVertex); | |
653 | PonctualEdge = (Pnew.Distance(PV)<Tol); | |
654 | } | |
655 | TopoDS_Edge anEdge; | |
656 | BRepLib_EdgeError error = makeEdge.Error(); | |
657 | if (error==BRepLib_LineThroughIdenticPoints || PonctualEdge) { | |
658 | IsDegenerated = Standard_True; | |
659 | anEdge = E1; | |
660 | } | |
661 | else { | |
662 | anEdge = makeEdge; | |
663 | anEdge.Orientation(E1.Orientation()); | |
664 | // anEdge.Location(E1.Location()); | |
665 | } | |
666 | return anEdge; | |
667 | } | |
668 | ||
669 | ||
670 | //======================================================================= | |
671 | //function : UpDateHistory | |
672 | //purpose : | |
673 | //======================================================================= | |
674 | void ChFi2d_Builder::UpDateHistory(const TopoDS_Edge& E1, | |
675 | const TopoDS_Edge& E2, | |
676 | const TopoDS_Edge& TrimE1, | |
677 | const TopoDS_Edge& TrimE2, | |
678 | const TopoDS_Edge& NewEdge, | |
679 | const Standard_Integer Id) | |
680 | { | |
681 | if (Id == 1) // the new edge is a fillet | |
682 | fillets.Append(NewEdge); | |
683 | else // the new edge is a chamfer | |
684 | chamfers.Append(NewEdge); | |
685 | if (history.IsBound(E1)) history.UnBind(E1); | |
686 | if ( status != ChFi2d_FirstEdgeDegenerated | |
687 | && status != ChFi2d_BothEdgesDegenerated) { | |
688 | if (!E1.IsSame(TrimE1)) history.Bind(E1, TrimE1); | |
689 | } | |
690 | if (history.IsBound(E2)) history.UnBind(E2); | |
691 | if ( status != ChFi2d_LastEdgeDegenerated | |
692 | && status != ChFi2d_BothEdgesDegenerated) { | |
693 | if (!E2.IsSame(TrimE2)) history.Bind(E2, TrimE2); | |
694 | } | |
695 | } // UpDateHistory | |
696 | ||
697 | ||
698 | //======================================================================= | |
699 | //function : UpDateHistory | |
700 | //purpose : | |
701 | //======================================================================= | |
702 | void ChFi2d_Builder::UpDateHistory(const TopoDS_Edge& E1, | |
703 | const TopoDS_Edge& E2, | |
704 | const TopoDS_Edge& TrimE1, | |
705 | const TopoDS_Edge& TrimE2) | |
706 | { | |
707 | ||
708 | ||
709 | if (history.IsBound(E1)) history.UnBind(E1); | |
710 | if (!E1.IsSame(TrimE1)) history.Bind(E1, TrimE1); | |
711 | if (history.IsBound(E2)) history.UnBind(E2); | |
712 | if (!E2.IsSame(TrimE2)) history.Bind(E2, TrimE2); | |
713 | } // UpDateHistory | |
714 | ||
715 | ||
716 | //======================================================================= | |
717 | //function : BasisEdge | |
718 | //purpose : | |
719 | //======================================================================= | |
720 | const TopoDS_Edge& ChFi2d_Builder::BasisEdge(const TopoDS_Edge& E) const | |
721 | { | |
722 | TopTools_DataMapIteratorOfDataMapOfShapeShape iterator(history); | |
723 | TopoDS_Edge anEdge; | |
724 | while (iterator.More()) { | |
725 | anEdge = TopoDS::Edge(iterator.Value()); | |
726 | if (anEdge.IsSame(E)) { | |
727 | const TopoDS_Edge& anotherEdge = TopoDS::Edge(iterator.Key()); | |
728 | return anotherEdge; | |
729 | } // if (anEdge.IsSame ... | |
730 | iterator.Next(); | |
731 | } // while (Iterator.More ... | |
732 | return E; | |
733 | } // BasisEdge | |
734 | ||
735 | ||
736 | //======================================================================= | |
737 | //function : BuildFilletEdge | |
738 | //purpose : | |
739 | //======================================================================= | |
740 | TopoDS_Edge ChFi2d_Builder::BuildFilletEdge(const TopoDS_Vertex& V, | |
741 | const TopoDS_Edge& AdjEdge1, | |
742 | const TopoDS_Edge& AdjEdge2, | |
743 | const Standard_Real Radius, | |
744 | TopoDS_Vertex& NewExtr1, | |
745 | TopoDS_Vertex& NewExtr2) | |
746 | { | |
747 | TopoDS_Edge E1, E2; | |
748 | E1 = AdjEdge1; | |
749 | E2 = AdjEdge2; | |
750 | TopoDS_Vertex V1 = TopExp::FirstVertex(E1); | |
751 | TopoDS_Vertex V2 = TopExp::LastVertex(E1); | |
752 | TopoDS_Vertex V3 = TopExp::FirstVertex(E2); | |
753 | TopoDS_Vertex V4 = TopExp::LastVertex(E2); | |
754 | ||
755 | //======================================================================== | |
81bba717 | 756 | // The first arc is found. + |
7fd59977 | 757 | //======================================================================== |
758 | ||
96a95605 DB |
759 | TopAbs_Orientation O1; |
760 | TopAbs_Orientation OE1; | |
7fd59977 | 761 | OE1 = E1.Orientation(); |
7fd59977 | 762 | E1.Orientation(TopAbs_FORWARD); |
763 | E2.Orientation(TopAbs_FORWARD); | |
764 | TopoDS_Shape aLocalShape = E1.EmptyCopied(); | |
765 | TopoDS_Edge Ebid1 = TopoDS::Edge(aLocalShape); | |
766 | aLocalShape = E2.EmptyCopied(); | |
767 | TopoDS_Edge Ebid2 = TopoDS::Edge(aLocalShape); | |
768 | // TopoDS_Edge Ebid1 = TopoDS::Edge(E1.EmptyCopied()); | |
769 | // TopoDS_Edge Ebid2 = TopoDS::Edge(E2.EmptyCopied()); | |
770 | Standard_Real param1,param2,param3,param4; | |
771 | ||
772 | //======================================================================== | |
81bba717 | 773 | // Save non-modified parts of edges concerned. + |
7fd59977 | 774 | //======================================================================== |
775 | ||
776 | if (V1.IsSame(V)) { | |
777 | param1 = BRep_Tool::Parameter(V1,E1); | |
778 | param2 = BRep_Tool::Parameter(V2,E1); | |
779 | O1 = V2.Orientation(); | |
780 | } | |
781 | else { | |
782 | param1 = BRep_Tool::Parameter(V2,E1); | |
783 | param2 = BRep_Tool::Parameter(V1,E1); | |
784 | O1 = V1.Orientation(); | |
785 | } | |
786 | if (V3.IsSame(V)) { | |
787 | param3 = BRep_Tool::Parameter(V3,E2); | |
788 | param4 = BRep_Tool::Parameter(V4,E2); | |
7fd59977 | 789 | } |
790 | else { | |
791 | param3 = BRep_Tool::Parameter(V4,E2); | |
792 | param4 = BRep_Tool::Parameter(V3,E2); | |
7fd59977 | 793 | } |
794 | ||
795 | //======================================================================== | |
81bba717 | 796 | // Restore geometric supports. + |
7fd59977 | 797 | //======================================================================== |
798 | ||
799 | Handle(Geom2d_Curve) C1,C2; | |
800 | Standard_Real ufirst1,ulast1,ufirst2,ulast2,U1,U2,PU1,PU2,Vv1,Vv2; | |
801 | Standard_Real PPU1,PPU2; | |
802 | C1 = BRep_Tool::CurveOnSurface(E1,newFace,ufirst1,ulast1); | |
803 | C2 = BRep_Tool::CurveOnSurface(E2,newFace,ufirst2,ulast2); | |
804 | ||
805 | //======================================================================== | |
81bba717 | 806 | // Determination of the face for fillet. + |
7fd59977 | 807 | //======================================================================== |
808 | ||
809 | gp_Pnt2d p; | |
810 | gp_Vec2d Ve1,Ve2; | |
811 | gp_Vec2d Ve3,Ve4; | |
812 | Standard_Boolean Sens1 , Sens2; | |
813 | ||
814 | Handle(Geom2d_Curve) basisC1,basisC2; | |
815 | Handle(Geom2d_TrimmedCurve) T1 = Handle(Geom2d_TrimmedCurve)::DownCast(C1); | |
816 | if (!T1.IsNull()) | |
817 | basisC1 = Handle(Geom2d_Curve)::DownCast(T1->BasisCurve()); | |
818 | else | |
819 | basisC1 = Handle(Geom2d_Curve)::DownCast(C1); | |
820 | Handle(Geom2d_TrimmedCurve) T2 = Handle(Geom2d_TrimmedCurve)::DownCast(C2); | |
821 | if (!T2.IsNull()) | |
822 | basisC2 = Handle(Geom2d_Curve)::DownCast(T2->BasisCurve()); | |
823 | else | |
824 | basisC2 = Handle(Geom2d_Curve)::DownCast(C2); | |
825 | ||
826 | if (basisC1->DynamicType() == STANDARD_TYPE(Geom2d_Circle)) { | |
827 | Handle(Geom2d_Circle) CC1 = Handle(Geom2d_Circle)::DownCast(basisC1); | |
828 | ElCLib::D1(param1,CC1->Circ2d(),p,Ve1); | |
829 | Sens1 = (CC1->Circ2d()).IsDirect(); | |
830 | } // if (C1->DynamicType() ... | |
831 | else { | |
832 | Handle(Geom2d_Line) CC1 = Handle(Geom2d_Line)::DownCast(basisC1); | |
833 | ElCLib::D1(param1,CC1->Lin2d(),p,Ve1); | |
834 | Sens1=Standard_True; | |
835 | } // else ... | |
836 | if (basisC2->DynamicType() == STANDARD_TYPE(Geom2d_Circle)) { | |
837 | Handle(Geom2d_Circle) CC2 = Handle(Geom2d_Circle)::DownCast(basisC2); | |
838 | ElCLib::D1(param3,CC2->Circ2d(),p,Ve2); | |
839 | Sens2 = (CC2->Circ2d()).IsDirect(); | |
840 | } // if if (C2->DynamicType() ... | |
841 | else { | |
842 | Handle(Geom2d_Line) CC2 = Handle(Geom2d_Line)::DownCast(basisC2); | |
843 | ElCLib::D1(param3,CC2->Lin2d(),p,Ve2); | |
844 | Sens2=Standard_True; | |
845 | } // else ... | |
846 | ||
847 | TopoDS_Edge filletEdge; | |
848 | ||
849 | Standard_Real cross = Ve1.Crossed(Ve2); | |
850 | Ve3 = Ve1; | |
851 | Ve4 = Ve2; | |
852 | ||
81bba717 | 853 | // processing of tangency or downcast point |
7fd59977 | 854 | if (Ve1.IsParallel(Ve2,Precision::Angular())) { |
81bba717 | 855 | // Ve1 and Ve2 are parallel : cross at 0 |
7fd59977 | 856 | cross = 0.; |
857 | if (param1<param2) { | |
858 | Ve3 = -Ve1; | |
859 | } | |
860 | if (param3>param4) { | |
861 | Ve4 = -Ve2; | |
862 | } | |
863 | ||
864 | if (! Ve4.IsOpposite(Ve3,Precision::Angular())) { | |
81bba717 | 865 | // There is a true tangency point and the calculation is stopped |
7fd59977 | 866 | status = ChFi2d_TangencyError; |
867 | return filletEdge; | |
868 | } | |
81bba717 | 869 | // Otherwise this is a downcast point, and the calculation is continued |
7fd59977 | 870 | } |
871 | ||
872 | GccEnt_Position Qual1,Qual2; | |
873 | if (cross < 0.) { | |
874 | if (param3 > param4 ) { | |
875 | if(Sens1 == Standard_True){ | |
876 | Qual1 = GccEnt_enclosed; | |
877 | } | |
878 | else { | |
879 | Qual1 = GccEnt_outside; | |
880 | } | |
881 | } | |
882 | else { | |
883 | if(Sens1 == Standard_True){ | |
884 | Qual1 = GccEnt_outside; | |
885 | } | |
886 | else { | |
887 | Qual1 = GccEnt_enclosed; | |
888 | } | |
889 | } | |
890 | if (param1 > param2) { | |
891 | if(Sens2 == Standard_True) | |
892 | Qual2 = GccEnt_outside; | |
893 | else | |
894 | Qual2 = GccEnt_enclosed; | |
895 | } | |
896 | else { | |
897 | if(Sens2 == Standard_True) | |
898 | Qual2 = GccEnt_enclosed; | |
899 | else | |
900 | Qual2 = GccEnt_outside; | |
901 | } | |
902 | } // if (cross < 0 ... | |
903 | else { | |
904 | if (param3 > param4 ) { | |
905 | if( Sens1 == Standard_True) | |
906 | Qual1 = GccEnt_outside; | |
907 | else | |
908 | Qual1 = GccEnt_enclosed; | |
909 | } | |
910 | else { | |
911 | if( Sens1 == Standard_True) | |
912 | Qual1 = GccEnt_enclosed; | |
913 | else | |
914 | Qual1 = GccEnt_outside; | |
915 | } | |
916 | if (param1 > param2 ) { | |
917 | if( Sens2 == Standard_True) | |
918 | Qual2 = GccEnt_enclosed; | |
919 | else | |
920 | Qual2 = GccEnt_outside; | |
921 | } | |
922 | else { | |
923 | if( Sens2 == Standard_True) | |
924 | Qual2 = GccEnt_outside; | |
925 | else | |
926 | Qual2 = GccEnt_enclosed; | |
927 | } | |
928 | } // else ... | |
929 | ||
930 | Standard_Real Tol = Precision::Confusion(); | |
931 | Geom2dGcc_Circ2d2TanRad Fillet(Geom2dGcc_QualifiedCurve(basisC1,Qual1), | |
932 | Geom2dGcc_QualifiedCurve(basisC2,Qual2), | |
933 | Radius, Tol); | |
934 | if (!Fillet.IsDone() || Fillet.NbSolutions()==0) { | |
935 | status = ChFi2d_ComputationError; | |
936 | return filletEdge; | |
937 | } | |
938 | else if (Fillet.NbSolutions() >= 1) { | |
939 | status = ChFi2d_IsDone; | |
940 | Standard_Integer numsol = 1; | |
941 | Standard_Integer nsol = 1; | |
942 | TopoDS_Vertex Vertex1,Vertex2; | |
943 | gp_Pnt2d Ptg1,Ptg2; | |
944 | Standard_Real dist; | |
945 | Standard_Real dist1 = 1.e40; | |
946 | Standard_Boolean inside = Standard_False; | |
947 | while (nsol<=Fillet.NbSolutions()) { | |
948 | Fillet.Tangency1(nsol,PU1,PU2,Ptg1); | |
949 | dist = Ptg1.Distance(p); | |
950 | if (basisC1->DynamicType() == STANDARD_TYPE(Geom2d_Line)) { | |
951 | inside = (PU2<param1 && PU2>param2) || (PU2<param2 && PU2>param1); | |
952 | if ( inside && dist < dist1) { | |
953 | numsol = nsol; | |
954 | dist1 = dist; | |
955 | } // if ((((inside && ... | |
956 | } // if (C1->DynamicType( ... | |
957 | else { | |
958 | Fillet.Tangency2(nsol,PPU1,PPU2,Ptg2); | |
959 | dist = Ptg2.Distance(p); | |
960 | inside = (PPU2<param3 && PPU2>param4) || (PPU2<param4 && PPU2>param3); | |
81bba717 | 961 | // case of arc of circle passing on the sewing |
7fd59977 | 962 | if ( ( basisC2->DynamicType() == STANDARD_TYPE(Geom2d_Circle) ) && |
c6541a0c | 963 | ( (2*M_PI<param3 && 2*M_PI>param4) || (2*M_PI<param4 && 2*M_PI>param3) ) ) { |
7fd59977 | 964 | // cas param3<param4 |
c6541a0c D |
965 | inside = (param3<PPU2 && PPU2<2*M_PI) |
966 | || (0<=PPU2 && PPU2<param4-2*M_PI); | |
7fd59977 | 967 | // cas param4<param3 |
c6541a0c D |
968 | inside = inside || (param4<PPU2 && PPU2<2*M_PI) |
969 | || (0<=PPU2 && PPU2<param3-2*M_PI); | |
7fd59977 | 970 | } |
971 | if ( inside && dist < dist1) { | |
972 | numsol = nsol; | |
973 | dist1 = dist; | |
974 | } // if ((((param3 ... | |
975 | } // else ... | |
976 | nsol++; | |
977 | } // while (nsol ... | |
978 | gp_Circ2d cir(Fillet.ThisSolution(numsol)); | |
979 | Handle(Geom2d_Circle) circle = new Geom2d_Circle(cir); | |
980 | ||
981 | BRep_Builder B; | |
982 | BRepAdaptor_Surface Adaptor3dSurface(refFace); | |
983 | Handle(Geom_Plane) refSurf = new Geom_Plane(Adaptor3dSurface.Plane()); | |
984 | Fillet.Tangency1(numsol,U1,U2,Ptg1); | |
985 | Fillet.Tangency2(numsol,Vv1,Vv2,Ptg2); | |
986 | ||
81bba717 | 987 | // check the validity of parameters |
f10018ad J |
988 | //// modified by jgv, 08.08.2011 for bug 0022695 //// |
989 | //inside = (U2<param1 && U2>param2) || (U2<param2 && U2>param1); | |
990 | inside = (U2 < param1 && U2 >= param2) || (U2 <= param2 && U2 > param1); | |
991 | ///////////////////////////////////////////////////// | |
7fd59977 | 992 | if ( (basisC1->DynamicType() == STANDARD_TYPE(Geom2d_Circle)) |
c6541a0c | 993 | && ( (2*M_PI<param1 && 2*M_PI>param2) || (2*M_PI<param2 && 2*M_PI>param1) ) ) { |
81bba717 | 994 | // arc of circle containing the circle origin |
995 | // case param1<param2 | |
c6541a0c | 996 | inside = (param1<U2 && U2<2*M_PI) || (0<=U2 && U2<param2-2*M_PI); |
81bba717 | 997 | // case param2<param1 |
c6541a0c | 998 | inside = inside || (param2<U2 && U2<2*M_PI) || (0<=U2 && U2<param1-2*M_PI); |
7fd59977 | 999 | } |
1000 | if (!inside) { | |
1001 | status = ChFi2d_ComputationError; | |
1002 | return filletEdge; | |
1003 | } | |
1004 | ||
f10018ad J |
1005 | //// modified by jgv, 08.08.2011 for bug 0022695 //// |
1006 | //inside = (Vv2<param3 && Vv2>param4) || (Vv2<param4 && Vv2>param3); | |
1007 | inside = (Vv2 < param3 && Vv2 >= param4) || (Vv2 <= param4 && Vv2 > param3); | |
1008 | ///////////////////////////////////////////////////// | |
7fd59977 | 1009 | if ( (basisC2->DynamicType() == STANDARD_TYPE(Geom2d_Circle)) |
c6541a0c | 1010 | && ( (2*M_PI<param3 && 2*M_PI>param4) || (2*M_PI<param4 && 2*M_PI>param3) ) ) { |
81bba717 | 1011 | // arc of circle containing the circle origin |
7fd59977 | 1012 | // cas param3<param4 |
c6541a0c | 1013 | inside = (param3<Vv2 && Vv2<2*M_PI) || (0<=Vv2 && Vv2<param4-2*M_PI); |
7fd59977 | 1014 | // cas param4<param3 |
c6541a0c | 1015 | inside = inside || (param4<Vv2 && Vv2<2*M_PI) || (0<=Vv2 && Vv2<param3-2*M_PI); |
7fd59977 | 1016 | } |
1017 | if (!inside) { | |
1018 | status = ChFi2d_ComputationError; | |
1019 | return filletEdge; | |
1020 | } | |
1021 | ||
1022 | gp_Pnt p1 = Adaptor3dSurface.Value(Ptg1.X(), Ptg1.Y()); | |
1023 | gp_Pnt p2 = Adaptor3dSurface.Value(Ptg2.X(), Ptg2.Y()); | |
1024 | B.MakeVertex(Vertex1, p1,Tol); | |
1025 | NewExtr1 = Vertex1; | |
1026 | if (Abs(U2-ufirst1) <= Precision::PConfusion()) { | |
1027 | NewExtr1 = V1; | |
1028 | } | |
1029 | if (Abs(U2-ulast1) <= Precision::PConfusion()) { | |
1030 | NewExtr1 = V2; | |
1031 | } | |
1032 | ||
1033 | B.MakeVertex(Vertex2, p2,Tol); | |
1034 | NewExtr2 = Vertex2; | |
1035 | if (Abs(Vv2-ufirst2) <= Precision::PConfusion()) { | |
1036 | NewExtr2 = V3; | |
1037 | } | |
1038 | if (Abs(Vv2-ulast2) <= Precision::PConfusion()) { | |
1039 | NewExtr2 = V4; | |
1040 | } | |
1041 | ||
1042 | //======================================================================= | |
81bba717 | 1043 | // Update tops of the fillet. + |
7fd59977 | 1044 | //======================================================================= |
1045 | gp_Pnt Pntbid; | |
1046 | gp_Pnt2d sommet; | |
1047 | Pntbid = BRep_Tool::Pnt(V); | |
1048 | sommet = gp_Pnt2d(Pntbid.X(),Pntbid.Y()); | |
1049 | ||
1050 | gp_Pnt pntBid; | |
1051 | gp_Pnt2d somBid; | |
1052 | if (V1.IsSame(V)) { | |
1053 | pntBid = BRep_Tool::Pnt(V2); | |
1054 | somBid = gp_Pnt2d(pntBid.X(),pntBid.Y()); | |
1055 | } | |
1056 | else { | |
1057 | pntBid = BRep_Tool::Pnt(V1); | |
1058 | somBid = gp_Pnt2d(pntBid.X(),pntBid.Y()); | |
1059 | } | |
1060 | ||
1061 | gp_Vec2d vec; | |
1062 | ElCLib::D1(U1,cir,Ptg1,vec); | |
1063 | ||
1064 | gp_Vec2d vec1; | |
1065 | if (basisC1->DynamicType() == STANDARD_TYPE(Geom2d_Circle)) { | |
1066 | Handle(Geom2d_Circle) CC1 = Handle(Geom2d_Circle)::DownCast(basisC1); | |
1067 | gp_Circ2d cir2d(CC1->Circ2d()); | |
1068 | Standard_Real par = ElCLib::Parameter(cir2d,Ptg1); | |
1069 | gp_Pnt2d Pd; | |
1070 | ElCLib::D1(par,cir2d,Pd,vec1); | |
1071 | } // if (C1->DynamicType() ... | |
1072 | else if (basisC1->DynamicType() == STANDARD_TYPE(Geom2d_Line)) { | |
1073 | Handle(Geom2d_Line) CC1 = Handle(Geom2d_Line)::DownCast(basisC1); | |
1074 | gp_Lin2d lin2d(CC1->Lin2d()); | |
1075 | Standard_Real par = ElCLib::Parameter(lin2d,sommet); | |
1076 | vec1 = gp_Vec2d(sommet.X()-somBid.X(),sommet.Y()-somBid.Y()); | |
1077 | gp_Pnt2d Pd; | |
1078 | ElCLib::D1(par,lin2d,Pd,vec1); | |
1079 | } // else if ... | |
1080 | ||
1081 | if (OE1 == TopAbs_REVERSED) { | |
1082 | vec1.Reverse(); | |
1083 | } // if (OE1 ... | |
1084 | Standard_Real cross = vec1*vec; | |
1085 | Standard_Boolean Sense = cross > 0.; | |
c6541a0c D |
1086 | if (U1 > Vv1 && U1 > 2.*M_PI) { |
1087 | ElCLib::AdjustPeriodic(0.,2.*M_PI,Precision::Confusion(),U1,Vv1); | |
7fd59977 | 1088 | } // if (U1 ... |
0ebaa4db | 1089 | if ( (O1 == TopAbs_FORWARD && OE1 == TopAbs_FORWARD) || |
1090 | (O1 == TopAbs_REVERSED && OE1 == TopAbs_REVERSED) ) { | |
7fd59977 | 1091 | filletEdge = BRepLib_MakeEdge(circle, refSurf, |
1092 | NewExtr1, NewExtr2, U1, Vv1); | |
1093 | } // if (O1 == ... | |
1094 | else { | |
1095 | filletEdge = BRepLib_MakeEdge(circle, refSurf, | |
1096 | NewExtr2, NewExtr1, Vv1, U1); | |
1097 | } // else ... | |
1098 | if (!Sense) { | |
1099 | TopAbs_Orientation S1 = filletEdge.Orientation(); | |
0ebaa4db | 1100 | if ((O1 == TopAbs_FORWARD && OE1 == TopAbs_FORWARD) || |
1101 | (O1 == TopAbs_REVERSED && OE1 == TopAbs_REVERSED) ) { | |
7fd59977 | 1102 | filletEdge = BRepLib_MakeEdge(circle, refSurf, |
1103 | NewExtr2, NewExtr1, Vv1, U1); | |
1104 | } | |
1105 | else { | |
1106 | filletEdge = BRepLib_MakeEdge(circle, refSurf, | |
1107 | NewExtr1, NewExtr2, U1, Vv1); | |
1108 | } | |
1109 | if (S1 == TopAbs_FORWARD) { | |
1110 | filletEdge.Orientation(TopAbs_REVERSED); | |
1111 | } | |
1112 | else { | |
1113 | filletEdge.Orientation(TopAbs_FORWARD); | |
1114 | } | |
1115 | } // if (!Sense | |
1116 | ||
1117 | } // else if | |
1118 | ||
1119 | BRepLib::BuildCurves3d(filletEdge); | |
1120 | return filletEdge; | |
1121 | } // BuildFilletEdge | |
1122 | ||
1123 | ||
1124 | //======================================================================= | |
1125 | //function : IsAFillet | |
1126 | //purpose : | |
1127 | //======================================================================= | |
1128 | ||
1129 | Standard_Boolean ChFi2d_Builder::IsAFillet(const TopoDS_Edge& E) const | |
1130 | { | |
1131 | Standard_Integer i = 1; | |
1132 | while (i <= fillets.Length()) { | |
1133 | const TopoDS_Edge& currentEdge = TopoDS::Edge(fillets.Value(i)); | |
1134 | if (currentEdge.IsSame(E)) return Standard_True; | |
1135 | i++; | |
1136 | } | |
1137 | return Standard_False; | |
1138 | } // IsAFillet | |
1139 | ||
1140 | ||
1141 | //======================================================================= | |
1142 | //function : IsAChamfer | |
1143 | //purpose : | |
1144 | //======================================================================= | |
1145 | ||
1146 | Standard_Boolean ChFi2d_Builder::IsAChamfer(const TopoDS_Edge& E) const | |
1147 | { | |
1148 | Standard_Integer i = 1; | |
1149 | while (i <= chamfers.Length()) { | |
1150 | const TopoDS_Edge& currentEdge = TopoDS::Edge(chamfers.Value(i)); | |
1151 | if (currentEdge.IsSame(E)) return Standard_True; | |
1152 | i++; | |
1153 | } | |
1154 | return Standard_False; | |
1155 | } // IsAChamfer | |
1156 | ||
1157 | ||
1158 | ||
1159 | //======================================================================= | |
1160 | //function : IsLineOrCircle | |
1161 | //purpose : | |
1162 | //======================================================================= | |
1163 | ||
1164 | Standard_Boolean IsLineOrCircle(const TopoDS_Edge& E, | |
1165 | const TopoDS_Face& F) | |
1166 | { | |
1167 | Standard_Real first, last; | |
1168 | TopLoc_Location loc; | |
1169 | // syntaxe invalide sur NT | |
1170 | // const Handle(Geom2d_Curve)& C = | |
1171 | // BRep_Tool::CurveOnSurface(E,F,first,last); | |
1172 | Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,first,last); | |
1173 | Handle(Geom2d_Curve) basisC; | |
1174 | Handle(Geom2d_TrimmedCurve) TC = Handle(Geom2d_TrimmedCurve)::DownCast(C); | |
1175 | if (!TC.IsNull()) | |
1176 | basisC = Handle(Geom2d_Curve)::DownCast(TC->BasisCurve()); | |
1177 | else | |
1178 | basisC = Handle(Geom2d_Curve)::DownCast(C); | |
1179 | ||
1180 | if ( basisC->DynamicType() == STANDARD_TYPE(Geom2d_Circle) | |
1181 | || basisC->DynamicType() == STANDARD_TYPE(Geom2d_Line) ) { | |
1182 | return Standard_True; | |
1183 | } | |
1184 | else { | |
1185 | return Standard_False; | |
1186 | } // else ... | |
1187 | } // IsLineOrCircle |