0022048: Visualization, AIS_InteractiveContext - single object selection should alway...
[occt.git] / src / IntPatch / IntPatch_PointLine.cxx
CommitLineData
d4b867e6 1// Created on: 2015-02-18
2// Created by: Nikolai BUKHALOV
3// Copyright (c) 1995-1999 Matra Datavision
4// Copyright (c) 1999-2015 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
42cf5bc1 17#include <IntPatch_PointLine.hxx>
e2e0498b 18
19#include <Adaptor3d_HSurface.hxx>
42cf5bc1 20#include <IntSurf_PntOn2S.hxx>
e2e0498b 21#include <Precision.hxx>
d4b867e6 22
92efcf78 23IMPLEMENT_STANDARD_RTTIEXT(IntPatch_PointLine,IntPatch_Line)
24
d4b867e6 25IntPatch_PointLine::IntPatch_PointLine (const Standard_Boolean Tang,
26 const IntSurf_TypeTrans Trans1,
27 const IntSurf_TypeTrans Trans2) :
28 IntPatch_Line(Tang, Trans1, Trans2)
29{}
30
31IntPatch_PointLine::IntPatch_PointLine (const Standard_Boolean Tang,
32 const IntSurf_Situation Situ1,
33 const IntSurf_Situation Situ2) :
34 IntPatch_Line(Tang, Situ1, Situ2)
35{}
36
37IntPatch_PointLine::IntPatch_PointLine (const Standard_Boolean Tang) :
38 IntPatch_Line(Tang)
39{}
40
e2e0498b 41//=======================================================================
42//function : CurvatureRadiusOfIntersLine
43//purpose :
44// ATTENTION!!!
45// Returns negative value if computation is not possible
46//=======================================================================
47Standard_Real IntPatch_PointLine::
48 CurvatureRadiusOfIntersLine(const Handle(Adaptor3d_HSurface)& theS1,
49 const Handle(Adaptor3d_HSurface)& theS2,
50 const IntSurf_PntOn2S& theUVPoint)
51{
52 const Standard_Real aSmallValue = 1.0/Precision::Infinite();
53 const Standard_Real aSqSmallValue = aSmallValue*aSmallValue;
54
55 Standard_Real aU1 = 0.0, aV1 = 0.0, aU2 = 0.0, aV2 = 0.0;
56 theUVPoint.Parameters(aU1, aV1, aU2, aV2);
57 gp_Pnt aPt;
58 gp_Vec aDU1, aDV1, aDUU1, aDUV1, aDVV1;
59 gp_Vec aDU2, aDV2, aDUU2, aDUV2, aDVV2;
60
61 theS1->D2(aU1, aV1, aPt, aDU1, aDV1, aDUU1, aDVV1, aDUV1);
62 theS2->D2(aU2, aV2, aPt, aDU2, aDV2, aDUU2, aDVV2, aDUV2);
63
64#if 0
65 //The code in this block contains TEST CASES for
66 //this algorithm only. It is stupedly to create OCCT-test for
67 //the method, which will be changed possibly never.
68 //However, if we do something in this method we can check its
69 //functionality easily. For that:
70 // 1. Initialyze aTestID variable by the correct value;
71 // 2. Compile this test code fragment.
72
73 int aTestID = 0;
74 Standard_Real anExpectedSqRad = -1.0;
75 switch(aTestID)
76 {
77 case 1:
78 //Intersection between two spherical surfaces: O1(0.0, 0.0, 0.0), R1 = 3
79 //and O2(5.0, 0.0, 0.0), R2 = 5.0.
80 //Considered point has coordinates: (0.9, 0.0, 0.3*sqrt(91.0)).
81
82 aDU1.SetCoord(0.00000000000000000, 0.90000000000000002, 0.00000000000000000);
83 aDV1.SetCoord(-2.8618176042508372, 0.00000000000000000, 0.90000000000000002);
84 aDUU1.SetCoord(-0.90000000000000002, 0.00000000000000000, 0.00000000000000000);
85 aDUV1.SetCoord(0.00000000000000000, -2.8618176042508372, 0.00000000000000000);
86 aDVV1.SetCoord(-0.90000000000000002, 0.00000000000000000, -2.8618176042508372);
87 aDU2.SetCoord(0.00000000000000000, -4.0999999999999996, 0.00000000000000000);
88 aDV2.SetCoord(-2.8618176042508372, 0.00000000000000000, -4.0999999999999996);
89 aDUU2.SetCoord(4.0999999999999996, 0.00000000000000000, 0.00000000000000000);
90 aDUV2.SetCoord(0.00000000000000000, -2.8618176042508372, 0.00000000000000000);
91 aDVV2.SetCoord(4.0999999999999996, 0.00000000000000000, -2.8618176042508372);
92 anExpectedSqRad = 819.0/100.0;
93 break;
94 case 2:
95 //Intersection between spherical surfaces: O1(0.0, 0.0, 0.0), R1 = 10
96 //and the plane 3*x+4*y+z=26.
97 //Considered point has coordinates: (-1.68, 5.76, 8.0).
98
99 aDU1.SetCoord(-5.76, -1.68, 0.0);
100 aDV1.SetCoord(2.24, -7.68, 6.0);
101 aDUU1.SetCoord(1.68, -5.76, 0.0);
102 aDUV1.SetCoord(7.68, 2.24, 0.0);
103 aDVV1.SetCoord(1.68, -5.76, -8.0);
104 aDU2.SetCoord(1.0, 0.0, -3.0);
105 aDV2.SetCoord(0.0, 1.0, -4.0);
106 aDUU2.SetCoord(0.0, 0.0, 0.0);
107 aDUV2.SetCoord(0.0, 0.0, 0.0);
108 aDVV2.SetCoord(0.0, 0.0, 0.0);
109 anExpectedSqRad = 74.0;
110 break;
111 default:
112 aTestID = 0;
113 break;
114 }
115#endif
116
117 const gp_Vec aN1(aDU1.Crossed(aDV1)), aN2(aDU2.Crossed(aDV2));
118 //Tangent vactor to the intersection curve
119 const gp_Vec aCTan(aN1.Crossed(aN2));
120 const Standard_Real aSqMagnFDer = aCTan.SquareMagnitude();
121
122 if(aSqMagnFDer < aSqSmallValue)
123 return -1.0;
124
125 Standard_Real aDuS1 = 0.0, aDvS1 = 0.0, aDuS2 = 0.0, aDvS2 = 1.0;
126
127 {
128 //This algorithm is described in NonSingularProcessing() function
129 //in ApproxInt_ImpPrmSvSurfaces.gxx file
130 Standard_Real aSqNMagn = aN1.SquareMagnitude();
131 gp_Vec aTgU(aCTan.Crossed(aDU1)), aTgV(aCTan.Crossed(aDV1));
132 Standard_Real aDeltaU = aTgV.SquareMagnitude()/aSqNMagn;
133 Standard_Real aDeltaV = aTgU.SquareMagnitude()/aSqNMagn;
134
135 aDuS1 = Sign(sqrt(aDeltaU), aTgV.Dot(aN1));
136 aDvS1 = -Sign(sqrt(aDeltaV), aTgU.Dot(aN1));
137
138 aSqNMagn = aN2.SquareMagnitude();
139 aTgU.SetXYZ(aCTan.Crossed(aDU2).XYZ());
140 aTgV.SetXYZ(aCTan.Crossed(aDV2).XYZ());
141 aDeltaU = aTgV.SquareMagnitude()/aSqNMagn;
142 aDeltaV = aTgU.SquareMagnitude()/aSqNMagn;
143
144 aDuS2 = Sign(sqrt(aDeltaU), aTgV.Dot(aN2));
145 aDvS2 = -Sign(sqrt(aDeltaV), aTgU.Dot(aN2));
146 }
147
148 //According to "Marching along surface/surface intersection curves
149 //with an adaptive step length"
150 //by Tz.E.Stoyagov
151 //(http://www.sciencedirect.com/science/article/pii/016783969290046R)
152 //we obtain the system:
153 // {A*a+B*b=F1
154 // {B*a+C*b=F2
155 //where a and b should be found.
156 //After that, 2nd derivative of the intersection curve can be computed as
157 // r''(t)=a*aN1+b*aN2.
158
159 const Standard_Real aA = aN1.Dot(aN1), aB = aN1.Dot(aN2), aC = aN2.Dot(aN2);
160 const Standard_Real aDetSyst = aB*aB - aA*aC;
161
162 if(Abs(aDetSyst) < aSmallValue)
163 {//Indetermined system solution
164 return -1.0;
165 }
166
167 const Standard_Real aF1 = aDuS1*aDuS1*aDUU1.Dot(aN1) +
168 2.0*aDuS1*aDvS1*aDUV1.Dot(aN1) +
169 aDvS1*aDvS1*aDVV1.Dot(aN1);
170 const Standard_Real aF2 = aDuS2*aDuS2*aDUU2.Dot(aN2) +
171 2.0*aDuS2*aDvS2*aDUV2.Dot(aN2) +
172 aDvS2*aDvS2*aDVV2.Dot(aN2);
173
174 //Principal normal to the intersection curve
175 const gp_Vec aCNorm((aF1*aC-aF2*aB)/aDetSyst*aN1 + (aA*aF2-aF1*aB)/aDetSyst*aN2);
176 const Standard_Real aSqMagnSDer = aCNorm.CrossSquareMagnitude(aCTan);
177
178 if(aSqMagnSDer < aSqSmallValue)
179 {//Intersection curve has null curvature in observed point
180 return Precision::Infinite();
181 }
182
183 //square of curvature radius
184 const Standard_Real aFactSqRad = aSqMagnFDer*aSqMagnFDer*aSqMagnFDer/aSqMagnSDer;
185
186#if 0
187 if(aTestID)
188 {
189 if(Abs(aFactSqRad - anExpectedSqRad) < Precision::Confusion())
190 {
191 printf("OK: Curvature radius is equal to expected (%5.10g)", anExpectedSqRad);
192 }
193 else
194 {
195 printf("Error: Curvature radius is not equal to expected: %5.10g != %5.10g",
196 aFactSqRad, anExpectedSqRad);
197 }
198 }
199#endif
d4b867e6 200
e2e0498b 201 return sqrt(aFactSqRad);
202}