0031668: Visualization - WebGL sample doesn't work on Emscripten 1.39
[occt.git] / src / ChFiKPart / ChFiKPart_ComputeData_ChPlnCon.cxx
1 // Created on: 1995-05-30
2 // Created by: Stagiaire Flore Lantheaume
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 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
17
18 #include <Adaptor3d_HSurface.hxx>
19 #include <ChFiDS_Spine.hxx>
20 #include <ChFiDS_SurfData.hxx>
21 #include <ChFiKPart_ComputeData.hxx>
22 #include <ChFiKPart_ComputeData_ChAsymPlnCon.hxx>
23 #include <ChFiKPart_ComputeData_Fcts.hxx>
24 #include <ElCLib.hxx>
25 #include <ElSLib.hxx>
26 #include <Geom2d_Circle.hxx>
27 #include <Geom2d_Line.hxx>
28 #include <Geom_Circle.hxx>
29 #include <Geom_ConicalSurface.hxx>
30 #include <gp.hxx>
31 #include <gp_Ax2.hxx>
32 #include <gp_Ax3.hxx>
33 #include <gp_Circ.hxx>
34 #include <gp_Dir.hxx>
35 #include <gp_Dir2d.hxx>
36 #include <gp_Lin2d.hxx>
37 #include <gp_Pnt.hxx>
38 #include <gp_Pnt2d.hxx>
39 #include <gp_Vec.hxx>
40 #include <Precision.hxx>
41 #include <TopOpeBRepDS_DataStructure.hxx>
42
43 //=======================================================================
44 //function : MakeChamfer
45 //purpose  : Compute the chamfer in the particular case Plane/Cone or 
46 //           Cylinder/Plane
47 //           Compute the SurfData <Data> of the chamfer build on the <Spine>
48 //           between the plane <Pln> and the cone <Con>, with the 
49 //           distances <Dis1> on <Pln> and <Dis2> on <Con>.
50 //           <Or1> and <Or2> are the orientations of <Pln> and <Con>
51 //           and <Ofpl> this of the face carried by <Pln>.
52 //           <First> is the start point on the <Spine>
53 //           <Plandab> is equal to True if the plane is the surface S1
54 //           <fu> and <lu> are the first and last u parameters of the
55 //           cone
56 //out      : True if the chanfer has been computed
57 //           False else
58 //=======================================================================
59 Standard_Boolean ChFiKPart_MakeChamfer(TopOpeBRepDS_DataStructure& DStr,
60                                        const Handle(ChFiDS_SurfData)& Data, 
61                                        const ChFiDS_ChamfMode theMode,
62                                        const gp_Pln& Pln, 
63                                        const gp_Cone& Con, 
64                                        const Standard_Real fu,
65                                        const Standard_Real lu,
66                                        const TopAbs_Orientation Or1,
67                                        const TopAbs_Orientation Or2,
68                                        const Standard_Real theDis1, 
69                                        const Standard_Real theDis2,
70                                        const gp_Circ& Spine, 
71                                        const Standard_Real First, 
72                                        const TopAbs_Orientation Ofpl,
73                                        const Standard_Boolean plandab)
74 {
75
76   Standard_Real angcon = Con.SemiAngle();
77
78   Standard_Real Dis1 = theDis1, Dis2 = theDis2;
79   Standard_Real Alpha = M_PI/2 - angcon;
80   Standard_Real CosHalfAlpha = Cos(Alpha/2);
81   if (theMode == ChFiDS_ConstThroatChamfer)
82     Dis1 = Dis2 = theDis1 / CosHalfAlpha;
83   else if (theMode == ChFiDS_ConstThroatWithPenetrationChamfer)
84   {
85     Standard_Real aDis1 = Min(theDis1, theDis2);
86     Standard_Real aDis2 = Max(theDis1, theDis2);
87     Standard_Real dis1dis1 = aDis1*aDis1, dis2dis2 = aDis2*aDis2;
88     Standard_Real SinAlpha = Sin(Alpha);
89     Standard_Real CosAlpha = Cos(Alpha);
90     Standard_Real CotanAlpha = CosAlpha/SinAlpha;
91     Dis1 = sqrt(dis2dis2 - dis1dis1) - aDis1*CotanAlpha;
92     Standard_Real CosBeta = sqrt(1-dis1dis1/dis2dis2)*CosAlpha + aDis1/aDis2*SinAlpha;
93     Standard_Real FullDist1 = aDis2/CosBeta;
94     Dis2 = FullDist1 - aDis1/SinAlpha;
95   }
96   
97   Standard_Real sincon =Abs(Sin(angcon));
98   Standard_Real angle;
99   Standard_Boolean IsResol;
100
101   gp_Ax3 PosPl = Pln.Position();
102   gp_Dir Dpl = PosPl.XDirection().Crossed(PosPl.YDirection());
103   if ( Or1 == TopAbs_REVERSED ) Dpl.Reverse();
104
105   // compute the origin of the conical chamfer PtPl
106   gp_Pnt Or = Con.Location();
107   Standard_Real u,v;
108   ElSLib::PlaneParameters(PosPl,Or,u,v);
109 #ifdef OCCT_DEBUG
110   gp_Pnt2d pt2dPln(u,v);
111 #endif
112   ElSLib::PlaneD0(u,v,PosPl,Or);
113
114   gp_Pnt PtSp;
115   gp_Vec DSp;
116   ElCLib::D1(First,Spine,PtSp,DSp);
117 #ifdef OCCT_DEBUG
118   gp_Dir Dx(gp_Vec(Or,PtSp));
119 #endif
120   //compute the normal to the cone in PtSp
121   gp_Vec deru,derv;
122   gp_Pnt PtCon;
123   ElSLib::Parameters(Con,PtSp,u,v);
124   ElSLib::D1(u,v,Con,PtCon ,deru,derv);
125   gp_Dir Dcon( deru.Crossed(derv) );
126   if ( Or2 == TopAbs_REVERSED ) Dcon.Reverse();
127   
128   Standard_Boolean ouvert = ( Dpl.Dot(Dcon) >= 0.);
129
130   if (!ouvert) {
131     if (Abs(Dis1 - Dis2 * sincon) > Precision::Confusion()) {
132       Standard_Real abscos = Abs(Dis2 - Dis1 * sincon);
133       angle = ATan((Dis1 * Cos(angcon)) / abscos);
134     }
135     else {
136       angle = angcon;
137     }
138   }
139   else {
140     angle = ATan((Dis1 * Cos(angcon)) / (Dis2 + Dis1 * sincon));
141   }
142
143   Standard_Boolean DisOnP = Standard_False;
144
145   IsResol = ChFiKPart_MakeChAsym(DStr,  Data, Pln, Con, fu, lu, Or1, Or2,
146                                  Dis2, angle, Spine,  First,  Ofpl, plandab, DisOnP);
147
148   return IsResol;
149
150 }
151  
152 /*
153  // Compute the chamfer surface(cone)
154   gp_Ax3 PosPl = Pln.Position();
155   gp_Dir Dpl = PosPl.XDirection().Crossed(PosPl.YDirection());
156   gp_Dir norf = Dpl;
157   if (Ofpl == TopAbs_REVERSED ) norf.Reverse();
158   if ( Or1 == TopAbs_REVERSED ) Dpl.Reverse();
159
160     // compute the origin of the conical chamfer PtPl
161   gp_Pnt Or = Con.Location();
162   Standard_Real u,v;
163   ElSLib::PlaneParameters(PosPl,Or,u,v);
164   gp_Pnt2d pt2dPln(u,v);
165   ElSLib::PlaneD0(u,v,PosPl,Or);
166   gp_Pnt PtPl = Or;
167
168   gp_Pnt PtSp;
169   gp_Vec DSp;
170   ElCLib::D1(First,Spine,PtSp,DSp);
171   gp_Dir Dx(gp_Vec(PtPl,PtSp));
172
173     //compute the normal to the cone in PtSp
174   gp_Vec deru,derv;
175   gp_Pnt PtCon;
176   ElSLib::Parameters(Con,PtSp,u,v);
177   ElSLib::D1(u,v,Con,PtCon ,deru,derv);
178   gp_Dir Dcon( deru.Crossed(derv) );
179   if ( Or2 == TopAbs_REVERSED ) Dcon.Reverse();
180   
181   Standard_Boolean dedans = ( Dx.Dot(Dcon) <= 0.);
182   Standard_Boolean ouvert = ( Dpl.Dot(Dcon) >= 0.);
183
184     // variables used to compute the semiangle of the chamfer
185   Standard_Real angle = Con.SemiAngle();
186   Standard_Real move = Dis2 * Cos(angle);
187   Or.SetCoord( Or.X()+ move*Dpl.X(),
188                Or.Y()+ move*Dpl.Y(),
189                Or.Z()+ move*Dpl.Z());
190
191   gp_Dir Vec1(Or.X()-PtPl.X(), Or.Y()-PtPl.Y(), Or.Z()-PtPl.Z());
192   Standard_Real Dis;
193   if (ouvert)
194     Dis = Dis1 + Dis2*Abs(Sin(angle));
195   else
196     Dis = Dis1 - Dis2*Abs(Sin(angle));
197
198   gp_Pnt Pt(Or.X()+Dis*PosPl.XDirection().X(),
199             Or.Y()+Dis*PosPl.XDirection().Y(),
200             Or.Z()+Dis*PosPl.XDirection().Z());
201   gp_Dir Vec2( Pt.X()-PtPl.X(), Pt.Y()-PtPl.Y(), Pt.Z()-PtPl.Z());
202
203     // compute the parameters of the conical chamfer
204   Standard_Real ChamfRad,SemiAngl;
205   Standard_Boolean pointu = Standard_False;
206
207   if (dedans) {
208     ChamfRad = Spine.Radius() - Dis1;
209     if ( Abs(ChamfRad)<=Precision::Confusion() ) pointu = Standard_True;
210     if( ChamfRad < 0 ) {
211 #ifdef OCCT_DEBUG
212       std::cout<<"le chanfrein ne passe pas"<<std::endl;
213 #endif
214       return Standard_False;
215     }
216   }
217   else {
218     ChamfRad = Spine.Radius() + Dis1;
219     gp_Dir Dplr = Dpl.Reversed();
220     Dpl = Dplr;
221   }
222
223   gp_Ax3 ChamfAx3(PtPl,Dpl,Dx);
224   SemiAngl = Vec1.Angle(Vec2);
225
226   Handle (Geom_ConicalSurface)
227     gcon = new Geom_ConicalSurface( ChamfAx3, SemiAngl, ChamfRad );
228
229     // changes due to the fact the parameters of the chamfer must go increasing
230     // from surface S1 to surface S2
231   if ( (dedans && !plandab) || (!dedans && plandab) ) {
232     gcon->VReverse();// be carefull : the SemiAngle was changed
233     ChamfAx3 = gcon->Position();
234     SemiAngl = gcon->SemiAngle();
235   }
236
237     // changes due to the fact we have reversed the V direction of 
238     // parametrization
239   if (ChamfAx3.YDirection().Dot(DSp) <= 0.) {
240     ChamfAx3.YReverse();
241     gcon->SetPosition(ChamfAx3);
242   }
243
244   Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(gcon,DStr));
245
246
247   //compute the chamfer's orientation according to the orientation
248   // of the faces
249
250     //search the normal to the conical chamfer
251   gp_Pnt P;
252   u=0.;
253   if (plandab)
254     v = sqrt(Dis*Dis + move*move);
255   else
256     v = - sqrt(Dis*Dis + move*move);
257   ElSLib::ConeD1(u,v,ChamfAx3,ChamfRad,SemiAngl,P,deru,derv);
258   gp_Dir norchamf(deru.Crossed(derv));
259
260   Standard_Boolean toreverse = (norf.Dot(norchamf)<= 0.);
261
262   if (toreverse)
263     Data->ChangeOrientation() = TopAbs_REVERSED;
264   else
265     Data->ChangeOrientation() = TopAbs_FORWARD; 
266
267
268   //we load the faceInterference with the pcurves and
269   // the 3d curves
270
271     // Case of the plane face
272     // NB: in the case 'pointu', no pcurve on the plane surface
273     // and no intersection plane-chamfer are needed
274
275     // intersection plane-chamfer
276   Handle(Geom_Circle) GCirPln;
277   Handle(Geom2d_Circle) GCir2dPln;
278   gp_Ax2 CirAx2 = ChamfAx3.Ax2();
279   CirAx2.SetLocation(PtPl);
280
281   if (!pointu) {
282     Pt.SetCoord(PtPl.X()+ChamfRad*Dx.X(),
283                 PtPl.Y()+ChamfRad*Dx.Y(),
284                 PtPl.Z()+ChamfRad*Dx.Z());
285     gp_Circ CirPln(CirAx2,ChamfRad);
286     GCirPln = new Geom_Circle(CirPln);
287   
288       //pcurve on the plane
289     ElSLib::PlaneParameters(PosPl,Pt ,u,v);
290     gp_Pnt2d p2dPln(u,v);
291     gp_Dir2d d2d(DSp.Dot(PosPl.XDirection()),DSp.Dot(PosPl.YDirection()));
292     gp_Ax22d ax2dPln(pt2dPln, gp_Dir2d(gp_Vec2d(pt2dPln,p2dPln)),d2d);
293     gp_Circ2d cir2dPln(ax2dPln,ChamfRad);
294     GCir2dPln = new Geom2d_Circle(cir2dPln);
295   }
296
297       //pcurve on chamfer
298   gp_Pnt2d p2dch;
299   p2dch.SetCoord(0.,0.);
300   ElSLib::ConeD1(0.,0.,ChamfAx3,ChamfRad,SemiAngl,Pt,deru,derv);
301   gp_Lin2d lin2dch(p2dch,gp::DX2d());
302   Handle(Geom2d_Line) GLin2dCh1 = new Geom2d_Line(lin2dch);
303
304       //orientation
305   TopAbs_Orientation trans; 
306   gp_Dir norpl = PosPl.XDirection().Crossed(PosPl.YDirection());
307   if (!pointu)
308     norchamf.SetXYZ (deru.Crossed(derv).XYZ());
309   toreverse = ( norchamf.Dot(norpl) <= 0. );
310   if ((toreverse && plandab) || (!toreverse && !plandab)){ 
311     trans = TopAbs_FORWARD;
312   }
313   else { 
314     trans = TopAbs_REVERSED; 
315   }
316
317   if(plandab){
318     Data->ChangeInterferenceOnS1().
319       SetInterference(ChFiKPart_IndexCurveInDS(GCirPln,DStr),
320                       trans,GCir2dPln,GLin2dCh1);
321   }
322   else{
323     Data->ChangeInterferenceOnS2().
324       SetInterference(ChFiKPart_IndexCurveInDS(GCirPln,DStr),
325                       trans,GCir2dPln,GLin2dCh1);
326   }
327
328
329     // Case of the conical face
330
331       //intersection cone-chamfer
332   Standard_Real Rad;
333   if (dedans)
334     Rad = ChamfRad + Dis;
335   else
336     Rad = ChamfRad - Dis;
337
338   CirAx2.SetLocation(Or);
339   gp_Circ CirCon(CirAx2, Rad);
340   Handle(Geom_Circle) GCirCon = new Geom_Circle(CirCon);  
341
342       //pcurve on chamfer
343   if (plandab)
344     v = sqrt(Dis*Dis + move*move);
345   else
346     v = - sqrt(Dis*Dis + move*move);
347   p2dch.SetCoord(0.,v);
348   ElSLib::ConeD1(0.,v,ChamfAx3,ChamfRad,SemiAngl,Pt,deru,derv);
349   lin2dch.SetLocation(p2dch);
350   Handle(Geom2d_Line) GLin2dCh2 = new Geom2d_Line(lin2dch);
351   
352       //pcurve on cone
353   norchamf.SetXYZ (deru.Crossed(derv).XYZ());
354
355   Pt.SetCoord(Or.X()+Rad*Dx.X(),
356               Or.Y()+Rad*Dx.Y(),
357               Or.Z()+Rad*Dx.Z());
358   ElSLib::Parameters(Con,Pt ,u,v);
359   Standard_Real tol = Precision::PConfusion();
360   if(u >= 2*M_PI - tol && u <= 2*M_PI) u = 0.;
361   if(u >= fu - tol && u < fu) u = fu;
362   if(u <= lu + tol && u > lu) u = lu;
363   if(u < fu || u > lu) u = ElCLib::InPeriod(u,fu,fu + 2*M_PI);
364   ElSLib::D1(u,v,Con,Pt,deru,derv);
365   gp_Pnt2d p2dCon(u,v);
366   gp_Dir2d d2dCon;
367   if ( deru.Dot(DSp)<=0. )
368     d2dCon = - gp::DX2d();
369   else
370     d2dCon = gp::DX2d();
371   gp_Lin2d lin2dCon(p2dCon,d2dCon);
372   Handle(Geom2d_Line) GLin2dCon = new Geom2d_Line(lin2dCon);
373
374       //orientation
375   gp_Dir norcon = deru.Crossed(derv);
376   toreverse = ( norchamf.Dot(norcon) <= 0. );
377   if ((toreverse && plandab) || (!toreverse && !plandab) ) {
378     trans = TopAbs_REVERSED;
379   }
380   else {
381     trans = TopAbs_FORWARD;
382   }
383
384   if(plandab){
385     Data->ChangeInterferenceOnS2().
386       SetInterference(ChFiKPart_IndexCurveInDS(GCirCon,DStr),
387                       trans,GLin2dCon,GLin2dCh2);
388   }
389   else{
390     Data->ChangeInterferenceOnS1().
391       SetInterference(ChFiKPart_IndexCurveInDS(GCirCon,DStr),
392                       trans,GLin2dCon,GLin2dCh2);
393   }
394   
395
396   return Standard_True;
397 }
398
399 */
400
401
402
403
404
405