0024870: Provide OCCT RTTI test cases
[occt.git] / src / StepToGeom / StepToGeom_MakeTrimmedCurve.cxx
CommitLineData
b311480e 1// Created on: 1994-11-04
2// Created by: Frederic MAUPAS
3// Copyright (c) 1994-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
b311480e 16
7fd59977 17//:n9 abv 16.02.99: PRO10107: check parameters on curve with PConfusion()!
18//:o6 abv 18.02.99: r0301_db #63077: application of parameter Factor moved
19//:p0 abv 19.02.99: management of 'done' flag improved
20//:p3 abv 23.02.99: bm4_id_punch_d.stp #1313: shift of parameters on ellipse with R1 < R2
21// abv 09.02.99: S4136: eliminate using BRepAPI::Precision()
22
42cf5bc1 23#include <ElCLib.hxx>
24#include <Geom_BoundedCurve.hxx>
7fd59977 25#include <Geom_CartesianPoint.hxx>
26#include <Geom_Curve.hxx>
42cf5bc1 27#include <Geom_TrimmedCurve.hxx>
28#include <gp_Pnt.hxx>
29#include <Precision.hxx>
30#include <ShapeAnalysis_Curve.hxx>
31#include <StepGeom_Axis2Placement3d.hxx>
7fd59977 32#include <StepGeom_CartesianPoint.hxx>
7fd59977 33#include <StepGeom_Circle.hxx>
42cf5bc1 34#include <StepGeom_Conic.hxx>
7fd59977 35#include <StepGeom_Ellipse.hxx>
7fd59977 36#include <StepGeom_HArray1OfTrimmingSelect.hxx>
42cf5bc1 37#include <StepGeom_Hyperbola.hxx>
38#include <StepGeom_Line.hxx>
39#include <StepGeom_Parabola.hxx>
7fd59977 40#include <StepGeom_TrimmedCurve.hxx>
42cf5bc1 41#include <StepGeom_TrimmingSelect.hxx>
42#include <StepGeom_Vector.hxx>
7fd59977 43#include <StepToGeom_MakeCartesianPoint.hxx>
44#include <StepToGeom_MakeCurve.hxx>
42cf5bc1 45#include <StepToGeom_MakeTrimmedCurve.hxx>
7fd59977 46#include <UnitsMethods.hxx>
7fd59977 47
42cf5bc1 48//#include <GeomAPI_ProjectPointOnCurve.hxx>
49//#include <BRepAPI.hxx>
7fd59977 50// ----------------------------------------------------------------
51// ExtractParameter
52// ----------------------------------------------------------------
53//:o6 abv 18 Feb 99: parameter Factor added
54//:p3 abv 23 Feb 99: parameter Shift added
7fd59977 55static Standard_Boolean ExtractParameter
56(const Handle(Geom_Curve) & aGeomCurve,
57 const Handle(StepGeom_HArray1OfTrimmingSelect) & TS,
58 const Standard_Integer nbSel,
59 const Standard_Integer MasterRep,
60 const Standard_Real Factor,
61 const Standard_Real Shift,
62 Standard_Real & aParam)
63{
64 Handle(StepGeom_CartesianPoint) aPoint;
65 Handle(Geom_CartesianPoint) theGeomPnt;
66 Standard_Integer i;
67//:S4136 Standard_Real precBrep = BRepAPI::Precision();
68 for ( i = 1 ; i <= nbSel ; i++) {
69 StepGeom_TrimmingSelect theSel = TS->Value(i);
70 if (MasterRep == 2 && theSel.CaseMember() > 0) {
71 aParam = Shift + Factor * theSel.ParameterValue();
72 return Standard_True;
73 }
74 else if (MasterRep == 1 && theSel.CaseNumber() > 0) {
75 aPoint = theSel.CartesianPoint();
76 StepToGeom_MakeCartesianPoint::Convert(aPoint,theGeomPnt);
77 gp_Pnt thegpPnt = theGeomPnt->Pnt();
78
79 //:S4136: use advanced algorithm
80 ShapeAnalysis_Curve sac;
81 gp_Pnt p;
82 sac.Project ( aGeomCurve, thegpPnt, Precision::Confusion(), p, aParam );
83/* //:S4136
84 //Trim == natural boundary ?
85 if(aGeomCurve->IsKind(STANDARD_TYPE(Geom_BoundedCurve))) {
86 Standard_Real frstPar = aGeomCurve->FirstParameter();
87 Standard_Real lstPar = aGeomCurve->LastParameter();
88 gp_Pnt frstPnt = aGeomCurve->Value(frstPar);
89 gp_Pnt lstPnt = aGeomCurve->Value(lstPar);
90 if(frstPnt.IsEqual(thegpPnt,precBrep)) {
91 aParam = frstPar;
92 return Standard_True;
93 }
94 if(lstPnt.IsEqual(thegpPnt,precBrep)) {
95 aParam = lstPar;
96 return Standard_True;
97 }
98 }
99 // Project Point On Curve
100 GeomAPI_ProjectPointOnCurve PPOC(thegpPnt, aGeomCurve);
101 if (PPOC.NbPoints() == 0) {
102 return Standard_False;
103 }
104 aParam = PPOC.LowerDistanceParameter();
105*/
106 return Standard_True;
107 }
108 }
109// if the MasterRepresentation is unspecified:
110// if a ParameterValue exists, it is prefered
111
112 for ( i = 1 ; i <= nbSel ; i++) {
113 StepGeom_TrimmingSelect theSel = TS->Value(i);
114 if (theSel.CaseMember() > 0) {
115 aParam = Shift + Factor * theSel.ParameterValue();
116
117 return Standard_True;
118 }
119 }
120// if no ParameterValue exists, it is created from the CartesianPointValue
121
122 for ( i = 1 ; i <= nbSel ; i++) {
123 StepGeom_TrimmingSelect theSel = TS->Value(i);
124 if (theSel.CaseNumber() > 0) {
125 aPoint = theSel.CartesianPoint();
126 StepToGeom_MakeCartesianPoint::Convert(aPoint,theGeomPnt);
127 gp_Pnt thegpPnt = theGeomPnt->Pnt();
128 // Project Point On Curve
129 ShapeAnalysis_Curve sac;
130 gp_Pnt p;
131 sac.Project ( aGeomCurve, thegpPnt, Precision::Confusion(), p, aParam );
132/*
133 GeomAPI_ProjectPointOnCurve PPOC(thegpPnt, aGeomCurve);
134 if (PPOC.NbPoints() == 0) {
135 return Standard_False;
136 }
137 aParam = PPOC.LowerDistanceParameter();
138*/
139 return Standard_True;
140 }
141 }
142 return Standard_False; // I suppose
143}
144
145
146//=============================================================================
147// Creation d' une Trimmed Curve de Geom a partir d' une Trimmed Curve de Step
148//=============================================================================
149
150Standard_Boolean StepToGeom_MakeTrimmedCurve::Convert (const Handle(StepGeom_TrimmedCurve)& SC, Handle(Geom_TrimmedCurve)& CC)
151{
152 const Handle(StepGeom_Curve) theSTEPCurve = SC->BasisCurve();
153 Handle(Geom_Curve) theCurve;
154 if (!StepToGeom_MakeCurve::Convert(theSTEPCurve,theCurve))
155 return Standard_False;
156
157 const Handle(StepGeom_HArray1OfTrimmingSelect)& theTrimSel1 = SC->Trim1();
158 const Handle(StepGeom_HArray1OfTrimmingSelect)& theTrimSel2 = SC->Trim2();
159 const Standard_Integer nbSel1 = SC->NbTrim1();
160 const Standard_Integer nbSel2 = SC->NbTrim2();
161
162 Standard_Integer MasterRep;
163 switch (SC->MasterRepresentation())
164 {
165 case StepGeom_tpCartesian: MasterRep = 1; break;
166 case StepGeom_tpParameter: MasterRep = 2; break;
167 default: MasterRep = 0;
168 }
169
170 //gka 18.02.04 analysis for case when MasterRep = .Unspecified
171 //and parameters are specified as CARTESIAN_POINT
172 Standard_Boolean isPoint = Standard_False;
173 if(MasterRep == 0 || (MasterRep == 2 && nbSel1 >1 && nbSel2 > 1)) {
174 Standard_Integer ii;
175 for(ii = 1; ii <= nbSel1; ii++)
176 {
177 if (!(theTrimSel1->Value(ii).CartesianPoint().IsNull()))
178 {
179 for(ii = 1; ii <= nbSel2; ii++)
180 {
181 if (!(theTrimSel2->Value(ii).CartesianPoint().IsNull()))
182 {
183 isPoint = Standard_True;
184 break;
185 }
186 }
187 break;
188 }
189 }
190 }
191
192 //:o6 abv 18 Feb 99: computation of factor moved
193 Standard_Real fact = 1., shift = 0.;
194 if (theSTEPCurve->IsKind(STANDARD_TYPE(StepGeom_Line))) {
195 const Handle(StepGeom_Line) theLine =
196 Handle(StepGeom_Line)::DownCast(theSTEPCurve);
197 fact = theLine->Dir()->Magnitude() * UnitsMethods::LengthFactor();
198 }
199 else if (theSTEPCurve->IsKind(STANDARD_TYPE(StepGeom_Circle)) ||
200 theSTEPCurve->IsKind(STANDARD_TYPE(StepGeom_Ellipse))) {
c6541a0c 201// if (trim1 > 2.1*M_PI || trim2 > 2.1*M_PI) fact = M_PI / 180.;
7fd59977 202 fact = UnitsMethods::PlaneAngleFactor();
203 //:p3 abv 23 Feb 99: shift on pi/2 on ellipse with R1 < R2
204 const Handle(StepGeom_Ellipse) ellipse = Handle(StepGeom_Ellipse)::DownCast(theSTEPCurve);
205 if ( !ellipse.IsNull() && ellipse->SemiAxis1() - ellipse->SemiAxis2() < 0. )
c6541a0c 206 shift = 0.5 * M_PI;
7fd59977 207
208 // skl 04.02.2002 for OCC133: we can not make TrimmedCurve if
209 // there is no X-direction in StepGeom_Axis2Placement3d
210 const Handle(StepGeom_Conic) conic = Handle(StepGeom_Conic)::DownCast(theSTEPCurve);
211 // CKY 6-FEB-2004 for Airbus-MedialAxis :
212 // this restriction does not apply for trimming by POINTS
213 if(!conic.IsNull() && MasterRep != 1) {
214 const StepGeom_Axis2Placement a2p = conic->Position();
215 if(a2p.CaseNum(a2p.Value())==2) {
216 if( !a2p.Axis2Placement3d()->HasRefDirection() ) {
217 ////gka 18.02.04 analysis for case when MasterRep = .Unspecified
218 //and parameters are specified as CARTESIAN_POINT
219 if(isPoint /*&& !MasterRep*/)
220 MasterRep =1;
221 else {
222 if ( SC->SenseAgreement() )
c6541a0c 223 CC = new Geom_TrimmedCurve(theCurve, 0., 2.*M_PI, Standard_True);
7fd59977 224 else
c6541a0c 225 CC = new Geom_TrimmedCurve(theCurve, 2.*M_PI, 0., Standard_False);
7fd59977 226 return Standard_True;
227 }
228 }
229 }
230 }
231 }
232
233 Standard_Real trim1 = 0.;
234 Standard_Real trim2 = 0.;
235 Handle(StepGeom_CartesianPoint) TrimCP1, TrimCP2;
236 const Standard_Boolean FoundParam1 = ExtractParameter(theCurve, theTrimSel1, nbSel1, MasterRep, fact, shift, trim1);
237 const Standard_Boolean FoundParam2 = ExtractParameter(theCurve, theTrimSel2, nbSel2, MasterRep, fact, shift, trim2);
238
239 if (FoundParam1 && FoundParam2) {
240 const Standard_Real cf = theCurve->FirstParameter();
241 const Standard_Real cl = theCurve->LastParameter();
242 //: abv 09.04.99: S4136: bm2_ug_t4-B.stp #70610: protect against OutOfRange
243 if ( !theCurve->IsPeriodic() ) {
244 if ( trim1 < cf ) trim1 = cf;
245 else if ( trim1 > cl ) trim1 = cl;
246 if ( trim2 < cf ) trim2 = cf;
247 else if ( trim2 > cl ) trim2 = cl;
248 }
249 if (Abs(trim1 - trim2) < Precision::PConfusion()) {
250 if (theCurve->IsPeriodic()) {
251 ElCLib::AdjustPeriodic(cf,cl,Precision::PConfusion(),trim1,trim2);
252 }
253 else if (theCurve->IsClosed()) {
254 if (Abs(trim1 - cf) < Precision::PConfusion()) {
255 trim2 += cl;
256 }
257 else {
258 trim1 -= cl;
259 }
260 }
261 else {
7fd59977 262 return Standard_False;
263 }
264 }
265// CKY 16-DEC-1997 : USA60035 le texte de Part42 parle de degres
266// mais des systemes ecrivent en radians. Exploiter UnitsMethods
267//:o6 trim1 = trim1 * fact;
268//:o6 trim2 = trim2 * fact;
269 if ( SC->SenseAgreement() )
270 CC = new Geom_TrimmedCurve(theCurve, trim1, trim2, Standard_True);
271 else //:abv 29.09.00 PRO20362: reverse parameters in case of reversed curve
272 CC = new Geom_TrimmedCurve(theCurve, trim2, trim1, Standard_False);
273 return Standard_True;
274 }
275 return Standard_False;
276}