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); |
172 | //BRepAdaptor_Surface aBAS (aFx, Standard_False); |
173 | GeomAdaptor_Surface aGAS (aS); |
174 | aType=aGAS.GetType(); |
175 | if (aType!=GeomAbs_Cylinder) { |
176 | return; |
177 | } |
178 | // |
179 | Standard_Integer i, aNbV; |
180 | Standard_Real aTol, aTol2, aD2, aD2max, aT1, aT2, aT; |
181 | TopoDS_Edge aE1, aE2, aEi, aEj; |
182 | gp_Pnt aP, aPV; |
183 | gp_Pnt2d aP2D; |
184 | TopoDS_Face aF; |
185 | BRep_Builder aBB; |
186 | TopTools_IndexedDataMapOfShapeListOfShape aMVE; |
187 | TopTools_ListIteratorOfListOfShape aIt; |
188 | // |
189 | aF=aFx; |
190 | aF.Orientation(TopAbs_FORWARD); |
191 | // |
192 | TopExp::MapShapesAndAncestors(aF, TopAbs_VERTEX, TopAbs_EDGE, aMVE); |
193 | aNbV=aMVE.Extent(); |
194 | for (i=1; i<=aNbV; ++i) { |
195 | const TopoDS_Vertex& aV=TopoDS::Vertex(aMVE.FindKey(i)); |
196 | aPV=BRep_Tool::Pnt(aV); |
197 | aTol=BRep_Tool::Tolerance(aV); |
198 | aTol2=aTol*aTol; |
199 | // |
200 | aD2max=-1.; |
201 | const TopTools_ListOfShape& aLE=aMVE.FindFromIndex(i); |
202 | aIt.Initialize(aLE); |
203 | for (; aIt.More(); aIt.Next()) { |
204 | const TopoDS_Edge& aE=TopoDS::Edge(aIt.Value()); |
205 | aT=BRep_Tool::Parameter(aV, aE); |
206 | const Handle(Geom2d_Curve)& aC2D=BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2); |
207 | aC2D->D0(aT, aP2D); |
208 | //aP=aBAS.Value(aP2D.X(), aP2D.Y()); |
209 | aS->D0(aP2D.X(), aP2D.Y(), aP); |
210 | aD2=aPV.SquareDistance(aP); |
211 | if (aD2>aD2max) { |
212 | aD2max=aD2; |
213 | } |
214 | } |
215 | if (aD2max>aTol2) { |
216 | aTol=sqrt(aD2max); |
217 | aBB.UpdateVertex(aV, aTol); |
218 | } |
219 | } |
220 | } |
221 | //======================================================================= |
222 | // Function : CorrectEdgeTolerance |
223 | // purpose : Correct tolerances for Edge |
224 | //======================================================================= |
225 | void CorrectEdgeTolerance (const TopoDS_Edge& myShape, |
226 | const TopoDS_Face& S, |
227 | const Standard_Real aMaxTol) |
228 | { |
229 | // |
230 | // 1. Minimum of conditions to Perform |
231 | Handle (BRep_CurveRepresentation) myCref; |
232 | Handle (Adaptor3d_HCurve) myHCurve; |
233 | |
234 | myCref.Nullify(); |
235 | |
236 | Handle(BRep_TEdge)& TEx = *((Handle(BRep_TEdge)*)&myShape.TShape()); |
237 | BRep_ListIteratorOfListOfCurveRepresentation itcrx(TEx->Curves()); |
238 | Standard_Boolean Degenerated, SameParameterx, SameRangex; |
239 | |
240 | Standard_Integer unique = 0; |
241 | |
242 | Degenerated = TEx->Degenerated(); |
243 | SameParameterx = TEx->SameParameter(); |
244 | SameRangex = TEx->SameRange(); |
245 | |
246 | if (!SameRangex && SameParameterx) { |
247 | return; |
248 | } |
249 | |
250 | Handle(Geom_Curve) C3d; |
251 | while (itcrx.More()) { |
252 | const Handle(BRep_CurveRepresentation)& cr = itcrx.Value(); |
253 | if (cr->IsCurve3D()) { |
254 | unique++; |
255 | if (myCref.IsNull() && !cr->Curve3D().IsNull()) { |
256 | myCref = cr; |
257 | } |
258 | } |
259 | itcrx.Next(); |
260 | } |
261 | |
262 | if (unique==0) { |
263 | return;//...No3DCurve |
264 | } |
265 | if (unique>1) { |
266 | return;//...Multiple3DCurve; |
267 | } |
268 | |
269 | if (myCref.IsNull() && !Degenerated) { |
270 | itcrx.Initialize(TEx->Curves()); |
271 | while (itcrx.More()) { |
272 | const Handle(BRep_CurveRepresentation)& cr = itcrx.Value(); |
273 | if (cr->IsCurveOnSurface()) { |
274 | myCref = cr; |
275 | break; |
276 | } |
277 | itcrx.Next(); |
278 | } |
279 | } |
280 | |
281 | else if (!myCref.IsNull() && Degenerated){ |
282 | return ;//...InvalidDegeneratedFlag; |
283 | } |
284 | |
285 | if (!myCref.IsNull()) { |
286 | const Handle(BRep_GCurve)& GCref = *((Handle(BRep_GCurve)*)&myCref); |
287 | Standard_Real First,Last; |
288 | GCref->Range(First,Last); |
289 | if (Last<=First) { |
290 | myCref.Nullify(); |
291 | return ;//InvalidRange; |
292 | } |
293 | |
294 | else { |
295 | if (myCref->IsCurve3D()) { |
296 | Handle(Geom_Curve) C3dx = Handle(Geom_Curve)::DownCast |
297 | (myCref->Curve3D()->Transformed (myCref->Location().Transformation())); |
298 | GeomAdaptor_Curve GAC3d(C3dx, First, Last); |
299 | myHCurve = new GeomAdaptor_HCurve(GAC3d); |
300 | } |
301 | else { // curve on surface |
302 | Handle(Geom_Surface) Sref = myCref->Surface(); |
303 | Sref = Handle(Geom_Surface)::DownCast(Sref->Transformed(myCref->Location().Transformation())); |
304 | const Handle(Geom2d_Curve)& PCref = myCref->PCurve(); |
305 | Handle(GeomAdaptor_HSurface) GAHSref = new GeomAdaptor_HSurface(Sref); |
306 | Handle(Geom2dAdaptor_HCurve) GHPCref = new Geom2dAdaptor_HCurve(PCref, First, Last); |
307 | Adaptor3d_CurveOnSurface ACSref(GHPCref,GAHSref); |
308 | myHCurve = new Adaptor3d_HCurveOnSurface(ACSref); |
309 | } |
310 | } |
311 | } |
312 | |
313 | //=============================================== |
314 | // 2. Tolerances in InContext |
315 | { |
316 | if (myCref.IsNull()) |
317 | return; |
318 | Standard_Boolean ok=Standard_True;; |
319 | |
320 | Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&myShape.TShape()); |
321 | Standard_Real Tol = BRep_Tool::Tolerance(TopoDS::Edge(myShape)); |
322 | Standard_Real aNewTol=Tol; |
323 | |
324 | Standard_Boolean SameParameter = TE->SameParameter(); |
325 | Standard_Boolean SameRange = TE->SameRange(); |
326 | Standard_Real First = myHCurve->FirstParameter(); |
327 | Standard_Real Last = myHCurve->LastParameter(); |
328 | //Standard_Real Delta =1.e-14; |
329 | Standard_Real Delta =1.e-12; |
330 | |
331 | Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &S.TShape()); |
332 | const TopLoc_Location& Floc = S.Location(); |
333 | const TopLoc_Location& TFloc = TF->Location(); |
334 | const Handle(Geom_Surface)& Su = TF->Surface(); |
335 | TopLoc_Location L = (Floc * TFloc).Predivided(myShape.Location()); |
336 | // Standard_Boolean checkclosed = Standard_False; |
337 | Standard_Boolean pcurvefound = Standard_False; |
338 | |
339 | BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves()); |
340 | while (itcr.More()) { |
341 | const Handle(BRep_CurveRepresentation)& cr = itcr.Value(); |
342 | if (cr != myCref && cr->IsCurveOnSurface(Su,L)) { |
343 | pcurvefound = Standard_True; |
344 | const Handle(BRep_GCurve)& GC = *((Handle(BRep_GCurve)*)&cr); |
345 | Standard_Real f,l; |
346 | GC->Range(f,l); |
347 | if (SameRange && (f != First || l != Last)) { |
348 | return ;//BRepCheck_InvalidSameRangeFlag); |
349 | if (SameParameter) { |
350 | return; //BRepCheck_InvalidSameParameterFlag); |
351 | } |
352 | } |
353 | |
354 | Handle(Geom_Surface) Sb = cr->Surface(); |
355 | Sb = Handle(Geom_Surface)::DownCast (Su->Transformed(L.Transformation())); |
356 | Handle(Geom2d_Curve) PC = cr->PCurve(); |
357 | Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(Sb); |
358 | Handle(Geom2dAdaptor_HCurve) GHPC = new Geom2dAdaptor_HCurve(PC,f,l); |
359 | Adaptor3d_CurveOnSurface ACS(GHPC,GAHS); |
360 | ok = Validate(myHCurve->Curve(), ACS, Tol, SameParameter, aNewTol); |
361 | if (ok) { |
362 | if (cr->IsCurveOnClosedSurface()) { |
363 | //return ;// BRepCheck::Add(lst,BRepCheck_InvalidCurveOnClosedSurface); |
364 | } |
365 | else { |
366 | //return;//BRepCheck::Add(lst,BRepCheck_InvalidCurveOnSurface); |
367 | } |
368 | if (SameParameter) { |
369 | //return;//BRepCheck::Add(lst,BRepCheck_InvalidSameParameterFlag); |
370 | } |
371 | // |
372 | if (aNewTol<aMaxTol) { |
373 | TE->UpdateTolerance(aNewTol+Delta); |
374 | // |
375 | CorrectVertexTolerance(myShape); |
376 | } |
377 | } |
378 | |
379 | if (cr->IsCurveOnClosedSurface()) { |
380 | //checkclosed = Standard_True; |
381 | GHPC->ChangeCurve2d().Load(cr->PCurve2(),f,l); // same bounds |
382 | ACS.Load(GAHS); // sans doute inutile |
383 | ACS.Load(GHPC); // meme remarque... |
384 | ok = Validate(myHCurve->Curve(),ACS,Tol,SameParameter, aNewTol); |
385 | if (ok) { |
386 | //return;//BRepCheck::Add(lst,BRepCheck_InvalidCurveOnClosedSurface); |
387 | if (SameParameter) { |
388 | //return;//BRepCheck::Add(lst,BRepCheck_InvalidSameParameterFlag); |
389 | } |
390 | if (aNewTol<aMaxTol) { |
391 | TE->UpdateTolerance(aNewTol+Delta); |
392 | CorrectVertexTolerance(myShape); |
393 | } |
394 | } |
395 | } |
396 | } |
397 | itcr.Next(); |
398 | } |
399 | |
400 | if (!pcurvefound) { |
401 | Handle(Geom_Plane) P; |
402 | Handle(Standard_Type) styp = Su->DynamicType(); |
403 | if (styp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) { |
404 | P = Handle(Geom_Plane)::DownCast(Handle(Geom_RectangularTrimmedSurface):: |
405 | DownCast(Su)->BasisSurface()); |
406 | } |
407 | else { |
408 | P = Handle(Geom_Plane)::DownCast(Su); |
409 | } |
410 | if (P.IsNull()) { // not a plane |
411 | return;//BRepCheck::Add(lst,BRepCheck_NoCurveOnSurface); |
412 | } |
413 | |
414 | else {// on fait la projection a la volee, comme BRep_Tool |
415 | P = Handle(Geom_Plane)::DownCast(P->Transformed(L.Transformation())); |
416 | //on projette Cref sur ce plan |
417 | Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(P); |
418 | |
419 | // Dub - Normalement myHCurve est une GeomAdaptor_HCurve |
420 | GeomAdaptor_Curve& Gac = Handle(GeomAdaptor_HCurve)::DownCast(myHCurve)->ChangeCurve(); |
421 | Handle(Geom_Curve) C3dx = Gac.Curve(); |
422 | Handle(Geom_Curve) ProjOnPlane = GeomProjLib::ProjectOnPlane |
423 | (new Geom_TrimmedCurve(C3dx,First,Last), P, P->Position().Direction(), Standard_True); |
424 | |
425 | Handle(GeomAdaptor_HCurve) aHCurve = new GeomAdaptor_HCurve(ProjOnPlane); |
426 | |
427 | ProjLib_ProjectedCurve proj(GAHS,aHCurve); |
428 | Handle(Geom2d_Curve) PC = Geom2dAdaptor::MakeCurve(proj); |
429 | Handle(Geom2dAdaptor_HCurve) GHPC = |
430 | new Geom2dAdaptor_HCurve(PC, myHCurve->FirstParameter(), myHCurve->LastParameter()); |
431 | |
432 | Adaptor3d_CurveOnSurface ACS(GHPC,GAHS); |
433 | |
434 | Standard_Boolean okx = Validate(myHCurve->Curve(),ACS, |
435 | Tol,Standard_True, aNewTol); // voir dub... |
436 | if (okx) { |
437 | //return;//BRepCheck::Add(lst,BRepCheck_InvalidCurveOnSurface); |
438 | if (aNewTol<aMaxTol) { |
439 | TE->UpdateTolerance(aNewTol+Delta); |
440 | CorrectVertexTolerance(myShape); |
441 | } |
442 | } |
443 | } |
444 | |
445 | }//end of if (!pcurvefound) { |
446 | } // end of 2. Tolerances in InContext |
447 | |
448 | } |
449 | |
450 | //======================================================================= |
451 | // Function : CorrectShapeTolerances |
452 | // purpose : |
453 | //======================================================================= |
454 | void BOPTools_AlgoTools::CorrectShapeTolerances(const TopoDS_Shape& aShape) |
455 | { |
456 | TopExp_Explorer aExp; |
457 | Standard_Integer aDim; |
458 | // |
459 | aDim=Dimension(aShape); |
460 | if (aDim == 1) { |
461 | aExp.Init(aShape, TopAbs_EDGE); |
462 | for (; aExp.More(); aExp.Next()) { |
463 | const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current(); |
464 | UpdateVertices(aE); |
465 | } |
466 | } else { |
467 | aExp.Init(aShape, TopAbs_FACE); |
468 | for (; aExp.More(); aExp.Next()) { |
469 | const TopoDS_Face& aF = *(TopoDS_Face*)&aExp.Current(); |
470 | UpdateEdges(aF); |
471 | } |
472 | } |
473 | } |
474 | |
475 | //======================================================================= |
476 | //function : CorrectVertexTolerance |
477 | //purpose : |
478 | //======================================================================= |
479 | void CorrectVertexTolerance(const TopoDS_Edge& aE) |
480 | { |
481 | Standard_Integer k, aNbV; |
482 | Standard_Real aTolE, aTolV; |
483 | TopTools_IndexedMapOfShape aVMap; |
484 | |
485 | aTolE=BRep_Tool::Tolerance(aE); |
486 | |
487 | TopExp::MapShapes(aE, TopAbs_VERTEX, aVMap); |
488 | aNbV=aVMap.Extent(); |
489 | for (k=1; k<=aNbV; ++k) { |
490 | const TopoDS_Vertex& aV=TopoDS::Vertex(aVMap(k)); |
491 | aTolV=BRep_Tool::Tolerance(aV); |
492 | if (aTolV<aTolE) { |
493 | Handle(BRep_TVertex)& aTV = *((Handle(BRep_TVertex)*)&aV.TShape()); |
494 | aTV->UpdateTolerance(aTolE); |
495 | } |
496 | } |
497 | } |
498 | |
499 | #define NCONTROL 23 |
500 | //======================================================================= |
501 | //function : Validate |
502 | //purpose : |
503 | //======================================================================= |
504 | Standard_Boolean Validate(const Adaptor3d_Curve& CRef, |
505 | const Adaptor3d_Curve& Other, |
506 | const Standard_Real Tol, |
507 | const Standard_Boolean SameParameter, |
508 | Standard_Real& aNewTolerance) |
509 | { |
510 | Standard_Real First, Last, MaxDistance, aD, Tol2; |
511 | |
512 | First = CRef.FirstParameter(); |
513 | Last = CRef.LastParameter(); |
514 | MaxDistance = 0.; |
515 | Tol2 = Tol*Tol; |
516 | |
517 | Standard_Integer i, aNC1=NCONTROL-1; |
518 | |
519 | Standard_Boolean aFlag=Standard_False; |
520 | Standard_Boolean proj = (!SameParameter || |
521 | First != Other.FirstParameter() || |
522 | Last != Other.LastParameter()); |
523 | // |
524 | // 1. |
525 | if (!proj) { |
526 | for (i = 0; i < NCONTROL; i++) { |
527 | Standard_Real prm = ((aNC1-i)*First + i*Last)/aNC1; |
528 | gp_Pnt pref = CRef.Value(prm); |
529 | gp_Pnt pother = Other.Value(prm); |
530 | |
531 | aD=pref.SquareDistance(pother); |
532 | |
533 | if (aD > Tol2) { |
534 | if (aD>MaxDistance) { |
535 | MaxDistance=aD; |
536 | } |
537 | aFlag=Standard_True; |
538 | } |
539 | } |
540 | |
541 | if (aFlag) { |
542 | aNewTolerance=sqrt(MaxDistance); |
543 | } |
544 | return aFlag; |
545 | } |
546 | |
547 | // |
548 | // 2. |
549 | else { |
550 | Extrema_LocateExtPC refd,otherd; |
551 | Standard_Real OFirst, OLast; |
552 | OFirst = Other.FirstParameter(); |
553 | OLast = Other.LastParameter(); |
554 | |
555 | gp_Pnt pd = CRef.Value(First); |
556 | gp_Pnt pdo = Other.Value(OFirst); |
557 | |
558 | aD = pd.SquareDistance(pdo); |
559 | if (aD > Tol2) { |
560 | if (aD>MaxDistance) { |
561 | MaxDistance=aD; |
562 | } |
563 | aFlag=Standard_True; |
564 | } |
565 | |
566 | pd = CRef.Value(Last); |
567 | pdo = Other.Value(OLast); |
568 | aD = pd.SquareDistance(pdo); |
569 | if (aD > Tol2 && aD > MaxDistance) { |
570 | MaxDistance=aD; |
571 | aFlag=Standard_True; |
572 | } |
573 | |
574 | refd.Initialize(CRef, First, Last, CRef.Resolution(Tol)); |
575 | otherd.Initialize(Other, OFirst, OLast, Other.Resolution(Tol)); |
576 | |
577 | for (i = 2; i< aNC1; i++) { |
578 | Standard_Real rprm = ((aNC1-i)*First + i*Last)/aNC1; |
579 | gp_Pnt pref = CRef.Value(rprm); |
580 | |
581 | Standard_Real oprm = ((aNC1-i)*OFirst + i*OLast)/aNC1; |
582 | gp_Pnt pother = Other.Value(oprm); |
583 | |
584 | refd.Perform(pother,rprm); |
585 | if (!refd.IsDone() || refd.SquareDistance() > Tol2) { |
586 | if (refd.IsDone()) { |
587 | aD=refd.SquareDistance(); |
588 | if (aD > Tol2 && aD>MaxDistance) { |
589 | aFlag=Standard_True; |
590 | MaxDistance=aD; |
591 | } |
592 | } |
593 | } |
594 | |
595 | otherd.Perform(pref,oprm); |
596 | if (!otherd.IsDone() || otherd.SquareDistance() > Tol2) { |
597 | |
598 | if (otherd.IsDone()) { |
599 | aD=otherd.SquareDistance(); |
600 | if (aD > Tol2 && aD>MaxDistance) { |
601 | aFlag=Standard_True; |
602 | MaxDistance=aD; |
603 | } |
604 | } |
605 | } |
606 | } |
607 | } |
608 | |
609 | aD=sqrt (MaxDistance); |
610 | aNewTolerance=aD; |
611 | |
612 | return aFlag; |
613 | |
614 | } |
615 | |
616 | //======================================================================= |
617 | // Function : CheckEdge |
618 | // purpose : Correct tolerances for Vertices on Edge |
619 | //======================================================================= |
620 | void CheckEdge (const TopoDS_Edge& Ed, const Standard_Real aMaxTol) |
621 | { |
622 | TopoDS_Edge E=Ed; |
623 | E.Orientation(TopAbs_FORWARD); |
624 | |
625 | gp_Pnt Controlp; |
626 | |
627 | TopExp_Explorer aVExp; |
628 | aVExp.Init(E, TopAbs_VERTEX); |
629 | for (; aVExp.More(); aVExp.Next()) { |
630 | TopoDS_Vertex aVertex= TopoDS::Vertex(aVExp.Current()); |
631 | |
632 | Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &aVertex.TShape()); |
633 | const gp_Pnt& prep = TV->Pnt(); |
634 | |
635 | Standard_Real Tol, aD2, aNewTolerance, dd; |
636 | |
637 | Tol =BRep_Tool::Tolerance(aVertex); |
638 | Tol = Max(Tol, BRep_Tool::Tolerance(E)); |
639 | dd=0.1*Tol; |
640 | Tol*=Tol; |
641 | |
642 | const TopLoc_Location& Eloc = E.Location(); |
643 | BRep_ListIteratorOfListOfPointRepresentation itpr; |
644 | |
645 | Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&E.TShape()); |
646 | BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves()); |
647 | while (itcr.More()) { |
648 | const Handle(BRep_CurveRepresentation)& cr = itcr.Value(); |
649 | const TopLoc_Location& loc = cr->Location(); |
650 | TopLoc_Location L = (Eloc * loc).Predivided(aVertex.Location()); |
651 | |
652 | if (cr->IsCurve3D()) { |
653 | const Handle(Geom_Curve)& C = cr->Curve3D(); |
654 | if (!C.IsNull()) { |
655 | itpr.Initialize(TV->Points()); |
656 | while (itpr.More()) { |
657 | const Handle(BRep_PointRepresentation)& pr = itpr.Value(); |
658 | if (pr->IsPointOnCurve(C,L)) { |
659 | Controlp = C->Value(pr->Parameter()); |
660 | Controlp.Transform(L.Transformation()); |
661 | aD2=prep.SquareDistance(Controlp); |
662 | if (aD2 > Tol) { |
663 | aNewTolerance=sqrt(aD2)+dd; |
664 | if (aNewTolerance<aMaxTol) |
665 | TV->UpdateTolerance(aNewTolerance); |
666 | } |
667 | } |
668 | itpr.Next(); |
669 | } |
670 | |
671 | TopAbs_Orientation orv = aVertex.Orientation(); |
672 | if (orv == TopAbs_FORWARD || orv == TopAbs_REVERSED) { |
673 | const Handle(BRep_GCurve)& GC = *((Handle(BRep_GCurve)*)&cr); |
674 | |
675 | if (orv==TopAbs_FORWARD) |
676 | Controlp = C->Value(GC->First()); |
677 | else |
678 | Controlp = C->Value(GC->Last()); |
679 | |
680 | Controlp.Transform(L.Transformation()); |
681 | aD2=prep.SquareDistance(Controlp); |
682 | |
683 | if (aD2 > Tol) { |
684 | aNewTolerance=sqrt(aD2)+dd; |
685 | if (aNewTolerance<aMaxTol) |
686 | TV->UpdateTolerance(aNewTolerance); |
687 | } |
688 | } |
689 | } |
690 | } |
691 | itcr.Next(); |
692 | } |
693 | } |
694 | } |
695 | |
696 | //======================================================================= |
697 | // Function : UpdateVertices |
698 | // purpose : |
699 | //======================================================================= |
700 | void UpdateVertices(const TopoDS_Edge& aE) |
701 | { |
702 | Standard_Real aTolE, aTolV; |
703 | TopoDS_Iterator aItE; |
704 | BRep_Builder aBB; |
705 | // |
706 | aTolE = BRep_Tool::Tolerance(aE); |
707 | aItE.Initialize(aE); |
708 | for (; aItE.More(); aItE.Next()) { |
709 | const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aItE.Value(); |
710 | aTolV = BRep_Tool::Tolerance(aV); |
711 | if (aTolV < aTolE) { |
712 | aBB.UpdateVertex(aV, aTolE); |
713 | } |
714 | } |
715 | } |
716 | //======================================================================= |
717 | // Function : UpdateEdges |
718 | // purpose : |
719 | //======================================================================= |
720 | void UpdateEdges(const TopoDS_Face& aF) |
721 | { |
722 | Standard_Real aTolF, aTolE, aTolV; |
723 | TopoDS_Iterator aItF, aItW, aItE; |
724 | BRep_Builder aBB; |
725 | // |
726 | aTolF = BRep_Tool::Tolerance(aF); |
727 | aItF.Initialize(aF); |
728 | for (; aItF.More(); aItF.Next()) { |
729 | const TopoDS_Shape& aS = aItF.Value(); |
730 | if (aS.ShapeType()==TopAbs_WIRE) { |
731 | aItW.Initialize(aS); |
732 | for (; aItW.More(); aItW.Next()) { |
733 | const TopoDS_Edge& aE = *(TopoDS_Edge*)&aItW.Value(); |
734 | aTolE = BRep_Tool::Tolerance(aE); |
735 | if (aTolE < aTolF) { |
736 | aBB.UpdateEdge(aE, aTolF); |
737 | aTolE = aTolF; |
738 | } |
739 | UpdateVertices(aE); |
740 | } |
741 | } |
742 | else { |
743 | const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aItF.Value(); |
744 | aTolV = BRep_Tool::Tolerance(aV); |
745 | if (aTolV < aTolE) { |
746 | aBB.UpdateVertex(aV, aTolF); |
747 | } |
748 | } |
749 | } |
750 | } |