b311480e |
1 | // Created on: 1995-01-05 |
2 | // Created by: Christophe MARION |
3 | // Copyright (c) 1995-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 | |
17 | #include <HLRTopoBRep_FaceIsoLiner.ixx> |
18 | #include <TopAbs.hxx> |
19 | #include <TopExp.hxx> |
20 | #include <TopExp_Explorer.hxx> |
21 | #include <TopoDS.hxx> |
22 | #include <TopoDS_Edge.hxx> |
23 | #include <TopTools_Array1OfShape.hxx> |
24 | #include <TColStd_Array1OfBoolean.hxx> |
25 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
26 | //#include <BRepAdaptor_Curve2d.hxx> |
27 | #include <BRepAdaptor_Surface.hxx> |
28 | #include <BRepTools.hxx> |
29 | #include <BRep_Tool.hxx> |
30 | #include <BRep_Builder.hxx> |
31 | #include <Geom2d_Curve.hxx> |
32 | #include <Geom2d_TrimmedCurve.hxx> |
33 | #include <Geom2d_Line.hxx> |
34 | #include <Geom2dHatch_Hatcher.hxx> |
35 | #include <Geom2dHatch_Intersector.hxx> |
36 | #include <HatchGen_ErrorStatus.hxx> |
37 | #include <HatchGen_Domain.hxx> |
38 | #include <HatchGen_PointOnHatching.hxx> |
39 | #include <HatchGen_PointOnElement.hxx> |
40 | #include <Precision.hxx> |
41 | |
42 | const Standard_Real IntersectorConfusion = 1.e-10; |
43 | const Standard_Real IntersectorTangency = 1.e-10; |
44 | const Standard_Real HatcherConfusion2d = 1.e-8; |
45 | const Standard_Real HatcherConfusion3d = 1.e-8; |
46 | const Standard_Real Infinite = 100.; |
47 | |
48 | //======================================================================= |
49 | // Function : Perform |
50 | // Purpose : Builds isoparametric curves with a hatcher. |
51 | //======================================================================= |
52 | |
53 | void HLRTopoBRep_FaceIsoLiner::Perform (const Standard_Integer FI, |
54 | const TopoDS_Face& F, |
55 | HLRTopoBRep_Data& DS, |
56 | const Standard_Integer nbIsos) |
57 | { |
aefdc31b |
58 | (void)FI; // avoid compiler warning |
59 | |
7fd59977 |
60 | Standard_Real UMin, UMax, VMin, VMax, U1, U2; |
61 | Standard_Integer ne = 0; |
62 | //BRep_Builder Builder; |
63 | TopoDS_Edge Edge; |
64 | TopExp_Explorer ExpEdges; |
65 | TopoDS_Face TF = F; |
66 | TF.Orientation (TopAbs_FORWARD); |
67 | gp_Pnt2d P; |
68 | gp_Pnt P1, P2; |
69 | TopoDS_Vertex V1U, V2U, V1V, V2V; |
70 | |
71 | Geom2dHatch_Intersector Intersector |
72 | (IntersectorConfusion,IntersectorTangency); |
73 | Geom2dHatch_Hatcher Hatcher |
74 | (Intersector,HatcherConfusion2d,HatcherConfusion3d,Standard_True); |
75 | |
76 | BRepTools::UVBounds (TF, UMin, UMax, VMin, VMax); |
77 | Standard_Boolean InfiniteUMin = Precision::IsNegativeInfinite (UMin); |
78 | Standard_Boolean InfiniteUMax = Precision::IsPositiveInfinite (UMax); |
79 | Standard_Boolean InfiniteVMin = Precision::IsNegativeInfinite (VMin); |
80 | Standard_Boolean InfiniteVMax = Precision::IsPositiveInfinite (VMax); |
81 | |
82 | if (InfiniteUMin && InfiniteUMax) { |
83 | UMin = - Infinite; |
84 | UMax = Infinite; |
85 | } |
86 | else if (InfiniteUMin) |
87 | UMin = UMax - Infinite; |
88 | else if (InfiniteUMax) |
89 | UMax = UMin + Infinite; |
90 | |
91 | if (InfiniteVMin && InfiniteVMax) { |
92 | VMin = - Infinite; |
93 | VMax = Infinite; |
94 | } |
95 | else if (InfiniteVMin) |
96 | VMin = VMax - Infinite; |
97 | else if (InfiniteVMax) |
98 | VMax = VMin + Infinite; |
99 | |
100 | for (ExpEdges.Init (TF, TopAbs_EDGE); // Edges of the face TF |
101 | ExpEdges.More(); |
102 | ExpEdges.Next()) ne++; |
103 | |
104 | if (DS.FaceHasIntL(TF)) { // OutLines built on face TF. |
105 | |
106 | TopTools_ListIteratorOfListOfShape itE; |
107 | for(itE.Initialize(DS.FaceIntL(TF)); |
108 | itE.More(); |
109 | itE.Next()) |
110 | ne++; |
111 | } |
112 | |
113 | TopTools_Array1OfShape SH(1,ne); |
114 | TColStd_Array1OfBoolean IL(1,ne); // internal OutLine |
115 | |
116 | for (ExpEdges.Init (TF, TopAbs_EDGE); |
117 | ExpEdges.More(); |
118 | ExpEdges.Next()) { |
119 | Standard_Integer IndE; |
120 | const TopoDS_Edge& newE = TopoDS::Edge(ExpEdges.Current()); |
121 | const Handle(Geom2d_Curve) PC = |
122 | BRep_Tool::CurveOnSurface (newE, TF, U1, U2); |
123 | if( Abs(PC->FirstParameter() - U1) <= Precision::PConfusion() |
124 | && Abs(PC->LastParameter() - U2) <= Precision::PConfusion()) { |
125 | IndE = Hatcher.AddElement (PC, newE.Orientation()); |
126 | } |
127 | else { |
128 | Handle (Geom2d_TrimmedCurve) TPC = |
129 | new Geom2d_TrimmedCurve (PC, U1, U2); |
543a9964 |
130 | Geom2dAdaptor_Curve aGAC (TPC); |
131 | IndE = Hatcher.AddElement (aGAC, newE.Orientation()); |
7fd59977 |
132 | } |
133 | SH(IndE) = newE; |
134 | if (DS.IsOutLFaceEdge(TF,newE)) IL(IndE) = Standard_True; |
135 | else IL(IndE) = Standard_False; |
136 | } |
137 | |
138 | if (DS.FaceHasIntL(TF)) { // get the internal OutLines built on face F. |
139 | TopTools_ListIteratorOfListOfShape itE; |
140 | for(itE.Initialize(DS.FaceIntL(TF)); |
141 | itE.More(); |
142 | itE.Next()) { |
143 | Standard_Integer IndE; |
144 | const TopoDS_Edge& newE = TopoDS::Edge(itE.Value()); |
145 | const Handle(Geom2d_Curve) PC = |
146 | BRep_Tool::CurveOnSurface (newE, TF, U1, U2); |
147 | if( Abs(PC->FirstParameter() - U1) <= Precision::PConfusion() |
148 | && Abs(PC->LastParameter() - U2) <= Precision::PConfusion()) { |
149 | IndE = Hatcher.AddElement (PC, TopAbs_INTERNAL); |
150 | } |
151 | else { |
152 | Handle (Geom2d_TrimmedCurve) TPC = |
153 | new Geom2d_TrimmedCurve (PC, U1, U2); |
543a9964 |
154 | Geom2dAdaptor_Curve aGAC (TPC); |
155 | IndE = Hatcher.AddElement (aGAC, TopAbs_INTERNAL); |
7fd59977 |
156 | } |
157 | SH(IndE) = newE; |
158 | IL(IndE) = Standard_True; |
159 | } |
160 | } |
161 | |
162 | //----------------------------------------------------------------------- |
163 | // Creation des hachures. |
164 | //----------------------------------------------------------------------- |
165 | |
166 | BRepAdaptor_Surface Surface (TF); |
167 | Standard_Real Tolerance = BRep_Tool::Tolerance (TF); |
168 | |
169 | Standard_Integer IIso; |
170 | Standard_Real DeltaU = Abs (UMax - UMin); |
171 | Standard_Real DeltaV = Abs (VMax - VMin); |
172 | Standard_Real Confusion = Min (DeltaU, DeltaV) * HatcherConfusion3d; |
173 | Hatcher.Confusion3d (Confusion); |
174 | |
175 | //----------------------------------------------------------------------- |
176 | // Courbes Iso U. |
177 | //----------------------------------------------------------------------- |
178 | |
179 | Standard_Real StepU = DeltaU / (Standard_Real) nbIsos; |
180 | if (StepU > Confusion) { |
181 | Standard_Real UPrm = UMin + StepU / 2.; |
182 | gp_Dir2d Dir (0., 1.); |
183 | |
184 | for (IIso = 1; IIso <= nbIsos; IIso++) { |
185 | gp_Pnt2d Ori (UPrm, 0.); |
186 | Handle (Geom2d_Line) IsoLine = new Geom2d_Line (Ori, Dir); |
187 | |
543a9964 |
188 | Geom2dAdaptor_Curve aGAC (IsoLine); |
189 | Standard_Integer IndH = Hatcher.AddHatching (aGAC); |
7fd59977 |
190 | Hatcher.Trim (IndH); |
191 | if (Hatcher.TrimDone (IndH) && !Hatcher.TrimFailed (IndH)) |
192 | Hatcher.ComputeDomains (IndH); |
193 | if (!Hatcher.IsDone (IndH)) { |
0797d9d3 |
194 | #ifdef OCCT_DEBUG |
aefdc31b |
195 | cout << "HLRTopoBRep::MakeIsoLines : Face " << FI << endl; |
7fd59977 |
196 | cout << "U iso of parameter: " << UPrm; |
197 | switch (Hatcher.Status (IndH)) { |
198 | case HatchGen_NoProblem : |
199 | cout << " No Problem" << endl; |
200 | break; |
201 | case HatchGen_TrimFailure : |
202 | cout << " Trim Failure" << endl; |
203 | break; |
204 | case HatchGen_TransitionFailure : |
205 | cout << " Transition Failure" << endl; |
206 | break; |
207 | case HatchGen_IncoherentParity : |
208 | cout << " Incoherent Parity" << endl; |
209 | break; |
210 | case HatchGen_IncompatibleStates : |
211 | cout << " Incompatible States" << endl; |
212 | break; |
213 | } |
aefdc31b |
214 | #endif |
7fd59977 |
215 | Hatcher.RemHatching (IndH); |
216 | continue; |
217 | } |
218 | |
219 | Standard_Integer NbDom = Hatcher.NbDomains (IndH); |
220 | if (NbDom > 0) { |
221 | |
222 | for (Standard_Integer IDom = 1; IDom <= NbDom; IDom++) { |
223 | const HatchGen_Domain& Dom = Hatcher.Domain (IndH, IDom); |
224 | Standard_Real U1 = Dom.HasFirstPoint() ? |
225 | Dom.FirstPoint().Parameter() : VMin - Infinite; |
226 | Standard_Real U2 = Dom.HasSecondPoint() ? |
227 | Dom.SecondPoint().Parameter() : VMax + Infinite; |
228 | IsoLine->D0 (U1, P); |
229 | Surface.D0 (P.X(), P.Y(), P1); |
230 | IsoLine->D0 (U2, P); |
231 | Surface.D0 (P.X(), P.Y(), P2); |
232 | if (Dom.HasFirstPoint()) { // Iso U - Premier point |
233 | const HatchGen_PointOnHatching& PntH = Dom.FirstPoint(); |
234 | |
235 | for (Standard_Integer IPntE = 1; |
236 | IPntE <= PntH.NbPoints(); |
237 | IPntE++) { |
238 | const HatchGen_PointOnElement& PntE = PntH.Point(IPntE); |
239 | V1U = HLRTopoBRep_FaceIsoLiner::MakeVertex |
240 | (TopoDS::Edge(SH(PntE.Index())), |
241 | P1,PntE.Parameter(),Tolerance,DS); |
242 | if (IL(PntE.Index())) DS.AddOutV(V1U); |
243 | } |
244 | } |
245 | if (Dom.HasSecondPoint()) { // Iso U - Deuxieme point |
246 | const HatchGen_PointOnHatching& PntH = Dom.SecondPoint(); |
247 | |
248 | for (Standard_Integer IPntE = 1; |
249 | IPntE <= PntH.NbPoints(); |
250 | IPntE++) { |
251 | const HatchGen_PointOnElement& PntE = PntH.Point(IPntE); |
252 | V2U = HLRTopoBRep_FaceIsoLiner::MakeVertex |
253 | (TopoDS::Edge(SH(PntE.Index())), |
254 | P2,PntE.Parameter(),Tolerance,DS); |
255 | if (IL(PntE.Index())) DS.AddOutV(V2U); |
256 | } |
257 | } |
258 | if(!V1U.IsNull() && !V2U.IsNull()) |
259 | HLRTopoBRep_FaceIsoLiner::MakeIsoLine |
260 | (F,IsoLine,V1U,V2U,U1,U2,Tolerance,DS); |
261 | } |
262 | } |
263 | |
264 | Hatcher.RemHatching (IndH); |
265 | UPrm += StepU; |
266 | } |
267 | } |
268 | |
269 | //----------------------------------------------------------------------- |
270 | // Courbes Iso V. |
271 | //----------------------------------------------------------------------- |
272 | |
273 | Standard_Real StepV = DeltaV / (Standard_Real) nbIsos; |
274 | if (StepV > Confusion) { |
275 | Standard_Real VPrm = VMin + StepV / 2.; |
276 | gp_Dir2d Dir (1., 0.); |
277 | |
278 | for (IIso = 1; IIso <= nbIsos; IIso++) { |
279 | gp_Pnt2d Ori (0., VPrm); |
280 | Handle (Geom2d_Line) IsoLine = new Geom2d_Line (Ori, Dir); |
281 | |
543a9964 |
282 | Geom2dAdaptor_Curve aGAC (IsoLine); |
283 | Standard_Integer IndH = Hatcher.AddHatching (aGAC); |
7fd59977 |
284 | Hatcher.Trim (IndH); |
285 | if (Hatcher.TrimDone (IndH) && !Hatcher.TrimFailed (IndH)) |
286 | Hatcher.ComputeDomains (IndH); |
287 | if (!Hatcher.IsDone (IndH)) { |
0797d9d3 |
288 | #ifdef OCCT_DEBUG |
7fd59977 |
289 | cout << "HLRTopoBRep::MakeIsoLines : Face " << FI << endl; |
290 | cout << "V iso of parameter: " << VPrm; |
291 | switch (Hatcher.Status (IndH)) { |
292 | case HatchGen_NoProblem : |
293 | cout << " No Problem" << endl; |
294 | break; |
295 | case HatchGen_TrimFailure : |
296 | cout << " Trim Failure" << endl; |
297 | break; |
298 | case HatchGen_TransitionFailure : |
299 | cout << " Transition Failure" << endl; |
300 | break; |
301 | case HatchGen_IncoherentParity : |
302 | cout << " Incoherent Parity" << endl; |
303 | break; |
304 | case HatchGen_IncompatibleStates : |
305 | cout << " Incompatible States" << endl; |
306 | break; |
307 | } |
aefdc31b |
308 | #endif |
7fd59977 |
309 | Hatcher.RemHatching (IndH); |
310 | continue; |
311 | } |
312 | |
313 | Standard_Integer NbDom = Hatcher.NbDomains (IndH); |
314 | if (NbDom > 0) { |
315 | |
316 | for (Standard_Integer IDom = 1; IDom <= NbDom; IDom++) { |
317 | const HatchGen_Domain& Dom = Hatcher.Domain (IndH, IDom); |
318 | Standard_Real U1 = Dom.HasFirstPoint() ? |
319 | Dom.FirstPoint().Parameter() : VMin - Infinite; |
320 | Standard_Real U2 = Dom.HasSecondPoint() ? |
321 | Dom.SecondPoint().Parameter() : VMax + Infinite; |
322 | IsoLine->D0 (U1, P); |
323 | Surface.D0 (P.X(), P.Y(), P1); |
324 | IsoLine->D0 (U2, P); |
325 | Surface.D0 (P.X(), P.Y(), P2); |
326 | if (Dom.HasFirstPoint()) { // Iso V - Premier point |
327 | const HatchGen_PointOnHatching& PntH = Dom.FirstPoint(); |
328 | |
329 | for (Standard_Integer IPntE = 1; |
330 | IPntE <= PntH.NbPoints(); |
331 | IPntE++) { |
332 | const HatchGen_PointOnElement& PntE = PntH.Point(IPntE); |
333 | V1V = HLRTopoBRep_FaceIsoLiner::MakeVertex |
334 | (TopoDS::Edge(SH(PntE.Index())), |
335 | P1,PntE.Parameter(),Tolerance,DS); |
336 | |
337 | if (IL(PntE.Index())) DS.AddOutV(V1V); |
338 | } |
339 | } |
340 | if (Dom.HasSecondPoint()) { // Iso V - Deuxieme point |
341 | const HatchGen_PointOnHatching& PntH = Dom.SecondPoint(); |
342 | |
343 | for (Standard_Integer IPntE = 1; |
344 | IPntE <= PntH.NbPoints(); |
345 | IPntE++) { |
346 | const HatchGen_PointOnElement& PntE = PntH.Point(IPntE); |
347 | V2V = HLRTopoBRep_FaceIsoLiner::MakeVertex |
348 | (TopoDS::Edge(SH(PntE.Index())), |
349 | P2,PntE.Parameter(),Tolerance,DS); |
350 | if (IL(PntE.Index())) DS.AddOutV(V2V); |
351 | } |
352 | } |
353 | if(!V1V.IsNull() && !V2V.IsNull()) |
354 | HLRTopoBRep_FaceIsoLiner::MakeIsoLine |
355 | (F,IsoLine,V1V,V2V,U1,U2,Tolerance,DS); |
356 | } |
357 | } |
358 | |
359 | Hatcher.RemHatching (IndH); |
360 | VPrm += StepV; |
361 | } |
362 | } |
363 | } |
364 | |
365 | //======================================================================= |
366 | //function : MakeVertex |
367 | //purpose : |
368 | //======================================================================= |
369 | |
370 | TopoDS_Vertex |
371 | HLRTopoBRep_FaceIsoLiner::MakeVertex (const TopoDS_Edge& E, |
372 | const gp_Pnt& P, |
373 | const Standard_Real Par, |
374 | const Standard_Real Tol, |
375 | HLRTopoBRep_Data& DS) |
376 | { |
377 | TopoDS_Vertex V, VF, VL; |
378 | BRep_Builder B; |
379 | TopExp::Vertices (E, VF, VL); |
380 | if (P.IsEqual(BRep_Tool::Pnt(VF),BRep_Tool::Tolerance(VF))) |
381 | return VF; |
382 | if (P.IsEqual(BRep_Tool::Pnt(VL),BRep_Tool::Tolerance(VL))) |
383 | return VL; |
384 | |
385 | for (DS.InitVertex(E); DS.MoreVertex(); DS.NextVertex()) { |
386 | TopoDS_Vertex curV = DS.Vertex(); |
387 | Standard_Real curP = DS.Parameter(); |
388 | if (P.IsEqual(BRep_Tool::Pnt(curV),BRep_Tool::Tolerance(curV))) { |
389 | V = curV; |
390 | break; |
391 | } |
392 | else if (Par < curP) { |
393 | B.MakeVertex(V,P,Tol); |
394 | V.Orientation(TopAbs_INTERNAL); |
395 | DS.InsertBefore(V,Par); |
396 | break; |
397 | } |
398 | } |
399 | |
400 | if (!DS.MoreVertex()) { |
401 | B.MakeVertex(V,P,Tol); |
402 | V.Orientation(TopAbs_INTERNAL); |
403 | DS.Append(V,Par); |
404 | } |
405 | |
406 | return V; |
407 | } |
408 | |
409 | //======================================================================= |
410 | //function : MakeIsoLine |
411 | //purpose : |
412 | //======================================================================= |
413 | |
414 | void HLRTopoBRep_FaceIsoLiner::MakeIsoLine (const TopoDS_Face& F, |
415 | const Handle(Geom2d_Line)& Iso, |
416 | TopoDS_Vertex& V1, |
417 | TopoDS_Vertex& V2, |
418 | const Standard_Real U1, |
419 | const Standard_Real U2, |
420 | const Standard_Real Tol, |
421 | HLRTopoBRep_Data& DS) |
422 | { |
423 | BRep_Builder B; |
424 | TopoDS_Edge E; |
425 | E.Orientation (TopAbs_INTERNAL); |
426 | V1.Orientation (TopAbs_FORWARD); |
427 | V2.Orientation (TopAbs_REVERSED); |
428 | B.MakeEdge (E); |
429 | B.UpdateEdge (E, Iso, F, Tol); |
430 | B.Add (E, V1); |
431 | B.UpdateVertex (V1, U1, E, Tol); |
432 | B.Add (E, V2); |
433 | B.UpdateVertex (V2, U2, E, Tol); |
434 | DS.AddIsoL(F).Append(E); |
435 | } |
436 | |