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
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.
17 #include <HLRTopoBRep_FaceIsoLiner.ixx>
20 #include <TopExp_Explorer.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>
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.;
48 //=======================================================================
50 // Purpose : Builds isoparametric curves with a hatcher.
51 //=======================================================================
53 void HLRTopoBRep_FaceIsoLiner::Perform (const Standard_Integer FI,
56 const Standard_Integer nbIsos)
58 (void)FI; // avoid compiler warning
60 Standard_Real UMin, UMax, VMin, VMax, U1, U2;
61 Standard_Integer ne = 0;
62 //BRep_Builder Builder;
64 TopExp_Explorer ExpEdges;
66 TF.Orientation (TopAbs_FORWARD);
69 TopoDS_Vertex V1U, V2U, V1V, V2V;
71 Geom2dHatch_Intersector Intersector
72 (IntersectorConfusion,IntersectorTangency);
73 Geom2dHatch_Hatcher Hatcher
74 (Intersector,HatcherConfusion2d,HatcherConfusion3d,Standard_True);
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);
82 if (InfiniteUMin && InfiniteUMax) {
86 else if (InfiniteUMin)
87 UMin = UMax - Infinite;
88 else if (InfiniteUMax)
89 UMax = UMin + Infinite;
91 if (InfiniteVMin && InfiniteVMax) {
95 else if (InfiniteVMin)
96 VMin = VMax - Infinite;
97 else if (InfiniteVMax)
98 VMax = VMin + Infinite;
100 for (ExpEdges.Init (TF, TopAbs_EDGE); // Edges of the face TF
102 ExpEdges.Next()) ne++;
104 if (DS.FaceHasIntL(TF)) { // OutLines built on face TF.
106 TopTools_ListIteratorOfListOfShape itE;
107 for(itE.Initialize(DS.FaceIntL(TF));
113 TopTools_Array1OfShape SH(1,ne);
114 TColStd_Array1OfBoolean IL(1,ne); // internal OutLine
116 for (ExpEdges.Init (TF, TopAbs_EDGE);
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());
128 Handle (Geom2d_TrimmedCurve) TPC =
129 new Geom2d_TrimmedCurve (PC, U1, U2);
130 IndE = Hatcher.AddElement (TPC, newE.Orientation());
133 if (DS.IsOutLFaceEdge(TF,newE)) IL(IndE) = Standard_True;
134 else IL(IndE) = Standard_False;
137 if (DS.FaceHasIntL(TF)) { // get the internal OutLines built on face F.
138 TopTools_ListIteratorOfListOfShape itE;
139 for(itE.Initialize(DS.FaceIntL(TF));
142 Standard_Integer IndE;
143 const TopoDS_Edge& newE = TopoDS::Edge(itE.Value());
144 const Handle(Geom2d_Curve) PC =
145 BRep_Tool::CurveOnSurface (newE, TF, U1, U2);
146 if( Abs(PC->FirstParameter() - U1) <= Precision::PConfusion()
147 && Abs(PC->LastParameter() - U2) <= Precision::PConfusion()) {
148 IndE = Hatcher.AddElement (PC, TopAbs_INTERNAL);
151 Handle (Geom2d_TrimmedCurve) TPC =
152 new Geom2d_TrimmedCurve (PC, U1, U2);
153 IndE = Hatcher.AddElement (TPC, TopAbs_INTERNAL);
156 IL(IndE) = Standard_True;
160 //-----------------------------------------------------------------------
161 // Creation des hachures.
162 //-----------------------------------------------------------------------
164 BRepAdaptor_Surface Surface (TF);
165 Standard_Real Tolerance = BRep_Tool::Tolerance (TF);
167 Standard_Integer IIso;
168 Standard_Real DeltaU = Abs (UMax - UMin);
169 Standard_Real DeltaV = Abs (VMax - VMin);
170 Standard_Real Confusion = Min (DeltaU, DeltaV) * HatcherConfusion3d;
171 Hatcher.Confusion3d (Confusion);
173 //-----------------------------------------------------------------------
175 //-----------------------------------------------------------------------
177 Standard_Real StepU = DeltaU / (Standard_Real) nbIsos;
178 if (StepU > Confusion) {
179 Standard_Real UPrm = UMin + StepU / 2.;
180 gp_Dir2d Dir (0., 1.);
182 for (IIso = 1; IIso <= nbIsos; IIso++) {
183 gp_Pnt2d Ori (UPrm, 0.);
184 Handle (Geom2d_Line) IsoLine = new Geom2d_Line (Ori, Dir);
186 Standard_Integer IndH = Hatcher.AddHatching (IsoLine);
188 if (Hatcher.TrimDone (IndH) && !Hatcher.TrimFailed (IndH))
189 Hatcher.ComputeDomains (IndH);
190 if (!Hatcher.IsDone (IndH)) {
192 cout << "HLRTopoBRep::MakeIsoLines : Face " << FI << endl;
193 cout << "U iso of parameter: " << UPrm;
194 switch (Hatcher.Status (IndH)) {
195 case HatchGen_NoProblem :
196 cout << " No Problem" << endl;
198 case HatchGen_TrimFailure :
199 cout << " Trim Failure" << endl;
201 case HatchGen_TransitionFailure :
202 cout << " Transition Failure" << endl;
204 case HatchGen_IncoherentParity :
205 cout << " Incoherent Parity" << endl;
207 case HatchGen_IncompatibleStates :
208 cout << " Incompatible States" << endl;
212 Hatcher.RemHatching (IndH);
216 Standard_Integer NbDom = Hatcher.NbDomains (IndH);
219 for (Standard_Integer IDom = 1; IDom <= NbDom; IDom++) {
220 const HatchGen_Domain& Dom = Hatcher.Domain (IndH, IDom);
221 Standard_Real U1 = Dom.HasFirstPoint() ?
222 Dom.FirstPoint().Parameter() : VMin - Infinite;
223 Standard_Real U2 = Dom.HasSecondPoint() ?
224 Dom.SecondPoint().Parameter() : VMax + Infinite;
226 Surface.D0 (P.X(), P.Y(), P1);
228 Surface.D0 (P.X(), P.Y(), P2);
229 if (Dom.HasFirstPoint()) { // Iso U - Premier point
230 const HatchGen_PointOnHatching& PntH = Dom.FirstPoint();
232 for (Standard_Integer IPntE = 1;
233 IPntE <= PntH.NbPoints();
235 const HatchGen_PointOnElement& PntE = PntH.Point(IPntE);
236 V1U = HLRTopoBRep_FaceIsoLiner::MakeVertex
237 (TopoDS::Edge(SH(PntE.Index())),
238 P1,PntE.Parameter(),Tolerance,DS);
239 if (IL(PntE.Index())) DS.AddOutV(V1U);
242 if (Dom.HasSecondPoint()) { // Iso U - Deuxieme point
243 const HatchGen_PointOnHatching& PntH = Dom.SecondPoint();
245 for (Standard_Integer IPntE = 1;
246 IPntE <= PntH.NbPoints();
248 const HatchGen_PointOnElement& PntE = PntH.Point(IPntE);
249 V2U = HLRTopoBRep_FaceIsoLiner::MakeVertex
250 (TopoDS::Edge(SH(PntE.Index())),
251 P2,PntE.Parameter(),Tolerance,DS);
252 if (IL(PntE.Index())) DS.AddOutV(V2U);
255 if(!V1U.IsNull() && !V2U.IsNull())
256 HLRTopoBRep_FaceIsoLiner::MakeIsoLine
257 (F,IsoLine,V1U,V2U,U1,U2,Tolerance,DS);
261 Hatcher.RemHatching (IndH);
266 //-----------------------------------------------------------------------
268 //-----------------------------------------------------------------------
270 Standard_Real StepV = DeltaV / (Standard_Real) nbIsos;
271 if (StepV > Confusion) {
272 Standard_Real VPrm = VMin + StepV / 2.;
273 gp_Dir2d Dir (1., 0.);
275 for (IIso = 1; IIso <= nbIsos; IIso++) {
276 gp_Pnt2d Ori (0., VPrm);
277 Handle (Geom2d_Line) IsoLine = new Geom2d_Line (Ori, Dir);
279 Standard_Integer IndH = Hatcher.AddHatching (IsoLine);
281 if (Hatcher.TrimDone (IndH) && !Hatcher.TrimFailed (IndH))
282 Hatcher.ComputeDomains (IndH);
283 if (!Hatcher.IsDone (IndH)) {
285 cout << "HLRTopoBRep::MakeIsoLines : Face " << FI << endl;
286 cout << "V iso of parameter: " << VPrm;
287 switch (Hatcher.Status (IndH)) {
288 case HatchGen_NoProblem :
289 cout << " No Problem" << endl;
291 case HatchGen_TrimFailure :
292 cout << " Trim Failure" << endl;
294 case HatchGen_TransitionFailure :
295 cout << " Transition Failure" << endl;
297 case HatchGen_IncoherentParity :
298 cout << " Incoherent Parity" << endl;
300 case HatchGen_IncompatibleStates :
301 cout << " Incompatible States" << endl;
305 Hatcher.RemHatching (IndH);
309 Standard_Integer NbDom = Hatcher.NbDomains (IndH);
312 for (Standard_Integer IDom = 1; IDom <= NbDom; IDom++) {
313 const HatchGen_Domain& Dom = Hatcher.Domain (IndH, IDom);
314 Standard_Real U1 = Dom.HasFirstPoint() ?
315 Dom.FirstPoint().Parameter() : VMin - Infinite;
316 Standard_Real U2 = Dom.HasSecondPoint() ?
317 Dom.SecondPoint().Parameter() : VMax + Infinite;
319 Surface.D0 (P.X(), P.Y(), P1);
321 Surface.D0 (P.X(), P.Y(), P2);
322 if (Dom.HasFirstPoint()) { // Iso V - Premier point
323 const HatchGen_PointOnHatching& PntH = Dom.FirstPoint();
325 for (Standard_Integer IPntE = 1;
326 IPntE <= PntH.NbPoints();
328 const HatchGen_PointOnElement& PntE = PntH.Point(IPntE);
329 V1V = HLRTopoBRep_FaceIsoLiner::MakeVertex
330 (TopoDS::Edge(SH(PntE.Index())),
331 P1,PntE.Parameter(),Tolerance,DS);
333 if (IL(PntE.Index())) DS.AddOutV(V1V);
336 if (Dom.HasSecondPoint()) { // Iso V - Deuxieme point
337 const HatchGen_PointOnHatching& PntH = Dom.SecondPoint();
339 for (Standard_Integer IPntE = 1;
340 IPntE <= PntH.NbPoints();
342 const HatchGen_PointOnElement& PntE = PntH.Point(IPntE);
343 V2V = HLRTopoBRep_FaceIsoLiner::MakeVertex
344 (TopoDS::Edge(SH(PntE.Index())),
345 P2,PntE.Parameter(),Tolerance,DS);
346 if (IL(PntE.Index())) DS.AddOutV(V2V);
349 if(!V1V.IsNull() && !V2V.IsNull())
350 HLRTopoBRep_FaceIsoLiner::MakeIsoLine
351 (F,IsoLine,V1V,V2V,U1,U2,Tolerance,DS);
355 Hatcher.RemHatching (IndH);
361 //=======================================================================
362 //function : MakeVertex
364 //=======================================================================
367 HLRTopoBRep_FaceIsoLiner::MakeVertex (const TopoDS_Edge& E,
369 const Standard_Real Par,
370 const Standard_Real Tol,
371 HLRTopoBRep_Data& DS)
373 TopoDS_Vertex V, VF, VL;
375 TopExp::Vertices (E, VF, VL);
376 if (P.IsEqual(BRep_Tool::Pnt(VF),BRep_Tool::Tolerance(VF)))
378 if (P.IsEqual(BRep_Tool::Pnt(VL),BRep_Tool::Tolerance(VL)))
381 for (DS.InitVertex(E); DS.MoreVertex(); DS.NextVertex()) {
382 TopoDS_Vertex curV = DS.Vertex();
383 Standard_Real curP = DS.Parameter();
384 if (P.IsEqual(BRep_Tool::Pnt(curV),BRep_Tool::Tolerance(curV))) {
388 else if (Par < curP) {
389 B.MakeVertex(V,P,Tol);
390 V.Orientation(TopAbs_INTERNAL);
391 DS.InsertBefore(V,Par);
396 if (!DS.MoreVertex()) {
397 B.MakeVertex(V,P,Tol);
398 V.Orientation(TopAbs_INTERNAL);
405 //=======================================================================
406 //function : MakeIsoLine
408 //=======================================================================
410 void HLRTopoBRep_FaceIsoLiner::MakeIsoLine (const TopoDS_Face& F,
411 const Handle(Geom2d_Line)& Iso,
414 const Standard_Real U1,
415 const Standard_Real U2,
416 const Standard_Real Tol,
417 HLRTopoBRep_Data& DS)
421 E.Orientation (TopAbs_INTERNAL);
422 V1.Orientation (TopAbs_FORWARD);
423 V2.Orientation (TopAbs_REVERSED);
425 B.UpdateEdge (E, Iso, F, Tol);
427 B.UpdateVertex (V1, U1, E, Tol);
429 B.UpdateVertex (V2, U2, E, Tol);
430 DS.AddIsoL(F).Append(E);