0025418: Debug output to be limited to OCC development environment
[occt.git] / src / BRepFill / BRepFill_SectionPlacement.cxx
1 // Created on: 1998-02-11
2 // Created by: Philippe MANGIN
3 // Copyright (c) 1998-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 #include <BRepFill_SectionPlacement.ixx>
18
19 #include <TopExp_Explorer.hxx>
20 #include <TopExp.hxx>
21 #include <TopAbs_ShapeEnum.hxx>
22 #include <TopoDS_Edge.hxx>
23 #include <TopoDS_Vertex.hxx>
24 #include <TopoDS.hxx>
25 #include <BRep_Tool.hxx>
26 #include <BRepAdaptor_HCurve.hxx>
27 #include <BRepAdaptor_HCompCurve.hxx>
28 #include <BRepExtrema_DistShapeShape.hxx>
29 #include <BRepExtrema_SupportType.hxx>
30
31 #include <Geom_Curve.hxx>
32 #include <Geom_CartesianPoint.hxx>
33 #include <Geom_TrimmedCurve.hxx>
34 #include <Geom_Line.hxx>
35 #include <Geom_BSplineCurve.hxx>
36 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
37 #include <GeomAdaptor_HCurve.hxx>
38 #include <GeomFill_SectionPlacement.hxx>
39 #include <GeomFill_LocationLaw.hxx>
40
41 #include <Standard_ConstructionError.hxx>
42 #include <Standard_NotImplemented.hxx>
43 #include <TColStd_Array1OfReal.hxx>
44 #include <TColStd_Array1OfInteger.hxx>
45 #include <Precision.hxx>
46
47 #ifdef OCCT_DEBUG
48 static Standard_Boolean myDebug = Standard_False;
49 #endif
50
51 static Standard_Real SearchParam(const Handle(BRepFill_LocationLaw)& Law,
52                                  const Standard_Integer Ind,
53                                  const TopoDS_Vertex& TheV)
54 {
55   Standard_Real t;
56   TopoDS_Edge E;
57   E = Law->Edge(Ind);
58   t = BRep_Tool::Parameter(TheV, E);
59   if (E.Orientation() == TopAbs_REVERSED) {
60     Standard_Real f, l, Lf, Ll;
61     Handle(Geom_Curve) C;
62     C = BRep_Tool::Curve(E,f,l);
63     Lf = Law->Law(Ind)->GetCurve()->FirstParameter();
64     Ll = Law->Law(Ind)->GetCurve()->LastParameter();
65     t = Ll - (t-f)*(Ll-Lf)/(l-f);
66   }
67   return t;
68 }
69                                  
70                                  
71
72 BRepFill_SectionPlacement::
73 BRepFill_SectionPlacement(const Handle(BRepFill_LocationLaw)& Law,
74                           const TopoDS_Shape& Section,
75                           const Standard_Boolean WithContact,
76                           const Standard_Boolean WithCorrection) :
77                           myLaw(Law), mySection(Section)
78 {
79  TopoDS_Vertex VNull;
80  VNull.Nullify();
81  Perform(WithContact, WithCorrection, VNull);
82 }
83
84 BRepFill_SectionPlacement::
85 BRepFill_SectionPlacement(const Handle(BRepFill_LocationLaw)& Law,
86                           const TopoDS_Shape& Section,
87                           const TopoDS_Shape& Vertex,
88                           const Standard_Boolean WithContact,
89                           const Standard_Boolean WithCorrection) :
90                           myLaw(Law), mySection(Section)
91 {
92  Perform(WithContact, WithCorrection, Vertex);
93 }
94
95  void BRepFill_SectionPlacement::Perform(const Standard_Boolean WithContact,
96                                          const Standard_Boolean WithCorrection,
97                                          const TopoDS_Shape& Vertex) 
98 {
99   TopoDS_Vertex TheV; 
100   TheV = TopoDS::Vertex(Vertex);
101   Standard_Integer ii; 
102   Standard_Integer Ind1 = 0, Ind2 = 0;
103   Standard_Boolean Bof, isVertex = Standard_False;
104   Standard_Real First = 0., Last = 0.;
105   TopExp_Explorer Ex;
106   TopoDS_Edge E;
107   TopoDS_Vertex V;
108   Handle(Geom_Curve) C;
109   Handle(Geom_TrimmedCurve) TC; 
110
111   // modified by NIZHNY-OCC629  Thu Jul 24 14:11:45 2003
112   Standard_Boolean isFound = Standard_False;
113   Ex.Init(mySection, TopAbs_EDGE);
114   for(; Ex.More(); Ex.Next()) {
115     E = TopoDS::Edge(Ex.Current());
116     // avoid null, degenerated edges
117     if( E.IsNull() || BRep_Tool::Degenerated(E) ) continue;
118     C = BRep_Tool::Curve(E, First, Last);
119     if( C.IsNull() ) continue;
120     isFound = Standard_True;
121     break;
122   }
123   if( !isFound )
124     isVertex = Standard_True;
125   else
126     {
127       TC = new (Geom_TrimmedCurve)(C, First, Last);
128       Ex.Next();
129       
130       if( Ex.More() ) {
131         Standard_Real tolrac, epsV, tol = Precision::Confusion();
132         GeomConvert_CompCurveToBSplineCurve Conv(TC);
133         for (; Ex.More(); Ex.Next()) {
134           E = TopoDS::Edge(Ex.Current());
135           // avoid null, degenerated edges
136           if( E.IsNull() || BRep_Tool::Degenerated(E) ) continue;
137           TopoDS_Vertex VFirst, VLast;
138           TopExp::Vertices(E,VFirst, VLast);
139           epsV = Max(BRep_Tool::Tolerance(VFirst), BRep_Tool::Tolerance(VLast));
140           C = BRep_Tool::Curve(E, First, Last);
141           if( C.IsNull() ) continue;
142           TC = new (Geom_TrimmedCurve)(C, First, Last);
143           tolrac = Min(tol,epsV);
144           Bof = Conv.Add(TC, tolrac);
145           if (!Bof) {
146             tolrac = Max(tol,epsV);
147             Bof = Conv.Add(TC, tolrac);
148           }
149         }
150         C = Conv.BSplineCurve();
151       }
152       else C = TC; // On garde l'unique courbe
153     }
154
155   // modified by NIZHNY-629  Fri Jul 25 11:10:27 2003 b
156
157 //   // punctual section
158 //  Ex.Init(mySection, TopAbs_EDGE);
159 //   Standard_Boolean isPonctual = Standard_False;
160 //  if (Ex.More()) {
161 //    E = TopoDS::Edge(Ex.Current());
162 //    isPonctual = BRep_Tool::Degenerated(E);
163 //  }
164
165 //   Ex.Init(mySection, TopAbs_EDGE);
166 //   if (Ex.More()&&!isPonctual) { 
167 //     E = TopoDS::Edge(Ex.Current());
168 //     C = BRep_Tool::Curve(E, First, Last);
169 //     TC = new (Geom_TrimmedCurve)(C, First, Last);
170 //     Ex.Next();
171 //     if (Ex.More()) { // On essai d'avoir un echantillon representatif
172 //       Standard_Real tolrac, epsV, tol = Precision::Confusion();
173 //       GeomConvert_CompCurveToBSplineCurve Conv(TC);
174 //       for (; Ex.More(); Ex.Next()) {
175 //      E = TopoDS::Edge(Ex.Current());
176 //      TopoDS_Vertex VFirst, VLast;
177 //      TopExp::Vertices(E,VFirst, VLast);
178 //      epsV = Max(BRep_Tool::Tolerance(VFirst), BRep_Tool::Tolerance(VLast));
179 //      C = BRep_Tool::Curve(E, First, Last);
180 //      TC = new (Geom_TrimmedCurve)(C, First, Last);
181 //      tolrac = Min(tol,epsV);
182 //      Bof = Conv.Add(TC, tolrac);
183 //      if (!Bof) {
184 //        tolrac = Max(tol,epsV);
185 //        Bof = Conv.Add(TC, tolrac);
186 //      }
187 //       }
188 //       C = Conv.BSplineCurve();
189 //     }
190 //     else C = TC; // On garde l'unique courbe
191 //   }
192 //   else {
193 //     // Localisation par distance Shape/Shape
194 //     Standard_Real Tpos;
195 //     BRepExtrema_DistShapeShape Ext(mySection, myLaw->Wire());
196     
197 //     if (! Ext.IsDone()) 
198 //        Standard_ConstructionError::Raise("Distance Vertex/Spine");
199
200 //     if (Ext.SupportTypeShape2(1) == BRepExtrema_IsOnEdge) {
201 //       TopoDS_Shape sbis = Ext.SupportOnShape2(1);
202 //       E = TopoDS::Edge(sbis);
203 //       Ext.ParOnEdgeS2(1, Tpos); 
204 //     }
205 //     else {
206 //       TopoDS_Vertex Vf, Vl,V;
207 //       TopoDS_Shape sbis = Ext.SupportOnShape2(1);
208 //       V = TopoDS::Vertex(sbis);
209 //       for (ii=1, Ind1=0 ; ii<=myLaw->NbLaw(); ii++) {
210 //      E = myLaw->Edge(ii);
211 //      TopExp::Vertices(E, Vf, Vl);
212 //      if ((V.IsSame(Vf)) || (V.IsSame(Vl))) {
213 //        if (Ind1 == 0) Ind1 = ii;
214 //        else Ind2 = ii;
215 //      }
216 //       }
217       
218 //       // On invente une section
219 //       gp_Dir D(0, 0, 1);
220 //       gp_Pnt Origine, PV;
221 //       Origine = BRep_Tool::Pnt(V);
222 //       Standard_Real length;
223
224 //       if (Ext.SupportTypeShape1(1) == BRepExtrema_IsVertex) {
225 //      TopoDS_Shape aLocalShape = Ext.SupportOnShape1(1);
226 //         PV = BRep_Tool::Pnt(TopoDS::Vertex(aLocalShape));
227 // //        PV = BRep_Tool::Pnt(TopoDS::Vertex(Ext.SupportOnShape1(1)));
228 //       }
229 //       else {
230 //         PV = BRep_Tool::Pnt(TopoDS::Vertex(mySection));
231 //       }
232 //       length = Origine.Distance(PV);
233 //       if (length > Precision::Confusion()) {
234 //      gp_Vec theVec(Origine, PV);
235 //      D.SetXYZ(theVec.XYZ());
236 //       }
237 //       else length = 10*Precision::Confusion();
238 //       Handle(Geom_Line) CL = new (Geom_Line) (Origine, D);
239 //       TC = new (Geom_TrimmedCurve)(CL, 0., length);
240 //       C = TC; 
241 //       isVertex = Standard_True;
242 //     }
243 //   }
244
245 //   // Recherche du Vertex de positionnement
246 //   if (!TheV.IsNull()) {
247 //     Standard_Integer NbV = myLaw->NbLaw()+1;
248 //     for (ii=1, Ind1=0; ii<=NbV && (!Ind1); ii++)
249 //       if (TheV.IsSame(myLaw->Vertex(ii))) Ind1 = ii;
250     
251 //     if (Ind1 != 0) {
252 //       Ind2 =0;
253 //       isVertex = Standard_True;
254 //       if (Ind1==1) {
255 //      if (myLaw->IsClosed()) Ind2 =  NbV-1;
256 //       }
257 //       else {
258 //      Ind1--;
259 //      if (Ind1 < NbV-1)
260 //        Ind2 = Ind1+1;
261 //       }
262 //     }
263 //     else {
264 //       TheV.Nullify(); // On oublie cette option...
265 //     }
266 //   }
267
268   // modified by NIZHNY-629  Fri Jul 25 11:11:06 2003 e
269
270
271   // Construction
272   Handle(Geom_Geometry) theSection = C;
273   if (isVertex)
274     {
275       Ex.Init(mySection, TopAbs_VERTEX);
276       TopoDS_Vertex theVertex = TopoDS::Vertex(Ex.Current());
277       gp_Pnt thePoint = BRep_Tool::Pnt(theVertex);
278       theSection = new Geom_CartesianPoint(thePoint);
279     }
280
281   GeomFill_SectionPlacement Place(myLaw->Law(1), theSection);
282
283   // In the general case : Localisation via concatenation of the spine
284   TColStd_Array1OfReal SuperKnot(1, myLaw->NbLaw()+1); 
285   TColStd_Array1OfInteger Index(1, myLaw->NbLaw()); 
286   for (ii=1; ii<=myLaw->NbLaw(); ii++) {
287     SuperKnot(ii+1) = Index(ii) = ii;
288   }
289   SuperKnot(1) = 0;
290   
291   Handle(BRepAdaptor_HCompCurve) adpPath = 
292     new (BRepAdaptor_HCompCurve) (myLaw->Wire());
293   
294   Place.Perform(adpPath, Precision::Confusion());
295   
296   Standard_Real theParam = Place.ParameterOnPath(), 
297                 eps = Precision::PConfusion();
298
299 #ifdef OCCT_DEBUG
300   if (myDebug) {
301     gp_Pnt P_Path;
302     P_Path = adpPath->Value(theParam);
303     cout << "Point on Path" << P_Path.X() << ", " 
304       <<  P_Path.Y() << ", " << P_Path.Z() << ", " << endl; 
305   }
306 #endif
307   
308   for (ii=1, Bof=Standard_True; ii<=myLaw->NbLaw() && Bof; ii++) {
309     Bof = !((SuperKnot(ii)-eps<=theParam) && 
310             (SuperKnot(ii+1)+eps>= theParam));
311     if (!Bof) {
312       Ind1 = ii;
313       if ( (Abs(theParam-SuperKnot(ii))<eps) && (ii>1) ) Ind2 = ii-1;
314         else if ((Abs(theParam-SuperKnot(ii+1))<eps) && 
315                  (ii<myLaw->NbLaw()) ) Ind2 = ii+1;
316     }
317   }
318   
319   if (Bof) Standard_ConstructionError::Raise("Interval non trouve !!");
320   Ind1 = Index(Ind1);
321   if (Ind2) Ind2 = Index(Ind2);
322   
323   // Positioning on the localized edge (or 2 Edges)
324   Standard_Real Angle;
325   Place.SetLocation(myLaw->Law(Ind1));
326   if(TheV.IsNull())
327     Place.Perform(Precision::Confusion());
328   else {
329     Place.Perform(SearchParam(myLaw, Ind1, TheV), 
330                   Precision::Confusion());    
331   }
332
333   myTrsf = Place.Transformation(WithContact, WithCorrection);
334   myIndex = Ind1;
335   myParam = Place.ParameterOnPath();
336   Angle =  Place.Angle();
337
338   if (Ind2) {
339     Place.SetLocation(myLaw->Law(Ind2));
340     if (TheV.IsNull())
341       Place.Perform(Precision::Confusion());
342     else {
343       if (Ind1 == Ind2) TheV.Reverse();
344       Place.Perform(SearchParam(myLaw, Ind2,TheV), 
345                     Precision::Confusion()); 
346     }
347     if (Place.Angle() > Angle) {
348       myTrsf = Place.Transformation(WithContact, WithCorrection);
349       myIndex = Ind2;
350       myParam = Place.ParameterOnPath();
351     }                                                   
352   }
353 }
354
355  const gp_Trsf& BRepFill_SectionPlacement::Transformation() const
356 {
357   return myTrsf;
358 }
359
360  Standard_Real BRepFill_SectionPlacement::AbscissaOnPath()
361 {
362   return myLaw->Abscissa(myIndex, myParam);
363 }