1 // Created on: 1995-01-06
2 // Created by: Frederic MAUPAS
3 // Copyright (c) 1995-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 under
9 // the terms of the GNU Lesser General Public License 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 //pdn 11.01.99 #144 bm1_pe_t4 protection of exceptions in draw
18 // abv 13.04.99 S4136: eliminate BRepAPI::Precision()
20 #include <StepToTopoDS_GeometricTool.ixx>
21 #include <Standard_ErrorHandler.hxx>
22 #include <Standard_Failure.hxx>
24 #include <StepToTopoDS.hxx>
25 //#include <StepToTopoDS_ExtPCOnS.hxx>
26 #include <BRepTools_WireExplorer.hxx>
28 #include <StepGeom_PcurveOrSurface.hxx>
29 #include <StepGeom_Pcurve.hxx>
30 #include <StepGeom_Line.hxx>
31 #include <StepGeom_CartesianPoint.hxx>
32 #include <StepGeom_Vector.hxx>
33 #include <StepGeom_Direction.hxx>
34 #include <StepGeom_SeamCurve.hxx>
35 #include <StepRepr_DefinitionalRepresentation.hxx>
36 #include <StepShape_OrientedEdge.hxx>
37 //#include <BRepAPI.hxx>
38 #include <BRep_Tool.hxx>
39 #include <BRepTools.hxx>
40 #include <BRep_Builder.hxx>
43 #include <gp_Vec2d.hxx>
44 #include <GeomAdaptor_Curve.hxx>
45 #include <GeomAPI_ProjectPointOnCurve.hxx>
46 #include <GeomAPI_ProjectPointOnSurf.hxx>
47 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
48 #include <GeomAbs_Shape.hxx>
49 #include <GeomAbs_CurveType.hxx>
50 #include <Geom2d_Line.hxx>
51 #include <Geom2d_Curve.hxx>
52 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
53 #include <Geom2dAPI_InterCurveCurve.hxx>
54 #include <Geom2d_TrimmedCurve.hxx>
55 #include <Geom_BoundedCurve.hxx>
56 #include <Geom_Line.hxx>
57 #include <Geom_CylindricalSurface.hxx>
58 #include <Geom_ConicalSurface.hxx>
59 #include <Geom_SphericalSurface.hxx>
60 #include <Geom_ToroidalSurface.hxx>
61 #include <Geom_Plane.hxx>
62 #include <Geom_BSplineSurface.hxx>
63 #include <Geom_BSplineCurve.hxx>
64 #include <TopExp_Explorer.hxx>
67 #include <Precision.hxx>
68 #include <Transfer_TransientProcess.hxx>
71 // ----------------------------------------------------------------------------
73 // Purpose : returns true if the surface curve has at least one pcurve lying
75 // ----------------------------------------------------------------------------
77 Standard_Integer StepToTopoDS_GeometricTool::PCurve
78 (const Handle(StepGeom_SurfaceCurve)& SurfCurve,
79 const Handle(StepGeom_Surface)& BasisSurf,
80 Handle(StepGeom_Pcurve)& thePCurve, const Standard_Integer last)
82 Standard_Integer NbAssGeom = SurfCurve->NbAssociatedGeometry();
84 for (Standard_Integer i= last+1; i<=NbAssGeom; i++) {
85 thePCurve = SurfCurve->AssociatedGeometryValue(i).Pcurve();
86 if (!thePCurve.IsNull()) {
87 if (thePCurve->BasisSurface() == BasisSurf) return i;
94 // ----------------------------------------------------------------------------
95 // Method : IsSeamCurve
96 // Purpose : Two edges of the same wire references the same oriented edge
97 // Then the surface_curve is a seam curve
98 // ----------------------------------------------------------------------------
100 Standard_Boolean StepToTopoDS_GeometricTool::IsSeamCurve
101 (const Handle(StepGeom_SurfaceCurve)& SurfCurve,
102 const Handle(StepGeom_Surface)& Surf,
103 const Handle(StepShape_Edge)& StepEdge,
104 const Handle(StepShape_EdgeLoop)& EdgeLoop)
106 if (!Handle(StepGeom_SeamCurve)::DownCast(SurfCurve).IsNull())
107 return Standard_True;
109 if (SurfCurve->NbAssociatedGeometry() != 2) return Standard_False;
111 Handle(StepGeom_Pcurve) StepPCurve1 =
112 SurfCurve->AssociatedGeometryValue(1).Pcurve();
113 Handle(StepGeom_Pcurve) StepPCurve2 =
114 SurfCurve->AssociatedGeometryValue(2).Pcurve();
116 // Do the two pcurves lye on the same surface ?
118 if ((!StepPCurve1.IsNull() && !StepPCurve2.IsNull()) &&
119 (StepPCurve1->BasisSurface() == Surf) &&
120 (StepPCurve2->BasisSurface()== Surf)) {
122 Standard_Integer NbEdge = EdgeLoop->NbEdgeList();
123 Standard_Integer nbOE = 0;
125 Handle(StepShape_OrientedEdge) OrEdge;
127 for (Standard_Integer i = 1; i <= NbEdge; i ++ ) {
128 OrEdge = EdgeLoop->EdgeListValue(i);
129 if (StepEdge == OrEdge->EdgeElement()) nbOE ++;
131 // two oriented edges of the same wire share the same edge
132 if (nbOE == 2) return Standard_True;
134 return Standard_False;
137 // ----------------------------------------------------------------------------
138 // Method : IsLikeSeam
139 // Purpose : The two pcurves lies on the same surface but on different wires.
140 // This is typical situation in CATIA BRep : a cylinder is coded
141 // with two faces on the same 'Closed' BSplineSurf, which in the
142 // range of gp_Resolution is not identified as closed
143 // ----------------------------------------------------------------------------
145 Standard_Boolean StepToTopoDS_GeometricTool::IsLikeSeam
146 (const Handle(StepGeom_SurfaceCurve)& SurfCurve,
147 const Handle(StepGeom_Surface)& Surf,
148 const Handle(StepShape_Edge)& StepEdge,
149 const Handle(StepShape_EdgeLoop)& EdgeLoop)
151 if (SurfCurve->NbAssociatedGeometry() != 2) return Standard_False;
153 Handle(StepGeom_Pcurve) StepPCurve1 =
154 SurfCurve->AssociatedGeometryValue(1).Pcurve();
155 Handle(StepGeom_Pcurve) StepPCurve2 =
156 SurfCurve->AssociatedGeometryValue(2).Pcurve();
158 // Do the two pcurves lye on the same surface ?
160 if ((!StepPCurve1.IsNull() && !StepPCurve2.IsNull()) &&
161 (StepPCurve1->BasisSurface() == Surf) &&
162 (StepPCurve2->BasisSurface() == Surf)) {
164 Standard_Integer NbEdge = EdgeLoop->NbEdgeList();
165 Standard_Integer nbOE = 0;
167 Handle(StepShape_OrientedEdge) OrEdge;
169 for (Standard_Integer i = 1; i <= NbEdge; i ++ ) {
170 OrEdge = EdgeLoop->EdgeListValue(i);
171 if (StepEdge == OrEdge->EdgeElement()) nbOE ++;
173 // the two oriented edges are not in the same wire
175 // check is the two pcurve are not indentical ?
176 Handle(StepGeom_Line) line1 = Handle(StepGeom_Line)::DownCast
177 (StepPCurve1->ReferenceToCurve()->ItemsValue(1));
178 Handle(StepGeom_Line) line2 = Handle(StepGeom_Line)::DownCast
179 (StepPCurve2->ReferenceToCurve()->ItemsValue(1));
180 if (!line1.IsNull() && !line2.IsNull()) {
181 // Same Origin in X OR Y && Same Vector ??
182 // WITHIN A given tolerance !!!
183 Standard_Real DeltaX = Abs(line1->Pnt()->CoordinatesValue(1) -
184 line2->Pnt()->CoordinatesValue(1));
185 Standard_Real DeltaY = Abs(line1->Pnt()->CoordinatesValue(2) -
186 line2->Pnt()->CoordinatesValue(2));
188 Standard_Real DeltaDirX =
189 Abs(line1->Dir()->Orientation()->DirectionRatiosValue(1) -
190 line2->Dir()->Orientation()->DirectionRatiosValue(1));
191 Standard_Real DeltaDirY =
192 Abs(line1->Dir()->Orientation()->DirectionRatiosValue(2) -
193 line2->Dir()->Orientation()->DirectionRatiosValue(2));
195 Standard_Real preci2d = Precision::PConfusion(); //:S4136: Parametric(BRepAPI::Precision(),10);
197 if ((DeltaX < preci2d) || (DeltaY < preci2d))
198 return ((DeltaDirX < preci2d) && (DeltaDirY < preci2d));
199 else return Standard_False;
201 // Warning : la manipulation de tolerances dans ce contexte est un
202 // peu trop dangeureux.
203 // il serait preferable de plus de ne pas restreindre au
204 // cas de deux lignes.
205 // un mode plus convenable de detection serait de se servir
206 // des isos (ou bords naturels) de la surface de base
207 // et de detecter que les deux courbes se trouvent sur le
208 // bord de fermeture.
209 // il faut toutefois prevoir le cas ou les deux courbes
210 // sont confondues (ex : CATIA, "couture" de separation
211 // en deux faces d un support periodique.
212 // Ce travail reste evidement A FAIRE !!! ...
214 else return Standard_False;
216 return Standard_False;
218 return Standard_False;
221 // ----------------------------------------------------------------------------
222 // Method : UpdateParam3d
223 // Purpose : According to the type of curve update parameter (w1>w2)
224 // This situation occurs when an edge crosses the parametric origin.
225 // ----------------------------------------------------------------------------
227 Standard_Boolean StepToTopoDS_GeometricTool::UpdateParam3d
228 (const Handle(Geom_Curve)& theCurve, Standard_Real& w1, Standard_Real& w2,
229 const Standard_Real preci)
231 // w1 et/ou w2 peuvent etre en dehors des bornes naturelles de la courbe.
232 // On donnera alors la valeur en bout a w1 et/ou w2
234 Standard_Real cf = theCurve->FirstParameter();
235 Standard_Real cl = theCurve->LastParameter();
236 // Standard_Real preci = BRepAPI::Precision();
238 if (theCurve->IsKind(STANDARD_TYPE(Geom_BoundedCurve)) && !theCurve->IsClosed()) {
241 cout << "Update Edge First Parameter to Curve First Parameter" << endl;
247 cout << "Update Edge First Parameter to Curve Last Parameter" << endl;
253 cout << "Update Edge Last Parameter to Curve First Parameter" << endl;
259 cout << "Update Edge Last Parameter to Curve Last Parameter" << endl;
265 if (w1 < w2) return Standard_True;
267 if (theCurve->IsPeriodic())
268 ElCLib::AdjustPeriodic(cf,cl,Precision::PConfusion(),w1,w2); //:a7 abv 11 Feb 98: preci -> PConfusion()
269 else if (theCurve->IsClosed()) {
270 // l'un des points projecte se trouve sur l'origine du parametrage
271 // de la courbe 3D. L algo a donne cl +- preci au lieu de cf ou vice-versa
272 // DANGER precision 3d applique a une espace 1d
274 // w2 = cf au lieu de w2 = cl
275 if (Abs(w2 - cf) < Precision::PConfusion() /*preci*/) w2 = cl ;
276 // w1 = cl au lieu de w1 = cf
277 else if (Abs(w1 - cl) < Precision::PConfusion() /*preci*/) w1 = cf;
279 // on se trouve dans un cas ou l origine est traversee
280 // illegal sur une courbe fermee non periodique
281 // on inverse quand meme les parametres !!!!!!
283 //:S4136 abv 20 Apr 99: r0701_ug.stp #6230: add check in 3d
284 if ( theCurve->Value(w1).Distance(theCurve->Value(cf)) < preci ) w1 = cf;
285 if ( theCurve->Value(w2).Distance(theCurve->Value(cl)) < preci ) w2 = cl;
288 cout << "Warning : parameter range of edge crossing non periodic curve origin" << endl;
290 Standard_Real tmp = w1;
296 // The curve is closed within the 3D tolerance
297 else if (theCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) {
298 Handle(Geom_BSplineCurve) aBSpline =
299 Handle(Geom_BSplineCurve)::DownCast(theCurve);
300 if (aBSpline->StartPoint().Distance(aBSpline->EndPoint()) <= preci ) {
301 //:S4136 <= BRepAPI::Precision()) {
302 // l'un des points projecte se trouve sur l'origine du parametrage
303 // de la courbe 3D. L algo a donne cl +- preci au lieu de cf ou vice-versa
304 // DANGER precision 3d applique a une espace 1d
306 // w2 = cf au lieu de w2 = cl
307 if (Abs(w2 - cf) < Precision::PConfusion() /*preci*/) w2 = cl ;
308 // w1 = cl au lieu de w1 = cf
309 else if (Abs(w1 - cl) < Precision::PConfusion() /*preci*/) w1 = cf;
311 // on se trouve dans un cas ou l origine est traversee
312 // illegal sur une courbe fermee non periodique
313 // on inverse quand meme les parametres !!!!!!
316 cout << "Warning : parameter range of edge crossing non periodic curve origin" << endl;
318 Standard_Real tmp = w1;
323 //abv 15.03.00 #72 bm1_pe_t4 protection of exceptions in draw
324 else if ( w1 > w2 ) {
326 cout << "Warning: parameter range is bad; curve reversed" << endl;
328 w1 = theCurve->ReversedParameter ( w1 );
329 w2 = theCurve->ReversedParameter ( w2 );
332 //:j9 abv 11 Dec 98: PRO7747 #4875, after :j8: else
333 if (w1 == w2) { //gka 10.07.1998 file PRO7656 entity 33334
335 return Standard_False;
340 cout << "UpdateParam3d Failed" << endl;
341 cout << " - Curve Type : " << theCurve->DynamicType() << endl;
342 cout << " - Param 1 : " << w1 << endl;
343 cout << " - Param 2 : " << w2 << endl;
345 //abv 15.03.00 #72 bm1_pe_t4 protection of exceptions in draw
348 cout << "Warning: parameter range is bad; curve reversed" << endl;
350 w1 = theCurve->ReversedParameter ( w1 );
351 w2 = theCurve->ReversedParameter ( w2 );
354 //pdn 11.01.99 #144 bm1_pe_t4 protection of exceptions in draw
356 w1 -= Precision::PConfusion();
357 w2 += Precision::PConfusion();
359 return Standard_False;
361 return Standard_True;