0024968: Impove BRepMesh_Classifier to cope with intersection of huge number of wires
[occt.git] / src / BRepMesh / BRepMesh_Classifier.cxx
CommitLineData
b311480e 1// Created on: 1997-06-26
2// Created by: Laurent PAINNOT
3// Copyright (c) 1997-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
01a6e62b 17#include <BRepMesh_Classifier.hxx>
7fd59977 18
7fd59977 19#include <Precision.hxx>
31b81068 20#include <gp_Pnt2d.hxx>
7fd59977 21#include <CSLib_Class2d.hxx>
01a6e62b 22#include <TColgp_Array1OfPnt2d.hxx>
23
24//=======================================================================
25//function : Constructor
26//purpose :
27//=======================================================================
28BRepMesh_Classifier::BRepMesh_Classifier()
29{
30}
7fd59977 31
01a6e62b 32//=======================================================================
33//function : Perform
34//purpose :
35//=======================================================================
36TopAbs_State BRepMesh_Classifier::Perform(const gp_Pnt2d& thePoint) const
37{
38 Standard_Boolean isOut = Standard_False;
39 Standard_Integer aNb = myTabClass.Length();
40
41 for (Standard_Integer i = 1; i <= aNb; i++)
42 {
43 Standard_Integer aCur = ((CSLib_Class2d*)myTabClass(i))->SiDans(thePoint);
44 if (aCur == 0)
45 {
46 // Point is ON, but mark it as OUT
47 isOut = Standard_True;
48 }
49 else
50 isOut = myTabOrient(i) ? (aCur == -1) : (aCur == 1);
51
52 if (isOut)
53 return TopAbs_OUT;
54 }
7fd59977 55
01a6e62b 56 return TopAbs_IN;
57}
7fd59977 58
7fd59977 59//=======================================================================
01a6e62b 60//function : RegisterWire
7fd59977 61//purpose :
62//=======================================================================
01a6e62b 63void BRepMesh_Classifier::RegisterWire(
64 const NCollection_Sequence<gp_Pnt2d>& theWire,
65 const Standard_Real theTolUV,
66 const Standard_Real theUmin,
67 const Standard_Real theUmax,
68 const Standard_Real theVmin,
69 const Standard_Real theVmax)
7fd59977 70{
01a6e62b 71 const Standard_Integer aNbPnts = theWire.Length();
67263fce 72 if (aNbPnts < 2)
73 return;
7fd59977 74
75 // Accumulate angle
67263fce 76 TColgp_Array1OfPnt2d aPClass(1, aNbPnts);
77 Standard_Real anAngle = 0.0;
01a6e62b 78 gp_Pnt2d p1 = theWire(1), p2 = theWire(2), p3;
67263fce 79 aPClass(1) = p1;
80 aPClass(2) = p2;
01a6e62b 81
82 const Standard_Real aAngTol = Precision::Angular();
83 const Standard_Real aSqConfusion =
84 Precision::PConfusion() * Precision::PConfusion();
85
67263fce 86 for (Standard_Integer i = 1; i <= aNbPnts; i++)
7fd59977 87 {
67263fce 88 Standard_Integer ii = i + 2;
89 if (ii > aNbPnts)
7fd59977 90 {
67263fce 91 p3 = aPClass(ii - aNbPnts);
7fd59977 92 }
93 else
94 {
01a6e62b 95 p3 = theWire.Value(ii);
67263fce 96 aPClass(ii) = p3;
7fd59977 97 }
67263fce 98
7fd59977 99 gp_Vec2d A(p1,p2), B(p2,p3);
01a6e62b 100 if (A.SquareMagnitude() > aSqConfusion &&
101 B.SquareMagnitude() > aSqConfusion)
7fd59977 102 {
67263fce 103 const Standard_Real aCurAngle = A.Angle(B);
104 const Standard_Real aCurAngleAbs = Abs(aCurAngle);
7fd59977 105 // Check if vectors are opposite
01a6e62b 106 if (aCurAngleAbs > aAngTol && (M_PI - aCurAngleAbs) > aAngTol)
7fd59977 107 {
67263fce 108 anAngle += aCurAngle;
7fd59977 109 p1 = p2;
110 }
111 }
112 p2 = p3;
113 }
114 // Check for zero angle - treat self intersecting wire as outer
01a6e62b 115 if (Abs(anAngle) < aAngTol)
67263fce 116 anAngle = 0.0;
7fd59977 117
01a6e62b 118 myTabClass.Append( (void *)new CSLib_Class2d(aPClass,
119 theTolUV, theTolUV, theUmin, theVmin, theUmax, theVmax) );
120 myTabOrient.Append( !(anAngle < 0.0) );
7fd59977 121}
122
7fd59977 123//=======================================================================
124//function : Destroy
125//purpose :
126//=======================================================================
7fd59977 127void BRepMesh_Classifier::Destroy()
128{
67263fce 129 Standard_Integer aNb = myTabClass.Length();
130 for (Standard_Integer i = 1; i <= aNb; i++)
7fd59977 131 {
67263fce 132 if (myTabClass(i))
7fd59977 133 {
67263fce 134 delete ((CSLib_Class2d*)myTabClass(i));
135 myTabClass(i) = NULL;
7fd59977 136 }
137 }
01a6e62b 138
139 myTabClass.Clear();
140 myTabOrient.Clear();
7fd59977 141}