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