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
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
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>
29 //=======================================================================
30 //function : Hatch_Hatcher
32 //=======================================================================
33 Hatch_Hatcher::Hatch_Hatcher(const Standard_Real Tol,
34 const Standard_Boolean Oriented) :
40 //=======================================================================
43 //=======================================================================
45 void Hatch_Hatcher::AddLine(const gp_Lin2d& L, const Hatch_LineForm T)
51 //=======================================================================
54 //=======================================================================
56 void Hatch_Hatcher::AddLine(const gp_Dir2d& D,
57 const Standard_Real Dist)
59 Standard_Real X = D.X();
60 Standard_Real Y = D.Y();
61 gp_Pnt2d O(-Y * Dist, X * Dist);
63 AddLine(L,Hatch_ANYLINE);
66 //=======================================================================
69 //=======================================================================
71 void Hatch_Hatcher::AddXLine(const Standard_Real X)
76 AddLine(L,Hatch_XLINE);
79 //=======================================================================
82 //=======================================================================
84 void Hatch_Hatcher::AddYLine(const Standard_Real Y)
89 AddLine(L,Hatch_YLINE);
92 //=======================================================================
95 //=======================================================================
97 void Hatch_Hatcher::Trim
99 const Standard_Integer Index)
101 Trim(L,RealFirst(),RealLast(),Index);
104 //=======================================================================
107 //=======================================================================
109 void Hatch_Hatcher::Trim
111 const Standard_Real Start,
112 const Standard_Real End,
113 const Standard_Integer Index)
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;
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;
138 // insert the parameter
139 myLines(iLine).AddIntersection (Pinter.ParamOnFirst(),
142 Pinter.ParamOnSecond(),
149 //=======================================================================
152 //=======================================================================
154 void Hatch_Hatcher::Trim
157 const Standard_Integer Index)
160 if (Abs(V.X()) > .9 * RealLast())
162 else if (Abs(V.Y()) > .9 * RealLast())
164 if (V.Magnitude() > myToler) {
167 Trim(L,0,P1.Distance(P2),Index);
171 //=======================================================================
172 //function : NbIntervals
174 //=======================================================================
176 Standard_Integer Hatch_Hatcher::NbIntervals() const
178 Standard_Integer i, nb = 0;
179 for (i = 1; i <= myLines.Length(); i++)
180 nb += NbIntervals(i);
184 //=======================================================================
187 //=======================================================================
189 Standard_Integer Hatch_Hatcher::NbLines() const
191 return myLines.Length();
194 //=======================================================================
197 //=======================================================================
199 const gp_Lin2d& Hatch_Hatcher::Line(const Standard_Integer I) const
201 return myLines(I).myLin;
204 //=======================================================================
205 //function : LineForm
207 //=======================================================================
209 Hatch_LineForm Hatch_Hatcher::LineForm(const Standard_Integer I) const
211 return myLines(I).myForm;
214 //=======================================================================
215 //function : Coordinate
217 //=======================================================================
219 Standard_Real Hatch_Hatcher::Coordinate(const Standard_Integer I) const
221 switch (myLines(I).myForm) {
224 return myLines(I).myLin.Location().X();
227 return myLines(I).myLin.Location().Y();
230 throw Standard_OutOfRange("Hatcher : not an X or Y line");
236 //=======================================================================
237 //function : NbIntervals
239 //=======================================================================
241 Standard_Integer Hatch_Hatcher::NbIntervals(const Standard_Integer I) const
243 Standard_Integer l = myLines(I).myInters.Length();
245 l = myOrient ? 1 : 0;
248 if (myOrient) if (!myLines(I).myInters(1).myStart) l++;
253 //=======================================================================
256 //=======================================================================
258 Standard_Real Hatch_Hatcher::Start(const Standard_Integer I,
259 const Standard_Integer J) const
261 if (myLines(I).myInters.IsEmpty()) {
262 if (J != 1 || !myOrient) throw Standard_OutOfRange();
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;
273 //=======================================================================
274 //function : StartIndex
276 //=======================================================================
278 void Hatch_Hatcher::StartIndex
279 (const Standard_Integer I,
280 const Standard_Integer J,
281 Standard_Integer& Index,
282 Standard_Real& Par2) const
284 if (myLines(I).myInters.IsEmpty()) {
285 if (J != 1) throw Standard_OutOfRange();
290 Standard_Integer jj = 2*J - 1;
291 if (!myLines(I).myInters(1).myStart && myOrient) jj--;
297 Index = myLines(I).myInters(jj).myIndex;
298 Par2 = myLines(I).myInters(jj).myPar2;
303 //=======================================================================
306 //=======================================================================
308 Standard_Real Hatch_Hatcher::End(const Standard_Integer I,
309 const Standard_Integer J) const
311 if (myLines(I).myInters.IsEmpty()) {
312 if (J != 1 || !myOrient) throw Standard_OutOfRange();
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;
323 //=======================================================================
324 //function : EndIndex
326 //=======================================================================
328 void Hatch_Hatcher::EndIndex
329 (const Standard_Integer I,
330 const Standard_Integer J,
331 Standard_Integer& Index,
332 Standard_Real& Par2) const
334 if (myLines(I).myInters.IsEmpty()) {
335 if (J != 1) throw Standard_OutOfRange();
340 Standard_Integer jj = 2*J;
341 if (!myLines(I).myInters(1).myStart && myOrient) jj--;
342 if (jj > myLines(I).myInters.Length()) {
347 Index = myLines(I).myInters(jj).myIndex;
348 Par2 = myLines(I).myInters(jj).myPar2;