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