1 // Created on: 1998-02-11
2 // Created by: Philippe MANGIN
3 // Copyright (c) 1998-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
23 #include <BRepFill_SectionPlacement.ixx>
25 #include <TopExp_Explorer.hxx>
27 #include <TopAbs_ShapeEnum.hxx>
28 #include <TopoDS_Edge.hxx>
29 #include <TopoDS_Vertex.hxx>
31 #include <BRep_Tool.hxx>
32 #include <BRepAdaptor_HCurve.hxx>
33 #include <BRepAdaptor_HCompCurve.hxx>
34 #include <BRepExtrema_DistShapeShape.hxx>
35 #include <BRepExtrema_SupportType.hxx>
37 #include <Geom_Curve.hxx>
38 #include <Geom_CartesianPoint.hxx>
39 #include <Geom_TrimmedCurve.hxx>
40 #include <Geom_Line.hxx>
41 #include <Geom_BSplineCurve.hxx>
42 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
43 #include <GeomAdaptor_HCurve.hxx>
44 #include <GeomFill_SectionPlacement.hxx>
45 #include <GeomFill_LocationLaw.hxx>
47 #include <Standard_ConstructionError.hxx>
48 #include <Standard_NotImplemented.hxx>
49 #include <TColStd_Array1OfReal.hxx>
50 #include <TColStd_Array1OfInteger.hxx>
51 #include <Precision.hxx>
54 static Standard_Boolean myDebug = Standard_False;
57 static Standard_Real SearchParam(const Handle(BRepFill_LocationLaw)& Law,
58 const Standard_Integer Ind,
59 const TopoDS_Vertex& TheV)
64 t = BRep_Tool::Parameter(TheV, E);
65 if (E.Orientation() == TopAbs_REVERSED) {
66 Standard_Real f, l, Lf, Ll;
68 C = BRep_Tool::Curve(E,f,l);
69 Lf = Law->Law(Ind)->GetCurve()->FirstParameter();
70 Ll = Law->Law(Ind)->GetCurve()->LastParameter();
71 t = Ll - (t-f)*(Ll-Lf)/(l-f);
78 BRepFill_SectionPlacement::
79 BRepFill_SectionPlacement(const Handle(BRepFill_LocationLaw)& Law,
80 const TopoDS_Shape& Section,
81 const Standard_Boolean WithContact,
82 const Standard_Boolean WithCorrection) :
83 myLaw(Law), mySection(Section)
87 Perform(WithContact, WithCorrection, VNull);
90 BRepFill_SectionPlacement::
91 BRepFill_SectionPlacement(const Handle(BRepFill_LocationLaw)& Law,
92 const TopoDS_Shape& Section,
93 const TopoDS_Shape& Vertex,
94 const Standard_Boolean WithContact,
95 const Standard_Boolean WithCorrection) :
96 myLaw(Law), mySection(Section)
98 Perform(WithContact, WithCorrection, Vertex);
101 void BRepFill_SectionPlacement::Perform(const Standard_Boolean WithContact,
102 const Standard_Boolean WithCorrection,
103 const TopoDS_Shape& Vertex)
106 TheV = TopoDS::Vertex(Vertex);
108 Standard_Integer Ind1 = 0, Ind2 = 0;
109 Standard_Boolean Bof, isVertex = Standard_False;
110 Standard_Real First, Last;
114 Handle(Geom_Curve) C;
115 Handle(Geom_TrimmedCurve) TC;
117 // modified by NIZHNY-OCC629 Thu Jul 24 14:11:45 2003
118 Standard_Boolean isFound = Standard_False;
119 Ex.Init(mySection, TopAbs_EDGE);
120 for(; Ex.More(); Ex.Next()) {
121 E = TopoDS::Edge(Ex.Current());
122 // avoid null, degenerated edges
123 if( E.IsNull() || BRep_Tool::Degenerated(E) ) continue;
124 C = BRep_Tool::Curve(E, First, Last);
125 if( C.IsNull() ) continue;
126 isFound = Standard_True;
130 isVertex = Standard_True;
133 TC = new (Geom_TrimmedCurve)(C, First, Last);
137 Standard_Real tolrac, epsV, tol = Precision::Confusion();
138 GeomConvert_CompCurveToBSplineCurve Conv(TC);
139 for (; Ex.More(); Ex.Next()) {
140 E = TopoDS::Edge(Ex.Current());
141 // avoid null, degenerated edges
142 if( E.IsNull() || BRep_Tool::Degenerated(E) ) continue;
143 TopoDS_Vertex VFirst, VLast;
144 TopExp::Vertices(E,VFirst, VLast);
145 epsV = Max(BRep_Tool::Tolerance(VFirst), BRep_Tool::Tolerance(VLast));
146 C = BRep_Tool::Curve(E, First, Last);
147 if( C.IsNull() ) continue;
148 TC = new (Geom_TrimmedCurve)(C, First, Last);
149 tolrac = Min(tol,epsV);
150 Bof = Conv.Add(TC, tolrac);
152 tolrac = Max(tol,epsV);
153 Bof = Conv.Add(TC, tolrac);
156 C = Conv.BSplineCurve();
158 else C = TC; // On garde l'unique courbe
161 // modified by NIZHNY-629 Fri Jul 25 11:10:27 2003 b
163 // // punctual section
164 // Ex.Init(mySection, TopAbs_EDGE);
165 // Standard_Boolean isPonctual = Standard_False;
167 // E = TopoDS::Edge(Ex.Current());
168 // isPonctual = BRep_Tool::Degenerated(E);
171 // Ex.Init(mySection, TopAbs_EDGE);
172 // if (Ex.More()&&!isPonctual) {
173 // E = TopoDS::Edge(Ex.Current());
174 // C = BRep_Tool::Curve(E, First, Last);
175 // TC = new (Geom_TrimmedCurve)(C, First, Last);
177 // if (Ex.More()) { // On essai d'avoir un echantillon representatif
178 // Standard_Real tolrac, epsV, tol = Precision::Confusion();
179 // GeomConvert_CompCurveToBSplineCurve Conv(TC);
180 // for (; Ex.More(); Ex.Next()) {
181 // E = TopoDS::Edge(Ex.Current());
182 // TopoDS_Vertex VFirst, VLast;
183 // TopExp::Vertices(E,VFirst, VLast);
184 // epsV = Max(BRep_Tool::Tolerance(VFirst), BRep_Tool::Tolerance(VLast));
185 // C = BRep_Tool::Curve(E, First, Last);
186 // TC = new (Geom_TrimmedCurve)(C, First, Last);
187 // tolrac = Min(tol,epsV);
188 // Bof = Conv.Add(TC, tolrac);
190 // tolrac = Max(tol,epsV);
191 // Bof = Conv.Add(TC, tolrac);
194 // C = Conv.BSplineCurve();
196 // else C = TC; // On garde l'unique courbe
199 // // Localisation par distance Shape/Shape
200 // Standard_Real Tpos;
201 // BRepExtrema_DistShapeShape Ext(mySection, myLaw->Wire());
203 // if (! Ext.IsDone())
204 // Standard_ConstructionError::Raise("Distance Vertex/Spine");
206 // if (Ext.SupportTypeShape2(1) == BRepExtrema_IsOnEdge) {
207 // TopoDS_Shape sbis = Ext.SupportOnShape2(1);
208 // E = TopoDS::Edge(sbis);
209 // Ext.ParOnEdgeS2(1, Tpos);
212 // TopoDS_Vertex Vf, Vl,V;
213 // TopoDS_Shape sbis = Ext.SupportOnShape2(1);
214 // V = TopoDS::Vertex(sbis);
215 // for (ii=1, Ind1=0 ; ii<=myLaw->NbLaw(); ii++) {
216 // E = myLaw->Edge(ii);
217 // TopExp::Vertices(E, Vf, Vl);
218 // if ((V.IsSame(Vf)) || (V.IsSame(Vl))) {
219 // if (Ind1 == 0) Ind1 = ii;
224 // // On invente une section
225 // gp_Dir D(0, 0, 1);
226 // gp_Pnt Origine, PV;
227 // Origine = BRep_Tool::Pnt(V);
228 // Standard_Real length;
230 // if (Ext.SupportTypeShape1(1) == BRepExtrema_IsVertex) {
231 // TopoDS_Shape aLocalShape = Ext.SupportOnShape1(1);
232 // PV = BRep_Tool::Pnt(TopoDS::Vertex(aLocalShape));
233 // // PV = BRep_Tool::Pnt(TopoDS::Vertex(Ext.SupportOnShape1(1)));
236 // PV = BRep_Tool::Pnt(TopoDS::Vertex(mySection));
238 // length = Origine.Distance(PV);
239 // if (length > Precision::Confusion()) {
240 // gp_Vec theVec(Origine, PV);
241 // D.SetXYZ(theVec.XYZ());
243 // else length = 10*Precision::Confusion();
244 // Handle(Geom_Line) CL = new (Geom_Line) (Origine, D);
245 // TC = new (Geom_TrimmedCurve)(CL, 0., length);
247 // isVertex = Standard_True;
251 // // Recherche du Vertex de positionnement
252 // if (!TheV.IsNull()) {
253 // Standard_Integer NbV = myLaw->NbLaw()+1;
254 // for (ii=1, Ind1=0; ii<=NbV && (!Ind1); ii++)
255 // if (TheV.IsSame(myLaw->Vertex(ii))) Ind1 = ii;
259 // isVertex = Standard_True;
261 // if (myLaw->IsClosed()) Ind2 = NbV-1;
270 // TheV.Nullify(); // On oublie cette option...
274 // modified by NIZHNY-629 Fri Jul 25 11:11:06 2003 e
278 Handle(Geom_Geometry) theSection = C;
281 Ex.Init(mySection, TopAbs_VERTEX);
282 TopoDS_Vertex theVertex = TopoDS::Vertex(Ex.Current());
283 gp_Pnt thePoint = BRep_Tool::Pnt(theVertex);
284 theSection = new Geom_CartesianPoint(thePoint);
287 GeomFill_SectionPlacement Place(myLaw->Law(1), theSection);
289 // In the general case : Localisation via concatenation of the spine
290 TColStd_Array1OfReal SuperKnot(1, myLaw->NbLaw()+1);
291 TColStd_Array1OfInteger Index(1, myLaw->NbLaw());
292 for (ii=1; ii<=myLaw->NbLaw(); ii++) {
293 SuperKnot(ii+1) = Index(ii) = ii;
297 Handle(BRepAdaptor_HCompCurve) adpPath =
298 new (BRepAdaptor_HCompCurve) (myLaw->Wire());
300 Place.Perform(adpPath, Precision::Confusion());
302 Standard_Real theParam = Place.ParameterOnPath(),
303 eps = Precision::PConfusion();
308 P_Path = adpPath->Value(theParam);
309 cout << "Point on Path" << P_Path.X() << ", "
310 << P_Path.Y() << ", " << P_Path.Z() << ", " << endl;
314 for (ii=1, Bof=Standard_True; ii<=myLaw->NbLaw() && Bof; ii++) {
315 Bof = !((SuperKnot(ii)-eps<=theParam) &&
316 (SuperKnot(ii+1)+eps>= theParam));
319 if ( (Abs(theParam-SuperKnot(ii))<eps) && (ii>1) ) Ind2 = ii-1;
320 else if ((Abs(theParam-SuperKnot(ii+1))<eps) &&
321 (ii<myLaw->NbLaw()) ) Ind2 = ii+1;
325 if (Bof) Standard_ConstructionError::Raise("Interval non trouve !!");
327 if (Ind2) Ind2 = Index(Ind2);
329 // Positioning on the localized edge (or 2 Edges)
331 Place.SetLocation(myLaw->Law(Ind1));
333 Place.Perform(Precision::Confusion());
335 Place.Perform(SearchParam(myLaw, Ind1, TheV),
336 Precision::Confusion());
339 myTrsf = Place.Transformation(WithContact, WithCorrection);
341 myParam = Place.ParameterOnPath();
342 Angle = Place.Angle();
345 Place.SetLocation(myLaw->Law(Ind2));
347 Place.Perform(Precision::Confusion());
349 if (Ind1 == Ind2) TheV.Reverse();
350 Place.Perform(SearchParam(myLaw, Ind2,TheV),
351 Precision::Confusion());
353 if (Place.Angle() > Angle) {
354 myTrsf = Place.Transformation(WithContact, WithCorrection);
356 myParam = Place.ParameterOnPath();
361 const gp_Trsf& BRepFill_SectionPlacement::Transformation() const
366 Standard_Real BRepFill_SectionPlacement::AbscissaOnPath()
368 return myLaw->Abscissa(myIndex, myParam);