b311480e |
1 | // Created on: 1998-02-11 |
2 | // Created by: Philippe MANGIN |
3 | // Copyright (c) 1998-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
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 |
973c2be1 |
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. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
7fd59977 |
16 | |
7fd59977 |
17 | |
7fd59977 |
18 | #include <BRep_Tool.hxx> |
7fd59977 |
19 | #include <BRepAdaptor_HCompCurve.hxx> |
42cf5bc1 |
20 | #include <BRepAdaptor_HCurve.hxx> |
7fd59977 |
21 | #include <BRepExtrema_DistShapeShape.hxx> |
22 | #include <BRepExtrema_SupportType.hxx> |
42cf5bc1 |
23 | #include <BRepFill_LocationLaw.hxx> |
24 | #include <BRepFill_SectionPlacement.hxx> |
25 | #include <Geom_BSplineCurve.hxx> |
7fd59977 |
26 | #include <Geom_CartesianPoint.hxx> |
42cf5bc1 |
27 | #include <Geom_Curve.hxx> |
7fd59977 |
28 | #include <Geom_Line.hxx> |
42cf5bc1 |
29 | #include <Geom_TrimmedCurve.hxx> |
7fd59977 |
30 | #include <GeomAdaptor_HCurve.hxx> |
42cf5bc1 |
31 | #include <GeomConvert_CompCurveToBSplineCurve.hxx> |
7fd59977 |
32 | #include <GeomFill_LocationLaw.hxx> |
42cf5bc1 |
33 | #include <GeomFill_SectionPlacement.hxx> |
34 | #include <gp_Trsf.hxx> |
35 | #include <Precision.hxx> |
7fd59977 |
36 | #include <Standard_ConstructionError.hxx> |
37 | #include <Standard_NotImplemented.hxx> |
7fd59977 |
38 | #include <TColStd_Array1OfInteger.hxx> |
42cf5bc1 |
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> |
7fd59977 |
47 | |
0797d9d3 |
48 | #ifdef OCCT_DEBUG |
7fd59977 |
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; |
1d47d8d0 |
105 | Standard_Real First = 0., Last = 0.; |
7fd59977 |
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 | |
0d969553 |
158 | // // punctual section |
7fd59977 |
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()) |
9775fa61 |
199 | // throw Standard_ConstructionError("Distance Vertex/Spine"); |
7fd59977 |
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 | |
0d969553 |
284 | // In the general case : Localisation via concatenation of the spine |
7fd59977 |
285 | TColStd_Array1OfReal SuperKnot(1, myLaw->NbLaw()+1); |
7fd59977 |
286 | for (ii=1; ii<=myLaw->NbLaw(); ii++) { |
6c4c45b0 |
287 | SuperKnot(ii+1) = ii; |
7fd59977 |
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 | |
0797d9d3 |
299 | #ifdef OCCT_DEBUG |
7fd59977 |
300 | if (myDebug) { |
301 | gp_Pnt P_Path; |
302 | P_Path = adpPath->Value(theParam); |
04232180 |
303 | std::cout << "Point on Path" << P_Path.X() << ", " |
304 | << P_Path.Y() << ", " << P_Path.Z() << ", " << std::endl; |
7fd59977 |
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 | |
9775fa61 |
319 | if (Bof) throw Standard_ConstructionError("Interval non trouve !!"); |
6c4c45b0 |
320 | //Search of the <Ind1> by vertex <TheV> |
321 | if (!TheV.IsNull()) |
322 | for (Ind1 = 1; Ind1 <= myLaw->NbLaw(); Ind1++) |
323 | { |
324 | TopoDS_Edge anEdge = myLaw->Edge(Ind1); |
325 | TopoDS_Vertex V1, V2; |
326 | TopExp::Vertices(anEdge, V1, V2); |
327 | if (V1.IsSame(TheV) || V2.IsSame(TheV)) |
328 | break; |
329 | } |
330 | //////////////////// |
7fd59977 |
331 | |
0d969553 |
332 | // Positioning on the localized edge (or 2 Edges) |
7fd59977 |
333 | Standard_Real Angle; |
334 | Place.SetLocation(myLaw->Law(Ind1)); |
335 | if(TheV.IsNull()) |
336 | Place.Perform(Precision::Confusion()); |
337 | else { |
338 | Place.Perform(SearchParam(myLaw, Ind1, TheV), |
339 | Precision::Confusion()); |
340 | } |
341 | |
342 | myTrsf = Place.Transformation(WithContact, WithCorrection); |
343 | myIndex = Ind1; |
344 | myParam = Place.ParameterOnPath(); |
345 | Angle = Place.Angle(); |
346 | |
347 | if (Ind2) { |
348 | Place.SetLocation(myLaw->Law(Ind2)); |
349 | if (TheV.IsNull()) |
350 | Place.Perform(Precision::Confusion()); |
351 | else { |
352 | if (Ind1 == Ind2) TheV.Reverse(); |
353 | Place.Perform(SearchParam(myLaw, Ind2,TheV), |
354 | Precision::Confusion()); |
355 | } |
356 | if (Place.Angle() > Angle) { |
357 | myTrsf = Place.Transformation(WithContact, WithCorrection); |
358 | myIndex = Ind2; |
359 | myParam = Place.ParameterOnPath(); |
360 | } |
361 | } |
362 | } |
363 | |
364 | const gp_Trsf& BRepFill_SectionPlacement::Transformation() const |
365 | { |
366 | return myTrsf; |
367 | } |
368 | |
369 | Standard_Real BRepFill_SectionPlacement::AbscissaOnPath() |
370 | { |
371 | return myLaw->Abscissa(myIndex, myParam); |
372 | } |