summaryrefslogtreecommitdiff
path: root/src/ChFiKPart/ChFiKPart_ComputeData_ChAsymPlnPln.cxx
blob: 0872eb3b240c7b4b23226dbd21561727eea8bb1b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
// File:	ChFiKPart_ComputeData_ChAsymPlnPln.cxx
// Created:	Tue Jun 16 09:21:42 1998
// Author:	Philippe NOUAILLE
//		<pne@cleox.paris1.matra-dtv.fr>


#include <ChFiKPart_ComputeData.ixx>
#include <Precision.hxx>
#include <gp.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Lin2d.hxx>
#include <gp_Pnt.hxx>
#include <gp_Dir.hxx>
#include <gp_Lin.hxx>
#include <gp_Ax3.hxx>
#include <gp_Pln.hxx>

#include <ElCLib.hxx>
#include <ElSLib.hxx>

#include <Geom2d_Line.hxx>
#include <Geom_Line.hxx>

#include <Geom_Plane.hxx>

#include <IntAna_QuadQuadGeo.hxx>

#include <ChFiKPart_ComputeData_Fcts.hxx>




//=======================================================================
//function : MakeChAsym
//Purpose  : Compute the chamfer in the particular case plane/plane.
//           Compute the SurfData <Data> of the chamfer on the <Spine> 
//           between the plane <Pl1> and the plane <Pl2>, with distances
//           <Dis> and Angle on <Pl1> .
//           <First> is the parameter of the start point on the <Spine>
//           <Or1> and <Or2> are the orientations of the plane <Pl1> and
//           <Pl2>, and <Of1> the orientation of the face build on the
//           plane <Pl1>.
//Out      : True if the chamfer has been computed
//           False else
//=======================================================================

Standard_Boolean ChFiKPart_MakeChAsym(TopOpeBRepDS_DataStructure& DStr,
				      const Handle(ChFiDS_SurfData)& Data, 
				      const gp_Pln& Pl1, 
				      const gp_Pln& Pl2, 
				      const TopAbs_Orientation Or1,
				      const TopAbs_Orientation Or2,
				      const Standard_Real Dis, 
				      const Standard_Real Angle, 
				      const gp_Lin& Spine, 
				      const Standard_Real First, 
				      const TopAbs_Orientation Of1,
                                      const Standard_Boolean DisOnP1)
{

  // Creation of the plane which carry the chamfer

  // compute the normals to the planes Pl1 and Pl2
  gp_Ax3 Pos1 = Pl1.Position();
  gp_Dir D1   = Pos1.XDirection().Crossed(Pos1.YDirection());
  if (Or1 == TopAbs_REVERSED) { D1.Reverse(); }

  gp_Ax3 Pos2 = Pl2.Position();
  gp_Dir D2   = Pos2.XDirection().Crossed(Pos2.YDirection());
  if (Or2 == TopAbs_REVERSED) { D2.Reverse(); }

  // compute the intersection line of Pl1 and Pl2
  IntAna_QuadQuadGeo LInt (Pl1, Pl2, Precision::Angular(),
			   Precision::Confusion());
  
  gp_Pnt P;
  Standard_Real Fint;
  if (LInt.IsDone()) {
    Fint = ElCLib::Parameter(LInt.Line(1), ElCLib::Value(First, Spine));
    P = ElCLib::Value(Fint, LInt.Line(1));
  }
  else { return Standard_False; }

  gp_Dir LinAx1     = Spine.Direction();
  gp_Dir VecTransl1 = LinAx1.Crossed(D1);
  if ( VecTransl1.Dot(D2) < 0. )
    VecTransl1.Reverse();

  gp_Dir VecTransl2 = LinAx1.Crossed(D2);
  if ( VecTransl2.Dot(D1) < 0. )
    VecTransl2.Reverse();

  Standard_Real cosP, sinP, dis1, dis2;
  cosP = VecTransl1.Dot(VecTransl2);
  sinP = sqrt(1. - cosP * cosP);
   
  if (DisOnP1) {
    dis1 = Dis;
    dis2 = Dis / (cosP + sinP / Tan(Angle));    
  }  
  else {
    dis1 = Dis / (cosP + sinP / Tan(Angle));
    dis2 = Dis;
  }
  // Compute a point on the plane Pl1 and on the chamfer
  gp_Pnt P1( P.X() + dis1 * VecTransl1.X(),
	     P.Y() + dis1 * VecTransl1.Y(),
	     P.Z() + dis1 * VecTransl1.Z());

  // Point on the plane Pl2 and on the chamfer
  gp_Pnt P2( P.X() + dis2 * VecTransl2.X(),
	     P.Y() + dis2 * VecTransl2.Y(),
	     P.Z() + dis2 * VecTransl2.Z());

  //the middle point of P1 P2 is the origin of the chamfer
  gp_Pnt Po ( (P1.X() + P2.X()) / 2., (P1.Y() + P2.Y()) / 2., (P1.Z() + P2.Z()) / 2.); 
  
  // compute a second point on the plane Pl2 
  gp_Pnt Pp = ElCLib::Value(Fint + 10., LInt.Line(1));
  gp_Pnt P22(Pp.X() + dis2 * VecTransl2.X(),
	     Pp.Y() + dis2 * VecTransl2.Y(),
	     Pp.Z() + dis2 * VecTransl2.Z()); 
  
  // Compute the normal vector <AxisPlan> to the chamfer's plane
  gp_Dir V1 ( P2.X() - P1.X(), P2.Y() - P1.Y(), P2.Z() - P1.Z());
  gp_Dir V2 ( P22.X() - P1.X(), P22.Y() - P1.Y(), P22.Z() - P1.Z());
  gp_Dir AxisPlan = V1.Crossed(V2);

  gp_Dir xdir = LinAx1; // u axis
  gp_Ax3 PlanAx3 (Po, AxisPlan, xdir);
  if (PlanAx3.YDirection().Dot(D2)>=0.)  PlanAx3.YReverse();

  Handle(Geom_Plane) gpl= new Geom_Plane(PlanAx3);
  Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(gpl, DStr));

  // About the orientation of the chamfer plane
  // Compute the normal to the face 1
  gp_Dir norpl    = Pos1.XDirection().Crossed(Pos1.YDirection());
  gp_Dir norface1 = norpl;
  if (Of1 == TopAbs_REVERSED ) { norface1.Reverse(); }

  // Compute the orientation of the chamfer plane
  gp_Dir norplch = gpl->Pln().Position().XDirection().Crossed (
				gpl->Pln().Position().YDirection());

  gp_Dir DirCh12(gp_Vec(P1, P2));
  Standard_Boolean toreverse = ( norplch.Dot(norface1) <= 0. );
  if (VecTransl1.Dot(DirCh12) > 0)  toreverse = !toreverse;
  
  if (toreverse)
    Data->ChangeOrientation() = TopAbs_REVERSED; 
  else
    Data->ChangeOrientation() = TopAbs_FORWARD;

  // Loading of the FaceInterferences with pcurves & 3d curves.
  
  // case face 1 
  gp_Lin linPln(P1, xdir);
  Handle(Geom_Line) GLinPln1 = new Geom_Line(linPln);

  Standard_Real u, v;
  ElSLib::PlaneParameters(Pos1, P1, u, v);
  gp_Pnt2d p2dPln(u, v);
  gp_Dir2d dir2dPln( xdir.Dot(Pos1.XDirection()),
		     xdir.Dot(Pos1.YDirection()));
  gp_Lin2d lin2dPln(p2dPln, dir2dPln);
  Handle(Geom2d_Line) GLin2dPln1 = new Geom2d_Line(lin2dPln);

  ElSLib::PlaneParameters(PlanAx3, P1, u, v);
  p2dPln.SetCoord(u, v);
  lin2dPln.SetLocation(p2dPln);
  lin2dPln.SetDirection(gp::DX2d());
  Handle(Geom2d_Line) GLin2dPlnCh1 = new Geom2d_Line(lin2dPln);

  TopAbs_Orientation trans; 
  toreverse = ( norplch.Dot(norpl) <= 0. );
  if (VecTransl1.Dot(DirCh12) > 0)  toreverse = !toreverse;
  if (toreverse)
    trans = TopAbs_FORWARD;
  else 
    trans = TopAbs_REVERSED; 

  Data->ChangeInterferenceOnS1().
    SetInterference(ChFiKPart_IndexCurveInDS(GLinPln1, DStr),
		    trans, GLin2dPln1, GLin2dPlnCh1);


  // case face 2

  linPln.SetLocation(P2);
  Handle(Geom_Line) GLinPln2 = new Geom_Line(linPln);

  ElSLib::PlaneParameters(Pos2, P2, u, v);
  p2dPln.SetCoord(u, v);
  dir2dPln.SetCoord( xdir.Dot(Pos2.XDirection()),
		     xdir.Dot(Pos2.YDirection()));
  lin2dPln.SetLocation(p2dPln);
  lin2dPln.SetDirection(dir2dPln);
  Handle(Geom2d_Line) GLin2dPln2 = new Geom2d_Line(lin2dPln);

  ElSLib::PlaneParameters(PlanAx3, P2, u, v);
  p2dPln.SetCoord(u, v);
  lin2dPln.SetLocation(p2dPln);
  lin2dPln.SetDirection(gp::DX2d());
  Handle(Geom2d_Line) GLin2dPlnCh2 = new Geom2d_Line(lin2dPln);

  norpl = Pos2.XDirection().Crossed(Pos2.YDirection());
  toreverse = ( norplch.Dot(norpl) <= 0. );
  if (VecTransl2.Dot(DirCh12) < 0)  toreverse = !toreverse;
  if (toreverse)
    trans = TopAbs_REVERSED; 
  else
    trans = TopAbs_FORWARD; 

  Data->ChangeInterferenceOnS2().
    SetInterference(ChFiKPart_IndexCurveInDS(GLinPln2,DStr),
		    trans, GLin2dPln2, GLin2dPlnCh2);

  return Standard_True;

}