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
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
9 // under the terms of the GNU Lesser General Public 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.
17 #include <BRepFill_SectionPlacement.ixx>
19 #include <TopExp_Explorer.hxx>
21 #include <TopAbs_ShapeEnum.hxx>
22 #include <TopoDS_Edge.hxx>
23 #include <TopoDS_Vertex.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>
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>
41 #include <Standard_ConstructionError.hxx>
42 #include <Standard_NotImplemented.hxx>
43 #include <TColStd_Array1OfReal.hxx>
44 #include <TColStd_Array1OfInteger.hxx>
45 #include <Precision.hxx>
48 static Standard_Boolean myDebug = Standard_False;
51 static Standard_Real SearchParam(const Handle(BRepFill_LocationLaw)& Law,
52 const Standard_Integer Ind,
53 const TopoDS_Vertex& TheV)
58 t = BRep_Tool::Parameter(TheV, E);
59 if (E.Orientation() == TopAbs_REVERSED) {
60 Standard_Real f, l, Lf, Ll;
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);
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)
81 Perform(WithContact, WithCorrection, VNull);
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)
92 Perform(WithContact, WithCorrection, Vertex);
95 void BRepFill_SectionPlacement::Perform(const Standard_Boolean WithContact,
96 const Standard_Boolean WithCorrection,
97 const TopoDS_Shape& Vertex)
100 TheV = TopoDS::Vertex(Vertex);
102 Standard_Integer Ind1 = 0, Ind2 = 0;
103 Standard_Boolean Bof, isVertex = Standard_False;
104 Standard_Real First = 0., Last = 0.;
108 Handle(Geom_Curve) C;
109 Handle(Geom_TrimmedCurve) TC;
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;
124 isVertex = Standard_True;
127 TC = new (Geom_TrimmedCurve)(C, First, Last);
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);
146 tolrac = Max(tol,epsV);
147 Bof = Conv.Add(TC, tolrac);
150 C = Conv.BSplineCurve();
152 else C = TC; // On garde l'unique courbe
155 // modified by NIZHNY-629 Fri Jul 25 11:10:27 2003 b
157 // // punctual section
158 // Ex.Init(mySection, TopAbs_EDGE);
159 // Standard_Boolean isPonctual = Standard_False;
161 // E = TopoDS::Edge(Ex.Current());
162 // isPonctual = BRep_Tool::Degenerated(E);
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);
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);
184 // tolrac = Max(tol,epsV);
185 // Bof = Conv.Add(TC, tolrac);
188 // C = Conv.BSplineCurve();
190 // else C = TC; // On garde l'unique courbe
193 // // Localisation par distance Shape/Shape
194 // Standard_Real Tpos;
195 // BRepExtrema_DistShapeShape Ext(mySection, myLaw->Wire());
197 // if (! Ext.IsDone())
198 // Standard_ConstructionError::Raise("Distance Vertex/Spine");
200 // if (Ext.SupportTypeShape2(1) == BRepExtrema_IsOnEdge) {
201 // TopoDS_Shape sbis = Ext.SupportOnShape2(1);
202 // E = TopoDS::Edge(sbis);
203 // Ext.ParOnEdgeS2(1, Tpos);
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;
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;
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)));
230 // PV = BRep_Tool::Pnt(TopoDS::Vertex(mySection));
232 // length = Origine.Distance(PV);
233 // if (length > Precision::Confusion()) {
234 // gp_Vec theVec(Origine, PV);
235 // D.SetXYZ(theVec.XYZ());
237 // else length = 10*Precision::Confusion();
238 // Handle(Geom_Line) CL = new (Geom_Line) (Origine, D);
239 // TC = new (Geom_TrimmedCurve)(CL, 0., length);
241 // isVertex = Standard_True;
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;
253 // isVertex = Standard_True;
255 // if (myLaw->IsClosed()) Ind2 = NbV-1;
264 // TheV.Nullify(); // On oublie cette option...
268 // modified by NIZHNY-629 Fri Jul 25 11:11:06 2003 e
272 Handle(Geom_Geometry) theSection = C;
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);
281 GeomFill_SectionPlacement Place(myLaw->Law(1), theSection);
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;
291 Handle(BRepAdaptor_HCompCurve) adpPath =
292 new (BRepAdaptor_HCompCurve) (myLaw->Wire());
294 Place.Perform(adpPath, Precision::Confusion());
296 Standard_Real theParam = Place.ParameterOnPath(),
297 eps = Precision::PConfusion();
302 P_Path = adpPath->Value(theParam);
303 cout << "Point on Path" << P_Path.X() << ", "
304 << P_Path.Y() << ", " << P_Path.Z() << ", " << endl;
308 for (ii=1, Bof=Standard_True; ii<=myLaw->NbLaw() && Bof; ii++) {
309 Bof = !((SuperKnot(ii)-eps<=theParam) &&
310 (SuperKnot(ii+1)+eps>= theParam));
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;
319 if (Bof) Standard_ConstructionError::Raise("Interval non trouve !!");
321 if (Ind2) Ind2 = Index(Ind2);
323 // Positioning on the localized edge (or 2 Edges)
325 Place.SetLocation(myLaw->Law(Ind1));
327 Place.Perform(Precision::Confusion());
329 Place.Perform(SearchParam(myLaw, Ind1, TheV),
330 Precision::Confusion());
333 myTrsf = Place.Transformation(WithContact, WithCorrection);
335 myParam = Place.ParameterOnPath();
336 Angle = Place.Angle();
339 Place.SetLocation(myLaw->Law(Ind2));
341 Place.Perform(Precision::Confusion());
343 if (Ind1 == Ind2) TheV.Reverse();
344 Place.Perform(SearchParam(myLaw, Ind2,TheV),
345 Precision::Confusion());
347 if (Place.Angle() > Angle) {
348 myTrsf = Place.Transformation(WithContact, WithCorrection);
350 myParam = Place.ParameterOnPath();
355 const gp_Trsf& BRepFill_SectionPlacement::Transformation() const
360 Standard_Real BRepFill_SectionPlacement::AbscissaOnPath()
362 return myLaw->Abscissa(myIndex, myParam);