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