Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1994-03-25 |
2 | // Created by: Jean Marc LACHAUME | |
3 | // Copyright (c) 1994-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 | // |
973c2be1 | 8 | // This library is free software; you can redistribute it and / or modify it |
9 | // under the terms of the GNU Lesser General Public 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. | |
b311480e | 13 | // |
973c2be1 | 14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. | |
7fd59977 | 16 | |
17 | #include <DBRep_IsoBuilder.ixx> | |
18 | ||
19 | #include <Precision.hxx> | |
20 | #include <BRepTools.hxx> | |
21 | #include <BRep_Tool.hxx> | |
22 | #include <Geom2dAdaptor_Curve.hxx> | |
23 | #include <Geom2dHatch_Intersector.hxx> | |
24 | #include <Geom2d_Curve.hxx> | |
25 | #include <Geom2d_Line.hxx> | |
26 | #include <Geom2d_TrimmedCurve.hxx> | |
27 | #include <HatchGen_Domain.hxx> | |
28 | #include <Precision.hxx> | |
29 | #include <TopAbs_ShapeEnum.hxx> | |
30 | #include <TopExp_Explorer.hxx> | |
31 | #include <TopoDS.hxx> | |
32 | #include <TopoDS_Edge.hxx> | |
33 | #include <gp_Dir2d.hxx> | |
34 | #include <gp_Pnt2d.hxx> | |
35 | ||
36 | // Modified by Sergey KHROMOV - Thu Nov 9 12:08:37 2000 | |
37 | static Standard_Real IntersectorConfusion = 1.e-10 ; // -8 ; | |
38 | static Standard_Real IntersectorTangency = 1.e-10 ; // -8 ; | |
39 | // Modified by Sergey KHROMOV - Thu Nov 9 12:08:38 2000 | |
40 | static Standard_Real HatcherConfusion2d = 1.e-8 ; | |
41 | static Standard_Real HatcherConfusion3d = 1.e-8 ; | |
42 | ||
43 | //======================================================================= | |
44 | // Function : DBRep_IsoBuilder | |
45 | // Purpose : Constructeur. | |
46 | //======================================================================= | |
47 | ||
48 | DBRep_IsoBuilder::DBRep_IsoBuilder (const TopoDS_Face& TopologicalFace, | |
49 | const Standard_Real Infinite, | |
50 | const Standard_Integer NbIsos) : | |
51 | Geom2dHatch_Hatcher (Geom2dHatch_Intersector (IntersectorConfusion, | |
52 | IntersectorTangency), | |
53 | HatcherConfusion2d, | |
54 | HatcherConfusion3d, | |
55 | Standard_True, | |
56 | Standard_False) , | |
57 | myInfinite (Infinite) , | |
58 | myUMin (0.0) , | |
59 | myUMax (0.0) , | |
60 | myVMin (0.0) , | |
61 | myVMax (0.0) , | |
62 | myUPrm (1, NbIsos) , | |
63 | myUInd (1, NbIsos) , | |
64 | myVPrm (1, NbIsos) , | |
65 | myVInd (1, NbIsos) , | |
66 | myNbDom (0) | |
67 | { | |
68 | myUInd.Init(0); | |
69 | myVInd.Init(0); | |
70 | ||
71 | //----------------------------------------------------------------------- | |
72 | // If the Min Max bounds are infinite, there are bounded to Infinite | |
73 | // value. | |
74 | //----------------------------------------------------------------------- | |
75 | ||
76 | BRepTools::UVBounds (TopologicalFace, myUMin, myUMax, myVMin, myVMax) ; | |
77 | Standard_Boolean InfiniteUMin = Precision::IsNegativeInfinite (myUMin) ; | |
78 | Standard_Boolean InfiniteUMax = Precision::IsPositiveInfinite (myUMax) ; | |
79 | Standard_Boolean InfiniteVMin = Precision::IsNegativeInfinite (myVMin) ; | |
80 | Standard_Boolean InfiniteVMax = Precision::IsPositiveInfinite (myVMax) ; | |
81 | if (InfiniteUMin && InfiniteUMax) { | |
82 | myUMin = - Infinite ; | |
83 | myUMax = Infinite ; | |
84 | } else if (InfiniteUMin) { | |
85 | myUMin = myUMax - Infinite ; | |
86 | } else if (InfiniteUMax) { | |
87 | myUMax = myUMin + Infinite ; | |
88 | } | |
89 | if (InfiniteVMin && InfiniteVMax) { | |
90 | myVMin = - Infinite ; | |
91 | myVMax = Infinite ; | |
92 | } else if (InfiniteVMin) { | |
93 | myVMin = myVMax - Infinite ; | |
94 | } else if (InfiniteVMax) { | |
95 | myVMax = myVMin + Infinite ; | |
96 | } | |
97 | ||
98 | //----------------------------------------------------------------------- | |
99 | // Retreiving the edges and loading them into the hatcher. | |
100 | //----------------------------------------------------------------------- | |
101 | ||
ffe74e46 K |
102 | TopExp_Explorer ExpEdges; |
103 | for (ExpEdges.Init (TopologicalFace, TopAbs_EDGE); ExpEdges.More(); ExpEdges.Next()) | |
104 | { | |
105 | const TopoDS_Edge& TopologicalEdge = TopoDS::Edge (ExpEdges.Current()); | |
106 | Standard_Real U1, U2; | |
107 | const Handle(Geom2d_Curve) PCurve = BRep_Tool::CurveOnSurface (TopologicalEdge, TopologicalFace, U1, U2); | |
108 | ||
109 | if (PCurve.IsNull()) | |
110 | { | |
111 | #ifdef DEB | |
112 | cout << "DBRep_IsoBuilder : PCurve is null\n"; | |
113 | #endif | |
7fd59977 | 114 | return; |
115 | } | |
ffe74e46 K |
116 | else if (U1 == U2) |
117 | { | |
118 | #ifdef DEB | |
119 | cout << "DBRep_IsoBuilder PCurve : U1==U2\n"; | |
120 | #endif | |
7fd59977 | 121 | return; |
122 | } | |
123 | ||
124 | //-- Test if a TrimmedCurve is necessary | |
ffe74e46 K |
125 | if (Abs(PCurve->FirstParameter()-U1)<= Precision::PConfusion() |
126 | && Abs(PCurve->LastParameter()-U2)<= Precision::PConfusion()) | |
127 | { | |
128 | AddElement (PCurve, TopologicalEdge.Orientation()); | |
7fd59977 | 129 | } |
ffe74e46 K |
130 | else |
131 | { | |
132 | if (!PCurve->IsPeriodic()) | |
133 | { | |
134 | Handle (Geom2d_TrimmedCurve) TrimPCurve = Handle(Geom2d_TrimmedCurve)::DownCast (PCurve); | |
135 | if (!TrimPCurve.IsNull()) | |
136 | { | |
137 | if (TrimPCurve->BasisCurve()->FirstParameter() - U1 > Precision::PConfusion() || | |
138 | TrimPCurve->BasisCurve()->FirstParameter() - U2 > Precision::PConfusion() || | |
139 | U1 - TrimPCurve->BasisCurve()->LastParameter() > Precision::PConfusion() || | |
140 | U2 - TrimPCurve->BasisCurve()->LastParameter() > Precision::PConfusion()) | |
141 | { | |
142 | AddElement (PCurve, TopologicalEdge.Orientation()); | |
143 | #ifdef DEB | |
144 | cout << "DBRep_IsoBuilder TrimPCurve : parameters out of range\n"; | |
145 | cout << " U1(" << U1 << "), Umin(" << PCurve->FirstParameter() | |
146 | << "), U2(" << U2 << "), Umax(" << PCurve->LastParameter() << ")\n"; | |
147 | #endif | |
148 | return; | |
149 | } | |
150 | } | |
151 | else | |
152 | { | |
153 | if (PCurve->FirstParameter() - U1 > Precision::PConfusion()) | |
154 | { | |
155 | #ifdef DEB | |
156 | cout << "DBRep_IsoBuilder PCurve : parameters out of range\n"; | |
157 | cout << " U1(" << U1 << "), Umin(" << PCurve->FirstParameter() << ")\n"; | |
158 | #endif | |
159 | U1 = PCurve->FirstParameter(); | |
160 | } | |
161 | if (PCurve->FirstParameter() - U2 > Precision::PConfusion()) | |
162 | { | |
163 | #ifdef DEB | |
164 | cout << "DBRep_IsoBuilder PCurve : parameters out of range\n"; | |
165 | cout << " U2(" << U2 << "), Umin(" << PCurve->FirstParameter() << ")\n"; | |
166 | #endif | |
167 | U2 = PCurve->FirstParameter(); | |
168 | } | |
169 | if (U1 - PCurve->LastParameter() > Precision::PConfusion()) | |
170 | { | |
171 | #ifdef DEB | |
172 | cout << "DBRep_IsoBuilder PCurve : parameters out of range\n"; | |
173 | cout << " U1(" << U1 << "), Umax(" << PCurve->LastParameter() << ")\n"; | |
174 | #endif | |
175 | U1 = PCurve->LastParameter(); | |
176 | } | |
177 | if (U2 - PCurve->LastParameter() > Precision::PConfusion()) | |
178 | { | |
179 | #ifdef DEB | |
180 | cout << "DBRep_IsoBuilder PCurve : parameters out of range\n"; | |
181 | cout << " U2(" << U2 << "), Umax(" << PCurve->LastParameter() << ")\n"; | |
182 | #endif | |
183 | U2 = PCurve->LastParameter(); | |
184 | } | |
185 | } | |
7fd59977 | 186 | } |
ffe74e46 K |
187 | |
188 | // if U1 and U2 coincide-->do nothing | |
189 | if (Abs (U1 - U2) <= Precision::PConfusion()) continue; | |
190 | Handle (Geom2d_TrimmedCurve) TrimPCurve = new Geom2d_TrimmedCurve (PCurve, U1, U2); | |
191 | AddElement (TrimPCurve, TopologicalEdge.Orientation()); | |
7fd59977 | 192 | } |
193 | } | |
194 | ||
7fd59977 | 195 | //----------------------------------------------------------------------- |
196 | // Loading and trimming the hatchings. | |
197 | //----------------------------------------------------------------------- | |
198 | ||
199 | Standard_Integer IIso ; | |
200 | Standard_Real DeltaU = Abs (myUMax - myUMin) ; | |
201 | Standard_Real DeltaV = Abs (myVMax - myVMin) ; | |
202 | Standard_Real confusion = Min (DeltaU, DeltaV) * HatcherConfusion3d ; | |
203 | Confusion3d (confusion) ; | |
204 | ||
205 | Standard_Real StepU = DeltaU / (Standard_Real) NbIsos ; | |
206 | if (StepU > confusion) { | |
207 | Standard_Real UPrm = myUMin + StepU / 2. ; | |
208 | gp_Dir2d Dir (0., 1.) ; | |
209 | for (IIso = 1 ; IIso <= NbIsos ; IIso++) { | |
210 | myUPrm(IIso) = UPrm ; | |
211 | gp_Pnt2d Ori (UPrm, 0.) ; | |
212 | Geom2dAdaptor_Curve HCur (new Geom2d_Line (Ori, Dir)) ; | |
213 | myUInd(IIso) = AddHatching (HCur) ; | |
214 | UPrm += StepU ; | |
215 | } | |
216 | } | |
217 | ||
218 | Standard_Real StepV = DeltaV / (Standard_Real) NbIsos ; | |
219 | if (StepV > confusion) { | |
220 | Standard_Real VPrm = myVMin + StepV / 2. ; | |
221 | gp_Dir2d Dir (1., 0.) ; | |
222 | for (IIso = 1 ; IIso <= NbIsos ; IIso++) { | |
223 | myVPrm(IIso) = VPrm ; | |
224 | gp_Pnt2d Ori (0., VPrm) ; | |
225 | Geom2dAdaptor_Curve HCur (new Geom2d_Line (Ori, Dir)) ; | |
226 | myVInd(IIso) = AddHatching (HCur) ; | |
227 | VPrm += StepV ; | |
228 | } | |
229 | } | |
230 | ||
231 | //----------------------------------------------------------------------- | |
232 | // Computation. | |
233 | //----------------------------------------------------------------------- | |
234 | ||
235 | Trim() ; | |
236 | ||
237 | myNbDom = 0 ; | |
238 | for (IIso = 1 ; IIso <= NbIsos ; IIso++) { | |
239 | Standard_Integer Index ; | |
240 | ||
241 | Index = myUInd(IIso) ; | |
242 | if (Index != 0) { | |
243 | if (TrimDone (Index) && !TrimFailed (Index)) { | |
244 | ComputeDomains (Index); | |
245 | if (IsDone (Index)) myNbDom = myNbDom + Geom2dHatch_Hatcher::NbDomains (Index) ; | |
246 | } | |
247 | } | |
248 | ||
249 | Index = myVInd(IIso) ; | |
250 | if (Index != 0) { | |
251 | if (TrimDone (Index) && !TrimFailed (Index)) { | |
252 | ComputeDomains (Index); | |
253 | if (IsDone (Index)) myNbDom = myNbDom + Geom2dHatch_Hatcher::NbDomains (Index) ; | |
254 | } | |
255 | } | |
256 | } | |
257 | } | |
258 | ||
259 | //======================================================================= | |
260 | // Function : LoadIsos | |
261 | // Purpose : Loading of the isoparametric curves in the Data Structure | |
262 | // of a drawable face. | |
263 | //======================================================================= | |
264 | ||
265 | void DBRep_IsoBuilder::LoadIsos (const Handle(DBRep_Face)& Face) const | |
266 | { | |
267 | Standard_Integer NumIso = 0 ; | |
268 | ||
269 | for (Standard_Integer UIso = myUPrm.Lower() ; UIso <= myUPrm.Upper() ; UIso++) { | |
270 | Standard_Integer UInd = myUInd.Value (UIso) ; | |
271 | if (UInd != 0) { | |
272 | Standard_Real UPrm = myUPrm.Value (UIso) ; | |
273 | if (!IsDone (UInd)) { | |
274 | cout << "DBRep_IsoBuilder:: U iso of parameter: " << UPrm ; | |
275 | switch (Status (UInd)) { | |
276 | case HatchGen_NoProblem : cout << " No Problem" << endl ; break ; | |
277 | case HatchGen_TrimFailure : cout << " Trim Failure" << endl ; break ; | |
278 | case HatchGen_TransitionFailure : cout << " Transition Failure" << endl ; break ; | |
279 | case HatchGen_IncoherentParity : cout << " Incoherent Parity" << endl ; break ; | |
280 | case HatchGen_IncompatibleStates : cout << " Incompatible States" << endl ; break ; | |
281 | } | |
282 | } else { | |
283 | Standard_Integer NbDom = Geom2dHatch_Hatcher::NbDomains (UInd) ; | |
284 | for (Standard_Integer IDom = 1 ; IDom <= NbDom ; IDom++) { | |
285 | const HatchGen_Domain& Dom = Domain (UInd, IDom) ; | |
286 | Standard_Real V1 = Dom.HasFirstPoint() ? Dom.FirstPoint().Parameter() : myVMin - myInfinite ; | |
287 | Standard_Real V2 = Dom.HasSecondPoint() ? Dom.SecondPoint().Parameter() : myVMax + myInfinite ; | |
288 | NumIso++ ; | |
289 | Face->Iso (NumIso, GeomAbs_IsoU, UPrm, V1, V2) ; | |
290 | } | |
291 | } | |
292 | } | |
293 | } | |
294 | ||
295 | for (Standard_Integer VIso = myVPrm.Lower() ; VIso <= myVPrm.Upper() ; VIso++) { | |
296 | Standard_Integer VInd = myVInd.Value (VIso) ; | |
297 | if (VInd != 0) { | |
298 | Standard_Real VPrm = myVPrm.Value (VIso) ; | |
299 | if (!IsDone (VInd)) { | |
300 | cout << "DBRep_IsoBuilder:: V iso of parameter: " << VPrm ; | |
301 | switch (Status (VInd)) { | |
302 | case HatchGen_NoProblem : cout << " No Problem" << endl ; break ; | |
303 | case HatchGen_TrimFailure : cout << " Trim Failure" << endl ; break ; | |
304 | case HatchGen_TransitionFailure : cout << " Transition Failure" << endl ; break ; | |
305 | case HatchGen_IncoherentParity : cout << " Incoherent Parity" << endl ; break ; | |
306 | case HatchGen_IncompatibleStates : cout << " Incompatible States" << endl ; break ; | |
307 | } | |
308 | } else { | |
309 | Standard_Integer NbDom = Geom2dHatch_Hatcher::NbDomains (VInd) ; | |
310 | for (Standard_Integer IDom = 1 ; IDom <= NbDom ; IDom++) { | |
311 | const HatchGen_Domain& Dom = Domain (VInd, IDom) ; | |
312 | Standard_Real U1 = Dom.HasFirstPoint() ? Dom.FirstPoint().Parameter() : myVMin - myInfinite ; | |
313 | Standard_Real U2 = Dom.HasSecondPoint() ? Dom.SecondPoint().Parameter() : myVMax + myInfinite ; | |
314 | NumIso++ ; | |
315 | Face->Iso (NumIso, GeomAbs_IsoV, VPrm, U1, U2) ; | |
316 | } | |
317 | } | |
318 | } | |
319 | } | |
320 | } |