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