4e57c75e |
1 | // Created by: Peter KURNEV |
2 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
3 | // |
4 | // The content of this file is subject to the Open CASCADE Technology Public |
5 | // License Version 6.5 (the "License"). You may not use the content of this file |
6 | // except in compliance with the License. Please obtain a copy of the License |
7 | // at http://www.opencascade.org and read it completely before using this file. |
8 | // |
9 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
10 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
11 | // |
12 | // The Original Code and all software distributed under the License is |
13 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
14 | // Initial Developer hereby disclaims all such warranties, including without |
15 | // limitation, any warranties of merchantability, fitness for a particular |
16 | // purpose or non-infringement. Please see the License for the specific terms |
17 | // and conditions governing the rights and limitations under the License. |
18 | |
19 | |
20 | #include <BOPTools_AlgoTools.ixx> |
21 | |
22 | #include <TopTools_IndexedMapOfShape.hxx> |
23 | #include <TopExp.hxx> |
24 | #include <TopExp_Explorer.hxx> |
25 | |
26 | #include <TopoDS.hxx> |
27 | #include <TopoDS_Edge.hxx> |
28 | #include <TopoDS_Vertex.hxx> |
29 | #include <TopoDS_Face.hxx> |
30 | |
31 | #include <TopLoc_Location.hxx> |
32 | |
33 | #include <BRep_TVertex.hxx> |
34 | #include <BRep_TEdge.hxx> |
35 | #include <BRep_TFace.hxx> |
36 | #include <BRep_Tool.hxx> |
37 | #include <BRep_GCurve.hxx> |
38 | #include <BRep_ListIteratorOfListOfPointRepresentation.hxx> |
39 | #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx> |
40 | #include <BRep_CurveRepresentation.hxx> |
41 | #include <BRep_PointRepresentation.hxx> |
42 | |
43 | #include <Geom_Curve.hxx> |
44 | #include <Geom_Surface.hxx> |
45 | #include <Geom_Plane.hxx> |
46 | #include <Geom_TrimmedCurve.hxx> |
47 | |
48 | #include <GeomAdaptor_Curve.hxx> |
49 | #include <GeomAdaptor_HCurve.hxx> |
50 | #include <GeomAdaptor_HSurface.hxx> |
51 | |
52 | #include <Geom2d_Curve.hxx> |
53 | |
54 | #include <Geom2dAdaptor_HCurve.hxx> |
55 | #include <Geom_RectangularTrimmedSurface.hxx> |
56 | #include <Geom2dAdaptor.hxx> |
57 | #include <GeomProjLib.hxx> |
58 | |
59 | #include <ProjLib_ProjectedCurve.hxx> |
60 | #include <Extrema_LocateExtPC.hxx> |
61 | |
62 | #include <gp_Pnt.hxx> |
63 | |
64 | #include <Adaptor3d_HCurve.hxx> |
65 | #include <Adaptor3d_CurveOnSurface.hxx> |
66 | #include <Adaptor3d_HCurveOnSurface.hxx> |
67 | // |
68 | #include <BRepAdaptor_Surface.hxx> |
69 | #include <TopoDS_Iterator.hxx> |
70 | #include <TopoDS_Wire.hxx> |
71 | #include <TopoDS.hxx> |
72 | #include <BRepTools_WireExplorer.hxx> |
73 | #include <gp_Pnt2d.hxx> |
74 | #include <BRep_Tool.hxx> |
75 | #include <BRep_Tool.hxx> |
76 | #include <BRep_Builder.hxx> |
77 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> |
78 | #include <TopTools_ListOfShape.hxx> |
79 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
80 | #include <Geom2d_Curve.hxx> |
81 | #include <GeomAdaptor_Surface.hxx> |
82 | |
83 | static |
84 | void CheckEdge (const TopoDS_Edge& E, |
85 | const Standard_Real aMaxTol); |
86 | static |
87 | void CorrectEdgeTolerance (const TopoDS_Edge& myShape, |
88 | const TopoDS_Face& S, |
89 | const Standard_Real aMaxTol); |
90 | static |
91 | Standard_Boolean Validate(const Adaptor3d_Curve& CRef, |
92 | const Adaptor3d_Curve& Other, |
93 | const Standard_Real Tol, |
94 | const Standard_Boolean SameParameter, |
95 | Standard_Real& aNewTolerance); |
96 | |
97 | static |
98 | void CorrectVertexTolerance(const TopoDS_Edge& aE); |
99 | |
100 | static |
101 | void CorrectWires(const TopoDS_Face& aF); |
102 | |
103 | static |
104 | void UpdateEdges(const TopoDS_Face& aF); |
105 | |
106 | static |
107 | void UpdateVertices(const TopoDS_Edge& aE); |
108 | |
109 | //======================================================================= |
110 | // Function : CorrectTolerances |
111 | // purpose : |
112 | //======================================================================= |
113 | void BOPTools_AlgoTools::CorrectTolerances(const TopoDS_Shape& aShape, |
114 | const Standard_Real aMaxTol) |
115 | { |
116 | BOPTools_AlgoTools::CorrectPointOnCurve(aShape, aMaxTol); |
117 | BOPTools_AlgoTools::CorrectCurveOnSurface(aShape, aMaxTol); |
118 | } |
119 | |
120 | //======================================================================= |
121 | // Function : CorrectPointOnCurve |
122 | // purpose : |
123 | //======================================================================= |
124 | void BOPTools_AlgoTools::CorrectPointOnCurve(const TopoDS_Shape& S, |
125 | const Standard_Real aMaxTol) |
126 | { |
127 | Standard_Integer i, aNb; |
128 | TopTools_IndexedMapOfShape Edges; |
129 | TopExp::MapShapes (S, TopAbs_EDGE, Edges); |
130 | aNb=Edges.Extent(); |
131 | for (i=1; i<=aNb; i++) { |
132 | const TopoDS_Edge& E= TopoDS::Edge(Edges(i)); |
133 | CheckEdge(E, aMaxTol); |
134 | } |
135 | } |
136 | |
137 | //======================================================================= |
138 | // Function : CorrectCurveOnSurface |
139 | // purpose : |
140 | //======================================================================= |
141 | void BOPTools_AlgoTools::CorrectCurveOnSurface(const TopoDS_Shape& S, |
142 | const Standard_Real aMaxTol) |
143 | { |
144 | Standard_Integer i, aNbFaces, j, aNbEdges; |
145 | TopTools_IndexedMapOfShape Faces; |
146 | TopExp::MapShapes (S, TopAbs_FACE, Faces); |
147 | |
148 | aNbFaces=Faces.Extent(); |
149 | for (i=1; i<=aNbFaces; i++) { |
150 | const TopoDS_Face& F= TopoDS::Face(Faces(i)); |
151 | // |
152 | CorrectWires(F); |
153 | // |
154 | TopTools_IndexedMapOfShape Edges; |
155 | TopExp::MapShapes (F, TopAbs_EDGE, Edges); |
156 | aNbEdges=Edges.Extent(); |
157 | for (j=1; j<=aNbEdges; j++) { |
158 | const TopoDS_Edge& E= TopoDS::Edge(Edges(j)); |
159 | CorrectEdgeTolerance (E, F, aMaxTol); |
160 | } |
161 | } |
162 | } |
163 | //======================================================================= |
164 | // Function : CorrectWires |
165 | // purpose : |
166 | //======================================================================= |
167 | void CorrectWires(const TopoDS_Face& aFx) |
168 | { |
169 | GeomAbs_SurfaceType aType; |
170 | // |
171 | const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aFx); |
4e57c75e |
172 | GeomAdaptor_Surface aGAS (aS); |
173 | aType=aGAS.GetType(); |
174 | if (aType!=GeomAbs_Cylinder) { |
175 | return; |
176 | } |
177 | // |
178 | Standard_Integer i, aNbV; |
179 | Standard_Real aTol, aTol2, aD2, aD2max, aT1, aT2, aT; |
180 | TopoDS_Edge aE1, aE2, aEi, aEj; |
181 | gp_Pnt aP, aPV; |
182 | gp_Pnt2d aP2D; |
183 | TopoDS_Face aF; |
184 | BRep_Builder aBB; |
185 | TopTools_IndexedDataMapOfShapeListOfShape aMVE; |
186 | TopTools_ListIteratorOfListOfShape aIt; |
187 | // |
188 | aF=aFx; |
189 | aF.Orientation(TopAbs_FORWARD); |
190 | // |
191 | TopExp::MapShapesAndAncestors(aF, TopAbs_VERTEX, TopAbs_EDGE, aMVE); |
192 | aNbV=aMVE.Extent(); |
193 | for (i=1; i<=aNbV; ++i) { |
194 | const TopoDS_Vertex& aV=TopoDS::Vertex(aMVE.FindKey(i)); |
195 | aPV=BRep_Tool::Pnt(aV); |
196 | aTol=BRep_Tool::Tolerance(aV); |
197 | aTol2=aTol*aTol; |
198 | // |
199 | aD2max=-1.; |
200 | const TopTools_ListOfShape& aLE=aMVE.FindFromIndex(i); |
201 | aIt.Initialize(aLE); |
202 | for (; aIt.More(); aIt.Next()) { |
203 | const TopoDS_Edge& aE=TopoDS::Edge(aIt.Value()); |
204 | aT=BRep_Tool::Parameter(aV, aE); |
205 | const Handle(Geom2d_Curve)& aC2D=BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2); |
206 | aC2D->D0(aT, aP2D); |
4e57c75e |
207 | aS->D0(aP2D.X(), aP2D.Y(), aP); |
208 | aD2=aPV.SquareDistance(aP); |
209 | if (aD2>aD2max) { |
210 | aD2max=aD2; |
211 | } |
212 | } |
213 | if (aD2max>aTol2) { |
214 | aTol=sqrt(aD2max); |
215 | aBB.UpdateVertex(aV, aTol); |
216 | } |
217 | } |
218 | } |
219 | //======================================================================= |
220 | // Function : CorrectEdgeTolerance |
221 | // purpose : Correct tolerances for Edge |
222 | //======================================================================= |
223 | void CorrectEdgeTolerance (const TopoDS_Edge& myShape, |
224 | const TopoDS_Face& S, |
225 | const Standard_Real aMaxTol) |
226 | { |
227 | // |
228 | // 1. Minimum of conditions to Perform |
229 | Handle (BRep_CurveRepresentation) myCref; |
230 | Handle (Adaptor3d_HCurve) myHCurve; |
231 | |
232 | myCref.Nullify(); |
233 | |
234 | Handle(BRep_TEdge)& TEx = *((Handle(BRep_TEdge)*)&myShape.TShape()); |
235 | BRep_ListIteratorOfListOfCurveRepresentation itcrx(TEx->Curves()); |
236 | Standard_Boolean Degenerated, SameParameterx, SameRangex; |
237 | |
238 | Standard_Integer unique = 0; |
239 | |
240 | Degenerated = TEx->Degenerated(); |
241 | SameParameterx = TEx->SameParameter(); |
242 | SameRangex = TEx->SameRange(); |
243 | |
244 | if (!SameRangex && SameParameterx) { |
245 | return; |
246 | } |
247 | |
248 | Handle(Geom_Curve) C3d; |
249 | while (itcrx.More()) { |
250 | const Handle(BRep_CurveRepresentation)& cr = itcrx.Value(); |
251 | if (cr->IsCurve3D()) { |
252 | unique++; |
253 | if (myCref.IsNull() && !cr->Curve3D().IsNull()) { |
254 | myCref = cr; |
255 | } |
256 | } |
257 | itcrx.Next(); |
258 | } |
259 | |
260 | if (unique==0) { |
261 | return;//...No3DCurve |
262 | } |
263 | if (unique>1) { |
264 | return;//...Multiple3DCurve; |
265 | } |
266 | |
267 | if (myCref.IsNull() && !Degenerated) { |
268 | itcrx.Initialize(TEx->Curves()); |
269 | while (itcrx.More()) { |
270 | const Handle(BRep_CurveRepresentation)& cr = itcrx.Value(); |
271 | if (cr->IsCurveOnSurface()) { |
272 | myCref = cr; |
273 | break; |
274 | } |
275 | itcrx.Next(); |
276 | } |
277 | } |
278 | |
279 | else if (!myCref.IsNull() && Degenerated){ |
280 | return ;//...InvalidDegeneratedFlag; |
281 | } |
282 | |
283 | if (!myCref.IsNull()) { |
284 | const Handle(BRep_GCurve)& GCref = *((Handle(BRep_GCurve)*)&myCref); |
285 | Standard_Real First,Last; |
286 | GCref->Range(First,Last); |
287 | if (Last<=First) { |
288 | myCref.Nullify(); |
289 | return ;//InvalidRange; |
290 | } |
291 | |
292 | else { |
293 | if (myCref->IsCurve3D()) { |
294 | Handle(Geom_Curve) C3dx = Handle(Geom_Curve)::DownCast |
295 | (myCref->Curve3D()->Transformed (myCref->Location().Transformation())); |
296 | GeomAdaptor_Curve GAC3d(C3dx, First, Last); |
297 | myHCurve = new GeomAdaptor_HCurve(GAC3d); |
298 | } |
299 | else { // curve on surface |
300 | Handle(Geom_Surface) Sref = myCref->Surface(); |
301 | Sref = Handle(Geom_Surface)::DownCast(Sref->Transformed(myCref->Location().Transformation())); |
302 | const Handle(Geom2d_Curve)& PCref = myCref->PCurve(); |
303 | Handle(GeomAdaptor_HSurface) GAHSref = new GeomAdaptor_HSurface(Sref); |
304 | Handle(Geom2dAdaptor_HCurve) GHPCref = new Geom2dAdaptor_HCurve(PCref, First, Last); |
305 | Adaptor3d_CurveOnSurface ACSref(GHPCref,GAHSref); |
306 | myHCurve = new Adaptor3d_HCurveOnSurface(ACSref); |
307 | } |
308 | } |
309 | } |
310 | |
311 | //=============================================== |
312 | // 2. Tolerances in InContext |
313 | { |
314 | if (myCref.IsNull()) |
315 | return; |
316 | Standard_Boolean ok=Standard_True;; |
317 | |
318 | Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&myShape.TShape()); |
319 | Standard_Real Tol = BRep_Tool::Tolerance(TopoDS::Edge(myShape)); |
320 | Standard_Real aNewTol=Tol; |
321 | |
322 | Standard_Boolean SameParameter = TE->SameParameter(); |
323 | Standard_Boolean SameRange = TE->SameRange(); |
324 | Standard_Real First = myHCurve->FirstParameter(); |
325 | Standard_Real Last = myHCurve->LastParameter(); |
4e57c75e |
326 | Standard_Real Delta =1.e-12; |
327 | |
328 | Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &S.TShape()); |
329 | const TopLoc_Location& Floc = S.Location(); |
330 | const TopLoc_Location& TFloc = TF->Location(); |
331 | const Handle(Geom_Surface)& Su = TF->Surface(); |
332 | TopLoc_Location L = (Floc * TFloc).Predivided(myShape.Location()); |
4e57c75e |
333 | Standard_Boolean pcurvefound = Standard_False; |
334 | |
335 | BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves()); |
336 | while (itcr.More()) { |
337 | const Handle(BRep_CurveRepresentation)& cr = itcr.Value(); |
338 | if (cr != myCref && cr->IsCurveOnSurface(Su,L)) { |
339 | pcurvefound = Standard_True; |
340 | const Handle(BRep_GCurve)& GC = *((Handle(BRep_GCurve)*)&cr); |
341 | Standard_Real f,l; |
342 | GC->Range(f,l); |
343 | if (SameRange && (f != First || l != Last)) { |
d3f26155 |
344 | return ;//BRepCheck_InvalidSameRangeFlag; |
4e57c75e |
345 | } |
346 | |
347 | Handle(Geom_Surface) Sb = cr->Surface(); |
348 | Sb = Handle(Geom_Surface)::DownCast (Su->Transformed(L.Transformation())); |
349 | Handle(Geom2d_Curve) PC = cr->PCurve(); |
350 | Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(Sb); |
351 | Handle(Geom2dAdaptor_HCurve) GHPC = new Geom2dAdaptor_HCurve(PC,f,l); |
352 | Adaptor3d_CurveOnSurface ACS(GHPC,GAHS); |
353 | ok = Validate(myHCurve->Curve(), ACS, Tol, SameParameter, aNewTol); |
354 | if (ok) { |
355 | if (cr->IsCurveOnClosedSurface()) { |
356 | //return ;// BRepCheck::Add(lst,BRepCheck_InvalidCurveOnClosedSurface); |
357 | } |
358 | else { |
359 | //return;//BRepCheck::Add(lst,BRepCheck_InvalidCurveOnSurface); |
360 | } |
361 | if (SameParameter) { |
362 | //return;//BRepCheck::Add(lst,BRepCheck_InvalidSameParameterFlag); |
363 | } |
364 | // |
365 | if (aNewTol<aMaxTol) { |
366 | TE->UpdateTolerance(aNewTol+Delta); |
367 | // |
368 | CorrectVertexTolerance(myShape); |
369 | } |
370 | } |
371 | |
372 | if (cr->IsCurveOnClosedSurface()) { |
373 | //checkclosed = Standard_True; |
374 | GHPC->ChangeCurve2d().Load(cr->PCurve2(),f,l); // same bounds |
375 | ACS.Load(GAHS); // sans doute inutile |
376 | ACS.Load(GHPC); // meme remarque... |
377 | ok = Validate(myHCurve->Curve(),ACS,Tol,SameParameter, aNewTol); |
378 | if (ok) { |
379 | //return;//BRepCheck::Add(lst,BRepCheck_InvalidCurveOnClosedSurface); |
380 | if (SameParameter) { |
381 | //return;//BRepCheck::Add(lst,BRepCheck_InvalidSameParameterFlag); |
382 | } |
383 | if (aNewTol<aMaxTol) { |
384 | TE->UpdateTolerance(aNewTol+Delta); |
385 | CorrectVertexTolerance(myShape); |
386 | } |
387 | } |
388 | } |
389 | } |
390 | itcr.Next(); |
391 | } |
392 | |
393 | if (!pcurvefound) { |
394 | Handle(Geom_Plane) P; |
395 | Handle(Standard_Type) styp = Su->DynamicType(); |
396 | if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) { |
397 | P = Handle(Geom_Plane)::DownCast(Handle(Geom_RectangularTrimmedSurface):: |
398 | DownCast(Su)->BasisSurface()); |
399 | } |
400 | else { |
401 | P = Handle(Geom_Plane)::DownCast(Su); |
402 | } |
403 | if (P.IsNull()) { // not a plane |
404 | return;//BRepCheck::Add(lst,BRepCheck_NoCurveOnSurface); |
405 | } |
406 | |
407 | else {// on fait la projection a la volee, comme BRep_Tool |
408 | P = Handle(Geom_Plane)::DownCast(P->Transformed(L.Transformation())); |
409 | //on projette Cref sur ce plan |
410 | Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(P); |
411 | |
412 | // Dub - Normalement myHCurve est une GeomAdaptor_HCurve |
413 | GeomAdaptor_Curve& Gac = Handle(GeomAdaptor_HCurve)::DownCast(myHCurve)->ChangeCurve(); |
414 | Handle(Geom_Curve) C3dx = Gac.Curve(); |
415 | Handle(Geom_Curve) ProjOnPlane = GeomProjLib::ProjectOnPlane |
416 | (new Geom_TrimmedCurve(C3dx,First,Last), P, P->Position().Direction(), Standard_True); |
417 | |
418 | Handle(GeomAdaptor_HCurve) aHCurve = new GeomAdaptor_HCurve(ProjOnPlane); |
419 | |
420 | ProjLib_ProjectedCurve proj(GAHS,aHCurve); |
421 | Handle(Geom2d_Curve) PC = Geom2dAdaptor::MakeCurve(proj); |
422 | Handle(Geom2dAdaptor_HCurve) GHPC = |
423 | new Geom2dAdaptor_HCurve(PC, myHCurve->FirstParameter(), myHCurve->LastParameter()); |
424 | |
425 | Adaptor3d_CurveOnSurface ACS(GHPC,GAHS); |
426 | |
427 | Standard_Boolean okx = Validate(myHCurve->Curve(),ACS, |
428 | Tol,Standard_True, aNewTol); // voir dub... |
429 | if (okx) { |
430 | //return;//BRepCheck::Add(lst,BRepCheck_InvalidCurveOnSurface); |
431 | if (aNewTol<aMaxTol) { |
432 | TE->UpdateTolerance(aNewTol+Delta); |
433 | CorrectVertexTolerance(myShape); |
434 | } |
435 | } |
436 | } |
437 | |
438 | }//end of if (!pcurvefound) { |
439 | } // end of 2. Tolerances in InContext |
440 | |
441 | } |
442 | |
443 | //======================================================================= |
444 | // Function : CorrectShapeTolerances |
445 | // purpose : |
446 | //======================================================================= |
447 | void BOPTools_AlgoTools::CorrectShapeTolerances(const TopoDS_Shape& aShape) |
448 | { |
449 | TopExp_Explorer aExp; |
450 | Standard_Integer aDim; |
451 | // |
452 | aDim=Dimension(aShape); |
453 | if (aDim == 1) { |
454 | aExp.Init(aShape, TopAbs_EDGE); |
455 | for (; aExp.More(); aExp.Next()) { |
456 | const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current(); |
457 | UpdateVertices(aE); |
458 | } |
459 | } else { |
460 | aExp.Init(aShape, TopAbs_FACE); |
461 | for (; aExp.More(); aExp.Next()) { |
462 | const TopoDS_Face& aF = *(TopoDS_Face*)&aExp.Current(); |
463 | UpdateEdges(aF); |
464 | } |
465 | } |
466 | } |
467 | |
468 | //======================================================================= |
469 | //function : CorrectVertexTolerance |
470 | //purpose : |
471 | //======================================================================= |
472 | void CorrectVertexTolerance(const TopoDS_Edge& aE) |
473 | { |
474 | Standard_Integer k, aNbV; |
475 | Standard_Real aTolE, aTolV; |
476 | TopTools_IndexedMapOfShape aVMap; |
477 | |
478 | aTolE=BRep_Tool::Tolerance(aE); |
479 | |
480 | TopExp::MapShapes(aE, TopAbs_VERTEX, aVMap); |
481 | aNbV=aVMap.Extent(); |
482 | for (k=1; k<=aNbV; ++k) { |
483 | const TopoDS_Vertex& aV=TopoDS::Vertex(aVMap(k)); |
484 | aTolV=BRep_Tool::Tolerance(aV); |
485 | if (aTolV<aTolE) { |
486 | Handle(BRep_TVertex)& aTV = *((Handle(BRep_TVertex)*)&aV.TShape()); |
487 | aTV->UpdateTolerance(aTolE); |
488 | } |
489 | } |
490 | } |
491 | |
492 | #define NCONTROL 23 |
493 | //======================================================================= |
494 | //function : Validate |
495 | //purpose : |
496 | //======================================================================= |
497 | Standard_Boolean Validate(const Adaptor3d_Curve& CRef, |
498 | const Adaptor3d_Curve& Other, |
499 | const Standard_Real Tol, |
500 | const Standard_Boolean SameParameter, |
501 | Standard_Real& aNewTolerance) |
502 | { |
503 | Standard_Real First, Last, MaxDistance, aD, Tol2; |
504 | |
505 | First = CRef.FirstParameter(); |
506 | Last = CRef.LastParameter(); |
507 | MaxDistance = 0.; |
508 | Tol2 = Tol*Tol; |
509 | |
510 | Standard_Integer i, aNC1=NCONTROL-1; |
511 | |
512 | Standard_Boolean aFlag=Standard_False; |
513 | Standard_Boolean proj = (!SameParameter || |
514 | First != Other.FirstParameter() || |
515 | Last != Other.LastParameter()); |
516 | // |
517 | // 1. |
518 | if (!proj) { |
519 | for (i = 0; i < NCONTROL; i++) { |
520 | Standard_Real prm = ((aNC1-i)*First + i*Last)/aNC1; |
521 | gp_Pnt pref = CRef.Value(prm); |
522 | gp_Pnt pother = Other.Value(prm); |
523 | |
524 | aD=pref.SquareDistance(pother); |
525 | |
526 | if (aD > Tol2) { |
527 | if (aD>MaxDistance) { |
528 | MaxDistance=aD; |
529 | } |
530 | aFlag=Standard_True; |
531 | } |
532 | } |
533 | |
534 | if (aFlag) { |
535 | aNewTolerance=sqrt(MaxDistance); |
536 | } |
537 | return aFlag; |
538 | } |
539 | |
540 | // |
541 | // 2. |
542 | else { |
543 | Extrema_LocateExtPC refd,otherd; |
544 | Standard_Real OFirst, OLast; |
545 | OFirst = Other.FirstParameter(); |
546 | OLast = Other.LastParameter(); |
547 | |
548 | gp_Pnt pd = CRef.Value(First); |
549 | gp_Pnt pdo = Other.Value(OFirst); |
550 | |
551 | aD = pd.SquareDistance(pdo); |
552 | if (aD > Tol2) { |
553 | if (aD>MaxDistance) { |
554 | MaxDistance=aD; |
555 | } |
556 | aFlag=Standard_True; |
557 | } |
558 | |
559 | pd = CRef.Value(Last); |
560 | pdo = Other.Value(OLast); |
561 | aD = pd.SquareDistance(pdo); |
562 | if (aD > Tol2 && aD > MaxDistance) { |
563 | MaxDistance=aD; |
564 | aFlag=Standard_True; |
565 | } |
566 | |
567 | refd.Initialize(CRef, First, Last, CRef.Resolution(Tol)); |
568 | otherd.Initialize(Other, OFirst, OLast, Other.Resolution(Tol)); |
569 | |
570 | for (i = 2; i< aNC1; i++) { |
571 | Standard_Real rprm = ((aNC1-i)*First + i*Last)/aNC1; |
572 | gp_Pnt pref = CRef.Value(rprm); |
573 | |
574 | Standard_Real oprm = ((aNC1-i)*OFirst + i*OLast)/aNC1; |
575 | gp_Pnt pother = Other.Value(oprm); |
576 | |
577 | refd.Perform(pother,rprm); |
578 | if (!refd.IsDone() || refd.SquareDistance() > Tol2) { |
579 | if (refd.IsDone()) { |
580 | aD=refd.SquareDistance(); |
581 | if (aD > Tol2 && aD>MaxDistance) { |
582 | aFlag=Standard_True; |
583 | MaxDistance=aD; |
584 | } |
585 | } |
586 | } |
587 | |
588 | otherd.Perform(pref,oprm); |
589 | if (!otherd.IsDone() || otherd.SquareDistance() > Tol2) { |
590 | |
591 | if (otherd.IsDone()) { |
592 | aD=otherd.SquareDistance(); |
593 | if (aD > Tol2 && aD>MaxDistance) { |
594 | aFlag=Standard_True; |
595 | MaxDistance=aD; |
596 | } |
597 | } |
598 | } |
599 | } |
600 | } |
601 | |
602 | aD=sqrt (MaxDistance); |
603 | aNewTolerance=aD; |
604 | |
605 | return aFlag; |
606 | |
607 | } |
608 | |
609 | //======================================================================= |
610 | // Function : CheckEdge |
611 | // purpose : Correct tolerances for Vertices on Edge |
612 | //======================================================================= |
613 | void CheckEdge (const TopoDS_Edge& Ed, const Standard_Real aMaxTol) |
614 | { |
615 | TopoDS_Edge E=Ed; |
616 | E.Orientation(TopAbs_FORWARD); |
617 | |
618 | gp_Pnt Controlp; |
619 | |
620 | TopExp_Explorer aVExp; |
621 | aVExp.Init(E, TopAbs_VERTEX); |
622 | for (; aVExp.More(); aVExp.Next()) { |
623 | TopoDS_Vertex aVertex= TopoDS::Vertex(aVExp.Current()); |
624 | |
625 | Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &aVertex.TShape()); |
626 | const gp_Pnt& prep = TV->Pnt(); |
627 | |
628 | Standard_Real Tol, aD2, aNewTolerance, dd; |
629 | |
630 | Tol =BRep_Tool::Tolerance(aVertex); |
631 | Tol = Max(Tol, BRep_Tool::Tolerance(E)); |
632 | dd=0.1*Tol; |
633 | Tol*=Tol; |
634 | |
635 | const TopLoc_Location& Eloc = E.Location(); |
636 | BRep_ListIteratorOfListOfPointRepresentation itpr; |
637 | |
638 | Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&E.TShape()); |
639 | BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves()); |
640 | while (itcr.More()) { |
641 | const Handle(BRep_CurveRepresentation)& cr = itcr.Value(); |
642 | const TopLoc_Location& loc = cr->Location(); |
643 | TopLoc_Location L = (Eloc * loc).Predivided(aVertex.Location()); |
644 | |
645 | if (cr->IsCurve3D()) { |
646 | const Handle(Geom_Curve)& C = cr->Curve3D(); |
647 | if (!C.IsNull()) { |
648 | itpr.Initialize(TV->Points()); |
649 | while (itpr.More()) { |
650 | const Handle(BRep_PointRepresentation)& pr = itpr.Value(); |
651 | if (pr->IsPointOnCurve(C,L)) { |
652 | Controlp = C->Value(pr->Parameter()); |
653 | Controlp.Transform(L.Transformation()); |
654 | aD2=prep.SquareDistance(Controlp); |
655 | if (aD2 > Tol) { |
656 | aNewTolerance=sqrt(aD2)+dd; |
657 | if (aNewTolerance<aMaxTol) |
658 | TV->UpdateTolerance(aNewTolerance); |
659 | } |
660 | } |
661 | itpr.Next(); |
662 | } |
663 | |
664 | TopAbs_Orientation orv = aVertex.Orientation(); |
665 | if (orv == TopAbs_FORWARD || orv == TopAbs_REVERSED) { |
666 | const Handle(BRep_GCurve)& GC = *((Handle(BRep_GCurve)*)&cr); |
667 | |
668 | if (orv==TopAbs_FORWARD) |
669 | Controlp = C->Value(GC->First()); |
670 | else |
671 | Controlp = C->Value(GC->Last()); |
672 | |
673 | Controlp.Transform(L.Transformation()); |
674 | aD2=prep.SquareDistance(Controlp); |
675 | |
676 | if (aD2 > Tol) { |
677 | aNewTolerance=sqrt(aD2)+dd; |
678 | if (aNewTolerance<aMaxTol) |
679 | TV->UpdateTolerance(aNewTolerance); |
680 | } |
681 | } |
682 | } |
683 | } |
684 | itcr.Next(); |
685 | } |
686 | } |
687 | } |
688 | |
689 | //======================================================================= |
690 | // Function : UpdateVertices |
691 | // purpose : |
692 | //======================================================================= |
693 | void UpdateVertices(const TopoDS_Edge& aE) |
694 | { |
695 | Standard_Real aTolE, aTolV; |
696 | TopoDS_Iterator aItE; |
697 | BRep_Builder aBB; |
698 | // |
699 | aTolE = BRep_Tool::Tolerance(aE); |
700 | aItE.Initialize(aE); |
701 | for (; aItE.More(); aItE.Next()) { |
702 | const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aItE.Value(); |
703 | aTolV = BRep_Tool::Tolerance(aV); |
704 | if (aTolV < aTolE) { |
705 | aBB.UpdateVertex(aV, aTolE); |
706 | } |
707 | } |
708 | } |
709 | //======================================================================= |
710 | // Function : UpdateEdges |
711 | // purpose : |
712 | //======================================================================= |
713 | void UpdateEdges(const TopoDS_Face& aF) |
714 | { |
715 | Standard_Real aTolF, aTolE, aTolV; |
716 | TopoDS_Iterator aItF, aItW, aItE; |
717 | BRep_Builder aBB; |
718 | // |
719 | aTolF = BRep_Tool::Tolerance(aF); |
720 | aItF.Initialize(aF); |
721 | for (; aItF.More(); aItF.Next()) { |
722 | const TopoDS_Shape& aS = aItF.Value(); |
723 | if (aS.ShapeType()==TopAbs_WIRE) { |
724 | aItW.Initialize(aS); |
725 | for (; aItW.More(); aItW.Next()) { |
726 | const TopoDS_Edge& aE = *(TopoDS_Edge*)&aItW.Value(); |
727 | aTolE = BRep_Tool::Tolerance(aE); |
728 | if (aTolE < aTolF) { |
729 | aBB.UpdateEdge(aE, aTolF); |
730 | aTolE = aTolF; |
731 | } |
732 | UpdateVertices(aE); |
733 | } |
734 | } |
735 | else { |
736 | const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aItF.Value(); |
737 | aTolV = BRep_Tool::Tolerance(aV); |
738 | if (aTolV < aTolE) { |
739 | aBB.UpdateVertex(aV, aTolF); |
740 | } |
741 | } |
742 | } |
743 | } |