b311480e |
1 | // Created on: 1992-08-19 |
2 | // Created by: Modelistation |
3 | // Copyright (c) 1992-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
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 |
973c2be1 |
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. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
7fd59977 |
16 | |
42cf5bc1 |
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> |
7fd59977 |
23 | #include <Hatch_Line.hxx> |
7fd59977 |
24 | #include <Hatch_Parameter.hxx> |
42cf5bc1 |
25 | #include <IntAna2d_AnaIntersection.hxx> |
26 | #include <IntAna2d_IntPoint.hxx> |
7fd59977 |
27 | #include <Standard_OutOfRange.hxx> |
28 | |
29 | //======================================================================= |
30 | //function : Hatch_Hatcher |
31 | //purpose : |
32 | //======================================================================= |
7fd59977 |
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 | } |