0027300: Boolean operation produces invalid shape in terms of "bopargcheck" command
[occt.git] / src / GeomLib / GeomLib_CheckBSplineCurve.cxx
CommitLineData
b311480e 1// Created on: 1997-05-28
2// Created by: Xavier BENVENISTE
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
42cf5bc1 17
7fd59977 18#include <Geom_BSplineCurve.hxx>
42cf5bc1 19#include <GeomLib_CheckBSplineCurve.hxx>
7fd59977 20#include <gp_Pnt.hxx>
21#include <gp_Vec.hxx>
42cf5bc1 22#include <Standard_OutOfRange.hxx>
23#include <StdFail_NotDone.hxx>
24
7fd59977 25//=======================================================================
26//function : GeomLib_CheckBSplineCurve
27//purpose :
28//=======================================================================
7fd59977 29GeomLib_CheckBSplineCurve::GeomLib_CheckBSplineCurve(const Handle(Geom_BSplineCurve)& Curve,
30 const Standard_Real Tolerance,
31 const Standard_Real AngularTolerance)
32:myCurve(Curve),
33myDone(Standard_False),
34myFixFirstTangent(Standard_False),
35myFixLastTangent(Standard_False),
36myAngularTolerance(Abs(AngularTolerance)),
37myTolerance(Abs(Tolerance)),
38myFirstPole(1.0,0.0e0,0.e0),
39myLastPole(1.0e0,0.0e0,0.e0)
40{
41
42
43 Standard_Integer ii,
44 num_poles ;
45 Standard_Real tangent_magnitude,
46 value,
47 angular_value,
48 factor,
49 vector_magnitude ;
50 num_poles = Curve->NbPoles() ;
51 if (( ! myCurve->IsPeriodic() )&& num_poles >= 4) {
52
53 gp_Vec tangent,
54 diff,
55 a_vector;
56 for (ii = 1 ; ii <= 3 ; ii++) {
57 tangent.SetCoord(ii,myCurve->Pole(2).Coord(ii) - myCurve->Pole(1).Coord(ii)) ;
58 a_vector.SetCoord(ii, myCurve->Pole(3).Coord(ii) - myCurve->Pole(1).Coord(ii)) ;
59 }
60 tangent_magnitude = tangent.Magnitude() ;
61 vector_magnitude = a_vector.Magnitude() ;
62 if (tangent_magnitude > myTolerance &&
63 vector_magnitude > myTolerance)
64 {
65 value = tangent.Dot(a_vector) ;
66 if ( value < 0.0e0) {
67 for (ii = 1 ; ii <= 3 ; ii++) {
68 diff.SetCoord(ii, (tangent.Coord(ii) / tangent_magnitude) + (a_vector.Coord(ii) / vector_magnitude)) ;
69 }
70 angular_value =
71 diff.Magnitude() ;
72 if (angular_value < myAngularTolerance) {
73 myFixFirstTangent = Standard_True ;
74 factor = 1.0e0 ;
75 if (tangent_magnitude > 0.5e0 * vector_magnitude) {
76 factor = 0.5e0 * vector_magnitude / tangent_magnitude ;
77 }
78 for (ii = 1 ; ii <= 3 ; ii++) {
79 myFirstPole.SetCoord(ii, myCurve->Pole(1).Coord(ii) - factor * tangent.Coord(ii)) ;
80 }
81 }
82
83 }
84 }
85 for (ii = 1 ; ii <= 3 ; ii++) {
86 tangent.SetCoord(ii,myCurve->Pole(num_poles-1).Coord(ii) - myCurve->Pole(num_poles).Coord(ii)) ;
87 a_vector.SetCoord(ii, myCurve->Pole(num_poles-2).Coord(ii) - myCurve->Pole(num_poles).Coord(ii)) ;
88 }
89 tangent_magnitude = tangent.Magnitude() ;
90 vector_magnitude = a_vector.Magnitude() ;
91
92 if (tangent_magnitude > myTolerance &&
93 vector_magnitude > myTolerance)
94 {
95 value = tangent.Dot(a_vector) ;
96 if (value < 0.0e0) {
97 for (ii = 1 ; ii <= 3 ; ii++) {
98 diff.SetCoord(ii, (tangent.Coord(ii) / tangent_magnitude) + (a_vector.Coord(ii) / vector_magnitude)) ;
99 }
100 angular_value =
101 diff.Magnitude() ;
102 if ( angular_value < myAngularTolerance) {
103 myFixLastTangent = Standard_True ;
104 factor = 1.0e0 ;
105 if (tangent_magnitude > 0.5e0 * vector_magnitude) {
106 factor = 0.5e0 * vector_magnitude / tangent_magnitude ;
107 }
108 for (ii = 1 ; ii <= 3 ; ii++) {
109 myLastPole.SetCoord(ii, myCurve->Pole(num_poles).Coord(ii) - factor * tangent.Coord(ii)) ;
110 }
111 }
112
113 }
114 }
115
116 }
117 else {
118 myDone = Standard_True ;
119 }
120}
121
122//=======================================================================
123//function : NeedTangentFix
124//purpose :
125//=======================================================================
126
127void GeomLib_CheckBSplineCurve::NeedTangentFix(Standard_Boolean & FirstFlag,
128 Standard_Boolean & LastFlag) const
129{
130 FirstFlag = myFixFirstTangent ;
131 LastFlag = myFixLastTangent ;
132}
133//=======================================================================
134//function : FixTangent
135//purpose :
136//=======================================================================
137
138Handle(Geom_BSplineCurve) GeomLib_CheckBSplineCurve::FixedTangent(const Standard_Boolean FirstFlag,
139 const Standard_Boolean LastFlag)
140{
141 Handle(Geom_BSplineCurve) new_curve ;
142 if ((myFixFirstTangent && FirstFlag) ||(myFixLastTangent && LastFlag)) {
143 new_curve =
144 Handle(Geom_BSplineCurve)::DownCast(myCurve->Copy()) ;
145
146 }
147 if (myFixFirstTangent && FirstFlag) {
148 new_curve->SetPole(2,
149 myFirstPole) ;
150 }
151 if (myFixLastTangent && LastFlag) {
152 Standard_Integer num_poles = myCurve->NbPoles() ;
153 new_curve->SetPole(num_poles-1,
154 myLastPole) ;
155 }
156
157 myDone = Standard_True ;
158 return new_curve ;
159}
160//=======================================================================
161//function : FixTangent
162//purpose :
163//=======================================================================
164
165void GeomLib_CheckBSplineCurve::FixTangent(const Standard_Boolean FirstFlag,
166 const Standard_Boolean LastFlag)
167{
168
169 if (myFixFirstTangent && FirstFlag) {
170 myCurve->SetPole(2,
171 myFirstPole) ;
172 }
173 if (myFixLastTangent && LastFlag) {
174 Standard_Integer num_poles = myCurve->NbPoles() ;
175 myCurve->SetPole(num_poles-1,
176 myLastPole) ;
177 }
178
179 myDone = Standard_True ;
180}