0030679: Attached model hangs most of OCCT common functionality
[occt.git] / src / BRepMesh / BRepMesh_Classifier.cxx
1 // Created on: 2016-07-07
2 // Copyright (c) 2016 OPEN CASCADE SAS
3 // Created by: Oleg AGASHIN
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <BRepMesh_Classifier.hxx>
17
18 #include <Precision.hxx>
19 #include <gp_Pnt2d.hxx>
20 #include <CSLib_Class2d.hxx>
21 #include <TColgp_Array1OfPnt2d.hxx>
22
23 //=======================================================================
24 //function : Constructor
25 //purpose  : 
26 //=======================================================================
27 BRepMesh_Classifier::BRepMesh_Classifier()
28 {
29 }
30
31 //=======================================================================
32 //function : Destructor
33 //purpose  : 
34 //=======================================================================
35 BRepMesh_Classifier::~BRepMesh_Classifier()
36 {
37 }
38
39 //=======================================================================
40 //function : Perform
41 //purpose  : 
42 //=======================================================================
43 TopAbs_State BRepMesh_Classifier::Perform(const gp_Pnt2d& thePoint) const
44 {
45   Standard_Boolean isOut = Standard_False;
46   Standard_Integer aNb   = myTabClass.Length();
47   
48   for (Standard_Integer i = 0; i < aNb; i++)
49   {
50     const Standard_Integer aCur = myTabClass(i)->SiDans(thePoint);
51     if (aCur == 0)
52     {
53       // Point is ON, but mark it as OUT
54       isOut = Standard_True;
55     }
56     else
57     {
58       isOut = myTabOrient(i) ? (aCur == -1) : (aCur == 1);
59     }
60     
61     if (isOut)
62     {
63       return TopAbs_OUT;
64     }
65   }
66
67   return TopAbs_IN;
68 }
69
70 //=======================================================================
71 //function : RegisterWire
72 //purpose  : 
73 //=======================================================================
74 void BRepMesh_Classifier::RegisterWire(
75   const NCollection_Sequence<const gp_Pnt2d*>&   theWire,
76   const std::pair<Standard_Real, Standard_Real>& theTolUV,
77   const std::pair<Standard_Real, Standard_Real>& theRangeU,
78   const std::pair<Standard_Real, Standard_Real>& theRangeV)
79 {
80   const Standard_Integer aNbPnts = theWire.Length();
81   if (aNbPnts < 2)
82   {
83     return;
84   }
85
86   // Accumulate angle
87   TColgp_Array1OfPnt2d aPClass(1, aNbPnts);
88   Standard_Real anAngle = 0.0;
89   const gp_Pnt2d *p1 = theWire(1), *p2 = theWire(2), *p3;
90   aPClass(1) = *p1;
91   aPClass(2) = *p2;
92
93   const Standard_Real aAngTol = Precision::Angular();
94   const Standard_Real aSqConfusion =
95     Precision::PConfusion() * Precision::PConfusion();
96
97   for (Standard_Integer i = 1; i <= aNbPnts; i++)
98   { 
99     Standard_Integer ii = i + 2;
100     if (ii > aNbPnts)
101     {
102       p3 = &aPClass(ii - aNbPnts);
103     }
104     else
105     {
106       p3 = theWire.Value(ii);
107       aPClass(ii) = *p3;
108     }
109
110     const gp_Vec2d A(*p1,*p2), B(*p2,*p3);
111     if (A.SquareMagnitude() > aSqConfusion && 
112         B.SquareMagnitude() > aSqConfusion)
113     {
114       const Standard_Real aCurAngle    = A.Angle(B);
115       const Standard_Real aCurAngleAbs = Abs(aCurAngle);
116       // Check if vectors are opposite
117       if (aCurAngleAbs > aAngTol && (M_PI - aCurAngleAbs) > aAngTol)
118       {
119         anAngle += aCurAngle;
120         p1 = p2;
121       }
122     }
123     p2 = p3;
124   }
125   // Check for zero angle - treat self intersecting wire as outer
126   if (Abs(anAngle) < aAngTol)
127     anAngle = 0.0;
128
129   myTabClass.Append(new CSLib_Class2d(
130                     aPClass, theTolUV.first, theTolUV.second,
131                     theRangeU.first, theRangeV.first,
132                     theRangeU.second, theRangeV.second));
133
134   myTabOrient.Append( !(anAngle < 0.0) );
135 }