7fd59977 |
1 | //#4 szv S4163: optimizing |
2 | // pdn 20.04.99 S4181 Moving algorithm for transforming pcurves from IGES processor |
3 | // abv 05.05.99 S4137: adding methods for copying ranges, reassigning pcurves etc. |
4 | #include <ShapeBuild_Edge.ixx> |
5 | #include <Standard_ErrorHandler.hxx> |
6 | #include <Standard_Failure.hxx> |
7 | |
8 | #include <TopoDS.hxx> |
9 | #include <TopoDS_Iterator.hxx> |
10 | #include <TopExp.hxx> |
11 | #include <BRep_Builder.hxx> |
12 | #include <BRep_Tool.hxx> |
13 | #include <BRep_TEdge.hxx> |
14 | #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx> |
15 | #include <BRep_GCurve.hxx> |
16 | #include <BRepLib.hxx> |
17 | #include <BRepBuilderAPI_MakeEdge.hxx> |
18 | |
19 | #include <gp_Pnt.hxx> |
20 | #include <gp_Lin2d.hxx> |
21 | #include <gp_GTrsf2d.hxx> |
22 | #include <gp_Pln.hxx> |
23 | #include <ElCLib.hxx> |
24 | #include <Precision.hxx> |
25 | |
26 | #include <Geom2d_TrimmedCurve.hxx> |
27 | #include <Geom2d_Line.hxx> |
28 | #include <Geom2d_BSplineCurve.hxx> |
29 | #include <Geom2d_Conic.hxx> |
30 | #include <Geom2dConvert.hxx> |
31 | #include <Geom2dConvert_ApproxCurve.hxx> |
32 | #include <GeomAPI.hxx> |
33 | #include <Geom2d_BezierCurve.hxx> |
34 | #include <Geom2d_TrimmedCurve.hxx> |
35 | #include <BRep_Curve3D.hxx> |
36 | #include <BRep_CurveOnSurface.hxx> |
37 | #include <Geom2d_OffsetCurve.hxx> |
38 | #include <Geom_TrimmedCurve.hxx> |
39 | #include <Geom_OffsetCurve.hxx> |
40 | #include <TopTools_SequenceOfShape.hxx> |
41 | |
42 | //======================================================================= |
43 | //function : CopyReplaceVertices |
44 | //purpose : |
45 | //======================================================================= |
46 | |
47 | TopoDS_Edge ShapeBuild_Edge::CopyReplaceVertices (const TopoDS_Edge& edge, |
48 | const TopoDS_Vertex& V1, |
49 | const TopoDS_Vertex& V2) const |
50 | { |
51 | TopTools_SequenceOfShape aNMVertices; |
52 | TopoDS_Vertex newV1 = V1, newV2 = V2; |
53 | if ( newV1.IsNull() || newV2.IsNull() ) { |
54 | for ( TopoDS_Iterator it(edge); it.More(); it.Next() ) { |
55 | TopoDS_Vertex V = TopoDS::Vertex ( it.Value() ); |
56 | if ( V.Orientation() == TopAbs_FORWARD ) { |
57 | if ( newV1.IsNull() ) newV1 = V; |
58 | } |
59 | else if ( V.Orientation() == TopAbs_REVERSED ) { |
60 | if ( newV2.IsNull() ) newV2 = V; |
61 | } |
62 | else if(V1.IsNull() && V2.IsNull()) |
63 | aNMVertices.Append(V); |
64 | } |
65 | } |
66 | newV1.Orientation ( TopAbs_FORWARD ); |
67 | newV2.Orientation ( TopAbs_REVERSED ); |
68 | |
69 | //szv#4:S4163:12Mar99 SGI warns |
70 | TopoDS_Shape sh = edge.EmptyCopied(); |
71 | TopoDS_Edge E = TopoDS::Edge( sh ); |
72 | |
73 | BRep_Builder B; |
74 | if ( ! newV1.IsNull() ) B.Add ( E, newV1 ); |
75 | if ( ! newV2.IsNull() ) B.Add ( E, newV2 ); |
76 | |
77 | //addition of the internal or external vertices to edge |
78 | Standard_Integer i =1; |
79 | for( ; i <= aNMVertices.Length(); i++) |
80 | B.Add ( E,TopoDS::Vertex(aNMVertices.Value(i))); |
81 | |
82 | //S4054, rln 17.11.98 annie_surf.igs entity D77, 3D and pcurve have different |
83 | //ranges, after B.Range all the ranges become as 3D |
84 | CopyRanges ( E, edge ); |
85 | /* |
86 | for (BRep_ListIteratorOfListOfCurveRepresentation itcr |
87 | ((*((Handle(BRep_TEdge)*)&edge.TShape()))->ChangeCurves()); itcr.More(); itcr.Next()) { |
88 | Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value()); |
89 | if ( GC.IsNull() ) continue; |
90 | Standard_Real first, last; |
91 | GC->Range ( first, last ); |
92 | if ( GC->IsCurve3D() ) |
93 | B.Range ( E, first, last ); |
94 | else if ( GC->IsCurveOnSurface() ) |
95 | B.Range (E, GC->Surface(), edge.Location().Multiplied (GC->Location()), first, last);//BUC50003 entity 132 edge 1 |
96 | } |
97 | */ |
98 | return E; |
99 | } |
100 | |
101 | //======================================================================= |
102 | //function : CopyRanges |
103 | //purpose : |
104 | //======================================================================= |
105 | |
106 | // Added, cause invoke ShapeAnalysis leads to cyclic dependancy. |
107 | static Standard_Real AdjustByPeriod(const Standard_Real Val, |
108 | const Standard_Real ToVal, |
109 | const Standard_Real Period) |
110 | { |
111 | Standard_Real diff = Val - ToVal; |
112 | Standard_Real D = Abs ( diff ); |
113 | Standard_Real P = Abs ( Period ); |
114 | if ( D <= 0.5 * P ) return 0.; |
115 | if ( P < 1e-100 ) return diff; |
116 | return ( diff >0 ? -P : P ) * (Standard_Integer)( D / P + 0.5 ); |
117 | } |
118 | |
119 | static Standard_Boolean IsPeriodic(const Handle(Geom_Curve)& theCurve) |
120 | { |
121 | // 15.11.2002 PTV OCC966 |
122 | // remove regressions in DE tests (diva, divb, divc, toe3) in KAS:dev |
123 | // ask IsPeriodic on BasisCurve |
124 | Handle(Geom_Curve) aTmpCurve = theCurve; |
125 | while ( (aTmpCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve))) || |
126 | (aTmpCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) ) { |
127 | if (aTmpCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve))) |
128 | aTmpCurve = Handle(Geom_OffsetCurve)::DownCast(aTmpCurve)->BasisCurve(); |
129 | if (aTmpCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) |
130 | aTmpCurve = Handle(Geom_TrimmedCurve)::DownCast(aTmpCurve)->BasisCurve(); |
131 | } |
132 | return aTmpCurve->IsPeriodic(); |
133 | } |
134 | |
135 | Standard_Boolean IsPeriodic(const Handle(Geom2d_Curve)& theCurve) |
136 | { |
137 | // 15.11.2002 PTV OCC966 |
138 | // remove regressions in DE tests (diva, divb, divc, toe3) in KAS:dev |
139 | // ask IsPeriodic on BasisCurve |
140 | Handle(Geom2d_Curve) aTmpCurve = theCurve; |
141 | while ( (aTmpCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))) || |
142 | (aTmpCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) ) { |
143 | if (aTmpCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))) |
144 | aTmpCurve = Handle(Geom2d_OffsetCurve)::DownCast(aTmpCurve)->BasisCurve(); |
145 | if (aTmpCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) |
146 | aTmpCurve = Handle(Geom2d_TrimmedCurve)::DownCast(aTmpCurve)->BasisCurve(); |
147 | } |
148 | return aTmpCurve->IsPeriodic(); |
149 | } |
150 | |
151 | void ShapeBuild_Edge::CopyRanges (const TopoDS_Edge& toedge, |
152 | const TopoDS_Edge& fromedge, |
153 | const Standard_Real alpha, |
154 | const Standard_Real beta) const |
155 | { |
156 | /* BRep_Builder B; |
157 | for (BRep_ListIteratorOfListOfCurveRepresentation itcr |
158 | ((*((Handle(BRep_TEdge)*)&fromedge.TShape()))->ChangeCurves()); itcr.More(); itcr.Next()) { |
159 | Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value()); |
160 | if ( GC.IsNull() ) continue; |
161 | Standard_Real first, last; |
162 | GC->Range ( first, last ); |
163 | if ( GC->IsCurve3D() ) |
164 | B.Range ( toedge, first, last ); |
165 | else if ( GC->IsCurveOnSurface() ) |
166 | B.Range ( toedge, GC->Surface(), fromedge.Location().Multiplied (GC->Location()), first, last); |
167 | } |
168 | */ |
169 | for (BRep_ListIteratorOfListOfCurveRepresentation fromitcr |
170 | ((*((Handle(BRep_TEdge)*)&fromedge.TShape()))->ChangeCurves()); fromitcr.More(); fromitcr.Next()) { |
171 | Handle(BRep_GCurve) fromGC = Handle(BRep_GCurve)::DownCast(fromitcr.Value()); |
172 | if ( fromGC.IsNull() ) continue; |
173 | Standard_Boolean isC3d = fromGC->IsCurve3D(); |
174 | if(isC3d) { |
175 | if(fromGC->Curve3D().IsNull()) continue; } |
176 | else { |
177 | if(fromGC->PCurve().IsNull()) continue; } |
178 | |
179 | if ( ! isC3d && ! fromGC->IsCurveOnSurface()) continue; // only 3d curves and pcurves are treated |
180 | |
181 | Handle(Geom_Surface) surface; |
182 | TopLoc_Location L; |
183 | if ( ! isC3d ) { |
184 | surface = fromGC->Surface(); |
185 | L = fromGC->Location(); |
186 | } |
187 | |
188 | BRep_ListOfCurveRepresentation& tolist = (*((Handle(BRep_TEdge)*)&toedge.TShape()))->ChangeCurves(); |
189 | Handle(BRep_GCurve) toGC; |
190 | for (BRep_ListIteratorOfListOfCurveRepresentation toitcr (tolist); toitcr.More(); toitcr.Next()) { |
191 | toGC = Handle(BRep_GCurve)::DownCast(toitcr.Value()); |
192 | if ( toGC.IsNull() ) continue; |
193 | if ( isC3d ) { |
194 | if ( ! toGC->IsCurve3D() ) continue; |
195 | } |
196 | else if ( ! toGC->IsCurveOnSurface() || |
197 | surface != toGC->Surface() || L != toGC->Location() ) continue; |
198 | Standard_Real first = fromGC->First(); |
199 | Standard_Real last = fromGC->Last(); |
200 | Standard_Real len = last - first; |
201 | Standard_Real newF = first+alpha*len; |
202 | Standard_Real newL = first+beta*len; |
203 | |
204 | // PTV: 22.03.2002 fix for edge range. |
205 | // file test-m020306-v2.step Shell #665 (Faces #40110. #40239). |
206 | Standard_Real aPeriod=1., aCrvF=0., aCrvL=1.; |
207 | Standard_Boolean doCheck = Standard_False; |
208 | if (toGC->IsKind(STANDARD_TYPE(BRep_Curve3D))) { |
209 | Handle(Geom_Curve) aCrv3d = Handle(BRep_Curve3D)::DownCast(toGC)->Curve3D(); |
210 | // 15.11.2002 PTV OCC966 |
211 | if ( ! aCrv3d.IsNull() && IsPeriodic(aCrv3d) ) { |
212 | aPeriod = aCrv3d->Period(); |
213 | aCrvF = aCrv3d->FirstParameter(); |
214 | aCrvL = aCrv3d->LastParameter(); |
215 | doCheck = Standard_True; |
216 | } |
217 | } |
218 | else if (toGC->IsKind(STANDARD_TYPE(BRep_CurveOnSurface))) { |
219 | Handle(Geom2d_Curve) aCrv2d = Handle(BRep_CurveOnSurface)::DownCast(toGC)->PCurve(); |
220 | // 15.11.2002 PTV OCC966 |
221 | if (!aCrv2d.IsNull() && IsPeriodic(aCrv2d)) { |
222 | aPeriod = aCrv2d->Period(); |
223 | aCrvF = aCrv2d->FirstParameter(); |
224 | aCrvL = aCrv2d->LastParameter(); |
225 | doCheck = Standard_True; |
226 | } |
227 | } |
228 | if ( doCheck && ( (fabs(newF -aCrvF ) > Precision::PConfusion() && newF < aCrvF) || newF >= aCrvL ) ) { |
229 | Standard_Real aShift = AdjustByPeriod(newF, 0.5*(aCrvF+aCrvL), aPeriod); |
230 | newF += aShift; |
231 | newL += aShift; |
232 | BRep_Builder().SameRange(toedge,Standard_False); |
233 | BRep_Builder().SameParameter(toedge,Standard_False); |
234 | } |
235 | |
236 | toGC->SetRange ( newF, newL ); |
237 | break; |
238 | } |
239 | } |
240 | } |
241 | |
242 | //======================================================================= |
243 | //function : SetRange3d |
244 | //purpose : |
245 | //======================================================================= |
246 | |
247 | void ShapeBuild_Edge::SetRange3d (const TopoDS_Edge& edge, |
248 | const Standard_Real first, |
249 | const Standard_Real last) const |
250 | { |
251 | |
252 | for (BRep_ListIteratorOfListOfCurveRepresentation itcr |
253 | ((*((Handle(BRep_TEdge)*)&edge.TShape()))->ChangeCurves()); itcr.More(); itcr.Next()) { |
254 | Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value()); |
255 | if ( GC.IsNull() || !GC->IsCurve3D() ) continue; |
256 | GC->SetRange ( first, last ); |
257 | break; |
258 | } |
259 | } |
260 | |
261 | //======================================================================= |
262 | //function : CopyPCurves |
263 | //purpose : |
264 | //======================================================================= |
265 | |
266 | void ShapeBuild_Edge::CopyPCurves (const TopoDS_Edge& toedge, const TopoDS_Edge& fromedge) const |
267 | { |
268 | TopLoc_Location fromLoc = fromedge.Location(); |
269 | TopLoc_Location toLoc = toedge.Location(); |
270 | for (BRep_ListIteratorOfListOfCurveRepresentation fromitcr |
271 | ((*((Handle(BRep_TEdge)*)&fromedge.TShape()))->ChangeCurves()); fromitcr.More(); fromitcr.Next()) { |
272 | Handle(BRep_GCurve) fromGC = Handle(BRep_GCurve)::DownCast(fromitcr.Value()); |
273 | if ( fromGC.IsNull() ) continue; |
274 | if ( fromGC->IsCurveOnSurface() ) { |
275 | Handle(Geom_Surface) surface = fromGC->Surface(); |
276 | TopLoc_Location L = fromGC->Location(); |
277 | Standard_Boolean found = Standard_False; |
278 | BRep_ListOfCurveRepresentation& tolist = (*((Handle(BRep_TEdge)*)&toedge.TShape()))->ChangeCurves(); |
279 | Handle(BRep_GCurve) toGC; |
280 | for (BRep_ListIteratorOfListOfCurveRepresentation toitcr (tolist); toitcr.More() && !found; toitcr.Next()) { |
281 | toGC = Handle(BRep_GCurve)::DownCast(toitcr.Value()); |
282 | if ( toGC.IsNull() || !toGC->IsCurveOnSurface() || |
283 | surface != toGC->Surface() || L != toGC->Location() ) continue; |
284 | found = Standard_True; |
285 | break; |
286 | } |
287 | if (!found) { |
288 | toGC = Handle(BRep_GCurve)::DownCast(fromGC->Copy()); |
289 | tolist.Append (toGC); |
290 | } |
291 | Handle(Geom2d_Curve) pcurve = fromGC->PCurve(); |
292 | toGC->PCurve(Handle(Geom2d_Curve)::DownCast(pcurve->Copy())); |
293 | |
294 | //bug OCC209 invalid location of pcurve in the edge after copying |
295 | TopLoc_Location newLoc = (fromLoc*L).Predivided(toLoc);//(L * fromLoc).Predivided(toLoc); |
296 | toGC->Location(newLoc); |
297 | if ( fromGC->IsCurveOnClosedSurface() ) { |
298 | pcurve = fromGC->PCurve2(); |
299 | toGC->PCurve2(Handle(Geom2d_Curve)::DownCast(pcurve->Copy())); |
300 | } |
301 | } |
302 | } |
303 | } |
304 | //======================================================================= |
305 | //function : Copy |
306 | //purpose : |
307 | //======================================================================= |
308 | |
309 | TopoDS_Edge ShapeBuild_Edge::Copy (const TopoDS_Edge &edge, |
310 | const Standard_Boolean sharepcurves) const |
311 | { |
312 | TopoDS_Vertex dummy1, dummy2; |
313 | TopoDS_Edge newedge = CopyReplaceVertices ( edge, dummy1, dummy2 ); |
314 | if ( ! sharepcurves ) CopyPCurves ( newedge, edge ); |
315 | return newedge; |
316 | } |
317 | |
318 | //======================================================================= |
319 | //function : RemovePCurve |
320 | //purpose : |
321 | //======================================================================= |
322 | |
323 | void ShapeBuild_Edge::RemovePCurve (const TopoDS_Edge& edge, |
324 | const TopoDS_Face& face) const |
325 | { |
326 | BRep_Builder B; |
327 | Handle(Geom2d_Curve) c2dNull; |
328 | //:S4136 Standard_Real tol = BRep_Tool::Tolerance ( edge ); |
329 | if ( BRep_Tool::IsClosed ( edge, face ) ) |
330 | B.UpdateEdge ( edge, c2dNull, c2dNull, face, 0. ); //:S4136: tol |
331 | else B.UpdateEdge ( edge, c2dNull, face, 0. ); //:S4136: tol |
332 | } |
333 | |
334 | //======================================================================= |
335 | //function : RemovePCurve |
336 | //purpose : |
337 | //======================================================================= |
338 | |
339 | void ShapeBuild_Edge::RemovePCurve (const TopoDS_Edge& edge, |
340 | const Handle(Geom_Surface)& surf) const |
341 | { |
342 | RemovePCurve ( edge, surf, TopLoc_Location() ); |
343 | } |
344 | |
345 | //======================================================================= |
346 | //function : RemovePCurve |
347 | //purpose : |
348 | //======================================================================= |
349 | |
350 | void ShapeBuild_Edge::RemovePCurve (const TopoDS_Edge& edge, |
351 | const Handle(Geom_Surface)& surf, |
352 | const TopLoc_Location &loc) const |
353 | { |
354 | BRep_Builder B; |
355 | Handle(Geom2d_Curve) c2dNull; |
356 | //:S4136 Standard_Real tol = BRep_Tool::Tolerance ( edge ); |
357 | if ( BRep_Tool::IsClosed ( edge, surf, loc ) ) |
358 | B.UpdateEdge ( edge, c2dNull, c2dNull, surf, loc, 0. ); //:S4136: tol |
359 | else B.UpdateEdge ( edge, c2dNull, surf, loc, 0. ); //:S4136: tol |
360 | } |
361 | |
362 | //======================================================================= |
363 | //function : ReplacePCurve |
364 | //purpose : |
365 | //======================================================================= |
366 | |
367 | void ShapeBuild_Edge::ReplacePCurve (const TopoDS_Edge& edge, |
368 | const Handle(Geom2d_Curve)& pcurve, |
369 | const TopoDS_Face& face) const |
370 | { |
371 | BRep_Builder B; |
372 | Standard_Real f,l; |
373 | TopoDS_Shape dummy = edge.Reversed(); |
374 | TopoDS_Edge edgerev = TopoDS::Edge(dummy); |
375 | // reverse face to take second pcurve for seams like SA_Edge::PCurve() does |
376 | TopoDS_Face F = TopoDS::Face(face.Oriented ( TopAbs_FORWARD ) ); |
377 | Handle(Geom2d_Curve) pcurve0 = BRep_Tool::CurveOnSurface(edge,F,f,l); |
378 | Handle(Geom2d_Curve) c2d = BRep_Tool::CurveOnSurface(edgerev,F,f,l); |
379 | // Add pcurve to edge (either as single, or as seam) |
380 | if ( c2d.IsNull() || c2d == pcurve0 ) { // non-seam |
381 | B.UpdateEdge(edge,pcurve,face,0); |
382 | } |
383 | else { // seam |
384 | if(edge.Orientation()==TopAbs_FORWARD) |
385 | B.UpdateEdge(edge,pcurve,c2d,face,0); |
386 | else |
387 | B.UpdateEdge(edge,c2d,pcurve,face,0); |
388 | } |
389 | B.Range ( edge, face, f, l ); |
390 | } |
391 | |
392 | //======================================================================= |
393 | //function : ReassignPCurve |
394 | //purpose : |
395 | //======================================================================= |
396 | |
397 | // Count exact number of pcurves STORED in edge for face |
398 | // This makes difference for faces based on plane surfaces where pcurves can be |
399 | // not stored but returned by BRep_Tools::CurveOnSurface |
400 | static Standard_Integer CountPCurves (const TopoDS_Edge &edge, |
401 | const TopoDS_Face &face) |
402 | { |
403 | TopLoc_Location L; |
404 | Handle(Geom_Surface) S = BRep_Tool::Surface ( face, L ); |
405 | TopLoc_Location l = L.Predivided(edge.Location()); |
406 | |
407 | for (BRep_ListIteratorOfListOfCurveRepresentation itcr |
408 | ((*((Handle(BRep_TEdge)*)&edge.TShape()))->ChangeCurves()); itcr.More(); itcr.Next()) { |
409 | Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value()); |
410 | if ( ! GC.IsNull() && GC->IsCurveOnSurface ( S, l ) ) |
411 | return ( GC->IsCurveOnClosedSurface() ? 2 : 1 ); |
412 | } |
413 | return 0; |
414 | } |
415 | |
416 | Standard_Boolean ShapeBuild_Edge::ReassignPCurve (const TopoDS_Edge& edge, |
417 | const TopoDS_Face& old, |
418 | const TopoDS_Face& sub) const |
419 | { |
420 | Standard_Integer npcurves = CountPCurves ( edge, old ); |
421 | //if ( npcurves <1 ) return Standard_False; //gka |
422 | |
423 | Standard_Real f, l; |
424 | Handle(Geom2d_Curve) pc; |
425 | pc = BRep_Tool::CurveOnSurface ( edge, old, f, l ); |
426 | if ( pc.IsNull() ) return Standard_False; |
427 | else if( npcurves == 0) npcurves =1; //gka |
428 | |
429 | |
430 | BRep_Builder B; |
431 | |
432 | // if the pcurve was only one, remove; else leave second one |
433 | if ( npcurves >1 ) { |
434 | //smh#8 Porting AIX |
435 | TopoDS_Shape tmpshape = edge.Reversed(); |
436 | TopoDS_Edge erev = TopoDS::Edge (tmpshape); |
437 | Handle(Geom2d_Curve) pc2 = BRep_Tool::CurveOnSurface ( erev, old, f, l ); |
438 | B.UpdateEdge ( edge, pc2, old, 0. ); |
439 | B.Range ( edge, old, f, l ); |
440 | } |
441 | else RemovePCurve ( edge, old ); |
442 | |
443 | // if edge does not have yet pcurves on sub, just add; else add as first |
444 | Standard_Integer npcs = CountPCurves ( edge, sub ); |
445 | if ( npcs <1 ) B.UpdateEdge ( edge, pc, sub, 0. ); |
446 | else { |
447 | //smh#8 Porting AIX |
448 | TopoDS_Shape tmpshape = edge.Reversed(); |
449 | TopoDS_Edge erev = TopoDS::Edge (tmpshape); |
450 | Standard_Real cf, cl; |
451 | Handle(Geom2d_Curve) pcs = BRep_Tool::CurveOnSurface ( erev, sub, cf, cl ); |
452 | if ( edge.Orientation() == TopAbs_REVERSED ) // because B.UpdateEdge does not check edge orientation |
453 | B.UpdateEdge ( edge, pcs, pc, sub, 0. ); |
454 | else B.UpdateEdge ( edge, pc, pcs, sub, 0. ); |
455 | } |
456 | |
457 | B.Range ( edge, sub, f, l ); |
458 | |
459 | return Standard_True; |
460 | } |
461 | |
462 | //======================================================================= |
463 | //function : TransformPCurve |
464 | //purpose : |
465 | //======================================================================= |
466 | |
467 | Handle(Geom2d_Curve) ShapeBuild_Edge::TransformPCurve(const Handle(Geom2d_Curve)& pcurve, |
468 | const gp_Trsf2d& trans, |
469 | const Standard_Real uFact, |
470 | Standard_Real& aFirst, |
471 | Standard_Real& aLast) const |
472 | { |
473 | Handle(Geom2d_Curve) result = Handle(Geom2d_Curve)::DownCast(pcurve->Copy()); |
474 | if(trans.Form()!=gp_Identity) { |
475 | result->Transform (trans); |
476 | aFirst = result->TransformedParameter(aFirst,trans); |
477 | aLast = result->TransformedParameter(aLast, trans); |
478 | } |
479 | if(uFact==1.) |
480 | return result; |
481 | |
482 | if (result->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) { |
483 | Handle(Geom2d_TrimmedCurve) thecurve = Handle(Geom2d_TrimmedCurve)::DownCast(result); |
484 | result = thecurve->BasisCurve(); |
485 | } |
486 | |
487 | gp_GTrsf2d tMatu; |
488 | tMatu.SetAffinity(gp::OY2d(), uFact); |
489 | gp_XY pXY; |
490 | |
491 | if (result->IsKind(STANDARD_TYPE(Geom2d_Line))) { |
492 | Handle(Geom2d_Line) aLine2d = Handle(Geom2d_Line)::DownCast(result); |
493 | gp_Pnt2d Pf, Pl; |
494 | aLine2d->D0(aFirst,Pf); |
495 | pXY = Pf.XY(); |
496 | tMatu.Transforms(pXY); |
497 | Pf.SetXY(pXY); |
498 | aLine2d->D0(aLast, Pl); |
499 | pXY = Pl.XY(); |
500 | tMatu.Transforms(pXY); |
501 | Pl.SetXY(pXY); |
502 | gp_Lin2d line2d(Pf, gp_Dir2d(gp_Vec2d(Pf,Pl))); |
503 | aFirst = ElCLib::Parameter(line2d, Pf); |
504 | aLast = ElCLib::Parameter(line2d, Pl); |
505 | Handle(Geom2d_Line) Gline2d = new Geom2d_Line(line2d); |
506 | return Gline2d; |
507 | } |
508 | else if(result->IsKind(STANDARD_TYPE(Geom2d_BezierCurve))) { |
509 | Handle(Geom2d_BezierCurve) bezier = Handle(Geom2d_BezierCurve)::DownCast(result); |
510 | // transform the Poles of the BSplineCurve |
511 | Standard_Integer nbPol = bezier->NbPoles(); |
512 | gp_Pnt2d Pt1; |
513 | for (Standard_Integer i = 1; i<=nbPol ; i++) { |
514 | pXY = bezier->Pole(i).XY(); |
515 | tMatu.Transforms(pXY); |
516 | Pt1.SetXY(pXY); |
517 | bezier->SetPole(i, Pt1); |
518 | } |
519 | return bezier; |
520 | } else { |
521 | Handle(Geom2d_BSplineCurve) aBSpline2d; |
522 | if(result->IsKind(STANDARD_TYPE(Geom2d_Conic))) { |
523 | //gp_Pln pln(gp_Pnt(0,0,0),gp_Dir(0,0,1)); |
524 | //Handle(Geom_Curve) curve = GeomAPI::To3d(result,pln); |
525 | Handle(Geom2d_TrimmedCurve) tcurve = new Geom2d_TrimmedCurve(result,aFirst,aLast); //protection agains parabols ets |
526 | Geom2dConvert_ApproxCurve approx (tcurve, Precision::Approximation(), |
527 | GeomAbs_C1, 100, 6 ); |
528 | if ( approx.HasResult() ) |
529 | aBSpline2d = Handle(Geom2d_BSplineCurve)::DownCast(approx.Curve()); |
530 | else |
531 | aBSpline2d = Geom2dConvert::CurveToBSplineCurve(tcurve,Convert_QuasiAngular); |
532 | aFirst = aBSpline2d->FirstParameter(); |
533 | aLast = aBSpline2d->LastParameter(); |
534 | } |
535 | else if(!result->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) { |
536 | aBSpline2d = Geom2dConvert::CurveToBSplineCurve(result,Convert_QuasiAngular); |
537 | } |
538 | else |
539 | aBSpline2d = Handle(Geom2d_BSplineCurve)::DownCast(result); |
540 | |
541 | // transform the Poles of the BSplineCurve |
542 | Standard_Integer nbPol = aBSpline2d->NbPoles(); |
543 | gp_Pnt2d Pt1; |
544 | for (Standard_Integer i = 1; i<=nbPol ; i++) { |
545 | pXY = aBSpline2d->Pole(i).XY(); |
546 | tMatu.Transforms(pXY); |
547 | Pt1.SetXY(pXY); |
548 | aBSpline2d->SetPole(i, Pt1); |
549 | } |
550 | return aBSpline2d; |
551 | } |
552 | return result; |
553 | } |
554 | |
555 | //======================================================================= |
556 | //function : RemoveCurve3d |
557 | //purpose : |
558 | //======================================================================= |
559 | |
560 | void ShapeBuild_Edge::RemoveCurve3d (const TopoDS_Edge& edge) const |
561 | { |
562 | BRep_Builder B; |
563 | Handle(Geom_Curve) c3dNull; |
564 | //:S4136 Standard_Real tol = BRep_Tool::Tolerance (edge); |
565 | B.UpdateEdge (edge, c3dNull, 0. ); //:S4136: tol |
566 | } |
567 | |
568 | //======================================================================= |
569 | //function : BuildCurve3d |
570 | //purpose : |
571 | //======================================================================= |
572 | |
573 | Standard_Boolean ShapeBuild_Edge::BuildCurve3d (const TopoDS_Edge& edge) const |
574 | { |
575 | try { |
576 | OCC_CATCH_SIGNALS |
577 | //#48 rln 10.12.98 S4054 UKI60107-5 entity 365 |
578 | //C0 surface (but curve 3d is required as C1) and tolerance is 1e-07 |
579 | //lets use maximum of tolerance and default parameter 1.e-5 |
580 | //Another solutions: use quite big Tolerance or require C0 curve on C0 surface |
581 | if ( BRepLib::BuildCurve3d (edge, Max (1.e-5, BRep_Tool::Tolerance(edge) ) ) ) { |
582 | //#50 S4054 rln 14.12.98 write cylinder in BRep mode into IGES and read back |
583 | //with 2DUse_Forced - pcurve and removed 3D curves have different ranges |
584 | if (BRep_Tool::SameRange (edge)) { |
585 | Standard_Real first, last; |
586 | BRep_Tool::Range (edge, first, last); |
587 | BRep_Builder().Range (edge, first, last);//explicit setting for all reps |
588 | } |
589 | Handle(Geom_Curve) c3d; |
590 | Standard_Real f,l; |
591 | c3d = BRep_Tool::Curve(edge,f,l); |
592 | // 15.11.2002 PTV OCC966 |
593 | if(!IsPeriodic(c3d)) { |
594 | Standard_Boolean isLess = Standard_False; |
595 | if(f < c3d->FirstParameter()) { |
596 | isLess = Standard_True; |
597 | f = c3d->FirstParameter(); |
598 | } |
599 | if(l > c3d->LastParameter()) { |
600 | isLess = Standard_True; |
601 | l = c3d->LastParameter(); |
602 | } |
603 | if(isLess) { |
604 | SetRange3d(edge,f,l); |
605 | BRep_Builder().SameRange(edge,Standard_False); |
606 | } |
607 | } |
608 | |
609 | return Standard_True; |
610 | } |
611 | } |
612 | catch(Standard_Failure) { |
613 | #ifdef DEB |
614 | cout << "\nWarning: ShapeBuild_Edge: Exception in BuildCurve3d: "; |
615 | Standard_Failure::Caught()->Print(cout); cout << endl; |
616 | #endif |
617 | } |
618 | return Standard_False; |
619 | } |
620 | |
621 | |
622 | //======================================================================= |
623 | //function : MakeEdge |
624 | //purpose : |
625 | //======================================================================= |
626 | |
627 | void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom_Curve)& curve,const TopLoc_Location& L) const |
628 | { |
629 | MakeEdge (edge,curve, L, curve->FirstParameter(), curve->LastParameter()); |
630 | } |
631 | |
632 | //======================================================================= |
633 | //function : MakeEdge |
634 | //purpose : |
635 | //======================================================================= |
636 | |
637 | void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom_Curve)& curve,const TopLoc_Location& L,const Standard_Real p1,const Standard_Real p2) const |
638 | { |
639 | BRepBuilderAPI_MakeEdge ME (curve, p1, p2); |
640 | if (!ME.IsDone()) { |
641 | #ifdef DEB |
642 | cout << "\nWarning: ShapeBuild_Edge::MakeEdge BRepAPI_NotDone"; |
643 | #endif |
644 | return; |
645 | } |
646 | TopoDS_Edge E = ME.Edge(); |
647 | if (!L.IsIdentity()) { |
648 | BRep_Builder B; |
649 | B.UpdateEdge (E, curve, L, 0.); |
650 | B.Range (E, p1, p2); |
651 | |
652 | TopoDS_Vertex V1, V2; |
653 | TopExp::Vertices (E, V1, V2); |
654 | gp_Pnt P1 = BRep_Tool::Pnt (V1), P2 = BRep_Tool::Pnt (V2); |
655 | B.UpdateVertex (V1, P1.Transformed (L.Transformation()), 0.); |
656 | B.UpdateVertex (V2, P2.Transformed (L.Transformation()), 0.); |
657 | } |
658 | edge = E; |
659 | return; |
660 | } |
661 | |
662 | //======================================================================= |
663 | //function : MakeEdge |
664 | //purpose : |
665 | //======================================================================= |
666 | |
667 | void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom2d_Curve)& pcurve,const TopoDS_Face& face) const |
668 | { |
669 | MakeEdge (edge, pcurve, face, pcurve->FirstParameter(), pcurve->LastParameter()); |
670 | } |
671 | |
672 | //======================================================================= |
673 | //function : MakeEdge |
674 | //purpose : |
675 | //======================================================================= |
676 | |
677 | void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom2d_Curve)& pcurve,const TopoDS_Face& face,const Standard_Real p1,const Standard_Real p2) const |
678 | { |
679 | TopLoc_Location L; |
680 | const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L); |
681 | MakeEdge (edge, pcurve, S, L, p1, p2); |
682 | } |
683 | |
684 | //======================================================================= |
685 | //function : MakeEdge |
686 | //purpose : |
687 | //======================================================================= |
688 | |
689 | void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom2d_Curve)& pcurve, |
690 | const Handle(Geom_Surface)& S,const TopLoc_Location& L) const |
691 | { |
692 | MakeEdge(edge, pcurve, S, L, pcurve->FirstParameter(), pcurve->LastParameter()); |
693 | } |
694 | |
695 | //======================================================================= |
696 | //function : MakeEdge |
697 | //purpose : |
698 | //======================================================================= |
699 | |
700 | void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom2d_Curve)& pcurve, |
701 | const Handle(Geom_Surface)& S,const TopLoc_Location& L, |
702 | const Standard_Real p1,const Standard_Real p2) const |
703 | { |
704 | BRepBuilderAPI_MakeEdge ME (pcurve, S, p1, p2); |
705 | if (!ME.IsDone()) { |
706 | #ifdef DEB |
707 | cout << "\nWarning: ShapeBuild_Edge::MakeEdge BRepAPI_NotDone"; |
708 | #endif |
709 | return; |
710 | } |
711 | TopoDS_Edge E = ME.Edge(); |
712 | if (!L.IsIdentity()) { |
713 | RemovePCurve (E, S); |
714 | BRep_Builder B; |
715 | B.UpdateEdge (E, pcurve, S, L, 0.); |
716 | B.Range (E, S, L, p1, p2); |
717 | |
718 | TopoDS_Vertex V1, V2; |
719 | TopExp::Vertices (E, V1, V2); |
720 | gp_Pnt P1 = BRep_Tool::Pnt (V1), P2 = BRep_Tool::Pnt (V2); |
721 | B.UpdateVertex (V1, P1.Transformed (L.Transformation()), 0.); |
722 | B.UpdateVertex (V2, P2.Transformed (L.Transformation()), 0.); |
723 | } |
724 | edge = E; |
725 | return; |
726 | } |
727 | |