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 | |
23 | #include <StepToGeom_MakeTrimmedCurve.ixx> |
24 | #include <gp_Pnt.hxx> |
25 | #include <Geom_CartesianPoint.hxx> |
26 | #include <Geom_Curve.hxx> |
27 | #include <StepGeom_CartesianPoint.hxx> |
28 | #include <StepGeom_Line.hxx> |
29 | #include <StepGeom_Vector.hxx> |
30 | #include <StepGeom_Circle.hxx> |
31 | #include <StepGeom_Ellipse.hxx> |
32 | #include <StepGeom_Parabola.hxx> |
33 | #include <StepGeom_Hyperbola.hxx> |
34 | #include <StepGeom_TrimmingSelect.hxx> |
35 | #include <StepGeom_HArray1OfTrimmingSelect.hxx> |
36 | #include <StepGeom_TrimmedCurve.hxx> |
37 | #include <StepToGeom_MakeTrimmedCurve.hxx> |
38 | #include <StepToGeom_MakeCartesianPoint.hxx> |
39 | #include <StepToGeom_MakeCurve.hxx> |
40 | //#include <GeomAPI_ProjectPointOnCurve.hxx> |
41 | //#include <BRepAPI.hxx> |
42 | #include <ElCLib.hxx> |
43 | |
44 | #include <UnitsMethods.hxx> |
45 | #include <Precision.hxx> |
46 | #include <ShapeAnalysis_Curve.hxx> |
47 | #include <StepGeom_Axis2Placement3d.hxx> |
48 | |
49 | // ---------------------------------------------------------------- |
50 | // ExtractParameter |
51 | // ---------------------------------------------------------------- |
52 | //:o6 abv 18 Feb 99: parameter Factor added |
53 | //:p3 abv 23 Feb 99: parameter Shift added |
54 | |
55 | static 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 | |
150 | Standard_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 | } |