973c2be1 |
1 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
2 | // |
973c2be1 |
3 | // This file is part of Open CASCADE Technology software library. |
b311480e |
4 | // |
d5f74e42 |
5 | // This library is free software; you can redistribute it and/or modify it under |
6 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
7 | // by the Free Software Foundation, with special exception defined in the file |
8 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
9 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
10 | // |
973c2be1 |
11 | // Alternatively, this file may be used under the terms of Open CASCADE |
12 | // commercial license or contractual agreement. |
b311480e |
13 | |
42cf5bc1 |
14 | |
7fd59977 |
15 | #include <Adaptor3d_CurveOnSurface.hxx> |
42cf5bc1 |
16 | #include <BRep_Builder.hxx> |
7fd59977 |
17 | #include <BRep_GCurve.hxx> |
42cf5bc1 |
18 | #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx> |
19 | #include <BRep_ListIteratorOfListOfPointRepresentation.hxx> |
7fd59977 |
20 | #include <BRep_ListOfCurveRepresentation.hxx> |
7fd59977 |
21 | #include <BRep_ListOfPointRepresentation.hxx> |
7fd59977 |
22 | #include <BRep_PointOnCurve.hxx> |
23 | #include <BRep_PointOnCurveOnSurface.hxx> |
42cf5bc1 |
24 | #include <BRep_PointOnSurface.hxx> |
25 | #include <BRep_PointRepresentation.hxx> |
26 | #include <BRep_TEdge.hxx> |
27 | #include <BRep_Tool.hxx> |
28 | #include <BRep_TVertex.hxx> |
29 | #include <Geom2d_BSplineCurve.hxx> |
30 | #include <Geom2d_Curve.hxx> |
31 | #include <Geom2d_OffsetCurve.hxx> |
32 | #include <Geom2d_TrimmedCurve.hxx> |
33 | #include <Geom2dAdaptor_HCurve.hxx> |
34 | #include <Geom_Curve.hxx> |
35 | #include <Geom_Surface.hxx> |
36 | #include <GeomAdaptor_Curve.hxx> |
37 | #include <GeomAdaptor_HSurface.hxx> |
38 | #include <Precision.hxx> |
39 | #include <ShapeAnalysis.hxx> |
40 | #include <ShapeAnalysis_Curve.hxx> |
41 | #include <ShapeAnalysis_Edge.hxx> |
7fd59977 |
42 | #include <ShapeAnalysis_Surface.hxx> |
42cf5bc1 |
43 | #include <ShapeAnalysis_TransferParametersProj.hxx> |
44 | #include <ShapeBuild_Edge.hxx> |
45 | #include <Standard_Type.hxx> |
46 | #include <TColgp_SequenceOfPnt.hxx> |
47 | #include <TColStd_HArray1OfReal.hxx> |
48 | #include <TopLoc_Location.hxx> |
49 | #include <TopoDS.hxx> |
50 | #include <TopoDS_Edge.hxx> |
51 | #include <TopoDS_Face.hxx> |
52 | #include <TopoDS_Vertex.hxx> |
53 | |
92efcf78 |
54 | IMPLEMENT_STANDARD_RTTIEXT(ShapeAnalysis_TransferParametersProj,ShapeAnalysis_TransferParameters) |
55 | |
7fd59977 |
56 | //======================================================================= |
57 | //function : ShapeAnalysis_TransferParametersProj |
58 | //purpose : |
59 | //======================================================================= |
7fd59977 |
60 | ShapeAnalysis_TransferParametersProj::ShapeAnalysis_TransferParametersProj() |
61 | { |
62 | myMaxTolerance = 1; //Precision::Infinite(); ?? pdn |
63 | myForceProj = Standard_False; |
64 | myInitOK = Standard_False; |
65 | } |
66 | |
67 | |
68 | //======================================================================= |
69 | //function : ShapeAnalysis_TransferParametersProj |
70 | //purpose : |
71 | //======================================================================= |
72 | |
73 | ShapeAnalysis_TransferParametersProj::ShapeAnalysis_TransferParametersProj(const TopoDS_Edge& E, |
74 | const TopoDS_Face& F) |
75 | { |
76 | myMaxTolerance = 1; //Precision::Infinite(); ?? pdn |
77 | myForceProj = Standard_False; |
78 | Init(E,F); |
79 | } |
80 | |
81 | |
82 | //======================================================================= |
83 | //function : Init |
84 | //purpose : |
85 | //======================================================================= |
86 | |
87 | void ShapeAnalysis_TransferParametersProj::Init(const TopoDS_Edge& E, |
88 | const TopoDS_Face& F) |
89 | { |
90 | myInitOK = Standard_False; |
91 | ShapeAnalysis_TransferParameters::Init(E,F); |
92 | myEdge = E; |
93 | myPrecision = BRep_Tool::Tolerance(E); // it is better - skl OCC2851 |
94 | //myPrecision = Precision::Confusion(); |
95 | |
96 | myCurve = BRep_Tool::Curve (E, myFirst, myLast); |
97 | if ( myCurve.IsNull() ) { myFirst = 0.; myLast = 1.; return;} |
98 | |
99 | if ( F.IsNull() ) return; |
100 | |
101 | Standard_Real f2d, l2d; |
102 | ShapeAnalysis_Edge sae; |
103 | if(sae.PCurve (E, F, myCurve2d, f2d, l2d, Standard_False)) { |
104 | |
105 | Handle(Geom2dAdaptor_HCurve) AC2d = new Geom2dAdaptor_HCurve(myCurve2d,f2d,l2d); |
106 | Handle(Geom_Surface) aSurface = BRep_Tool::Surface(F,myLocation); |
107 | Handle(GeomAdaptor_HSurface) AdS = new GeomAdaptor_HSurface(aSurface); |
108 | |
109 | Adaptor3d_CurveOnSurface Ad1(AC2d,AdS); |
110 | myAC3d = Ad1;//new Adaptor3d_CurveOnSurface(AC2d,AdS); |
111 | myInitOK = Standard_True; |
112 | } |
113 | } |
114 | |
115 | |
116 | //======================================================================= |
117 | //function : Perform |
118 | //purpose : |
119 | //======================================================================= |
120 | |
121 | Handle(TColStd_HSequenceOfReal) ShapeAnalysis_TransferParametersProj::Perform |
122 | (const Handle(TColStd_HSequenceOfReal)& Knots, |
123 | const Standard_Boolean To2d) |
124 | { |
125 | //pdn |
126 | if( !myInitOK || |
127 | (! myForceProj && myPrecision < myMaxTolerance && BRep_Tool::SameParameter(myEdge))) |
128 | return ShapeAnalysis_TransferParameters::Perform(Knots,To2d); |
129 | |
130 | Handle(TColStd_HSequenceOfReal) resKnots = new TColStd_HSequenceOfReal; |
131 | |
132 | Standard_Integer len = Knots->Length(); |
133 | Standard_Real preci = 2*Precision::PConfusion(); |
134 | |
135 | Standard_Real first = (To2d ? myAC3d.FirstParameter() : myFirst); |
136 | Standard_Real last = (To2d ? myAC3d.LastParameter() : myLast); |
137 | Standard_Real maxPar = first; |
138 | Standard_Real lastPar = last; |
139 | Standard_Real prevPar = maxPar; |
140 | |
141 | Standard_Integer j; // svv Jan 10 2000 : porting on DEC |
142 | for(j = 1; j <= len; j++) { |
143 | Standard_Real par = PreformSegment(Knots->Value(j),To2d,prevPar,lastPar); |
144 | prevPar = par; |
145 | if(prevPar > lastPar) |
146 | prevPar -= preci; |
147 | resKnots->Append(par); |
148 | if(par > maxPar) |
149 | maxPar = par; |
150 | } |
151 | |
152 | //pdn correcting on periodic |
eafb234b |
153 | if(myCurve->IsClosed()) { |
7fd59977 |
154 | for(j = len; j >=1; j--) |
eafb234b |
155 | if(resKnots->Value(j) < maxPar) |
156 | resKnots->SetValue(j,(To2d ? myAC3d.LastParameter() : myCurve->LastParameter())-(len-j)*preci); |
7fd59977 |
157 | else |
eafb234b |
158 | break; |
159 | } |
7fd59977 |
160 | //pdn correction on range |
161 | for ( j=1; j <= len; j++ ) { |
162 | if ( resKnots->Value (j) < first ) resKnots->SetValue ( j, first ); |
163 | if ( resKnots->Value (j) > last ) resKnots->SetValue ( j, last ); |
164 | } |
165 | |
166 | return resKnots; |
167 | } |
168 | |
169 | |
170 | //======================================================================= |
171 | //function : PreformSegment |
172 | //purpose : |
173 | //======================================================================= |
174 | |
175 | Standard_Real ShapeAnalysis_TransferParametersProj::PreformSegment(const Standard_Real Param, |
176 | const Standard_Boolean To2d, |
177 | const Standard_Real First, |
178 | const Standard_Real Last) |
179 | { |
180 | Standard_Real linPar = ShapeAnalysis_TransferParameters::Perform(Param, To2d); |
181 | if( !myInitOK || |
182 | (! myForceProj && myPrecision < myMaxTolerance && BRep_Tool::SameParameter(myEdge))) |
183 | return linPar; |
184 | |
185 | Standard_Real linDev, projDev; |
186 | |
187 | ShapeAnalysis_Curve sac; |
188 | gp_Pnt pproj; |
189 | Standard_Real ppar; |
190 | if(To2d) { |
191 | gp_Pnt p1 = myCurve->Value(Param).Transformed(myLocation.Inverted()); |
192 | Handle(Adaptor3d_HSurface) AdS = myAC3d.GetSurface(); |
193 | Handle(Geom2dAdaptor_HCurve) AC2d = new Geom2dAdaptor_HCurve(myCurve2d,First,Last); |
194 | Adaptor3d_CurveOnSurface Ad1(AC2d,AdS); |
195 | projDev = sac.Project(Ad1,p1,myPrecision,pproj,ppar);//pdn |
196 | linDev = p1.Distance(Ad1.Value(linPar)); |
197 | } |
198 | else { |
199 | gp_Pnt p1 = myAC3d.Value(Param).Transformed(myLocation); |
200 | projDev = sac.Project(myCurve,p1,myPrecision,pproj,ppar,First,Last,Standard_False); |
201 | linDev = p1.Distance(myCurve->Value(linPar)); |
202 | } |
203 | |
204 | if ( linDev <= projDev || (linDev < myPrecision && linDev <= 2 * projDev ) ) |
205 | ppar = linPar; |
206 | return ppar; |
207 | } |
208 | |
209 | |
210 | //======================================================================= |
211 | //function : Perform |
212 | //purpose : |
213 | //======================================================================= |
214 | |
215 | Standard_Real ShapeAnalysis_TransferParametersProj::Perform(const Standard_Real Knot, |
216 | const Standard_Boolean To2d) |
217 | { |
218 | if( !myInitOK || |
219 | (! myForceProj && myPrecision < myMaxTolerance && BRep_Tool::SameParameter(myEdge))) |
220 | return ShapeAnalysis_TransferParameters::Perform(Knot, To2d); |
221 | |
222 | Standard_Real res; |
223 | if(To2d) |
224 | res = PreformSegment(Knot,To2d,myAC3d.FirstParameter(),myAC3d.LastParameter()); |
225 | else |
226 | res = PreformSegment(Knot,To2d,myFirst,myLast); |
227 | |
228 | //pdn correction on range |
229 | Standard_Real first = (To2d ? myAC3d.FirstParameter() : myFirst); |
230 | Standard_Real last = (To2d ? myAC3d.LastParameter() : myLast); |
231 | if ( res < first ) res = first; |
232 | if ( res > last ) res = last; |
233 | return res; |
234 | } |
235 | |
236 | |
237 | //======================================================================= |
238 | //function : CorrectParameter |
239 | //purpose : auxilary |
240 | //======================================================================= |
241 | static Standard_Real CorrectParameter(const Handle(Geom2d_Curve) crv, |
242 | const Standard_Real param) |
243 | { |
244 | if(crv->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) { |
245 | Handle(Geom2d_TrimmedCurve) tmp = Handle(Geom2d_TrimmedCurve)::DownCast (crv); |
246 | return CorrectParameter(tmp->BasisCurve(),param); |
247 | } |
248 | else if(crv->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))) { |
249 | Handle(Geom2d_OffsetCurve) tmp = Handle(Geom2d_OffsetCurve)::DownCast (crv); |
250 | return CorrectParameter(tmp->BasisCurve(),param); |
251 | } |
252 | else if(crv->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) { |
253 | Handle(Geom2d_BSplineCurve) bspline = Handle(Geom2d_BSplineCurve)::DownCast (crv); |
254 | for(Standard_Integer j = bspline->FirstUKnotIndex(); j <= bspline->LastUKnotIndex(); j++) { |
255 | Standard_Real valknot = bspline->Knot(j); |
256 | if( Abs(valknot-param)<Precision::PConfusion() ) |
257 | return valknot; |
258 | } |
259 | } |
260 | return param; |
261 | } |
262 | |
263 | |
264 | //======================================================================= |
265 | //function : TransferRange |
266 | //purpose : |
267 | //======================================================================= |
268 | |
269 | void ShapeAnalysis_TransferParametersProj::TransferRange(TopoDS_Edge& newEdge, |
270 | const Standard_Real prevPar, |
271 | const Standard_Real currPar, |
272 | const Standard_Boolean Is2d) |
273 | { |
274 | if( !myInitOK || |
275 | (! myForceProj && myPrecision < myMaxTolerance && BRep_Tool::SameParameter(myEdge))) { |
276 | ShapeAnalysis_TransferParameters::TransferRange(newEdge,prevPar,currPar,Is2d); |
277 | return; |
278 | } |
279 | |
280 | BRep_Builder B; |
281 | Standard_Boolean samerange = Standard_True; |
282 | ShapeBuild_Edge sbe; |
283 | sbe.CopyRanges(newEdge,myEdge); |
284 | gp_Pnt p1; |
285 | gp_Pnt p2; |
286 | Standard_Real alpha = 0, beta = 1; |
287 | Standard_Real preci = Precision::PConfusion(); |
288 | Standard_Real firstPar, lastPar; |
289 | if(prevPar < currPar) { |
290 | firstPar = prevPar; |
291 | lastPar = currPar; |
292 | } |
293 | else { |
294 | firstPar = currPar; |
295 | lastPar = prevPar; |
296 | } |
297 | if(Is2d) { |
298 | p1 = myAC3d.Value(firstPar).Transformed(myLocation); |
f4dee9bb |
299 | if(Precision::IsInfinite(p1.X()) || Precision::IsInfinite(p1.Y()) || |
300 | Precision::IsInfinite(p1.Z())) |
301 | { |
302 | B.SameRange(newEdge, Standard_False); |
303 | return; |
304 | } |
7fd59977 |
305 | p2 = myAC3d.Value(lastPar).Transformed(myLocation); |
f4dee9bb |
306 | if(Precision::IsInfinite(p2.X()) || Precision::IsInfinite(p2.Y()) || |
307 | Precision::IsInfinite(p2.Z())) |
308 | { |
309 | B.SameRange(newEdge, Standard_False); |
310 | return; |
311 | } |
7fd59977 |
312 | Standard_Real fact = myAC3d.LastParameter() - myAC3d.FirstParameter(); |
313 | if( fact > Epsilon(myAC3d.LastParameter()) ) { |
314 | alpha = ( firstPar - myAC3d.FirstParameter() ) / fact; |
315 | beta = ( lastPar - myAC3d.FirstParameter() ) / fact; |
316 | } |
317 | } |
318 | else { |
319 | p1 = myCurve->Value(firstPar); |
f4dee9bb |
320 | if(Precision::IsInfinite(p1.X()) || Precision::IsInfinite(p1.Y()) || |
321 | Precision::IsInfinite(p1.Z())) |
322 | { |
323 | B.SameRange(newEdge, Standard_False); |
324 | return; |
325 | } |
7fd59977 |
326 | p2 = myCurve->Value(lastPar); |
f4dee9bb |
327 | if(Precision::IsInfinite(p2.X()) || Precision::IsInfinite(p2.Y()) || |
328 | Precision::IsInfinite(p2.Z())) |
329 | { |
330 | B.SameRange(newEdge, Standard_False); |
331 | return; |
332 | } |
7fd59977 |
333 | Standard_Real fact = myLast - myFirst; |
334 | if( fact > Epsilon(myLast) ) { |
335 | alpha = ( firstPar - myFirst ) / fact; |
336 | beta = ( lastPar - myFirst ) / fact; |
337 | } |
338 | } |
339 | const Standard_Boolean useLinearFirst = (alpha < preci); |
340 | const Standard_Boolean useLinearLast = (1-beta < preci); |
341 | TopLoc_Location EdgeLoc = myEdge.Location(); |
342 | ShapeAnalysis_Curve sac; |
343 | gp_Pnt pproj; |
344 | Standard_Real ppar1,ppar2; |
345 | BRep_ListOfCurveRepresentation& tolist = (*((Handle(BRep_TEdge)*)&newEdge.TShape()))->ChangeCurves(); |
346 | Handle(BRep_GCurve) toGC; |
347 | for (BRep_ListIteratorOfListOfCurveRepresentation toitcr (tolist); toitcr.More(); toitcr.Next()) { |
348 | toGC = Handle(BRep_GCurve)::DownCast(toitcr.Value()); |
349 | if ( toGC.IsNull() ) continue; |
350 | TopLoc_Location loc = ( EdgeLoc * toGC->Location() ).Inverted(); |
351 | if ( toGC->IsCurve3D() ) { |
352 | if (!Is2d) { |
353 | ppar1 = firstPar; |
354 | ppar2 = lastPar; |
355 | } |
356 | else { |
357 | Handle(Geom_Curve) C3d = toGC->Curve3D(); |
358 | if (C3d.IsNull()) continue; |
359 | Standard_Real first = toGC->First(); |
360 | Standard_Real last = toGC->Last(); |
361 | Standard_Real len = last -first; |
362 | gp_Pnt ploc1 = p1.Transformed(loc); |
363 | gp_Pnt ploc2 = p2.Transformed(loc); |
364 | GeomAdaptor_Curve GAC(C3d,first,last); |
365 | // CATIA bplseitli.model FAC1155 - Copy: protection for degenerated edges(3d case for symmetry) |
366 | Standard_Real linFirst = first+alpha*len; |
367 | Standard_Real linLast = first+beta*len; |
368 | Standard_Real dist1 = sac.NextProject(linFirst,GAC,ploc1,myPrecision,pproj,ppar1); |
369 | Standard_Real dist2 = sac.NextProject(linLast,GAC,ploc2,myPrecision,pproj,ppar2); |
370 | Standard_Boolean useLinear = Abs(ppar1-ppar2) < preci; |
371 | |
372 | gp_Pnt pos1 = C3d->Value ( linFirst ); |
373 | gp_Pnt pos2 = C3d->Value ( linLast ); |
374 | Standard_Real d01 = pos1.Distance ( ploc1 ); |
375 | Standard_Real d02 = pos2.Distance ( ploc2 ); |
376 | if ( useLinearFirst || useLinear || d01 <= dist1 || ( d01 < myPrecision && d01 <= 2 * dist1 ) ) |
377 | ppar1 = linFirst; |
378 | if ( useLinearLast || useLinear || d02 <= dist2 || ( d02 < myPrecision && d02 <= 2 * dist2 ) ) |
379 | ppar2 = linLast; |
380 | } |
381 | if(ppar1 > ppar2) { |
382 | Standard_Real tmpP = ppar2; ppar2 = ppar1; ppar1 = tmpP; |
383 | } |
384 | if(ppar2-ppar1 < preci) { |
385 | if(ppar1-toGC->First() < preci) |
386 | ppar2+=2*preci; |
387 | else if(toGC->Last()-ppar2 < preci) |
388 | ppar1-=2*preci; |
389 | else { |
390 | ppar1 -= preci; |
391 | ppar2 += preci; |
392 | } |
393 | } |
394 | toGC->SetRange ( ppar1, ppar2); |
395 | //if(fabs(ppar1- firstPar) > Precision::PConfusion() || |
396 | // fabs(ppar2 - lastPar) >Precision::PConfusion()) // by LSS |
397 | if(ppar1!=firstPar || ppar2!=lastPar) |
398 | samerange = Standard_False; |
399 | |
400 | } |
401 | else if (toGC->IsCurveOnSurface()) { //continue; || |
402 | |
403 | Standard_Boolean localLinearFirst = useLinearFirst; |
404 | Standard_Boolean localLinearLast = useLinearLast; |
405 | Handle(Geom2d_Curve) C2d = toGC->PCurve(); |
406 | Standard_Real first = toGC->First(); |
407 | Standard_Real last = toGC->Last(); |
408 | Standard_Real len = last -first; |
409 | Handle(Geom2dAdaptor_HCurve) AC2d = new Geom2dAdaptor_HCurve(toGC->PCurve(),first,last); |
410 | Handle(GeomAdaptor_HSurface) AdS = new GeomAdaptor_HSurface( toGC->Surface()); |
411 | Adaptor3d_CurveOnSurface Ad1(AC2d,AdS); |
412 | ShapeAnalysis_Curve sac1; |
413 | |
414 | //gp_Pnt p1 = Ad1.Value(prevPar); |
415 | //gp_Pnt p2 = Ad1.Value(currPar); |
416 | gp_Pnt ploc1 = p1.Transformed(loc); |
417 | gp_Pnt ploc2 = p2.Transformed(loc); |
418 | // CATIA bplseitli.model FAC1155 - Copy: protection for degenerated edges |
419 | Standard_Real linFirst = first+alpha*len; |
420 | Standard_Real linLast = first+beta*len; |
421 | Standard_Real dist1 = sac1.NextProject(linFirst, Ad1, ploc1, myPrecision,pproj,ppar1); |
422 | Standard_Real dist2 = sac1.NextProject(linLast, Ad1, ploc2, myPrecision,pproj,ppar2); |
423 | |
424 | Standard_Boolean isFirstOnEnd = (ppar1-first)/len < Precision::PConfusion(); |
425 | Standard_Boolean isLastOnEnd = (last-ppar2)/len < Precision::PConfusion(); |
426 | Standard_Boolean useLinear = Abs(ppar1-ppar2) < Precision::PConfusion(); |
427 | if(isFirstOnEnd && ! localLinearFirst) |
428 | localLinearFirst = Standard_True; |
429 | if(isLastOnEnd && ! localLinearLast) |
430 | localLinearLast = Standard_True; |
431 | |
432 | gp_Pnt pos1 = Ad1.Value ( linFirst ); |
433 | gp_Pnt pos2 = Ad1.Value ( linLast ); |
434 | Standard_Real d01 = pos1.Distance ( ploc1 ); |
435 | Standard_Real d02 = pos2.Distance ( ploc2 ); |
436 | if ( localLinearFirst || useLinear || d01 <= dist1 || ( d01 < myPrecision && d01 <= 2 * dist1 ) ) |
437 | ppar1 = linFirst; |
438 | if ( localLinearLast || useLinear || d02 <= dist2 || ( d02 < myPrecision && d02 <= 2 * dist2 ) ) |
439 | ppar2 = linLast; |
440 | |
441 | if(ppar1 > ppar2) { |
442 | Standard_Real tmpP = ppar2; ppar2 = ppar1; ppar1 = tmpP; |
443 | } |
444 | ppar1 = CorrectParameter(C2d,ppar1); |
445 | ppar2 = CorrectParameter(C2d,ppar2); |
446 | if(ppar2-ppar1 < preci) { |
447 | if(ppar1-toGC->First() < preci) |
448 | ppar2+=2*preci; |
449 | else if(toGC->Last()-ppar2 < preci) |
450 | ppar1-=2*preci; |
451 | else { |
452 | ppar1 -= preci; |
453 | ppar2 += preci; |
454 | } |
455 | } |
456 | toGC->SetRange ( ppar1, ppar2); |
457 | //if(fabs(ppar1 - firstPar) > Precision::PConfusion() || |
458 | // fabs(ppar2 -lastPar) > Precision::PConfusion())// by LSS |
459 | if(ppar1 != firstPar || ppar2 != lastPar) |
460 | samerange = Standard_False; |
461 | } |
462 | } |
463 | B.SameRange(newEdge, samerange); |
464 | } |
465 | |
466 | |
467 | //======================================================================= |
468 | //function : IsSameRange |
469 | //purpose : |
470 | //======================================================================= |
471 | |
472 | Standard_Boolean ShapeAnalysis_TransferParametersProj::IsSameRange() const |
473 | { |
474 | |
475 | if( !myInitOK || |
476 | (! myForceProj && myPrecision < myMaxTolerance && BRep_Tool::SameParameter(myEdge))) |
477 | return ShapeAnalysis_TransferParameters::IsSameRange(); |
478 | else |
479 | return Standard_False; |
480 | } |
481 | |
482 | |
483 | //======================================================================= |
484 | //function : ForceProjection |
485 | //purpose : |
486 | //======================================================================= |
487 | |
488 | Standard_Boolean& ShapeAnalysis_TransferParametersProj::ForceProjection() |
489 | { |
490 | return myForceProj; |
491 | } |
492 | |
493 | //======================================================================= |
494 | //function : CopyNMVertex |
495 | //purpose : |
496 | //======================================================================= |
497 | |
498 | TopoDS_Vertex ShapeAnalysis_TransferParametersProj::CopyNMVertex (const TopoDS_Vertex& theV, |
499 | const TopoDS_Edge& toedge, |
500 | const TopoDS_Edge& fromedge) |
501 | { |
502 | TopoDS_Vertex anewV; |
503 | if(theV.Orientation() != TopAbs_INTERNAL && |
504 | theV.Orientation() != TopAbs_EXTERNAL) |
505 | return anewV; |
506 | |
507 | TopLoc_Location fromLoc; |
508 | Standard_Real f1,l1; |
509 | const Handle(Geom_Curve)& C1 = BRep_Tool::Curve(fromedge,fromLoc,f1,l1); |
510 | fromLoc = fromLoc.Predivided(theV.Location()); |
511 | |
512 | Standard_Real f2,l2; |
513 | Handle(Geom_Curve) C2 = BRep_Tool::Curve(toedge,f2,l2); |
514 | |
515 | anewV = TopoDS::Vertex(theV.EmptyCopied()); |
516 | gp_Pnt apv = BRep_Tool::Pnt(anewV); |
517 | |
518 | BRep_ListOfPointRepresentation& alistrep = |
519 | (*((Handle(BRep_TVertex)*)&anewV.TShape()))->ChangePoints(); |
520 | |
521 | BRep_ListIteratorOfListOfPointRepresentation itpr |
522 | ((*((Handle(BRep_TVertex)*) &theV.TShape()))->Points()); |
523 | |
524 | Standard_Real aOldPar = RealLast(); |
525 | Standard_Boolean hasRepr = Standard_False; |
526 | for ( ;itpr.More(); itpr.Next()) { |
527 | const Handle(BRep_PointRepresentation)& pr = itpr.Value(); |
528 | if(pr.IsNull()) |
529 | continue; |
530 | if(pr->IsPointOnCurve(C1,fromLoc)) { |
531 | aOldPar = pr->Parameter(); |
532 | hasRepr =Standard_True; |
533 | continue; |
534 | } |
535 | else if(pr->IsPointOnSurface()) { |
536 | Handle(BRep_PointOnSurface) aOld = Handle(BRep_PointOnSurface)::DownCast(pr); |
537 | Handle(BRep_PointOnSurface) aPS = new BRep_PointOnSurface(aOld->Parameter(), |
538 | aOld->Parameter2(), |
539 | aOld->Surface(), |
540 | aOld->Location()); |
541 | alistrep.Append(aPS); |
542 | continue; |
543 | } |
544 | else if(pr->IsPointOnCurveOnSurface()) { |
545 | Standard_Boolean found = Standard_False; |
546 | BRep_ListIteratorOfListOfCurveRepresentation fromitcr |
547 | ((*((Handle(BRep_TEdge)*)&fromedge.TShape()))->ChangeCurves()); |
548 | |
549 | for( ;fromitcr.More() && !found; fromitcr.Next()) { |
550 | Handle(BRep_GCurve) fromGC = Handle(BRep_GCurve)::DownCast(fromitcr.Value()); |
551 | if ( fromGC.IsNull() || !fromGC->IsCurveOnSurface()) continue; |
552 | |
553 | TopLoc_Location aL = fromGC->Location(); |
554 | aL.Predivided(theV.Location()); |
555 | Handle(Geom_Surface) surface1 = fromGC->Surface(); |
556 | Handle(Geom2d_Curve) ac2d1 = fromGC->PCurve(); |
557 | if (pr->IsPointOnCurveOnSurface(ac2d1,surface1,aL)) { |
558 | found = Standard_True; |
559 | if(!hasRepr) { |
560 | aOldPar = pr->Parameter(); |
561 | } |
562 | } |
563 | } |
564 | if(found) continue; |
565 | } |
566 | if(pr->IsPointOnCurve()) { |
567 | Handle(BRep_PointOnCurve) aPRep = new BRep_PointOnCurve(pr->Parameter(),pr->Curve(),pr->Location()); |
568 | alistrep.Append(aPRep); |
569 | } |
570 | else if(pr->IsPointOnCurveOnSurface() ) { |
571 | Handle(BRep_PointOnCurveOnSurface) aPonCS = |
572 | new BRep_PointOnCurveOnSurface(pr->Parameter(),pr->PCurve(),pr->Surface(),pr->Location()); |
573 | alistrep.Append(aPonCS); |
574 | } |
575 | } |
576 | Standard_Real apar = aOldPar; |
577 | Standard_Real aTol = BRep_Tool::Tolerance(theV); |
578 | if(!hasRepr || (fabs(f1-f2) > Precision::PConfusion() || fabs(l1-l2)> Precision::PConfusion())) { |
579 | gp_Pnt projP; |
580 | ShapeAnalysis_Curve sae; |
581 | Standard_Real adist = sae.Project(C2,apv,Precision::Confusion(),projP,apar); |
582 | if(aTol < adist) |
583 | aTol = adist; |
584 | } |
585 | BRep_Builder aB; |
586 | aB.UpdateVertex(anewV,apar,toedge,aTol); |
587 | |
588 | //update tolerance |
589 | Standard_Boolean needUpdate = Standard_False; |
590 | gp_Pnt aPV = (*((Handle(BRep_TVertex)*)&anewV.TShape()))->Pnt(); |
591 | TopLoc_Location toLoc = toedge.Location(); |
592 | BRep_ListIteratorOfListOfCurveRepresentation toitcr |
593 | ((*((Handle(BRep_TEdge)*)&toedge.TShape()))->ChangeCurves()); |
594 | |
595 | for( ;toitcr.More() ; toitcr.Next()) { |
596 | Handle(BRep_GCurve) toGC = Handle(BRep_GCurve)::DownCast(toitcr.Value()); |
597 | if ( toGC.IsNull() || !toGC->IsCurveOnSurface()) continue; |
598 | |
599 | TopLoc_Location aL = (toLoc*toGC->Location()).Predivided(theV.Location()); |
600 | //aL.Predivided(theV.Location()); |
601 | Handle(Geom_Surface) surface1 = toGC->Surface(); |
602 | Handle(Geom2d_Curve) ac2d1 = toGC->PCurve(); |
603 | gp_Pnt2d aP2d = ac2d1->Value(apar); |
604 | gp_Pnt aP3d = surface1->Value(aP2d.X(),aP2d.Y()); |
605 | aP3d.Transform(aL.Transformation()); |
606 | Standard_Real adist = aPV.Distance(aP3d); |
607 | if(adist > aTol) { |
608 | aTol = adist; |
609 | needUpdate = Standard_True; |
610 | } |
611 | |
612 | } |
613 | if(needUpdate) |
614 | aB.UpdateVertex(anewV,aTol); |
615 | return anewV; |
616 | } |
617 | |
618 | //======================================================================= |
619 | //function : CopyNMVertex |
620 | //purpose : |
621 | //======================================================================= |
622 | |
623 | TopoDS_Vertex ShapeAnalysis_TransferParametersProj::CopyNMVertex (const TopoDS_Vertex& theV, |
624 | const TopoDS_Face& toFace, |
625 | const TopoDS_Face& fromFace) |
626 | { |
627 | TopoDS_Vertex anewV; |
628 | if(theV.Orientation() != TopAbs_INTERNAL && |
629 | theV.Orientation() != TopAbs_EXTERNAL) |
630 | return anewV; |
631 | |
632 | |
633 | TopLoc_Location fromLoc; |
634 | TopLoc_Location toLoc; |
635 | Handle(Geom_Surface) fromSurf = BRep_Tool::Surface(fromFace,fromLoc); |
636 | Handle(Geom_Surface) toSurf = BRep_Tool::Surface(toFace,toLoc); |
637 | fromLoc = fromLoc.Predivided(theV.Location()); |
638 | |
639 | anewV = TopoDS::Vertex(theV.EmptyCopied()); |
640 | gp_Pnt apv = BRep_Tool::Pnt(anewV); |
641 | |
642 | |
643 | BRep_ListOfPointRepresentation& alistrep = |
644 | (*((Handle(BRep_TVertex)*)&anewV.TShape()))->ChangePoints(); |
645 | |
646 | BRep_ListIteratorOfListOfPointRepresentation itpr |
647 | ((*((Handle(BRep_TVertex)*) &theV.TShape()))->Points()); |
648 | |
649 | Standard_Boolean hasRepr = Standard_False; |
650 | Standard_Real apar1=0., apar2=0.; |
651 | for ( ;itpr.More(); itpr.Next()) { |
652 | const Handle(BRep_PointRepresentation)& pr = itpr.Value(); |
653 | if(pr.IsNull()) |
654 | continue; |
655 | TopLoc_Location aLoc = pr->Location(); |
656 | if( pr->IsPointOnCurveOnSurface()) { |
657 | Handle(BRep_PointOnCurveOnSurface) aPonCS = |
658 | new BRep_PointOnCurveOnSurface(pr->Parameter(),pr->PCurve(),pr->Surface(),aLoc); |
659 | alistrep.Append(aPonCS); |
660 | } |
661 | else if(pr->IsPointOnCurve()) { |
662 | Handle(BRep_PointOnCurve) aPRep = new BRep_PointOnCurve(pr->Parameter(),pr->Curve(),aLoc); |
663 | alistrep.Append(aPRep); |
664 | } |
665 | else if(pr->IsPointOnSurface()) { |
666 | Handle(BRep_PointOnSurface) aOld = Handle(BRep_PointOnSurface)::DownCast(pr); |
667 | |
668 | if(pr->IsPointOnSurface(fromSurf,fromLoc)) { |
669 | apar1= aOld->Parameter(); |
670 | apar2 = aOld->Parameter2(); |
671 | hasRepr = Standard_True; |
672 | } |
673 | else { |
674 | Handle(BRep_PointOnSurface) aPS = new BRep_PointOnSurface(aOld->Parameter(), |
675 | aOld->Parameter2(), |
676 | aOld->Surface(), |
677 | aOld->Location()); |
678 | alistrep.Append(aPS); |
679 | } |
680 | } |
681 | |
682 | } |
683 | Standard_Real aTol = BRep_Tool::Tolerance(anewV); |
684 | if(!hasRepr || (fromSurf != toSurf || fromLoc != toLoc)) { |
685 | Handle(Geom_Surface) aS = BRep_Tool::Surface(toFace); |
686 | Handle(ShapeAnalysis_Surface) aSurfTool = new ShapeAnalysis_Surface(aS); |
687 | gp_Pnt2d aP2d = aSurfTool->ValueOfUV(apv,Precision::Confusion()); |
688 | apar1 = aP2d.X(); |
689 | apar2 = aP2d.Y(); |
690 | |
691 | if(aTol < aSurfTool->Gap()) |
692 | aTol = aSurfTool->Gap() + 0.1*Precision::Confusion(); |
693 | //Handle(BRep_PointOnSurface) aPS = new BRep_PointOnSurface(aP2d.X(),aP2d.Y(),toSurf,toLoc); |
694 | //alistrep.Append(aPS); |
695 | } |
696 | |
697 | BRep_Builder aB; |
698 | aB.UpdateVertex(anewV,apar1,apar2,toFace,aTol); |
699 | return anewV; |
700 | } |
701 | |