1 // Created on: 1994-11-04
2 // Created by: Frederic MAUPAS
3 // Copyright (c) 1994-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.
21 //:n9 abv 16.02.99: PRO10107: check parameters on curve with PConfusion()!
22 //:o6 abv 18.02.99: r0301_db #63077: application of parameter Factor moved
23 //:p0 abv 19.02.99: management of 'done' flag improved
24 //:p3 abv 23.02.99: bm4_id_punch_d.stp #1313: shift of parameters on ellipse with R1 < R2
25 // abv 09.02.99: S4136: eliminate using BRepAPI::Precision()
27 #include <StepToGeom_MakeTrimmedCurve.ixx>
29 #include <Geom_CartesianPoint.hxx>
30 #include <Geom_Curve.hxx>
31 #include <StepGeom_CartesianPoint.hxx>
32 #include <StepGeom_Line.hxx>
33 #include <StepGeom_Vector.hxx>
34 #include <StepGeom_Circle.hxx>
35 #include <StepGeom_Ellipse.hxx>
36 #include <StepGeom_Parabola.hxx>
37 #include <StepGeom_Hyperbola.hxx>
38 #include <StepGeom_TrimmingSelect.hxx>
39 #include <StepGeom_HArray1OfTrimmingSelect.hxx>
40 #include <StepGeom_TrimmedCurve.hxx>
41 #include <StepToGeom_MakeTrimmedCurve.hxx>
42 #include <StepToGeom_MakeCartesianPoint.hxx>
43 #include <StepToGeom_MakeCurve.hxx>
44 //#include <GeomAPI_ProjectPointOnCurve.hxx>
45 //#include <BRepAPI.hxx>
48 #include <UnitsMethods.hxx>
49 #include <Precision.hxx>
50 #include <ShapeAnalysis_Curve.hxx>
51 #include <StepGeom_Axis2Placement3d.hxx>
53 // ----------------------------------------------------------------
55 // ----------------------------------------------------------------
56 //:o6 abv 18 Feb 99: parameter Factor added
57 //:p3 abv 23 Feb 99: parameter Shift added
59 static Standard_Boolean ExtractParameter
60 (const Handle(Geom_Curve) & aGeomCurve,
61 const Handle(StepGeom_HArray1OfTrimmingSelect) & TS,
62 const Standard_Integer nbSel,
63 const Standard_Integer MasterRep,
64 const Standard_Real Factor,
65 const Standard_Real Shift,
66 Standard_Real & aParam)
68 Handle(StepGeom_CartesianPoint) aPoint;
69 Handle(Geom_CartesianPoint) theGeomPnt;
71 //:S4136 Standard_Real precBrep = BRepAPI::Precision();
72 for ( i = 1 ; i <= nbSel ; i++) {
73 StepGeom_TrimmingSelect theSel = TS->Value(i);
74 if (MasterRep == 2 && theSel.CaseMember() > 0) {
75 aParam = Shift + Factor * theSel.ParameterValue();
78 else if (MasterRep == 1 && theSel.CaseNumber() > 0) {
79 aPoint = theSel.CartesianPoint();
80 StepToGeom_MakeCartesianPoint::Convert(aPoint,theGeomPnt);
81 gp_Pnt thegpPnt = theGeomPnt->Pnt();
83 //:S4136: use advanced algorithm
84 ShapeAnalysis_Curve sac;
86 sac.Project ( aGeomCurve, thegpPnt, Precision::Confusion(), p, aParam );
88 //Trim == natural boundary ?
89 if(aGeomCurve->IsKind(STANDARD_TYPE(Geom_BoundedCurve))) {
90 Standard_Real frstPar = aGeomCurve->FirstParameter();
91 Standard_Real lstPar = aGeomCurve->LastParameter();
92 gp_Pnt frstPnt = aGeomCurve->Value(frstPar);
93 gp_Pnt lstPnt = aGeomCurve->Value(lstPar);
94 if(frstPnt.IsEqual(thegpPnt,precBrep)) {
98 if(lstPnt.IsEqual(thegpPnt,precBrep)) {
100 return Standard_True;
103 // Project Point On Curve
104 GeomAPI_ProjectPointOnCurve PPOC(thegpPnt, aGeomCurve);
105 if (PPOC.NbPoints() == 0) {
106 return Standard_False;
108 aParam = PPOC.LowerDistanceParameter();
110 return Standard_True;
113 // if the MasterRepresentation is unspecified:
114 // if a ParameterValue exists, it is prefered
116 for ( i = 1 ; i <= nbSel ; i++) {
117 StepGeom_TrimmingSelect theSel = TS->Value(i);
118 if (theSel.CaseMember() > 0) {
119 aParam = Shift + Factor * theSel.ParameterValue();
121 return Standard_True;
124 // if no ParameterValue exists, it is created from the CartesianPointValue
126 for ( i = 1 ; i <= nbSel ; i++) {
127 StepGeom_TrimmingSelect theSel = TS->Value(i);
128 if (theSel.CaseNumber() > 0) {
129 aPoint = theSel.CartesianPoint();
130 StepToGeom_MakeCartesianPoint::Convert(aPoint,theGeomPnt);
131 gp_Pnt thegpPnt = theGeomPnt->Pnt();
132 // Project Point On Curve
133 ShapeAnalysis_Curve sac;
135 sac.Project ( aGeomCurve, thegpPnt, Precision::Confusion(), p, aParam );
137 GeomAPI_ProjectPointOnCurve PPOC(thegpPnt, aGeomCurve);
138 if (PPOC.NbPoints() == 0) {
139 return Standard_False;
141 aParam = PPOC.LowerDistanceParameter();
143 return Standard_True;
146 return Standard_False; // I suppose
150 //=============================================================================
151 // Creation d' une Trimmed Curve de Geom a partir d' une Trimmed Curve de Step
152 //=============================================================================
154 Standard_Boolean StepToGeom_MakeTrimmedCurve::Convert (const Handle(StepGeom_TrimmedCurve)& SC, Handle(Geom_TrimmedCurve)& CC)
156 const Handle(StepGeom_Curve) theSTEPCurve = SC->BasisCurve();
157 Handle(Geom_Curve) theCurve;
158 if (!StepToGeom_MakeCurve::Convert(theSTEPCurve,theCurve))
159 return Standard_False;
161 const Handle(StepGeom_HArray1OfTrimmingSelect)& theTrimSel1 = SC->Trim1();
162 const Handle(StepGeom_HArray1OfTrimmingSelect)& theTrimSel2 = SC->Trim2();
163 const Standard_Integer nbSel1 = SC->NbTrim1();
164 const Standard_Integer nbSel2 = SC->NbTrim2();
166 Standard_Integer MasterRep;
167 switch (SC->MasterRepresentation())
169 case StepGeom_tpCartesian: MasterRep = 1; break;
170 case StepGeom_tpParameter: MasterRep = 2; break;
171 default: MasterRep = 0;
174 //gka 18.02.04 analysis for case when MasterRep = .Unspecified
175 //and parameters are specified as CARTESIAN_POINT
176 Standard_Boolean isPoint = Standard_False;
177 if(MasterRep == 0 || (MasterRep == 2 && nbSel1 >1 && nbSel2 > 1)) {
179 for(ii = 1; ii <= nbSel1; ii++)
181 if (!(theTrimSel1->Value(ii).CartesianPoint().IsNull()))
183 for(ii = 1; ii <= nbSel2; ii++)
185 if (!(theTrimSel2->Value(ii).CartesianPoint().IsNull()))
187 isPoint = Standard_True;
196 //:o6 abv 18 Feb 99: computation of factor moved
197 Standard_Real fact = 1., shift = 0.;
198 if (theSTEPCurve->IsKind(STANDARD_TYPE(StepGeom_Line))) {
199 const Handle(StepGeom_Line) theLine =
200 Handle(StepGeom_Line)::DownCast(theSTEPCurve);
201 fact = theLine->Dir()->Magnitude() * UnitsMethods::LengthFactor();
203 else if (theSTEPCurve->IsKind(STANDARD_TYPE(StepGeom_Circle)) ||
204 theSTEPCurve->IsKind(STANDARD_TYPE(StepGeom_Ellipse))) {
205 // if (trim1 > 2.1*M_PI || trim2 > 2.1*M_PI) fact = M_PI / 180.;
206 fact = UnitsMethods::PlaneAngleFactor();
207 //:p3 abv 23 Feb 99: shift on pi/2 on ellipse with R1 < R2
208 const Handle(StepGeom_Ellipse) ellipse = Handle(StepGeom_Ellipse)::DownCast(theSTEPCurve);
209 if ( !ellipse.IsNull() && ellipse->SemiAxis1() - ellipse->SemiAxis2() < 0. )
212 // skl 04.02.2002 for OCC133: we can not make TrimmedCurve if
213 // there is no X-direction in StepGeom_Axis2Placement3d
214 const Handle(StepGeom_Conic) conic = Handle(StepGeom_Conic)::DownCast(theSTEPCurve);
215 // CKY 6-FEB-2004 for Airbus-MedialAxis :
216 // this restriction does not apply for trimming by POINTS
217 if(!conic.IsNull() && MasterRep != 1) {
218 const StepGeom_Axis2Placement a2p = conic->Position();
219 if(a2p.CaseNum(a2p.Value())==2) {
220 if( !a2p.Axis2Placement3d()->HasRefDirection() ) {
221 ////gka 18.02.04 analysis for case when MasterRep = .Unspecified
222 //and parameters are specified as CARTESIAN_POINT
223 if(isPoint /*&& !MasterRep*/)
226 if ( SC->SenseAgreement() )
227 CC = new Geom_TrimmedCurve(theCurve, 0., 2.*M_PI, Standard_True);
229 CC = new Geom_TrimmedCurve(theCurve, 2.*M_PI, 0., Standard_False);
230 return Standard_True;
237 Standard_Real trim1 = 0.;
238 Standard_Real trim2 = 0.;
239 Handle(StepGeom_CartesianPoint) TrimCP1, TrimCP2;
240 const Standard_Boolean FoundParam1 = ExtractParameter(theCurve, theTrimSel1, nbSel1, MasterRep, fact, shift, trim1);
241 const Standard_Boolean FoundParam2 = ExtractParameter(theCurve, theTrimSel2, nbSel2, MasterRep, fact, shift, trim2);
243 if (FoundParam1 && FoundParam2) {
244 const Standard_Real cf = theCurve->FirstParameter();
245 const Standard_Real cl = theCurve->LastParameter();
246 //: abv 09.04.99: S4136: bm2_ug_t4-B.stp #70610: protect against OutOfRange
247 if ( !theCurve->IsPeriodic() ) {
248 if ( trim1 < cf ) trim1 = cf;
249 else if ( trim1 > cl ) trim1 = cl;
250 if ( trim2 < cf ) trim2 = cf;
251 else if ( trim2 > cl ) trim2 = cl;
253 if (Abs(trim1 - trim2) < Precision::PConfusion()) {
254 if (theCurve->IsPeriodic()) {
255 ElCLib::AdjustPeriodic(cf,cl,Precision::PConfusion(),trim1,trim2);
257 else if (theCurve->IsClosed()) {
258 if (Abs(trim1 - cf) < Precision::PConfusion()) {
267 // cout << "Trimming Failed" << endl;
269 return Standard_False;
272 // CKY 16-DEC-1997 : USA60035 le texte de Part42 parle de degres
273 // mais des systemes ecrivent en radians. Exploiter UnitsMethods
274 //:o6 trim1 = trim1 * fact;
275 //:o6 trim2 = trim2 * fact;
276 if ( SC->SenseAgreement() )
277 CC = new Geom_TrimmedCurve(theCurve, trim1, trim2, Standard_True);
278 else //:abv 29.09.00 PRO20362: reverse parameters in case of reversed curve
279 CC = new Geom_TrimmedCurve(theCurve, trim2, trim1, Standard_False);
280 return Standard_True;
282 return Standard_False;