1 // File: BRepFill_SectionPlacement.cxx
2 // Created: Wed Feb 11 16:23:18 1998
3 // Author: Philippe MANGIN
7 #include <BRepFill_SectionPlacement.ixx>
9 #include <TopExp_Explorer.hxx>
11 #include <TopAbs_ShapeEnum.hxx>
12 #include <TopoDS_Edge.hxx>
13 #include <TopoDS_Vertex.hxx>
15 #include <BRep_Tool.hxx>
16 #include <BRepAdaptor_HCurve.hxx>
17 #include <BRepAdaptor_HCompCurve.hxx>
18 #include <BRepExtrema_DistShapeShape.hxx>
19 #include <BRepExtrema_SupportType.hxx>
21 #include <Geom_Curve.hxx>
22 #include <Geom_CartesianPoint.hxx>
23 #include <Geom_TrimmedCurve.hxx>
24 #include <Geom_Line.hxx>
25 #include <Geom_BSplineCurve.hxx>
26 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
27 #include <GeomAdaptor_HCurve.hxx>
28 #include <GeomFill_SectionPlacement.hxx>
29 #include <GeomFill_LocationLaw.hxx>
31 #include <Standard_ConstructionError.hxx>
32 #include <Standard_NotImplemented.hxx>
33 #include <TColStd_Array1OfReal.hxx>
34 #include <TColStd_Array1OfInteger.hxx>
35 #include <Precision.hxx>
38 static Standard_Boolean myDebug = Standard_False;
41 static Standard_Real SearchParam(const Handle(BRepFill_LocationLaw)& Law,
42 const Standard_Integer Ind,
43 const TopoDS_Vertex& TheV)
48 t = BRep_Tool::Parameter(TheV, E);
49 if (E.Orientation() == TopAbs_REVERSED) {
50 Standard_Real f, l, Lf, Ll;
52 C = BRep_Tool::Curve(E,f,l);
53 Lf = Law->Law(Ind)->GetCurve()->FirstParameter();
54 Ll = Law->Law(Ind)->GetCurve()->LastParameter();
55 t = Ll - (t-f)*(Ll-Lf)/(l-f);
62 BRepFill_SectionPlacement::
63 BRepFill_SectionPlacement(const Handle(BRepFill_LocationLaw)& Law,
64 const TopoDS_Shape& Section,
65 const Standard_Boolean WithContact,
66 const Standard_Boolean WithCorrection) :
67 myLaw(Law), mySection(Section)
71 Perform(WithContact, WithCorrection, VNull);
74 BRepFill_SectionPlacement::
75 BRepFill_SectionPlacement(const Handle(BRepFill_LocationLaw)& Law,
76 const TopoDS_Shape& Section,
77 const TopoDS_Shape& Vertex,
78 const Standard_Boolean WithContact,
79 const Standard_Boolean WithCorrection) :
80 myLaw(Law), mySection(Section)
82 Perform(WithContact, WithCorrection, Vertex);
85 void BRepFill_SectionPlacement::Perform(const Standard_Boolean WithContact,
86 const Standard_Boolean WithCorrection,
87 const TopoDS_Shape& Vertex)
90 TheV = TopoDS::Vertex(Vertex);
92 Standard_Integer Ind1 = 0, Ind2 = 0;
93 Standard_Boolean Bof, isVertex = Standard_False;
94 Standard_Real First, Last;
99 Handle(Geom_TrimmedCurve) TC;
101 // modified by NIZHNY-OCC629 Thu Jul 24 14:11:45 2003
102 Standard_Boolean isFound = Standard_False;
103 Ex.Init(mySection, TopAbs_EDGE);
104 for(; Ex.More(); Ex.Next()) {
105 E = TopoDS::Edge(Ex.Current());
106 // avoid null, degenerated edges
107 if( E.IsNull() || BRep_Tool::Degenerated(E) ) continue;
108 C = BRep_Tool::Curve(E, First, Last);
109 if( C.IsNull() ) continue;
110 isFound = Standard_True;
114 isVertex = Standard_True;
117 TC = new (Geom_TrimmedCurve)(C, First, Last);
121 Standard_Real tolrac, epsV, tol = Precision::Confusion();
122 GeomConvert_CompCurveToBSplineCurve Conv(TC);
123 for (; Ex.More(); Ex.Next()) {
124 E = TopoDS::Edge(Ex.Current());
125 // avoid null, degenerated edges
126 if( E.IsNull() || BRep_Tool::Degenerated(E) ) continue;
127 TopoDS_Vertex VFirst, VLast;
128 TopExp::Vertices(E,VFirst, VLast);
129 epsV = Max(BRep_Tool::Tolerance(VFirst), BRep_Tool::Tolerance(VLast));
130 C = BRep_Tool::Curve(E, First, Last);
131 if( C.IsNull() ) continue;
132 TC = new (Geom_TrimmedCurve)(C, First, Last);
133 tolrac = Min(tol,epsV);
134 Bof = Conv.Add(TC, tolrac);
136 tolrac = Max(tol,epsV);
137 Bof = Conv.Add(TC, tolrac);
140 C = Conv.BSplineCurve();
142 else C = TC; // On garde l'unique courbe
145 // modified by NIZHNY-629 Fri Jul 25 11:10:27 2003 b
147 // // section ponctuelle
148 // Ex.Init(mySection, TopAbs_EDGE);
149 // Standard_Boolean isPonctual = Standard_False;
151 // E = TopoDS::Edge(Ex.Current());
152 // isPonctual = BRep_Tool::Degenerated(E);
155 // Ex.Init(mySection, TopAbs_EDGE);
156 // if (Ex.More()&&!isPonctual) {
157 // E = TopoDS::Edge(Ex.Current());
158 // C = BRep_Tool::Curve(E, First, Last);
159 // TC = new (Geom_TrimmedCurve)(C, First, Last);
161 // if (Ex.More()) { // On essai d'avoir un echantillon representatif
162 // Standard_Real tolrac, epsV, tol = Precision::Confusion();
163 // GeomConvert_CompCurveToBSplineCurve Conv(TC);
164 // for (; Ex.More(); Ex.Next()) {
165 // E = TopoDS::Edge(Ex.Current());
166 // TopoDS_Vertex VFirst, VLast;
167 // TopExp::Vertices(E,VFirst, VLast);
168 // epsV = Max(BRep_Tool::Tolerance(VFirst), BRep_Tool::Tolerance(VLast));
169 // C = BRep_Tool::Curve(E, First, Last);
170 // TC = new (Geom_TrimmedCurve)(C, First, Last);
171 // tolrac = Min(tol,epsV);
172 // Bof = Conv.Add(TC, tolrac);
174 // tolrac = Max(tol,epsV);
175 // Bof = Conv.Add(TC, tolrac);
178 // C = Conv.BSplineCurve();
180 // else C = TC; // On garde l'unique courbe
183 // // Localisation par distance Shape/Shape
184 // Standard_Real Tpos;
185 // BRepExtrema_DistShapeShape Ext(mySection, myLaw->Wire());
187 // if (! Ext.IsDone())
188 // Standard_ConstructionError::Raise("Distance Vertex/Spine");
190 // if (Ext.SupportTypeShape2(1) == BRepExtrema_IsOnEdge) {
191 // TopoDS_Shape sbis = Ext.SupportOnShape2(1);
192 // E = TopoDS::Edge(sbis);
193 // Ext.ParOnEdgeS2(1, Tpos);
196 // TopoDS_Vertex Vf, Vl,V;
197 // TopoDS_Shape sbis = Ext.SupportOnShape2(1);
198 // V = TopoDS::Vertex(sbis);
199 // for (ii=1, Ind1=0 ; ii<=myLaw->NbLaw(); ii++) {
200 // E = myLaw->Edge(ii);
201 // TopExp::Vertices(E, Vf, Vl);
202 // if ((V.IsSame(Vf)) || (V.IsSame(Vl))) {
203 // if (Ind1 == 0) Ind1 = ii;
208 // // On invente une section
209 // gp_Dir D(0, 0, 1);
210 // gp_Pnt Origine, PV;
211 // Origine = BRep_Tool::Pnt(V);
212 // Standard_Real length;
214 // if (Ext.SupportTypeShape1(1) == BRepExtrema_IsVertex) {
215 // TopoDS_Shape aLocalShape = Ext.SupportOnShape1(1);
216 // PV = BRep_Tool::Pnt(TopoDS::Vertex(aLocalShape));
217 // // PV = BRep_Tool::Pnt(TopoDS::Vertex(Ext.SupportOnShape1(1)));
220 // PV = BRep_Tool::Pnt(TopoDS::Vertex(mySection));
222 // length = Origine.Distance(PV);
223 // if (length > Precision::Confusion()) {
224 // gp_Vec theVec(Origine, PV);
225 // D.SetXYZ(theVec.XYZ());
227 // else length = 10*Precision::Confusion();
228 // Handle(Geom_Line) CL = new (Geom_Line) (Origine, D);
229 // TC = new (Geom_TrimmedCurve)(CL, 0., length);
231 // isVertex = Standard_True;
235 // // Recherche du Vertex de positionnement
236 // if (!TheV.IsNull()) {
237 // Standard_Integer NbV = myLaw->NbLaw()+1;
238 // for (ii=1, Ind1=0; ii<=NbV && (!Ind1); ii++)
239 // if (TheV.IsSame(myLaw->Vertex(ii))) Ind1 = ii;
243 // isVertex = Standard_True;
245 // if (myLaw->IsClosed()) Ind2 = NbV-1;
254 // TheV.Nullify(); // On oublie cette option...
258 // modified by NIZHNY-629 Fri Jul 25 11:11:06 2003 e
262 Handle(Geom_Geometry) theSection = C;
265 Ex.Init(mySection, TopAbs_VERTEX);
266 TopoDS_Vertex theVertex = TopoDS::Vertex(Ex.Current());
267 gp_Pnt thePoint = BRep_Tool::Pnt(theVertex);
268 theSection = new Geom_CartesianPoint(thePoint);
271 GeomFill_SectionPlacement Place(myLaw->Law(1), theSection);
273 // Dans le cas generale : Localisation via une concatenation de la spine
274 TColStd_Array1OfReal SuperKnot(1, myLaw->NbLaw()+1);
275 TColStd_Array1OfInteger Index(1, myLaw->NbLaw());
276 for (ii=1; ii<=myLaw->NbLaw(); ii++) {
277 SuperKnot(ii+1) = Index(ii) = ii;
281 Handle(BRepAdaptor_HCompCurve) adpPath =
282 new (BRepAdaptor_HCompCurve) (myLaw->Wire());
284 Place.Perform(adpPath, Precision::Confusion());
286 Standard_Real theParam = Place.ParameterOnPath(),
287 eps = Precision::PConfusion();
292 P_Path = adpPath->Value(theParam);
293 cout << "Point on Path" << P_Path.X() << ", "
294 << P_Path.Y() << ", " << P_Path.Z() << ", " << endl;
298 for (ii=1, Bof=Standard_True; ii<=myLaw->NbLaw() && Bof; ii++) {
299 Bof = !((SuperKnot(ii)-eps<=theParam) &&
300 (SuperKnot(ii+1)+eps>= theParam));
303 if ( (Abs(theParam-SuperKnot(ii))<eps) && (ii>1) ) Ind2 = ii-1;
304 else if ((Abs(theParam-SuperKnot(ii+1))<eps) &&
305 (ii<myLaw->NbLaw()) ) Ind2 = ii+1;
309 if (Bof) Standard_ConstructionError::Raise("Interval non trouve !!");
311 if (Ind2) Ind2 = Index(Ind2);
313 // Positionnement sur l'edge (ou les 2 Edges) localisee(s)
315 Place.SetLocation(myLaw->Law(Ind1));
317 Place.Perform(Precision::Confusion());
319 Place.Perform(SearchParam(myLaw, Ind1, TheV),
320 Precision::Confusion());
323 myTrsf = Place.Transformation(WithContact, WithCorrection);
325 myParam = Place.ParameterOnPath();
326 Angle = Place.Angle();
329 Place.SetLocation(myLaw->Law(Ind2));
331 Place.Perform(Precision::Confusion());
333 if (Ind1 == Ind2) TheV.Reverse();
334 Place.Perform(SearchParam(myLaw, Ind2,TheV),
335 Precision::Confusion());
337 if (Place.Angle() > Angle) {
338 myTrsf = Place.Transformation(WithContact, WithCorrection);
340 myParam = Place.ParameterOnPath();
345 const gp_Trsf& BRepFill_SectionPlacement::Transformation() const
350 Standard_Real BRepFill_SectionPlacement::AbscissaOnPath()
352 return myLaw->Abscissa(myIndex, myParam);