7bd071ed |
1 | // Created on: 2016-07-07 |
2 | // Copyright (c) 2016 OPEN CASCADE SAS |
3 | // Created by: Oleg AGASHIN |
b311480e |
4 | // |
973c2be1 |
5 | // This file is part of Open CASCADE Technology software library. |
b311480e |
6 | // |
d5f74e42 |
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 |
973c2be1 |
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. |
b311480e |
12 | // |
973c2be1 |
13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. |
7fd59977 |
15 | |
01a6e62b |
16 | #include <BRepMesh_Classifier.hxx> |
7fd59977 |
17 | |
7fd59977 |
18 | #include <Precision.hxx> |
31b81068 |
19 | #include <gp_Pnt2d.hxx> |
7fd59977 |
20 | #include <CSLib_Class2d.hxx> |
01a6e62b |
21 | #include <TColgp_Array1OfPnt2d.hxx> |
22 | |
4945e8be |
23 | IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_Classifier, Standard_Transient) |
24 | |
01a6e62b |
25 | //======================================================================= |
26 | //function : Constructor |
27 | //purpose : |
28 | //======================================================================= |
29 | BRepMesh_Classifier::BRepMesh_Classifier() |
30 | { |
31 | } |
7fd59977 |
32 | |
7bd071ed |
33 | //======================================================================= |
34 | //function : Destructor |
35 | //purpose : |
36 | //======================================================================= |
37 | BRepMesh_Classifier::~BRepMesh_Classifier() |
38 | { |
39 | } |
40 | |
01a6e62b |
41 | //======================================================================= |
42 | //function : Perform |
43 | //purpose : |
44 | //======================================================================= |
45 | TopAbs_State BRepMesh_Classifier::Perform(const gp_Pnt2d& thePoint) const |
46 | { |
47 | Standard_Boolean isOut = Standard_False; |
48 | Standard_Integer aNb = myTabClass.Length(); |
49 | |
7bd071ed |
50 | for (Standard_Integer i = 0; i < aNb; i++) |
01a6e62b |
51 | { |
7bd071ed |
52 | const Standard_Integer aCur = myTabClass(i)->SiDans(thePoint); |
01a6e62b |
53 | if (aCur == 0) |
54 | { |
55 | // Point is ON, but mark it as OUT |
56 | isOut = Standard_True; |
57 | } |
58 | else |
7bd071ed |
59 | { |
01a6e62b |
60 | isOut = myTabOrient(i) ? (aCur == -1) : (aCur == 1); |
7bd071ed |
61 | } |
01a6e62b |
62 | |
63 | if (isOut) |
7bd071ed |
64 | { |
01a6e62b |
65 | return TopAbs_OUT; |
7bd071ed |
66 | } |
01a6e62b |
67 | } |
7fd59977 |
68 | |
01a6e62b |
69 | return TopAbs_IN; |
70 | } |
7fd59977 |
71 | |
7fd59977 |
72 | //======================================================================= |
01a6e62b |
73 | //function : RegisterWire |
7fd59977 |
74 | //purpose : |
75 | //======================================================================= |
01a6e62b |
76 | void BRepMesh_Classifier::RegisterWire( |
7bd071ed |
77 | const NCollection_Sequence<const gp_Pnt2d*>& theWire, |
78 | const std::pair<Standard_Real, Standard_Real>& theTolUV, |
79 | const std::pair<Standard_Real, Standard_Real>& theRangeU, |
80 | const std::pair<Standard_Real, Standard_Real>& theRangeV) |
7fd59977 |
81 | { |
01a6e62b |
82 | const Standard_Integer aNbPnts = theWire.Length(); |
67263fce |
83 | if (aNbPnts < 2) |
7bd071ed |
84 | { |
67263fce |
85 | return; |
7bd071ed |
86 | } |
7fd59977 |
87 | |
88 | // Accumulate angle |
67263fce |
89 | TColgp_Array1OfPnt2d aPClass(1, aNbPnts); |
90 | Standard_Real anAngle = 0.0; |
7bd071ed |
91 | const gp_Pnt2d *p1 = theWire(1), *p2 = theWire(2), *p3; |
92 | aPClass(1) = *p1; |
93 | aPClass(2) = *p2; |
01a6e62b |
94 | |
95 | const Standard_Real aAngTol = Precision::Angular(); |
96 | const Standard_Real aSqConfusion = |
97 | Precision::PConfusion() * Precision::PConfusion(); |
98 | |
67263fce |
99 | for (Standard_Integer i = 1; i <= aNbPnts; i++) |
7fd59977 |
100 | { |
67263fce |
101 | Standard_Integer ii = i + 2; |
102 | if (ii > aNbPnts) |
7fd59977 |
103 | { |
7bd071ed |
104 | p3 = &aPClass(ii - aNbPnts); |
7fd59977 |
105 | } |
106 | else |
107 | { |
01a6e62b |
108 | p3 = theWire.Value(ii); |
7bd071ed |
109 | aPClass(ii) = *p3; |
7fd59977 |
110 | } |
67263fce |
111 | |
7bd071ed |
112 | const gp_Vec2d A(*p1,*p2), B(*p2,*p3); |
01a6e62b |
113 | if (A.SquareMagnitude() > aSqConfusion && |
114 | B.SquareMagnitude() > aSqConfusion) |
7fd59977 |
115 | { |
67263fce |
116 | const Standard_Real aCurAngle = A.Angle(B); |
117 | const Standard_Real aCurAngleAbs = Abs(aCurAngle); |
7fd59977 |
118 | // Check if vectors are opposite |
01a6e62b |
119 | if (aCurAngleAbs > aAngTol && (M_PI - aCurAngleAbs) > aAngTol) |
7fd59977 |
120 | { |
67263fce |
121 | anAngle += aCurAngle; |
7fd59977 |
122 | p1 = p2; |
123 | } |
124 | } |
125 | p2 = p3; |
126 | } |
127 | // Check for zero angle - treat self intersecting wire as outer |
01a6e62b |
128 | if (Abs(anAngle) < aAngTol) |
67263fce |
129 | anAngle = 0.0; |
7fd59977 |
130 | |
7bd071ed |
131 | myTabClass.Append(new CSLib_Class2d( |
132 | aPClass, theTolUV.first, theTolUV.second, |
133 | theRangeU.first, theRangeV.first, |
134 | theRangeU.second, theRangeV.second)); |
01a6e62b |
135 | |
7bd071ed |
136 | myTabOrient.Append( !(anAngle < 0.0) ); |
7fd59977 |
137 | } |