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