0024023: Revamp the OCCT Handle -- ambiguity
[occt.git] / src / HLRTopoBRep / HLRTopoBRep_FaceIsoLiner.cxx
CommitLineData
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
42const Standard_Real IntersectorConfusion = 1.e-10;
43const Standard_Real IntersectorTangency = 1.e-10;
44const Standard_Real HatcherConfusion2d = 1.e-8;
45const Standard_Real HatcherConfusion3d = 1.e-8;
46const Standard_Real Infinite = 100.;
47
48//=======================================================================
49// Function : Perform
50// Purpose : Builds isoparametric curves with a hatcher.
51//=======================================================================
52
53void 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
370TopoDS_Vertex
371HLRTopoBRep_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
414void 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