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.
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>
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>
38 #include <TopExp_Explorer.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>
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.;
53 //=======================================================================
55 // Purpose : Builds isoparametric curves with a hatcher.
56 //=======================================================================
58 void HLRTopoBRep_FaceIsoLiner::Perform (const Standard_Integer FI,
61 const Standard_Integer nbIsos)
63 (void)FI; // avoid compiler warning
65 Standard_Real UMin, UMax, VMin, VMax, U1, U2;
66 Standard_Integer ne = 0;
67 //BRep_Builder Builder;
69 TopExp_Explorer ExpEdges;
71 TF.Orientation (TopAbs_FORWARD);
74 TopoDS_Vertex V1U, V2U, V1V, V2V;
76 Geom2dHatch_Intersector Intersector
77 (IntersectorConfusion,IntersectorTangency);
78 Geom2dHatch_Hatcher Hatcher
79 (Intersector,HatcherConfusion2d,HatcherConfusion3d,Standard_True);
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);
87 if (InfiniteUMin && InfiniteUMax) {
91 else if (InfiniteUMin)
92 UMin = UMax - Infinite;
93 else if (InfiniteUMax)
94 UMax = UMin + Infinite;
96 if (InfiniteVMin && InfiniteVMax) {
100 else if (InfiniteVMin)
101 VMin = VMax - Infinite;
102 else if (InfiniteVMax)
103 VMax = VMin + Infinite;
105 for (ExpEdges.Init (TF, TopAbs_EDGE); // Edges of the face TF
107 ExpEdges.Next()) ne++;
109 if (DS.FaceHasIntL(TF)) { // OutLines built on face TF.
111 TopTools_ListIteratorOfListOfShape itE;
112 for(itE.Initialize(DS.FaceIntL(TF));
118 TopTools_Array1OfShape SH(1,ne);
119 TColStd_Array1OfBoolean IL(1,ne); // internal OutLine
121 for (ExpEdges.Init (TF, TopAbs_EDGE);
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());
133 Handle (Geom2d_TrimmedCurve) TPC =
134 new Geom2d_TrimmedCurve (PC, U1, U2);
135 Geom2dAdaptor_Curve aGAC (TPC);
136 IndE = Hatcher.AddElement (aGAC, newE.Orientation());
139 if (DS.IsOutLFaceEdge(TF,newE)) IL(IndE) = Standard_True;
140 else IL(IndE) = Standard_False;
143 if (DS.FaceHasIntL(TF)) { // get the internal OutLines built on face F.
144 TopTools_ListIteratorOfListOfShape itE;
145 for(itE.Initialize(DS.FaceIntL(TF));
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);
157 Handle (Geom2d_TrimmedCurve) TPC =
158 new Geom2d_TrimmedCurve (PC, U1, U2);
159 Geom2dAdaptor_Curve aGAC (TPC);
160 IndE = Hatcher.AddElement (aGAC, TopAbs_INTERNAL);
163 IL(IndE) = Standard_True;
167 //-----------------------------------------------------------------------
168 // Creation des hachures.
169 //-----------------------------------------------------------------------
171 BRepAdaptor_Surface Surface (TF);
172 Standard_Real Tolerance = BRep_Tool::Tolerance (TF);
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);
180 //-----------------------------------------------------------------------
182 //-----------------------------------------------------------------------
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.);
189 for (IIso = 1; IIso <= nbIsos; IIso++) {
190 gp_Pnt2d Ori (UPrm, 0.);
191 Handle (Geom2d_Line) IsoLine = new Geom2d_Line (Ori, Dir);
193 Geom2dAdaptor_Curve aGAC (IsoLine);
194 Standard_Integer IndH = Hatcher.AddHatching (aGAC);
196 if (Hatcher.TrimDone (IndH) && !Hatcher.TrimFailed (IndH))
197 Hatcher.ComputeDomains (IndH);
198 if (!Hatcher.IsDone (IndH)) {
200 cout << "HLRTopoBRep::MakeIsoLines : Face " << FI << endl;
201 cout << "U iso of parameter: " << UPrm;
202 switch (Hatcher.Status (IndH)) {
203 case HatchGen_NoProblem :
204 cout << " No Problem" << endl;
206 case HatchGen_TrimFailure :
207 cout << " Trim Failure" << endl;
209 case HatchGen_TransitionFailure :
210 cout << " Transition Failure" << endl;
212 case HatchGen_IncoherentParity :
213 cout << " Incoherent Parity" << endl;
215 case HatchGen_IncompatibleStates :
216 cout << " Incompatible States" << endl;
220 Hatcher.RemHatching (IndH);
224 Standard_Integer NbDom = Hatcher.NbDomains (IndH);
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();
240 for (Standard_Integer IPntE = 1;
241 IPntE <= PntH.NbPoints();
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);
250 if (Dom.HasSecondPoint()) { // Iso U - Deuxieme point
251 const HatchGen_PointOnHatching& PntH = Dom.SecondPoint();
253 for (Standard_Integer IPntE = 1;
254 IPntE <= PntH.NbPoints();
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);
263 if(!V1U.IsNull() && !V2U.IsNull())
264 HLRTopoBRep_FaceIsoLiner::MakeIsoLine
265 (F,IsoLine,V1U,V2U,U11,U21,Tolerance,DS);
269 Hatcher.RemHatching (IndH);
274 //-----------------------------------------------------------------------
276 //-----------------------------------------------------------------------
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.);
283 for (IIso = 1; IIso <= nbIsos; IIso++) {
284 gp_Pnt2d Ori (0., VPrm);
285 Handle (Geom2d_Line) IsoLine = new Geom2d_Line (Ori, Dir);
287 Geom2dAdaptor_Curve aGAC (IsoLine);
288 Standard_Integer IndH = Hatcher.AddHatching (aGAC);
290 if (Hatcher.TrimDone (IndH) && !Hatcher.TrimFailed (IndH))
291 Hatcher.ComputeDomains (IndH);
292 if (!Hatcher.IsDone (IndH)) {
294 cout << "HLRTopoBRep::MakeIsoLines : Face " << FI << endl;
295 cout << "V iso of parameter: " << VPrm;
296 switch (Hatcher.Status (IndH)) {
297 case HatchGen_NoProblem :
298 cout << " No Problem" << endl;
300 case HatchGen_TrimFailure :
301 cout << " Trim Failure" << endl;
303 case HatchGen_TransitionFailure :
304 cout << " Transition Failure" << endl;
306 case HatchGen_IncoherentParity :
307 cout << " Incoherent Parity" << endl;
309 case HatchGen_IncompatibleStates :
310 cout << " Incompatible States" << endl;
314 Hatcher.RemHatching (IndH);
318 Standard_Integer NbDom = Hatcher.NbDomains (IndH);
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();
334 for (Standard_Integer IPntE = 1;
335 IPntE <= PntH.NbPoints();
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);
342 if (IL(PntE.Index())) DS.AddOutV(V1V);
345 if (Dom.HasSecondPoint()) { // Iso V - Deuxieme point
346 const HatchGen_PointOnHatching& PntH = Dom.SecondPoint();
348 for (Standard_Integer IPntE = 1;
349 IPntE <= PntH.NbPoints();
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);
358 if(!V1V.IsNull() && !V2V.IsNull())
359 HLRTopoBRep_FaceIsoLiner::MakeIsoLine
360 (F,IsoLine,V1V,V2V,U12,U22,Tolerance,DS);
364 Hatcher.RemHatching (IndH);
370 //=======================================================================
371 //function : MakeVertex
373 //=======================================================================
376 HLRTopoBRep_FaceIsoLiner::MakeVertex (const TopoDS_Edge& E,
378 const Standard_Real Par,
379 const Standard_Real Tol,
380 HLRTopoBRep_Data& DS)
382 TopoDS_Vertex V, VF, VL;
384 TopExp::Vertices (E, VF, VL);
385 if (P.IsEqual(BRep_Tool::Pnt(VF),BRep_Tool::Tolerance(VF)))
387 if (P.IsEqual(BRep_Tool::Pnt(VL),BRep_Tool::Tolerance(VL)))
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))) {
397 else if (Par < curP) {
398 B.MakeVertex(V,P,Tol);
399 V.Orientation(TopAbs_INTERNAL);
400 DS.InsertBefore(V,Par);
405 if (!DS.MoreVertex()) {
406 B.MakeVertex(V,P,Tol);
407 V.Orientation(TopAbs_INTERNAL);
414 //=======================================================================
415 //function : MakeIsoLine
417 //=======================================================================
419 void HLRTopoBRep_FaceIsoLiner::MakeIsoLine (const TopoDS_Face& F,
420 const Handle(Geom2d_Line)& Iso,
423 const Standard_Real U1,
424 const Standard_Real U2,
425 const Standard_Real Tol,
426 HLRTopoBRep_Data& DS)
430 E.Orientation (TopAbs_INTERNAL);
431 V1.Orientation (TopAbs_FORWARD);
432 V2.Orientation (TopAbs_REVERSED);
434 B.UpdateEdge (E, Iso, F, Tol);
436 B.UpdateVertex (V1, U1, E, Tol);
438 B.UpdateVertex (V2, U2, E, Tol);
439 DS.AddIsoL(F).Append(E);