0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[occt.git] / src / BRepCheck / BRepCheck_Vertex.cxx
1 // Created on: 1995-12-07
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <BRep_CurveRepresentation.hxx>
19 #include <BRep_GCurve.hxx>
20 #include <BRep_TEdge.hxx>
21 #include <BRep_TFace.hxx>
22 #include <BRep_Tool.hxx>
23 #include <BRep_TVertex.hxx>
24 #include <BRepCheck.hxx>
25 #include <BRepCheck_ListOfStatus.hxx>
26 #include <BRepCheck_Vertex.hxx>
27 #include <Geom2d_Curve.hxx>
28 #include <Geom_Curve.hxx>
29 #include <Geom_Surface.hxx>
30 #include <gp_Pnt2d.hxx>
31 #include <Standard_Type.hxx>
32 #include <TopExp_Explorer.hxx>
33 #include <TopoDS.hxx>
34 #include <TopoDS_Edge.hxx>
35 #include <TopoDS_Iterator.hxx>
36 #include <TopoDS_Shape.hxx>
37 #include <TopoDS_Vertex.hxx>
38
39 IMPLEMENT_STANDARD_RTTIEXT(BRepCheck_Vertex,BRepCheck_Result)
40
41 //=======================================================================
42 //function : BRepCheck_Vertex
43 //purpose  : 
44 //=======================================================================
45 BRepCheck_Vertex::BRepCheck_Vertex(const TopoDS_Vertex& V)
46 {
47   Init(V);
48 }
49
50
51
52 //=======================================================================
53 //function : Minimum
54 //purpose  :
55 //=======================================================================
56 void BRepCheck_Vertex::Minimum()
57 {
58   if (!myMin)
59   {
60     // checks the existence of a point 3D
61     Handle(BRepCheck_HListOfStatus) aNewList = new BRepCheck_HListOfStatus();
62     BRepCheck_ListOfStatus& lst = **myMap.Bound (myShape, aNewList);
63     lst.Append (BRepCheck_NoError);
64     myMin = Standard_True;
65   }
66 }
67
68
69 //=======================================================================
70 //function : InContext
71 //purpose  : 
72 //=======================================================================
73
74 void BRepCheck_Vertex::InContext(const TopoDS_Shape& S)
75 {
76   Handle(BRepCheck_HListOfStatus) aHList;
77   {
78     Standard_Mutex::Sentry aLock(myMutex.get());
79     if (myMap.IsBound (S))
80     {
81       return;
82     }
83
84     Handle(BRepCheck_HListOfStatus) aNewList = new BRepCheck_HListOfStatus();
85     aHList = *myMap.Bound (S, aNewList);
86   }
87   BRepCheck_ListOfStatus& lst = *aHList;
88
89   TopExp_Explorer exp(S, TopAbs_VERTEX);
90   for (; exp.More(); exp.Next())
91   {
92     if (exp.Current().IsSame(myShape)) {
93       break;
94     }
95   }
96   if (!exp.More())
97   {
98     BRepCheck::Add (lst, BRepCheck_SubshapeNotInShape);
99     return; // leaves
100   }
101
102
103   Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &myShape.TShape());
104   const gp_Pnt& prep = TV->Pnt();
105   gp_Pnt Controlp;
106
107   TopAbs_ShapeEnum styp = S.ShapeType();
108   switch (styp)
109   {
110     case TopAbs_EDGE:
111     {
112       // Try to find the vertex on the edge
113       const TopoDS_Edge& E = TopoDS::Edge(S);
114       TopoDS_Iterator itv(E.Oriented(TopAbs_FORWARD));
115       TopoDS_Vertex VFind;
116       Standard_Boolean multiple = Standard_False;
117       while (itv.More())
118       {
119         const TopoDS_Vertex& VF = TopoDS::Vertex(itv.Value());
120         if (itv.Value().IsSame(myShape))
121         {
122           if (VFind.IsNull())
123           {
124             VFind = VF;
125           }
126           else
127           {
128             if ((VFind.Orientation() == TopAbs_FORWARD &&
129                     VF.Orientation() == TopAbs_REVERSED) ||
130               (VFind.Orientation() == TopAbs_REVERSED &&
131                   VF.Orientation() == TopAbs_FORWARD))
132             {
133               // the vertex on the edge is at once F and R
134               multiple = Standard_True;
135             }
136             if (VFind.Orientation() != TopAbs_FORWARD &&
137                 VFind.Orientation() != TopAbs_REVERSED)
138             {
139               if (VF.Orientation() == TopAbs_FORWARD ||
140                   VF.Orientation() == TopAbs_REVERSED)
141               {
142                 VFind = VF;
143               }
144             }
145           }
146         }
147         itv.Next();
148       }
149
150       // VFind is not null for sure
151       TopAbs_Orientation orv = VFind.Orientation();
152
153       Standard_Real Tol = BRep_Tool::Tolerance(TopoDS::Vertex(myShape));
154       Tol = Max(Tol, BRep_Tool::Tolerance(E)); // to check
155       Tol *= Tol;
156
157       Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&E.TShape());
158       BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
159       const TopLoc_Location& Eloc = E.Location();
160
161       BRep_ListIteratorOfListOfPointRepresentation itpr;
162       while (itcr.More())
163       {
164         // For each CurveRepresentation, the provided parameter is checked
165         const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
166         const TopLoc_Location& loc = cr->Location();
167         TopLoc_Location L = (Eloc * loc).Predivided(myShape.Location());
168
169         if (cr->IsCurve3D())
170         {
171           const Handle(Geom_Curve)& C = cr->Curve3D();
172           if (!C.IsNull()) // edge non degenerated
173           {
174             itpr.Initialize(TV->Points());
175             while (itpr.More())
176             {
177               const Handle(BRep_PointRepresentation)& pr = itpr.Value();
178               if (pr->IsPointOnCurve (C, L))
179               {
180                 Controlp = C->Value (pr->Parameter());
181                 Controlp.Transform (L.Transformation());
182                 if (prep.SquareDistance (Controlp) > Tol)
183                 {
184                   BRepCheck::Add (lst, BRepCheck_InvalidPointOnCurve);
185                 }
186               }
187               itpr.Next();
188             }
189             if (orv == TopAbs_FORWARD || orv == TopAbs_REVERSED)
190             {
191               Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(cr);
192               if (orv == TopAbs_FORWARD || multiple)
193               {
194                 Controlp = C->Value(GC->First());
195                 Controlp.Transform(L.Transformation());
196                 if (prep.SquareDistance(Controlp) > Tol)
197                 {
198                   BRepCheck::Add (lst, BRepCheck_InvalidPointOnCurve);
199                 }
200               }
201               if (orv == TopAbs_REVERSED || multiple)
202               {
203                 Controlp = C->Value(GC->Last());
204                 Controlp.Transform(L.Transformation());
205                 if (prep.SquareDistance (Controlp) > Tol)
206                 {
207                   BRepCheck::Add (lst, BRepCheck_InvalidPointOnCurve);
208                 }
209               }
210             }
211           }
212         }
213         else if (cr->IsCurveOnSurface())
214         {
215           const Handle(Geom_Surface)& Su = cr->Surface();
216           const Handle(Geom2d_Curve)& PC = cr->PCurve();
217           Handle(Geom2d_Curve) PC2;
218           if (cr->IsCurveOnClosedSurface())
219           {
220             PC2 = cr->PCurve2();
221           }
222           itpr.Initialize(TV->Points());
223           while (itpr.More())
224           {
225             const Handle(BRep_PointRepresentation)& pr = itpr.Value();
226             if (pr->IsPointOnCurveOnSurface(PC, Su, L))
227             {
228               gp_Pnt2d p2d = PC->Value(pr->Parameter());
229               Controlp = Su->Value(p2d.X(), p2d.Y());
230               Controlp.Transform(L.Transformation());
231               if (prep.SquareDistance(Controlp) > Tol)
232               {
233                 BRepCheck::Add (lst, BRepCheck_InvalidPointOnCurveOnSurface);
234               }
235             }
236             if (!PC2.IsNull() && pr->IsPointOnCurveOnSurface (PC2, Su, L))
237             {
238               gp_Pnt2d p2d = PC2->Value(pr->Parameter());
239               Controlp = Su->Value(p2d.X(), p2d.Y());
240               Controlp.Transform(L.Transformation());
241               if (prep.SquareDistance(Controlp) > Tol)
242               {
243                 BRepCheck::Add (lst, BRepCheck_InvalidPointOnCurveOnSurface);
244               }
245             }
246             itpr.Next();
247           }
248         }
249         itcr.Next();
250       }
251       if (lst.IsEmpty())
252       {
253         lst.Append (BRepCheck_NoError);
254       }
255       break;
256     }
257     case TopAbs_FACE:
258     {
259       Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &S.TShape());
260       const TopLoc_Location& Floc = S.Location();
261       const TopLoc_Location& TFloc = TF->Location();
262       const Handle(Geom_Surface)& Su = TF->Surface();
263       TopLoc_Location L = (Floc * TFloc).Predivided(myShape.Location());
264
265       Standard_Real Tol = BRep_Tool::Tolerance(TopoDS::Vertex(myShape));
266       Tol = Max (Tol, BRep_Tool::Tolerance(TopoDS::Face(S))); // to check
267       Tol *= Tol;
268
269       BRep_ListIteratorOfListOfPointRepresentation itpr(TV->Points());
270       while (itpr.More())
271       {
272         const Handle(BRep_PointRepresentation)& pr = itpr.Value();
273         if (pr->IsPointOnSurface (Su, L))
274         {
275           Controlp = Su->Value (pr->Parameter(), pr->Parameter2());
276           Controlp.Transform(L.Transformation());
277           if (prep.SquareDistance(Controlp) > Tol)
278           {
279             BRepCheck::Add (lst, BRepCheck_InvalidPointOnSurface);
280           }
281         }
282         itpr.Next();
283       }
284       if (lst.IsEmpty())
285       {
286         lst.Append (BRepCheck_NoError);
287       }
288       break;
289     }
290     default:
291     {
292       break;
293     }
294   }
295 }
296
297 //=======================================================================
298 //function : Blind
299 //purpose  : 
300 //=======================================================================
301
302 void BRepCheck_Vertex::Blind()
303 {
304   if (myBlind) {
305     return;
306   }
307 //   modified by NIZHNY-MKK  Fri May  7 16:43:38 2004.BEGIN
308 //   The body of this function is removed because of its useless 
309 //   (see specification "Substitution existing set of evaluation DRAW commands to one").
310
311 //   Check all the representations  of the vertex. (i-e checks the TVertex
312 //   BRepCheck_ListOfStatus& lst = myMap(myShape);
313 //   lst.Clear(); // there was NoError...
314
315 //   Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &myShape.TShape());
316 //   const gp_Pnt& prep = TV->Pnt();
317 //   Standard_Real Tol  = BRep_Tool::Tolerance(TopoDS::Vertex(myShape));
318 //   Tol *= Tol;
319
320 //   gp_Pnt Controlp;
321 //   BRep_ListIteratorOfListOfPointRepresentation itpr(TV->Points());
322 //   BRepCheck_Status stat=BRepCheck_NoError;
323 //   while (itpr.More()) {
324 //     const Handle(BRep_PointRepresentation)& pr = itpr.Value();
325 //     const TopLoc_Location& loc = pr->Location();
326 //     if (pr->IsPointOnCurve()) {
327 //       Controlp = pr->Curve()->Value(pr->Parameter());
328 //       stat = BRepCheck_InvalidPointOnCurve;
329 //     }
330 //     else if (pr->IsPointOnCurveOnSurface()) {
331 //       gp_Pnt2d Puv = pr->PCurve()->Value(pr->Parameter());
332 //       Controlp = pr->Surface()->Value(Puv.X(),Puv.Y());
333 //       stat = BRepCheck_InvalidPointOnCurveOnSurface;
334 //     }
335 //     else if (pr->IsPointOnSurface()) {
336 //       Controlp = pr->Surface()->Value(pr->Parameter(),pr->Parameter2());
337 //       stat = BRepCheck_InvalidPointOnSurface;
338 //     }
339 //     Controlp.Transform(loc.Transformation());
340 //     if (prep.SquareDistance(Controlp) > Tol) {
341 //       BRepCheck::Add(lst,stat);
342 //     }
343 //     itpr.Next();
344 //   }
345
346 //   if (lst.IsEmpty()) {
347 //     lst.Append(BRepCheck_NoError);
348 //   }
349 // modified by NIZHNY-MKK  Fri May  7 16:43:45 2004.END
350   myBlind = Standard_True;
351 }
352
353
354 //=======================================================================
355 //function : Tolerance
356 //purpose  : 
357 //=======================================================================
358
359 Standard_Real BRepCheck_Vertex::Tolerance()
360 {
361
362   // Check all the representations  of the vertex. (i-e checks the TVertex
363   Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &myShape.TShape());
364   const gp_Pnt& prep = TV->Pnt();
365   Standard_Real Tol  = BRep_Tool::Tolerance(TopoDS::Vertex(myShape));
366   Tol *= Tol;
367
368   gp_Pnt Controlp;
369   Controlp = prep;
370   BRep_ListIteratorOfListOfPointRepresentation itpr(TV->Points());
371   while (itpr.More()) {
372     const Handle(BRep_PointRepresentation)& pr = itpr.Value();
373     const TopLoc_Location& loc = pr->Location();
374     if (pr->IsPointOnCurve()) {
375       if (!pr->Curve().IsNull())
376         Controlp = pr->Curve()->Value(pr->Parameter());
377     }
378     else if (pr->IsPointOnCurveOnSurface()) {
379       gp_Pnt2d Puv = pr->PCurve()->Value(pr->Parameter());
380       Controlp = pr->Surface()->Value(Puv.X(),Puv.Y());
381     }
382     else if (pr->IsPointOnSurface()) {
383       Controlp = pr->Surface()->Value(pr->Parameter(),pr->Parameter2());
384     }
385     Controlp.Transform(loc.Transformation());
386     if (prep.SquareDistance(Controlp) > Tol) {
387       Tol = prep.SquareDistance(Controlp);
388     }
389     itpr.Next();
390   }
391   return sqrt(Tol*1.05);
392 }
393