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