0024002: Overall code and build procedure refactoring -- automatic
[occt.git] / src / Hatch / Hatch_Hatcher.cxx
1 // Created on: 1992-08-19
2 // Created by: Modelistation
3 // Copyright (c) 1992-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 <gp_Dir2d.hxx>
19 #include <gp_Lin2d.hxx>
20 #include <gp_Pnt2d.hxx>
21 #include <gp_Vec2d.hxx>
22 #include <Hatch_Hatcher.hxx>
23 #include <Hatch_Line.hxx>
24 #include <Hatch_Parameter.hxx>
25 #include <IntAna2d_AnaIntersection.hxx>
26 #include <IntAna2d_IntPoint.hxx>
27 #include <Standard_OutOfRange.hxx>
28
29 //=======================================================================
30 //function : Hatch_Hatcher
31 //purpose  : 
32 //=======================================================================
33 Hatch_Hatcher::Hatch_Hatcher(const Standard_Real Tol,
34                              const Standard_Boolean Oriented) :
35        myToler(Tol),
36        myOrient(Oriented)
37 {
38 }
39
40 //=======================================================================
41 //function : AddLine
42 //purpose  : 
43 //=======================================================================
44
45 void  Hatch_Hatcher::AddLine(const gp_Lin2d& L, const Hatch_LineForm T)
46 {
47   Hatch_Line HL(L,T);
48   myLines.Append(HL);
49 }
50
51 //=======================================================================
52 //function : AddLine
53 //purpose  : 
54 //=======================================================================
55
56 void  Hatch_Hatcher::AddLine(const gp_Dir2d& D, 
57                              const Standard_Real Dist)
58 {
59   Standard_Real X = D.X();
60   Standard_Real Y = D.Y();
61   gp_Pnt2d O(-Y * Dist, X * Dist);
62   gp_Lin2d L(O,D);
63   AddLine(L,Hatch_ANYLINE);
64 }
65
66 //=======================================================================
67 //function : AddXLine
68 //purpose  : 
69 //=======================================================================
70
71 void  Hatch_Hatcher::AddXLine(const Standard_Real X)
72 {
73   gp_Pnt2d O(X,0);
74   gp_Dir2d D(0,1);
75   gp_Lin2d L(O,D);
76   AddLine(L,Hatch_XLINE);
77 }
78
79 //=======================================================================
80 //function : AddYLine
81 //purpose  : 
82 //=======================================================================
83
84 void  Hatch_Hatcher::AddYLine(const Standard_Real Y)
85 {
86   gp_Pnt2d O(0,Y);
87   gp_Dir2d D(1,0);
88   gp_Lin2d L(O,D);
89   AddLine(L,Hatch_YLINE);
90 }
91
92 //=======================================================================
93 //function : Trim
94 //purpose  : 
95 //=======================================================================
96
97 void  Hatch_Hatcher::Trim
98   (const gp_Lin2d& L,
99    const Standard_Integer Index)
100 {
101   Trim(L,RealFirst(),RealLast(),Index);
102 }
103
104 //=======================================================================
105 //function : Trim
106 //purpose  : 
107 //=======================================================================
108
109 void  Hatch_Hatcher::Trim
110   (const gp_Lin2d& L,
111    const Standard_Real Start,
112    const Standard_Real End,
113    const Standard_Integer Index)
114 {
115   IntAna2d_IntPoint        Pinter;
116   IntAna2d_AnaIntersection Inters;
117   Standard_Integer         iLine;
118   for (iLine = 1; iLine <= myLines.Length(); iLine++) {
119     Inters.Perform(myLines(iLine).myLin,L);
120     if (Inters.IsDone()) {
121       if (!Inters.IdenticalElements() && !Inters.ParallelElements()) {
122         // we have got something
123         Pinter  = Inters.Point(1);
124         Standard_Real linePar = Pinter.ParamOnSecond();
125         if (linePar -   Start < - myToler) continue;
126         if (linePar -   End   >   myToler) continue;
127         Standard_Real norm = L.Direction() ^ myLines(iLine).myLin.Direction();
128         if (linePar -   Start <   myToler) {
129           // on the limit of the trimming segment
130           // accept if the other extremity is on the left
131           if (norm < 0) continue;
132         }
133         if (linePar -   End   >  -myToler) {
134           // on the limit of the trimming segment
135           // accept if the other extremity is on the left
136           if (norm > 0) continue;
137         }
138         // insert the parameter
139         myLines(iLine).AddIntersection (Pinter.ParamOnFirst(),
140                                         norm > 0,
141                                         Index,
142                                         Pinter.ParamOnSecond(),
143                                         myToler);
144       }
145     }
146   }
147 }
148
149 //=======================================================================
150 //function : Trim
151 //purpose  : 
152 //=======================================================================
153
154 void  Hatch_Hatcher::Trim
155   (const gp_Pnt2d& P1, 
156    const gp_Pnt2d& P2,
157    const Standard_Integer Index)
158 {
159   gp_Vec2d V(P1,P2);
160   if (Abs(V.X()) > .9 * RealLast())
161     V.Multiply(1/V.X());
162   else if (Abs(V.Y()) > .9 * RealLast())
163     V.Multiply(1/V.Y());
164   if (V.Magnitude() > myToler) {
165     gp_Dir2d D(V);
166     gp_Lin2d L(P1,D);
167     Trim(L,0,P1.Distance(P2),Index);
168   }
169 }
170
171 //=======================================================================
172 //function : NbIntervals
173 //purpose  : 
174 //=======================================================================
175
176 Standard_Integer Hatch_Hatcher::NbIntervals() const
177 {
178   Standard_Integer i, nb = 0;
179   for (i = 1; i <= myLines.Length(); i++)
180     nb += NbIntervals(i);
181   return nb;
182 }
183
184 //=======================================================================
185 //function : NbLines
186 //purpose  : 
187 //=======================================================================
188
189 Standard_Integer Hatch_Hatcher::NbLines() const
190 {
191   return myLines.Length();
192 }
193
194 //=======================================================================
195 //function : Line
196 //purpose  : 
197 //=======================================================================
198
199 const gp_Lin2d& Hatch_Hatcher::Line(const Standard_Integer I) const
200 {
201   return myLines(I).myLin;
202 }
203
204 //=======================================================================
205 //function : LineForm
206 //purpose  : 
207 //=======================================================================
208
209 Hatch_LineForm Hatch_Hatcher::LineForm(const Standard_Integer I) const
210 {
211   return myLines(I).myForm;
212 }
213
214 //=======================================================================
215 //function : Coordinate
216 //purpose  : 
217 //=======================================================================
218
219 Standard_Real Hatch_Hatcher::Coordinate(const Standard_Integer I) const
220 {
221   switch (myLines(I).myForm) {
222     
223   case Hatch_XLINE :
224     return myLines(I).myLin.Location().X();
225
226   case Hatch_YLINE :
227     return myLines(I).myLin.Location().Y();
228
229   case Hatch_ANYLINE :
230     Standard_OutOfRange::Raise("Hatcher : not an X or Y line");
231     return 0.;
232   }
233
234   return 0.;
235 }
236
237 //=======================================================================
238 //function : NbIntervals
239 //purpose  : 
240 //=======================================================================
241
242 Standard_Integer Hatch_Hatcher::NbIntervals(const Standard_Integer I) const
243 {
244   Standard_Integer l = myLines(I).myInters.Length();
245   if (l == 0)
246     l = myOrient ? 1 : 0;
247   else {
248     l = l/2;
249     if (myOrient) if (!myLines(I).myInters(1).myStart) l++;
250   }
251   return l;
252 }
253
254 //=======================================================================
255 //function : Start
256 //purpose  : 
257 //=======================================================================
258
259 Standard_Real Hatch_Hatcher::Start(const Standard_Integer I,
260                                    const Standard_Integer J) const
261 {
262   if (myLines(I).myInters.IsEmpty()) {
263     if (J != 1 || !myOrient) Standard_OutOfRange::Raise();
264     return RealFirst();
265   }
266   else {
267     Standard_Integer jj = 2*J - 1;
268     if (!myLines(I).myInters(1).myStart && myOrient) jj--;
269     if (jj == 0) return RealFirst();
270     return myLines(I).myInters(jj).myPar1;
271   }
272 }
273
274 //=======================================================================
275 //function : StartIndex
276 //purpose  : 
277 //=======================================================================
278
279 void Hatch_Hatcher::StartIndex
280   (const Standard_Integer I,
281    const Standard_Integer J,
282    Standard_Integer& Index,
283    Standard_Real& Par2) const
284 {
285   if (myLines(I).myInters.IsEmpty()) {
286     if (J != 1) Standard_OutOfRange::Raise();
287     Index = 0;
288     Par2  = 0;
289   }
290   else {
291     Standard_Integer jj = 2*J - 1;
292     if (!myLines(I).myInters(1).myStart && myOrient) jj--;
293     if (jj == 0) {
294       Index = 0;
295       Par2  = 0;
296     }
297     else {
298       Index = myLines(I).myInters(jj).myIndex;
299       Par2  = myLines(I).myInters(jj).myPar2;
300     }
301   }
302 }
303
304 //=======================================================================
305 //function : End
306 //purpose  : 
307 //=======================================================================
308
309 Standard_Real Hatch_Hatcher::End(const Standard_Integer I,
310                                  const Standard_Integer J) const
311 {
312   if (myLines(I).myInters.IsEmpty()) {
313     if (J != 1 || !myOrient) Standard_OutOfRange::Raise();
314     return RealLast();
315   }
316   else {
317     Standard_Integer jj = 2*J;
318     if (!myLines(I).myInters(1).myStart && myOrient) jj--;
319     if (jj > myLines(I).myInters.Length()) return RealLast();
320     return myLines(I).myInters(jj).myPar1;
321   }
322 }
323
324 //=======================================================================
325 //function : EndIndex
326 //purpose  : 
327 //=======================================================================
328
329 void Hatch_Hatcher::EndIndex
330   (const Standard_Integer I,
331    const Standard_Integer J,
332    Standard_Integer& Index,
333    Standard_Real& Par2) const
334 {
335   if (myLines(I).myInters.IsEmpty()) {
336     if (J != 1) Standard_OutOfRange::Raise();
337     Index = 0;
338     Par2  = 0;
339   }
340   else {
341     Standard_Integer jj = 2*J;
342     if (!myLines(I).myInters(1).myStart && myOrient) jj--;
343     if (jj > myLines(I).myInters.Length()) {
344       Index = 0;
345       Par2  = 0;
346     }
347     else {
348       Index = myLines(I).myInters(jj).myIndex;
349       Par2  = myLines(I).myInters(jj).myPar2;
350     }
351   }
352 }