0031687: Draw Harness, ViewerTest - extend command vrenderparams with option updating...
[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     throw Standard_OutOfRange("Hatcher : not an X or Y line");
231   }
232
233   return 0.;
234 }
235
236 //=======================================================================
237 //function : NbIntervals
238 //purpose  : 
239 //=======================================================================
240
241 Standard_Integer Hatch_Hatcher::NbIntervals(const Standard_Integer I) const
242 {
243   Standard_Integer l = myLines(I).myInters.Length();
244   if (l == 0)
245     l = myOrient ? 1 : 0;
246   else {
247     l = l/2;
248     if (myOrient) if (!myLines(I).myInters(1).myStart) l++;
249   }
250   return l;
251 }
252
253 //=======================================================================
254 //function : Start
255 //purpose  : 
256 //=======================================================================
257
258 Standard_Real Hatch_Hatcher::Start(const Standard_Integer I,
259                                    const Standard_Integer J) const
260 {
261   if (myLines(I).myInters.IsEmpty()) {
262     if (J != 1 || !myOrient) throw Standard_OutOfRange();
263     return RealFirst();
264   }
265   else {
266     Standard_Integer jj = 2*J - 1;
267     if (!myLines(I).myInters(1).myStart && myOrient) jj--;
268     if (jj == 0) return RealFirst();
269     return myLines(I).myInters(jj).myPar1;
270   }
271 }
272
273 //=======================================================================
274 //function : StartIndex
275 //purpose  : 
276 //=======================================================================
277
278 void Hatch_Hatcher::StartIndex
279   (const Standard_Integer I,
280    const Standard_Integer J,
281    Standard_Integer& Index,
282    Standard_Real& Par2) const
283 {
284   if (myLines(I).myInters.IsEmpty()) {
285     if (J != 1) throw Standard_OutOfRange();
286     Index = 0;
287     Par2  = 0;
288   }
289   else {
290     Standard_Integer jj = 2*J - 1;
291     if (!myLines(I).myInters(1).myStart && myOrient) jj--;
292     if (jj == 0) {
293       Index = 0;
294       Par2  = 0;
295     }
296     else {
297       Index = myLines(I).myInters(jj).myIndex;
298       Par2  = myLines(I).myInters(jj).myPar2;
299     }
300   }
301 }
302
303 //=======================================================================
304 //function : End
305 //purpose  : 
306 //=======================================================================
307
308 Standard_Real Hatch_Hatcher::End(const Standard_Integer I,
309                                  const Standard_Integer J) const
310 {
311   if (myLines(I).myInters.IsEmpty()) {
312     if (J != 1 || !myOrient) throw Standard_OutOfRange();
313     return RealLast();
314   }
315   else {
316     Standard_Integer jj = 2*J;
317     if (!myLines(I).myInters(1).myStart && myOrient) jj--;
318     if (jj > myLines(I).myInters.Length()) return RealLast();
319     return myLines(I).myInters(jj).myPar1;
320   }
321 }
322
323 //=======================================================================
324 //function : EndIndex
325 //purpose  : 
326 //=======================================================================
327
328 void Hatch_Hatcher::EndIndex
329   (const Standard_Integer I,
330    const Standard_Integer J,
331    Standard_Integer& Index,
332    Standard_Real& Par2) const
333 {
334   if (myLines(I).myInters.IsEmpty()) {
335     if (J != 1) throw Standard_OutOfRange();
336     Index = 0;
337     Par2  = 0;
338   }
339   else {
340     Standard_Integer jj = 2*J;
341     if (!myLines(I).myInters(1).myStart && myOrient) jj--;
342     if (jj > myLines(I).myInters.Length()) {
343       Index = 0;
344       Par2  = 0;
345     }
346     else {
347       Index = myLines(I).myInters(jj).myIndex;
348       Par2  = myLines(I).myInters(jj).myPar2;
349     }
350   }
351 }