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 Standard_OutOfRange::Raise("Hatcher : not an X or Y line");
237 //=======================================================================
238 //function : NbIntervals
240 //=======================================================================
242 Standard_Integer Hatch_Hatcher::NbIntervals(const Standard_Integer I) const
244 Standard_Integer l = myLines(I).myInters.Length();
246 l = myOrient ? 1 : 0;
249 if (myOrient) if (!myLines(I).myInters(1).myStart) l++;
254 //=======================================================================
257 //=======================================================================
259 Standard_Real Hatch_Hatcher::Start(const Standard_Integer I,
260 const Standard_Integer J) const
262 if (myLines(I).myInters.IsEmpty()) {
263 if (J != 1 || !myOrient) Standard_OutOfRange::Raise();
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;
274 //=======================================================================
275 //function : StartIndex
277 //=======================================================================
279 void Hatch_Hatcher::StartIndex
280 (const Standard_Integer I,
281 const Standard_Integer J,
282 Standard_Integer& Index,
283 Standard_Real& Par2) const
285 if (myLines(I).myInters.IsEmpty()) {
286 if (J != 1) Standard_OutOfRange::Raise();
291 Standard_Integer jj = 2*J - 1;
292 if (!myLines(I).myInters(1).myStart && myOrient) jj--;
298 Index = myLines(I).myInters(jj).myIndex;
299 Par2 = myLines(I).myInters(jj).myPar2;
304 //=======================================================================
307 //=======================================================================
309 Standard_Real Hatch_Hatcher::End(const Standard_Integer I,
310 const Standard_Integer J) const
312 if (myLines(I).myInters.IsEmpty()) {
313 if (J != 1 || !myOrient) Standard_OutOfRange::Raise();
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;
324 //=======================================================================
325 //function : EndIndex
327 //=======================================================================
329 void Hatch_Hatcher::EndIndex
330 (const Standard_Integer I,
331 const Standard_Integer J,
332 Standard_Integer& Index,
333 Standard_Real& Par2) const
335 if (myLines(I).myInters.IsEmpty()) {
336 if (J != 1) Standard_OutOfRange::Raise();
341 Standard_Integer jj = 2*J;
342 if (!myLines(I).myInters(1).myStart && myOrient) jj--;
343 if (jj > myLines(I).myInters.Length()) {
348 Index = myLines(I).myInters(jj).myIndex;
349 Par2 = myLines(I).myInters(jj).myPar2;