Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1995-12-11 |
2 | // Created by: Jacques GOUSSARD | |
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. | |
7fd59977 | 16 | |
52d45841 | 17 | |
42cf5bc1 | 18 | #include <Adaptor3d_CurveOnSurface.hxx> |
19 | #include <Adaptor3d_HCurve.hxx> | |
20 | #include <Adaptor3d_HCurveOnSurface.hxx> | |
52d45841 | 21 | #include <Bnd_Box.hxx> |
42cf5bc1 | 22 | #include <BRep_CurveOnSurface.hxx> |
7fd59977 | 23 | #include <BRep_CurveRepresentation.hxx> |
7fd59977 | 24 | #include <BRep_GCurve.hxx> |
42cf5bc1 | 25 | #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx> |
26 | #include <BRep_ListOfCurveRepresentation.hxx> | |
52d45841 | 27 | #include <BRep_PolygonOnTriangulation.hxx> |
42cf5bc1 | 28 | #include <BRep_TEdge.hxx> |
29 | #include <BRep_TFace.hxx> | |
7fd59977 | 30 | #include <BRep_Tool.hxx> |
42cf5bc1 | 31 | #include <BRepAdaptor_Curve.hxx> |
32 | #include <BRepCheck.hxx> | |
33 | #include <BRepCheck_Edge.hxx> | |
34 | #include <BRepCheck_ListIteratorOfListOfStatus.hxx> | |
35 | #include <BRepCheck_ListOfStatus.hxx> | |
36 | #include <Extrema_LocateExtPC.hxx> | |
7fd59977 | 37 | #include <Geom2d_Curve.hxx> |
42cf5bc1 | 38 | #include <Geom2dAdaptor.hxx> |
7fd59977 | 39 | #include <Geom2dAdaptor_HCurve.hxx> |
42cf5bc1 | 40 | #include <Geom_Curve.hxx> |
41 | #include <Geom_Plane.hxx> | |
42 | #include <Geom_RectangularTrimmedSurface.hxx> | |
43 | #include <Geom_Surface.hxx> | |
44 | #include <Geom_TrimmedCurve.hxx> | |
7fd59977 | 45 | #include <GeomAdaptor_Curve.hxx> |
46 | #include <GeomAdaptor_HCurve.hxx> | |
47 | #include <GeomAdaptor_HSurface.hxx> | |
7fd59977 | 48 | #include <GeomProjLib.hxx> |
52d45841 | 49 | #include <Poly_PolygonOnTriangulation.hxx> |
50 | #include <Poly_Triangulation.hxx> | |
42cf5bc1 | 51 | #include <Precision.hxx> |
52 | #include <ProjLib_ProjectedCurve.hxx> | |
53 | #include <Standard_Type.hxx> | |
54 | #include <TColStd_Array1OfTransient.hxx> | |
55 | #include <TColStd_HArray1OfReal.hxx> | |
56 | #include <TopAbs_ShapeEnum.hxx> | |
57 | #include <TopExp_Explorer.hxx> | |
58 | #include <TopoDS.hxx> | |
59 | #include <TopoDS_Edge.hxx> | |
60 | #include <TopoDS_Face.hxx> | |
61 | #include <TopoDS_Shape.hxx> | |
7fd59977 | 62 | |
92efcf78 | 63 | IMPLEMENT_STANDARD_RTTIEXT(BRepCheck_Edge,BRepCheck_Result) |
64 | ||
171d8cd9 P |
65 | //modified by NIZNHY-PKV Thu May 05 09:01:57 2011f |
66 | static | |
67 | Standard_Boolean Validate(const Adaptor3d_Curve&, | |
b7723347 | 68 | const Adaptor3d_CurveOnSurface&, |
69 | const Standard_Real, | |
70 | const Standard_Boolean); | |
171d8cd9 P |
71 | static |
72 | void PrintProblematicPoint(const gp_Pnt&, | |
b7723347 | 73 | const Standard_Real, |
74 | const Standard_Real); | |
171d8cd9 P |
75 | |
76 | static | |
77 | Standard_Real Prec(const Adaptor3d_Curve& aAC3D, | |
b7723347 | 78 | const Adaptor3d_CurveOnSurface& aACS); |
171d8cd9 P |
79 | static |
80 | Standard_Real PrecCurve(const Adaptor3d_Curve& aAC3D); | |
81 | static | |
82 | Standard_Real PrecSurface(const Adaptor3d_CurveOnSurface& aACS); | |
83 | ||
84 | //static Standard_Boolean Validate(const Adaptor3d_Curve&, | |
85 | // const Adaptor3d_Curve&, | |
86 | // const Standard_Real, | |
87 | // const Standard_Boolean); | |
88 | //modified by NIZNHY-PKV Thu May 05 09:02:01 2011t | |
7fd59977 | 89 | |
52d45841 | 90 | static const Standard_Integer NCONTROL=23; |
7fd59977 | 91 | |
92 | //======================================================================= | |
93 | //function : BRepCheck_Edge | |
94 | //purpose : | |
95 | //======================================================================= | |
96 | ||
97 | BRepCheck_Edge::BRepCheck_Edge(const TopoDS_Edge& E) | |
98 | { | |
99 | Init(E); | |
100 | myGctrl = Standard_True; | |
101 | } | |
102 | ||
103 | //======================================================================= | |
104 | //function : Minimum | |
105 | //purpose : | |
106 | //======================================================================= | |
107 | ||
108 | void BRepCheck_Edge::Minimum() | |
109 | { | |
110 | ||
111 | if (!myMin) { | |
112 | BRepCheck_ListOfStatus thelist; | |
113 | myMap.Bind(myShape, thelist); | |
114 | BRepCheck_ListOfStatus& lst = myMap(myShape); | |
115 | myCref.Nullify(); | |
116 | ||
117 | // Existence et unicite d`une representation 3D | |
118 | Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&myShape.TShape()); | |
119 | BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves()); | |
120 | Standard_Boolean exist = Standard_False; | |
121 | Standard_Boolean unique = Standard_True; | |
122 | // Search for a 3D reference. If no existent one, creates it with the | |
123 | // first encountered CurveOnSurf; if multiple, chooses the first one... | |
b7723347 | 124 | |
7fd59977 | 125 | Standard_Boolean Degenerated = TE->Degenerated(); |
126 | Standard_Boolean SameParameter = TE->SameParameter(); | |
127 | Standard_Boolean SameRange = TE->SameRange(); | |
128 | if (!SameRange && SameParameter) { | |
129 | BRepCheck::Add(lst,BRepCheck_InvalidSameParameterFlag); | |
130 | } | |
b7723347 | 131 | // Handle(Geom_Curve) C3d; |
7fd59977 | 132 | |
133 | while (itcr.More()) { | |
134 | const Handle(BRep_CurveRepresentation)& cr = itcr.Value(); | |
135 | if (cr->IsCurve3D()) { | |
b7723347 | 136 | if (!exist) { |
137 | exist = Standard_True; | |
138 | } | |
139 | else { | |
140 | unique = Standard_False; | |
141 | } | |
142 | if (myCref.IsNull() && !cr->Curve3D().IsNull()) { | |
143 | myCref = cr; | |
144 | } | |
7fd59977 | 145 | } |
146 | itcr.Next(); | |
147 | } | |
148 | ||
149 | if (!exist) { | |
150 | BRepCheck::Add(lst,BRepCheck_No3DCurve); | |
151 | // myCref est nulle | |
152 | } | |
153 | else if (!unique) { | |
154 | BRepCheck::Add(lst,BRepCheck_Multiple3DCurve); | |
155 | } | |
156 | ||
157 | if (myCref.IsNull() && !Degenerated) { | |
158 | itcr.Initialize(TE->Curves()); | |
159 | while (itcr.More()) { | |
b7723347 | 160 | const Handle(BRep_CurveRepresentation)& cr = itcr.Value(); |
161 | if (cr->IsCurveOnSurface()) { | |
162 | myCref = cr; | |
163 | break; | |
164 | } | |
165 | itcr.Next(); | |
7fd59977 | 166 | } |
167 | } | |
168 | else if (!myCref.IsNull() && Degenerated){ | |
169 | BRepCheck::Add(lst,BRepCheck_InvalidDegeneratedFlag); | |
170 | } | |
171 | ||
172 | if (!myCref.IsNull()) { | |
c5f3a425 | 173 | Handle(BRep_GCurve) GCref (Handle(BRep_GCurve)::DownCast (myCref)); |
7fd59977 | 174 | Standard_Real First,Last; |
175 | GCref->Range(First,Last); | |
176 | if (Last<=First) { | |
b7723347 | 177 | myCref.Nullify(); |
178 | BRepCheck::Add(lst,BRepCheck_InvalidRange); | |
7fd59977 | 179 | } |
180 | else { | |
b7723347 | 181 | if (myCref->IsCurve3D()) { |
7fd59977 | 182 | // eap 6 Jun 2002 occ332 |
183 | // better transform C3d instead of transforming Surf upto C3d initial location, | |
184 | // on transformed BSpline surface 'same parameter' may seem wrong | |
185 | TopLoc_Location L = myShape.Location() * myCref->Location(); | |
b7723347 | 186 | Handle(Geom_Curve) C3d = Handle(Geom_Curve)::DownCast |
187 | (myCref->Curve3D()->Transformed | |
188 | (/*myCref->Location()*/L.Transformation())); | |
189 | GeomAdaptor_Curve GAC3d(C3d, C3d->TransformedParameter(First, L.Transformation()), | |
190 | C3d->TransformedParameter(Last, L.Transformation())); | |
191 | myHCurve = new GeomAdaptor_HCurve(GAC3d); | |
192 | } | |
193 | else { // curve on surface | |
194 | Handle(Geom_Surface) Sref = myCref->Surface(); | |
195 | Sref = Handle(Geom_Surface)::DownCast | |
196 | (Sref->Transformed(myCref->Location().Transformation())); | |
197 | const Handle(Geom2d_Curve)& PCref = myCref->PCurve(); | |
198 | Handle(GeomAdaptor_HSurface) GAHSref = new GeomAdaptor_HSurface(Sref); | |
199 | Handle(Geom2dAdaptor_HCurve) GHPCref = | |
200 | new Geom2dAdaptor_HCurve(PCref,First,Last); | |
201 | Adaptor3d_CurveOnSurface ACSref(GHPCref,GAHSref); | |
202 | myHCurve = new Adaptor3d_HCurveOnSurface(ACSref); | |
203 | } | |
7fd59977 | 204 | } |
205 | } | |
206 | if (lst.IsEmpty()) { | |
207 | lst.Append(BRepCheck_NoError); | |
208 | } | |
209 | myMin = Standard_True; | |
210 | } | |
211 | } | |
212 | ||
213 | ||
214 | //======================================================================= | |
215 | //function : InContext | |
216 | //purpose : | |
217 | //======================================================================= | |
218 | ||
219 | void BRepCheck_Edge::InContext(const TopoDS_Shape& S) | |
220 | { | |
221 | if (myMap.IsBound(S)) { | |
222 | return; | |
223 | } | |
224 | BRepCheck_ListOfStatus thelist; | |
225 | myMap.Bind(S, thelist); | |
226 | BRepCheck_ListOfStatus& lst = myMap(S); | |
227 | ||
228 | Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&myShape.TShape()); | |
229 | Standard_Real Tol = BRep_Tool::Tolerance(TopoDS::Edge(myShape)); | |
230 | ||
231 | TopAbs_ShapeEnum styp = S.ShapeType(); | |
b7723347 | 232 | // for (TopExp_Explorer exp(S,TopAbs_EDGE); exp.More(); exp.Next()) { |
7fd59977 | 233 | TopExp_Explorer exp(S,TopAbs_EDGE) ; |
234 | for ( ; exp.More(); exp.Next()) { | |
235 | if (exp.Current().IsSame(myShape)) { | |
236 | break; | |
237 | } | |
238 | } | |
239 | if (!exp.More()) { | |
240 | BRepCheck::Add(lst,BRepCheck_SubshapeNotInShape); | |
241 | return; | |
242 | } | |
b7723347 | 243 | |
52d45841 | 244 | switch (styp) |
245 | { | |
246 | case TopAbs_WIRE: | |
247 | { | |
248 | } | |
249 | break; | |
250 | ||
7fd59977 | 251 | case TopAbs_FACE: |
252 | if (!myCref.IsNull()) { | |
b7723347 | 253 | |
7fd59977 | 254 | Standard_Boolean SameParameter = TE->SameParameter(); |
255 | Standard_Boolean SameRange = TE->SameRange(); | |
b7723347 | 256 | // Modified by skv - Tue Apr 27 11:48:13 2004 Begin |
7fd59977 | 257 | if (!SameParameter || !SameRange) { |
b7723347 | 258 | if (!SameParameter) |
259 | BRepCheck::Add(lst,BRepCheck_InvalidSameParameterFlag); | |
260 | if (!SameRange) | |
261 | BRepCheck::Add(lst,BRepCheck_InvalidSameRangeFlag); | |
7fd59977 | 262 | |
b7723347 | 263 | return; |
7fd59977 | 264 | } |
b7723347 | 265 | // Modified by skv - Tue Apr 27 11:48:14 2004 End |
7fd59977 | 266 | Standard_Real First = myHCurve->FirstParameter(); |
267 | Standard_Real Last = myHCurve->LastParameter(); | |
268 | ||
269 | Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &S.TShape()); | |
270 | const TopLoc_Location& Floc = S.Location(); | |
271 | const TopLoc_Location& TFloc = TF->Location(); | |
272 | const Handle(Geom_Surface)& Su = TF->Surface(); | |
273 | TopLoc_Location L = (Floc * TFloc).Predivided(myShape.Location()); | |
b7723347 | 274 | TopLoc_Location LE = myShape.Location() * myCref->Location(); |
275 | const gp_Trsf& Etrsf = LE.Transformation(); | |
7fd59977 | 276 | Standard_Boolean pcurvefound = Standard_False; |
277 | ||
278 | BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves()); | |
279 | while (itcr.More()) { | |
b7723347 | 280 | const Handle(BRep_CurveRepresentation)& cr = itcr.Value(); |
281 | if (cr != myCref && cr->IsCurveOnSurface(Su,L)) { | |
282 | pcurvefound = Standard_True; | |
c5f3a425 | 283 | Handle(BRep_GCurve) GC (Handle(BRep_GCurve)::DownCast (cr)); |
b7723347 | 284 | Standard_Real f,l; |
285 | GC->Range(f,l); | |
286 | Standard_Real ff = f, ll = l; | |
287 | if(myCref->IsCurve3D()) | |
288 | { | |
289 | ff = myCref->Curve3D()->TransformedParameter(f, Etrsf); | |
290 | ll = myCref->Curve3D()->TransformedParameter(l, Etrsf); | |
291 | } | |
7fd59977 | 292 | // gka OCC |
b7723347 | 293 | // Modified by skv - Tue Apr 27 11:50:35 2004 Begin |
294 | if (Abs(ff-First) > Precision::PConfusion() || | |
295 | Abs(ll-Last) > Precision::PConfusion()) { | |
296 | BRepCheck::Add(lst,BRepCheck_InvalidSameRangeFlag); | |
297 | BRepCheck::Add(lst,BRepCheck_InvalidSameParameterFlag); | |
298 | } | |
299 | // Modified by skv - Tue Apr 27 11:50:37 2004 End | |
300 | if (myGctrl) { | |
301 | Handle(Geom_Surface) Sb = cr->Surface(); | |
302 | Sb = Handle(Geom_Surface)::DownCast | |
303 | // (Su->Transformed(L.Transformation())); | |
304 | (Su->Transformed(/*L*/(Floc * TFloc).Transformation())); | |
305 | Handle(Geom2d_Curve) PC = cr->PCurve(); | |
306 | Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(Sb); | |
307 | Handle(Geom2dAdaptor_HCurve) GHPC = new Geom2dAdaptor_HCurve(PC,f,l); | |
308 | Adaptor3d_CurveOnSurface ACS(GHPC,GAHS); | |
309 | Standard_Boolean ok = | |
310 | Validate(myHCurve->Curve() ,ACS,Tol,SameParameter); | |
311 | if (!ok) { | |
312 | if (cr->IsCurveOnClosedSurface()) { | |
313 | BRepCheck::Add(lst,BRepCheck_InvalidCurveOnClosedSurface); | |
314 | } | |
315 | else { | |
316 | BRepCheck::Add(lst,BRepCheck_InvalidCurveOnSurface); | |
317 | } | |
318 | // Modified by skv - Tue Apr 27 11:53:00 2004 Begin | |
319 | BRepCheck::Add(lst,BRepCheck_InvalidSameParameterFlag); | |
320 | // if (SameParameter) { | |
321 | // BRepCheck::Add(lst,BRepCheck_InvalidSameParameterFlag); | |
322 | // } | |
323 | // Modified by skv - Tue Apr 27 11:53:01 2004 End | |
324 | } | |
325 | if (cr->IsCurveOnClosedSurface()) { | |
326 | GHPC->ChangeCurve2d().Load(cr->PCurve2(),f,l); // same bounds | |
543a9964 | 327 | ACS.Load(GHPC, GAHS); // sans doute inutile |
b7723347 | 328 | ok = Validate(myHCurve->Curve(),ACS,Tol,SameParameter); |
329 | if (!ok) { | |
330 | BRepCheck::Add(lst,BRepCheck_InvalidCurveOnClosedSurface); | |
331 | // Modified by skv - Tue Apr 27 11:53:20 2004 Begin | |
332 | if (SameParameter) { | |
333 | BRepCheck::Add(lst,BRepCheck_InvalidSameParameterFlag); | |
334 | } | |
335 | // Modified by skv - Tue Apr 27 11:53:23 2004 End | |
336 | } | |
337 | } | |
338 | } | |
339 | } | |
340 | itcr.Next(); | |
7fd59977 | 341 | } |
342 | ||
343 | if (!pcurvefound) { | |
b7723347 | 344 | Handle(Geom_Plane) P; |
345 | Handle(Standard_Type) dtyp = Su->DynamicType(); | |
346 | if (dtyp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) { | |
347 | P = Handle(Geom_Plane)::DownCast | |
348 | (Handle(Geom_RectangularTrimmedSurface):: | |
349 | DownCast(Su)->BasisSurface()); | |
350 | } | |
351 | else { | |
352 | P = Handle(Geom_Plane)::DownCast(Su); | |
353 | } | |
354 | if (P.IsNull()) { // not a plane | |
355 | BRepCheck::Add(lst,BRepCheck_NoCurveOnSurface); | |
356 | } | |
357 | else { // on fait la projection a la volee, comme BRep_Tool | |
358 | // plan en position | |
359 | if (myGctrl) { | |
360 | P = Handle(Geom_Plane):: | |
361 | DownCast(P->Transformed(/*L*/(Floc * TFloc).Transformation()));// eap occ332 | |
362 | //on projette Cref sur ce plan | |
363 | Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(P); | |
364 | ||
365 | // Dub - Normalement myHCurve est une GeomAdaptor_HCurve | |
366 | GeomAdaptor_Curve& Gac = | |
367 | Handle(GeomAdaptor_HCurve)::DownCast(myHCurve)->ChangeCurve(); | |
368 | Handle(Geom_Curve) C3d = Gac.Curve(); | |
369 | Handle(Geom_Curve) ProjOnPlane = | |
370 | GeomProjLib::ProjectOnPlane(new Geom_TrimmedCurve(C3d,First,Last), | |
371 | P, P->Position().Direction(), | |
372 | Standard_True); | |
373 | Handle(GeomAdaptor_HCurve) aHCurve = | |
374 | new GeomAdaptor_HCurve(ProjOnPlane); | |
375 | ||
376 | ProjLib_ProjectedCurve proj(GAHS,aHCurve); | |
377 | Handle(Geom2d_Curve) PC = Geom2dAdaptor::MakeCurve(proj); | |
378 | Handle(Geom2dAdaptor_HCurve) GHPC = | |
379 | new Geom2dAdaptor_HCurve(PC, | |
380 | myHCurve->FirstParameter(), | |
381 | myHCurve->LastParameter()); | |
382 | ||
383 | Adaptor3d_CurveOnSurface ACS(GHPC,GAHS); | |
384 | ||
385 | Standard_Boolean ok = Validate(myHCurve->Curve(),ACS, | |
386 | Tol,Standard_True); // voir dub... | |
387 | if (!ok) { | |
388 | BRepCheck::Add(lst,BRepCheck_InvalidCurveOnSurface); | |
389 | } | |
390 | } | |
391 | } | |
7fd59977 | 392 | } |
393 | } | |
394 | break; | |
395 | case TopAbs_SOLID: | |
396 | { | |
397 | // on verifie que l`edge est bien connectee 2 fois (pas de bord libre) | |
398 | Standard_Integer nbconnection = 0; | |
399 | //TopExp_Explorer exp; | |
400 | for (exp.Init(S,TopAbs_FACE); exp.More(); exp.Next()) { | |
b7723347 | 401 | const TopoDS_Face& fac = TopoDS::Face(exp.Current()); |
402 | TopExp_Explorer exp2; | |
403 | for (exp2.Init(fac,TopAbs_EDGE); exp2.More(); exp2.Next()) { | |
404 | if (exp2.Current().IsSame(myShape)) { | |
405 | nbconnection++; | |
406 | } | |
407 | } | |
7fd59977 | 408 | } |
409 | if (nbconnection < 2 && !TE->Degenerated()) { | |
b7723347 | 410 | BRepCheck::Add(myMap(S),BRepCheck_FreeEdge); |
7fd59977 | 411 | } |
412 | else if (nbconnection > 2) { | |
b7723347 | 413 | BRepCheck::Add(myMap(S),BRepCheck_InvalidMultiConnexity); |
7fd59977 | 414 | } |
415 | else { | |
b7723347 | 416 | BRepCheck::Add(myMap(S),BRepCheck_NoError); |
7fd59977 | 417 | } |
418 | } | |
419 | break; | |
420 | default: | |
421 | break; | |
422 | } | |
423 | if (myMap(S).IsEmpty()) { | |
424 | myMap(S).Append(BRepCheck_NoError); | |
425 | } | |
426 | } | |
427 | ||
428 | ||
429 | //======================================================================= | |
430 | //function : Blind | |
431 | //purpose : | |
432 | //======================================================================= | |
433 | ||
434 | void BRepCheck_Edge::Blind() | |
435 | { | |
b7723347 | 436 | // Modified by skv - Tue Apr 27 11:36:01 2004 Begin |
437 | // The body of this function is removed because of its useless. | |
7fd59977 | 438 | if (!myBlind) { |
439 | myBlind = Standard_True; | |
440 | } | |
b7723347 | 441 | // Modified by skv - Tue Apr 27 11:36:02 2004 End |
7fd59977 | 442 | } |
443 | ||
444 | ||
445 | //======================================================================= | |
446 | //function : GeometricControls | |
447 | //purpose : | |
448 | //======================================================================= | |
449 | ||
450 | void BRepCheck_Edge::GeometricControls(const Standard_Boolean B) | |
451 | { | |
452 | myGctrl = B; | |
453 | } | |
454 | ||
455 | ||
456 | //======================================================================= | |
457 | //function : GeometricControls | |
458 | //purpose : | |
459 | //======================================================================= | |
460 | ||
461 | Standard_Boolean BRepCheck_Edge::GeometricControls() const | |
462 | { | |
463 | return myGctrl; | |
464 | } | |
465 | ||
52d45841 | 466 | //======================================================================= |
467 | //function : SetStatus | |
468 | //purpose : | |
469 | //======================================================================= | |
470 | void BRepCheck_Edge::SetStatus(const BRepCheck_Status theStatus) | |
471 | { | |
b7723347 | 472 | BRepCheck::Add(myMap(myShape),theStatus); |
52d45841 | 473 | } |
7fd59977 | 474 | |
475 | ||
476 | //======================================================================= | |
477 | //function : Tolerance | |
478 | //purpose : | |
479 | //======================================================================= | |
480 | ||
481 | Standard_Real BRepCheck_Edge::Tolerance() | |
482 | { | |
483 | Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&myShape.TShape()); | |
484 | Standard_Integer it, iRep=1, nbRep=(TE->Curves()).Extent(); | |
485 | if (nbRep<=1) { | |
486 | return Precision::Confusion(); | |
487 | } | |
488 | TColStd_Array1OfTransient theRep(1, nbRep*2); | |
489 | Standard_Real First, Last; | |
490 | if (!myHCurve.IsNull()) { | |
491 | First = myHCurve->FirstParameter(); | |
492 | Last= myHCurve->LastParameter(); | |
493 | } | |
494 | else { | |
495 | BRep_Tool::Range(TopoDS::Edge(myShape), First, Last); | |
496 | } | |
497 | ||
498 | BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves()); | |
499 | for (; itcr.More(); itcr.Next()) { | |
500 | const Handle(BRep_CurveRepresentation)& cr = itcr.Value(); | |
501 | if (cr->IsCurve3D() && !TE->Degenerated()) { | |
502 | //// modified by jgv, 20.03.03 //// | |
503 | TopLoc_Location Loc = myShape.Location() * cr->Location(); | |
504 | Handle(Geom_Curve) C3d = Handle(Geom_Curve)::DownCast | |
b7723347 | 505 | (cr->Curve3D()->Transformed( Loc.Transformation() )); |
7fd59977 | 506 | /////////////////////////////////// |
507 | GeomAdaptor_Curve GAC3d(C3d,First,Last); | |
508 | it=iRep; | |
509 | if (iRep>1) { | |
b7723347 | 510 | theRep(iRep)=theRep(1); |
511 | it=1; | |
7fd59977 | 512 | } |
513 | theRep(it) = new GeomAdaptor_HCurve(GAC3d); | |
514 | iRep++; | |
515 | } | |
516 | else if (cr->IsCurveOnSurface()) { | |
517 | { | |
518 | Handle(Geom_Surface) Sref = cr->Surface(); | |
b7723347 | 519 | //// modified by jgv, 20.03.03 //// |
520 | TopLoc_Location Loc = myShape.Location() * cr->Location(); | |
7fd59977 | 521 | Sref = Handle(Geom_Surface)::DownCast |
522 | (Sref->Transformed( Loc.Transformation() )); | |
b7723347 | 523 | /////////////////////////////////// |
7fd59977 | 524 | const Handle(Geom2d_Curve)& PCref = cr->PCurve(); |
525 | Handle(GeomAdaptor_HSurface) GAHSref = new GeomAdaptor_HSurface(Sref); | |
526 | Handle(Geom2dAdaptor_HCurve) GHPCref = | |
527 | new Geom2dAdaptor_HCurve(PCref,First,Last); | |
528 | Adaptor3d_CurveOnSurface ACSref(GHPCref,GAHSref); | |
529 | theRep(iRep) = new Adaptor3d_HCurveOnSurface(ACSref); | |
530 | iRep++; | |
531 | } | |
532 | if (cr->IsCurveOnClosedSurface()) { | |
b7723347 | 533 | Handle(Geom_Surface) Sref = cr->Surface(); |
534 | Sref = Handle(Geom_Surface)::DownCast | |
535 | (Sref->Transformed(cr->Location().Transformation())); | |
536 | const Handle(Geom2d_Curve)& PCref = cr->PCurve2(); | |
537 | Handle(GeomAdaptor_HSurface) GAHSref = new GeomAdaptor_HSurface(Sref); | |
538 | Handle(Geom2dAdaptor_HCurve) GHPCref = | |
539 | new Geom2dAdaptor_HCurve(PCref,First,Last); | |
540 | Adaptor3d_CurveOnSurface ACSref(GHPCref,GAHSref); | |
541 | theRep(iRep) = new Adaptor3d_HCurveOnSurface(ACSref); | |
542 | iRep++; | |
543 | nbRep++; | |
7fd59977 | 544 | } |
545 | } | |
546 | else { | |
547 | nbRep--; | |
548 | } | |
549 | } | |
550 | ||
551 | Standard_Real dist2, tol2, tolCal=0., prm; | |
552 | gp_Pnt center, othP; | |
96a95605 | 553 | Standard_Integer i; |
7fd59977 | 554 | for (i= 0; i< NCONTROL; i++) { |
555 | prm = ((NCONTROL-1-i)*First + i*Last)/(NCONTROL-1); | |
556 | tol2=dist2=0.; | |
557 | center=(*(Handle(Adaptor3d_HCurve)*)&theRep(1))->Value(prm); | |
558 | for (iRep=2; iRep<=nbRep; iRep++) { | |
559 | othP=(*(Handle(Adaptor3d_HCurve)*)&theRep(iRep))->Value(prm); | |
560 | dist2=center.SquareDistance(othP); | |
561 | if (dist2>tolCal) tolCal=dist2; | |
562 | } | |
563 | if (tol2>tolCal) { | |
564 | tolCal=tol2; | |
7fd59977 | 565 | } |
566 | } | |
567 | // On prend 5% de marge car au dessus on crontrole severement | |
568 | return sqrt(tolCal)*1.05; | |
569 | } | |
171d8cd9 | 570 | |
52d45841 | 571 | |
572 | //======================================================================= | |
573 | //function : CheckPolygonOnTriangulation | |
574 | //purpose : | |
575 | //======================================================================= | |
576 | BRepCheck_Status BRepCheck_Edge:: | |
b7723347 | 577 | CheckPolygonOnTriangulation(const TopoDS_Edge& theEdge) |
52d45841 | 578 | { |
579 | BRep_ListOfCurveRepresentation& aListOfCR = | |
b7723347 | 580 | (*((Handle(BRep_TEdge)*) &theEdge.TShape()))->ChangeCurves(); |
52d45841 | 581 | BRep_ListIteratorOfListOfCurveRepresentation anITCR(aListOfCR); |
582 | ||
583 | BRepAdaptor_Curve aBC; | |
584 | aBC.Initialize(theEdge); | |
585 | ||
586 | if(!aBC.Is3DCurve()) | |
587 | return BRepCheck_NoError; | |
588 | ||
589 | while (anITCR.More()) | |
590 | { | |
591 | if(!anITCR.Value()->IsPolygonOnTriangulation()) | |
592 | { | |
593 | anITCR.Next(); | |
594 | continue; | |
595 | } | |
596 | ||
597 | const Handle(BRep_CurveRepresentation) aCR = anITCR.Value(); | |
c5f3a425 | 598 | Handle(BRep_PolygonOnTriangulation) aPT (Handle(BRep_PolygonOnTriangulation)::DownCast(aCR)); |
52d45841 | 599 | |
600 | const TopLoc_Location aLL = theEdge.Location() * aPT->Location(); | |
601 | ||
602 | const Handle(Poly_Triangulation) aTriang = aCR->Triangulation(); | |
603 | const Handle(Poly_PolygonOnTriangulation) aPOnTriag = | |
b7723347 | 604 | aCR->IsPolygonOnClosedTriangulation() ? |
605 | aCR->PolygonOnTriangulation2() : | |
606 | aCR->PolygonOnTriangulation(); | |
52d45841 | 607 | const TColStd_Array1OfInteger& anIndices = aPOnTriag->Nodes(); |
608 | const TColgp_Array1OfPnt& Nodes = aTriang->Nodes(); | |
609 | const Standard_Integer aNbNodes = anIndices.Length(); | |
610 | ||
611 | const Standard_Real aTol = aPOnTriag->Deflection() + | |
b7723347 | 612 | BRep_Tool::Tolerance(theEdge); |
52d45841 | 613 | |
614 | if(aPOnTriag->HasParameters()) | |
615 | { | |
616 | for(Standard_Integer i = aPOnTriag->Parameters()->Lower(); | |
b7723347 | 617 | i <= aPOnTriag->Parameters()->Upper(); i++) |
52d45841 | 618 | { |
619 | const Standard_Real aParam = aPOnTriag->Parameters()->Value(i); | |
620 | const gp_Pnt aPE(aBC.Value(aParam)), | |
51740958 | 621 | aPnt(Nodes(anIndices(i)).Transformed(aLL)); |
52d45841 | 622 | |
51740958 | 623 | const Standard_Real aSQDist = aPE.SquareDistance(aPnt); |
52d45841 | 624 | if(aSQDist > aTol*aTol) |
625 | { | |
626 | return BRepCheck_InvalidPolygonOnTriangulation; | |
627 | } | |
628 | } | |
629 | } | |
630 | else | |
631 | { | |
632 | //If aPOnTriag does not have any parameters we will check if it | |
633 | //inscribes into Bounding box, which is built on the edge triangulation. | |
634 | ||
635 | Bnd_Box aB; | |
636 | ||
637 | for (Standard_Integer i = 1; i <= aNbNodes; i++) | |
638 | { | |
639 | if (aLL.IsIdentity()) | |
640 | aB.Add(Nodes(anIndices(i))); | |
641 | else | |
642 | aB.Add(Nodes(anIndices(i)).Transformed(aLL)); | |
643 | } | |
644 | ||
645 | aB.Enlarge(aTol); | |
646 | ||
647 | Standard_Real aFP = aBC.FirstParameter(); | |
648 | Standard_Real aLP = aBC.LastParameter(); | |
649 | ||
650 | const Standard_Real aStep = (aLP - aFP)/IntToReal(NCONTROL); | |
651 | gp_Pnt aP; | |
652 | Standard_Real aPar = aFP; | |
653 | ||
654 | for(Standard_Integer i = 1; i < NCONTROL; i ++) | |
655 | { | |
656 | aBC.D0(aPar, aP); | |
657 | if(aB.IsOut(aP)) | |
658 | { | |
659 | return BRepCheck_InvalidPolygonOnTriangulation; | |
660 | } | |
661 | ||
662 | aPar += aStep; | |
663 | } | |
664 | ||
665 | aBC.D0(aLP, aP); | |
666 | if(aB.IsOut(aP)) | |
667 | { | |
668 | return BRepCheck_InvalidPolygonOnTriangulation; | |
669 | } | |
670 | } | |
671 | ||
672 | anITCR.Next(); | |
673 | } | |
674 | ||
675 | return BRepCheck_NoError; | |
676 | } | |
677 | ||
171d8cd9 P |
678 | //======================================================================= |
679 | //function : Validate | |
680 | //purpose : | |
681 | //======================================================================= | |
682 | Standard_Boolean Validate(const Adaptor3d_Curve& CRef, | |
b7723347 | 683 | const Adaptor3d_CurveOnSurface& Other, |
684 | const Standard_Real Tol, | |
685 | const Standard_Boolean SameParameter) | |
171d8cd9 P |
686 | { |
687 | Standard_Boolean Status, proj; | |
688 | Standard_Real aPC, First, Last, Error; | |
689 | gp_Pnt problematic_point ; | |
690 | // | |
691 | Status = Standard_True; | |
692 | Error = 0.; | |
693 | First = CRef.FirstParameter(); | |
694 | Last = CRef.LastParameter(); | |
b7723347 | 695 | |
171d8cd9 P |
696 | aPC=Precision::PConfusion(); |
697 | proj = (!SameParameter || | |
b7723347 | 698 | Abs(Other.FirstParameter()-First) > aPC || |
699 | Abs( Other.LastParameter()-Last) > aPC); | |
52d45841 | 700 | if (!proj) |
701 | { | |
171d8cd9 | 702 | Standard_Integer i; |
6e6cd5d9 | 703 | Standard_Real Tol2, prm, dD; |
171d8cd9 P |
704 | gp_Pnt pref, pother; |
705 | //modified by NIZNHY-PKV Thu May 05 09:06:41 2011f | |
706 | //OCC22428 | |
707 | dD=Prec(CRef, Other);//3.e-15; | |
708 | Tol2=Tol+dD; | |
709 | Tol2=Tol2*Tol2; | |
710 | //Tol2=Tol*Tol; | |
711 | //modified by NIZNHY-PKV Thu May 05 09:06:47 2011t | |
b7723347 | 712 | |
52d45841 | 713 | for (i = 0; i < NCONTROL; ++i) { |
171d8cd9 P |
714 | prm = ((NCONTROL-1-i)*First + i*Last)/(NCONTROL-1); |
715 | pref = CRef.Value(prm); | |
716 | pother = Other.Value(prm); | |
717 | if (pref.SquareDistance(pother) > Tol2) { | |
b7723347 | 718 | problematic_point = pref ; |
719 | Status = Standard_False; | |
720 | Error = pref.Distance(pother); | |
721 | PrintProblematicPoint(problematic_point, Error, Tol); | |
722 | return Status; | |
171d8cd9 P |
723 | //goto FINISH ; |
724 | } | |
725 | } | |
726 | } | |
727 | else { | |
728 | Extrema_LocateExtPC refd,otherd; | |
729 | Standard_Real OFirst = Other.FirstParameter(); | |
730 | Standard_Real OLast = Other.LastParameter(); | |
731 | gp_Pnt pd = CRef.Value(First); | |
732 | gp_Pnt pdo = Other.Value(OFirst); | |
733 | Standard_Real distt = pd.SquareDistance(pdo); | |
734 | if (distt > Tol*Tol) { | |
735 | problematic_point = pd ; | |
736 | Status = Standard_False ; | |
737 | Error = Sqrt(distt); | |
738 | PrintProblematicPoint(problematic_point, Error, Tol); | |
739 | return Status; | |
740 | //goto FINISH ; | |
741 | } | |
742 | pd = CRef.Value(Last); | |
743 | pdo = Other.Value(OLast); | |
744 | distt = pd.SquareDistance(pdo); | |
745 | if (distt > Tol*Tol) { | |
746 | problematic_point = pd ; | |
747 | Status = Standard_False ; | |
748 | Error = Sqrt(distt); | |
749 | PrintProblematicPoint(problematic_point, Error, Tol); | |
750 | return Status; | |
751 | //goto FINISH ; | |
752 | } | |
753 | ||
754 | refd.Initialize(CRef,First,Last,CRef.Resolution(Tol)); | |
755 | otherd.Initialize(Other,OFirst,OLast,Other.Resolution(Tol)); | |
756 | for (Standard_Integer i = 2; i< NCONTROL-1; i++) { | |
757 | Standard_Real rprm = ((NCONTROL-1-i)*First + i*Last)/(NCONTROL-1); | |
758 | gp_Pnt pref = CRef.Value(rprm); | |
759 | Standard_Real oprm = ((NCONTROL-1-i)*OFirst + i*OLast)/(NCONTROL-1); | |
760 | gp_Pnt pother = Other.Value(oprm); | |
761 | refd.Perform(pother,rprm); | |
762 | if (!refd.IsDone() || refd.SquareDistance() > Tol * Tol) { | |
b7723347 | 763 | problematic_point = pref ; |
764 | Status = Standard_False ; | |
765 | if (refd.IsDone()) { | |
766 | Error = sqrt (refd.SquareDistance()); | |
767 | } | |
768 | else { | |
769 | Error = RealLast(); | |
770 | } | |
771 | PrintProblematicPoint(problematic_point, Error, Tol); | |
772 | return Status; | |
171d8cd9 P |
773 | //goto FINISH ; |
774 | } | |
775 | otherd.Perform(pref,oprm); | |
776 | if (!otherd.IsDone() || otherd.SquareDistance() > Tol * Tol) { | |
b7723347 | 777 | problematic_point = pref ; |
778 | Status = Standard_False ; | |
779 | if (otherd.IsDone()) { | |
780 | Error = sqrt (otherd.SquareDistance()); | |
781 | } | |
782 | else { | |
783 | Error = RealLast(); | |
784 | } | |
785 | PrintProblematicPoint(problematic_point, Error, Tol); | |
786 | return Status; | |
787 | //goto FINISH ; | |
171d8cd9 P |
788 | } |
789 | } | |
790 | } | |
171d8cd9 P |
791 | |
792 | return Status ; | |
b7723347 | 793 | |
171d8cd9 P |
794 | } |
795 | //======================================================================= | |
796 | //function : Prec | |
797 | //purpose : | |
798 | //======================================================================= | |
799 | Standard_Real Prec(const Adaptor3d_Curve& aAC3D, | |
b7723347 | 800 | const Adaptor3d_CurveOnSurface& aACS) |
171d8cd9 P |
801 | { |
802 | Standard_Real aXEmax, aXC, aXS; | |
803 | // | |
804 | aXC=PrecCurve(aAC3D); | |
805 | aXS=PrecSurface(aACS); | |
806 | aXEmax=(aXC>aXS) ? aXC: aXS; | |
807 | return aXEmax; | |
808 | } | |
809 | //======================================================================= | |
810 | //function : PrecCurve | |
811 | //purpose : | |
812 | //======================================================================= | |
813 | Standard_Real PrecCurve(const Adaptor3d_Curve& aAC3D) | |
814 | { | |
815 | Standard_Real aXEmax; | |
816 | GeomAbs_CurveType aCT; | |
817 | // | |
818 | aXEmax=RealEpsilon(); | |
819 | // | |
820 | aCT=aAC3D.GetType(); | |
821 | if (aCT==GeomAbs_Ellipse) { | |
822 | Standard_Integer i; | |
823 | Standard_Real aX[5], aXE; | |
824 | // | |
825 | gp_Elips aEL3D=aAC3D.Ellipse(); | |
826 | aEL3D.Location().Coord(aX[0], aX[1], aX[2]); | |
827 | aX[3]=aEL3D.MajorRadius(); | |
828 | aX[4]=aEL3D.MinorRadius(); | |
829 | aXEmax=-1.; | |
830 | for (i=0; i<5; ++i) { | |
831 | if (aX[i]<0.) { | |
b7723347 | 832 | aX[i]=-aX[i]; |
171d8cd9 P |
833 | } |
834 | aXE=Epsilon(aX[i]); | |
835 | if (aXE>aXEmax) { | |
b7723347 | 836 | aXEmax=aXE; |
171d8cd9 P |
837 | } |
838 | } | |
839 | }//if (aCT=GeomAbs_Ellipse) { | |
840 | // | |
841 | return aXEmax; | |
842 | } | |
843 | //======================================================================= | |
844 | //function : PrecSurface | |
845 | //purpose : | |
846 | //======================================================================= | |
847 | Standard_Real PrecSurface(const Adaptor3d_CurveOnSurface& aACS) | |
848 | { | |
849 | Standard_Real aXEmax; | |
850 | GeomAbs_SurfaceType aST; | |
851 | // | |
852 | aXEmax=RealEpsilon(); | |
853 | // | |
854 | const Handle(Adaptor3d_HSurface)& aAHS=aACS.GetSurface(); | |
855 | aST=aAHS->GetType(); | |
856 | if (aST==GeomAbs_Cone) { | |
857 | gp_Cone aCone=aAHS->Cone(); | |
858 | Standard_Integer i; | |
859 | Standard_Real aX[4], aXE; | |
860 | // | |
861 | aCone.Location().Coord(aX[0], aX[1], aX[2]); | |
862 | aX[3]=aCone.RefRadius(); | |
863 | aXEmax=-1.; | |
864 | for (i=0; i<4; ++i) { | |
865 | if (aX[i]<0.) { | |
b7723347 | 866 | aX[i]=-aX[i]; |
171d8cd9 P |
867 | } |
868 | aXE=Epsilon(aX[i]); | |
869 | if (aXE>aXEmax) { | |
b7723347 | 870 | aXEmax=aXE; |
171d8cd9 P |
871 | } |
872 | } | |
873 | }//if (aST==GeomAbs_Cone) { | |
874 | return aXEmax; | |
875 | } | |
876 | //======================================================================= | |
877 | //function : PrintProblematicPoint | |
878 | //purpose : | |
879 | //======================================================================= | |
0797d9d3 | 880 | #ifdef OCCT_DEBUG |
171d8cd9 | 881 | void PrintProblematicPoint(const gp_Pnt& problematic_point, |
b7723347 | 882 | const Standard_Real Error, |
883 | const Standard_Real Tol) | |
171d8cd9 P |
884 | { |
885 | cout << " **** probleme de SameParameter au point :" << endl; | |
886 | cout << " " << problematic_point.Coord(1) << " " | |
887 | << problematic_point.Coord(2) << " " << problematic_point.Coord(3) << endl ; | |
888 | cout << " Erreur detectee :" << Error << " Tolerance :" << Tol << endl; | |
889 | } | |
890 | #else | |
891 | void PrintProblematicPoint(const gp_Pnt&, | |
b7723347 | 892 | const Standard_Real, |
893 | const Standard_Real) | |
171d8cd9 P |
894 | { |
895 | } | |
896 | #endif |