0028468: Sweep with different sections raises Standard_NoSuchObject: BRep_Tool::...
[occt.git] / src / BRepFill / BRepFill_SectionPlacement.cxx
CommitLineData
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 49static Standard_Boolean myDebug = Standard_False;
50#endif
51
52static 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
73BRepFill_SectionPlacement::
74BRepFill_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
85BRepFill_SectionPlacement::
86BRepFill_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);
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
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}