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