b311480e |
1 | // Created on: 1995-02-22 |
2 | // Created by: Jacques GOUSSARD |
3 | // Copyright (c) 1995-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
8 | // This library is free software; you can redistribute it and/or modify it under |
9 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
10 | // by the Free Software Foundation, with special exception defined in the file |
11 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
12 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
7fd59977 |
16 | |
7fd59977 |
17 | |
42cf5bc1 |
18 | #include <BRep_Builder.hxx> |
19 | #include <BRep_GCurve.hxx> |
20 | #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx> |
21 | #include <BRep_TEdge.hxx> |
22 | #include <BRep_Tool.hxx> |
23 | #include <BRepAdaptor_Curve.hxx> |
24 | #include <BRepAdaptor_Curve2d.hxx> |
7fd59977 |
25 | #include <BRepFill_DataMapIteratorOfDataMapOfShapeSequenceOfReal.hxx> |
42cf5bc1 |
26 | #include <BRepFill_DataMapOfShapeSequenceOfReal.hxx> |
27 | #include <BRepLib.hxx> |
28 | #include <BRepLib_MakeVertex.hxx> |
29 | #include <BRepOffsetAPI_DraftAngle.hxx> |
7fd59977 |
30 | #include <BRepOffsetAPI_SequenceOfSequenceOfReal.hxx> |
31 | #include <BRepOffsetAPI_SequenceOfSequenceOfShape.hxx> |
42cf5bc1 |
32 | #include <BRepTools.hxx> |
7fd59977 |
33 | #include <BRepTools_Substitution.hxx> |
42cf5bc1 |
34 | #include <Draft_Modification.hxx> |
35 | #include <Geom2d_Curve.hxx> |
36 | #include <Geom_Surface.hxx> |
37 | #include <gp_Dir.hxx> |
38 | #include <gp_Pln.hxx> |
39 | #include <Precision.hxx> |
40 | #include <Standard_ConstructionError.hxx> |
41 | #include <Standard_NoSuchObject.hxx> |
42 | #include <Standard_NullObject.hxx> |
43 | #include <StdFail_NotDone.hxx> |
44 | #include <TColgp_SequenceOfPnt.hxx> |
45 | #include <TColStd_SequenceOfReal.hxx> |
7fd59977 |
46 | #include <TopExp.hxx> |
42cf5bc1 |
47 | #include <TopExp_Explorer.hxx> |
48 | #include <TopLoc_Location.hxx> |
49 | #include <TopoDS.hxx> |
50 | #include <TopoDS_Face.hxx> |
51 | #include <TopoDS_Iterator.hxx> |
52 | #include <TopoDS_Shape.hxx> |
7fd59977 |
53 | #include <TopoDS_Wire.hxx> |
42cf5bc1 |
54 | #include <TopTools_DataMapOfShapeSequenceOfShape.hxx> |
55 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
56 | #include <TopTools_SequenceOfShape.hxx> |
7fd59977 |
57 | |
3b77eff6 |
58 | #include <Geom2dInt_GInter.hxx> |
59 | #include <IntRes2d_IntersectionPoint.hxx> |
60 | |
7fd59977 |
61 | //======================================================================= |
62 | //function : BRepOffsetAPI_DraftAngle |
63 | //purpose : |
64 | //======================================================================= |
7fd59977 |
65 | BRepOffsetAPI_DraftAngle::BRepOffsetAPI_DraftAngle () {} |
66 | |
67 | |
68 | //======================================================================= |
69 | //function : BRepOffsetAPI_DraftAngle |
70 | //purpose : |
71 | //======================================================================= |
72 | |
73 | BRepOffsetAPI_DraftAngle::BRepOffsetAPI_DraftAngle (const TopoDS_Shape& S) |
74 | { |
75 | myInitialShape = S; |
76 | myModification = new Draft_Modification(S); |
77 | } |
78 | |
79 | |
80 | //======================================================================= |
81 | //function : Clear |
82 | //purpose : |
83 | //======================================================================= |
84 | |
85 | void BRepOffsetAPI_DraftAngle::Clear () |
86 | { |
87 | if (!myModification.IsNull()) { |
c5f3a425 |
88 | Handle(Draft_Modification)::DownCast (myModification)->Clear(); |
7fd59977 |
89 | } |
90 | } |
91 | |
92 | |
93 | //======================================================================= |
94 | //function : Init |
95 | //purpose : |
96 | //======================================================================= |
97 | |
98 | void BRepOffsetAPI_DraftAngle::Init (const TopoDS_Shape& S) |
99 | { |
100 | myInitialShape = S; |
101 | NotDone(); |
102 | if (!myModification.IsNull()) { |
c5f3a425 |
103 | Handle(Draft_Modification)::DownCast (myModification)->Init(S); |
7fd59977 |
104 | } |
105 | else { |
106 | myModification = new Draft_Modification(S); |
107 | } |
108 | } |
109 | |
110 | |
111 | //======================================================================= |
112 | //function : Add |
113 | //purpose : |
114 | //======================================================================= |
115 | |
116 | void BRepOffsetAPI_DraftAngle::Add(const TopoDS_Face& F, |
117 | const gp_Dir& D, |
118 | const Standard_Real Angle, |
119 | const gp_Pln& Plane, |
120 | const Standard_Boolean Flag) |
121 | { |
122 | // POP-DPF : protection |
123 | if ( Abs(Angle) <= 1.e-04 ) |
124 | return; |
125 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
c5f3a425 |
126 | Handle(Draft_Modification)::DownCast (myModification)->Add(F,D,Angle,Plane, Flag); |
7fd59977 |
127 | } |
128 | |
129 | |
130 | //======================================================================= |
131 | //function : AddDone |
132 | //purpose : |
133 | //======================================================================= |
134 | |
135 | Standard_Boolean BRepOffsetAPI_DraftAngle::AddDone () const |
136 | { |
137 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
c5f3a425 |
138 | return Handle(Draft_Modification)::DownCast (myModification) |
7fd59977 |
139 | ->ProblematicShape().IsNull(); |
140 | } |
141 | |
142 | |
143 | //======================================================================= |
144 | //function : Remove |
145 | //purpose : |
146 | //======================================================================= |
147 | |
148 | void BRepOffsetAPI_DraftAngle::Remove(const TopoDS_Face& F) |
149 | { |
150 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
c5f3a425 |
151 | Handle(Draft_Modification)::DownCast (myModification)->Remove(F); |
7fd59977 |
152 | } |
153 | |
154 | |
155 | //======================================================================= |
156 | //function : ProblematicShape |
157 | //purpose : |
158 | //======================================================================= |
159 | |
160 | const TopoDS_Shape& BRepOffsetAPI_DraftAngle::ProblematicShape () const |
161 | { |
162 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
c5f3a425 |
163 | return Handle(Draft_Modification)::DownCast (myModification)->ProblematicShape(); |
7fd59977 |
164 | } |
165 | |
166 | |
167 | //======================================================================= |
168 | //function : ErrorStatus |
169 | //purpose : |
170 | //======================================================================= |
171 | |
172 | Draft_ErrorStatus BRepOffsetAPI_DraftAngle::Status () const |
173 | { |
174 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
c5f3a425 |
175 | return Handle(Draft_Modification)::DownCast (myModification)->Error(); |
7fd59977 |
176 | } |
177 | |
178 | |
179 | //======================================================================= |
180 | //function : ConnectedFaces |
181 | //purpose : |
182 | //======================================================================= |
183 | |
184 | const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::ConnectedFaces |
185 | (const TopoDS_Face& F) const |
186 | { |
187 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
c5f3a425 |
188 | return Handle(Draft_Modification)::DownCast (myModification)->ConnectedFaces(F); |
7fd59977 |
189 | } |
190 | |
191 | |
192 | //======================================================================= |
193 | //function : ModifiedFaces |
194 | //purpose : |
195 | //======================================================================= |
196 | |
197 | const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::ModifiedFaces() const |
198 | { |
199 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
c5f3a425 |
200 | return Handle(Draft_Modification)::DownCast (myModification)->ModifiedFaces(); |
7fd59977 |
201 | } |
202 | |
203 | //======================================================================= |
2651bfde |
204 | //function : Generated |
7fd59977 |
205 | //purpose : |
206 | //======================================================================= |
207 | |
208 | const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::Generated(const TopoDS_Shape& S) |
209 | { |
210 | myGenerated.Clear(); |
211 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
c5f3a425 |
212 | Handle(Draft_Modification) DMod = Handle(Draft_Modification)::DownCast (myModification); |
7fd59977 |
213 | |
214 | if (S.ShapeType() == TopAbs_FACE) { |
215 | Handle(Geom_Surface) Surf; |
216 | TopLoc_Location L; |
217 | Standard_Real Tol; |
218 | Standard_Boolean RW,RF; |
219 | if (DMod->NewSurface(TopoDS::Face(S), Surf, L, Tol, RW, RF)) { |
2651bfde |
220 | if(myVtxToReplace.IsEmpty()) |
221 | { |
222 | myGenerated.Append(ModifiedShape (S)); |
223 | } |
224 | else |
225 | { |
226 | myGenerated.Append(mySubs.Value(ModifiedShape (S))); |
227 | } |
7fd59977 |
228 | } |
229 | } |
230 | return myGenerated; |
231 | } |
232 | |
233 | //======================================================================= |
2651bfde |
234 | //function : Modified |
7fd59977 |
235 | //purpose : |
236 | //======================================================================= |
237 | |
238 | const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::Modified(const TopoDS_Shape& S) |
239 | { |
240 | myGenerated.Clear(); |
241 | Standard_NullObject_Raise_if(myInitialShape.IsNull(),""); |
c5f3a425 |
242 | Handle(Draft_Modification) DMod = Handle(Draft_Modification)::DownCast (myModification); |
7fd59977 |
243 | |
244 | if (S.ShapeType() == TopAbs_FACE) { |
245 | Handle(Geom_Surface) Surf; |
246 | TopLoc_Location L; |
247 | Standard_Real Tol; |
248 | Standard_Boolean RW,RF; |
249 | |
250 | if (!DMod->NewSurface(TopoDS::Face(S), Surf, L, Tol, RW, RF)) { |
251 | // Ce n est pas une generation => peut etre une modif |
2651bfde |
252 | if(myVtxToReplace.IsEmpty()) |
253 | { |
254 | myGenerated.Append(ModifiedShape (S)); |
255 | } |
256 | else |
257 | { |
258 | myGenerated.Append(mySubs.Value(ModifiedShape (S))); |
259 | } |
7fd59977 |
260 | if (myGenerated.Extent() == 1 && myGenerated.First().IsSame(S)) { |
2651bfde |
261 | myGenerated.Clear(); |
7fd59977 |
262 | } |
263 | } |
264 | } |
265 | return myGenerated; |
266 | } |
267 | |
345d3056 |
268 | //======================================================================= |
269 | //function : ModifiedShape |
270 | //purpose : |
271 | //======================================================================= |
272 | |
273 | TopoDS_Shape BRepOffsetAPI_DraftAngle::ModifiedShape |
274 | (const TopoDS_Shape& S) const |
275 | { |
276 | if(S.ShapeType() == TopAbs_VERTEX) |
277 | { |
278 | if(myVtxToReplace.IsBound(S)) |
279 | { |
280 | return myVtxToReplace(S); |
281 | } |
282 | } |
2651bfde |
283 | if(myVtxToReplace.IsEmpty()) |
284 | { |
285 | return myModifier.ModifiedShape(S); |
286 | } |
287 | else |
288 | { |
289 | const TopoDS_Shape& aNS = myModifier.ModifiedShape(S); |
290 | return mySubs.Value(aNS); |
291 | } |
345d3056 |
292 | } |
7fd59977 |
293 | |
294 | //======================================================================= |
295 | //function : Build |
296 | //purpose : |
297 | //======================================================================= |
298 | |
299 | void BRepOffsetAPI_DraftAngle::Build() |
300 | { |
c5f3a425 |
301 | Handle(Draft_Modification)::DownCast (myModification)->Perform(); |
302 | if (!Handle(Draft_Modification)::DownCast (myModification)->IsDone()) { |
7fd59977 |
303 | NotDone(); |
304 | } |
305 | else { |
306 | DoModif(myInitialShape); |
7fd59977 |
307 | CorrectWires(); |
345d3056 |
308 | CorrectVertexTol(); |
7fd59977 |
309 | } |
310 | } |
311 | |
312 | //======================================================================= |
313 | //function : CorrectWires |
314 | //purpose : |
315 | //======================================================================= |
316 | |
317 | void BRepOffsetAPI_DraftAngle::CorrectWires() |
318 | { |
319 | Standard_Real TolInter = 1.e-7; |
320 | Standard_Integer i, j, k; |
321 | |
322 | TopTools_SequenceOfShape Eseq; |
323 | TopTools_SequenceOfShape Wseq; |
324 | TopTools_SequenceOfShape Fseq; |
325 | TopoDS_Shape CurEdge, CurWire, CurFace; |
326 | TopoDS_Iterator wit, eit; |
327 | |
328 | TopExp_Explorer fexp( myShape, TopAbs_FACE ); |
329 | for (; fexp.More(); fexp.Next()) |
345d3056 |
330 | { |
331 | CurFace = fexp.Current(); |
332 | wit.Initialize( CurFace ); |
333 | for (; wit.More(); wit.Next()) |
7fd59977 |
334 | { |
345d3056 |
335 | CurWire = wit.Value(); |
336 | TopTools_MapOfShape emap; |
337 | eit.Initialize( CurWire ); |
338 | for (; eit.More(); eit.Next()) |
339 | emap.Add( eit.Value() ); |
340 | TopTools_MapIteratorOfMapOfShape mapit( emap ); |
341 | for (; mapit.More(); mapit.Next()) |
342 | { |
343 | CurEdge = mapit.Key(); |
344 | if (BRepTools::IsReallyClosed( TopoDS::Edge(CurEdge), TopoDS::Face(CurFace) )) |
345 | { |
346 | Eseq.Append( CurEdge ); |
347 | Wseq.Append( CurWire ); |
348 | Fseq.Append( CurFace ); |
349 | } |
350 | } |
7fd59977 |
351 | } |
345d3056 |
352 | } |
7fd59977 |
353 | |
354 | BRepFill_DataMapOfShapeSequenceOfReal Emap; |
355 | |
356 | TopTools_SequenceOfShape NonSeam; |
357 | TopTools_SequenceOfShape NonSeamWires; |
358 | BRepOffsetAPI_SequenceOfSequenceOfReal ParsNonSeam; |
359 | BRepOffsetAPI_SequenceOfSequenceOfShape Seam; |
360 | BRepOffsetAPI_SequenceOfSequenceOfReal ParsSeam; |
361 | |
362 | TopTools_DataMapOfShapeShape WFmap; |
363 | TopTools_DataMapOfShapeListOfShape WWmap; |
364 | for (i = 1; i <= Eseq.Length(); i++) |
345d3056 |
365 | { |
366 | CurEdge = Eseq(i); |
367 | CurWire = Wseq(i); |
368 | CurFace = Fseq(i); |
3b77eff6 |
369 | // |
370 | const TopoDS_Face& aFace = TopoDS::Face(CurFace); |
371 | // |
372 | // Prepare 2D adaptors for intersection. |
373 | // The seam edge has two 2D curve, thus we have to create 2 adaptors |
374 | BRepAdaptor_Curve2d aBAC2D1(TopoDS::Edge(CurEdge), aFace); |
375 | BRepAdaptor_Curve2d aBAC2D1R(TopoDS::Edge(CurEdge.Reversed()), aFace); |
376 | // Get surface of the face to get 3D intersection point |
377 | TopLoc_Location aLoc; |
378 | const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(aFace, aLoc); |
379 | // Get the tolerance of the current edge to compare intersection points |
380 | Standard_Real aTolCurE = BRep_Tool::Tolerance(TopoDS::Edge(CurEdge)); |
381 | // |
345d3056 |
382 | wit.Initialize( CurFace ); |
383 | for (; wit.More(); wit.Next()) |
7fd59977 |
384 | { |
345d3056 |
385 | TopoDS_Shape aWire = wit.Value(); |
386 | if (! aWire.IsSame( CurWire )) |
387 | { |
388 | TColgp_SequenceOfPnt pts; |
345d3056 |
389 | Standard_Boolean Wadd = Standard_False; |
390 | eit.Initialize( aWire ); |
391 | for (; eit.More(); eit.Next()) |
392 | { |
3b77eff6 |
393 | const TopoDS_Edge& anEdge = TopoDS::Edge(eit.Value()); |
394 | // |
395 | // Prepare 2D adaptor for intersection |
396 | BRepAdaptor_Curve2d aBAC2D2(anEdge, aFace); |
397 | // Perform intersection |
398 | Geom2dInt_GInter aGInter; |
399 | aGInter.Perform(aBAC2D1, aBAC2D2, TolInter, TolInter); |
400 | if (!aGInter.IsDone() || aGInter.IsEmpty()) { |
401 | // If first intersection is empty try intersection with reversed edge |
402 | aGInter.Perform(aBAC2D1R, aBAC2D2, TolInter, TolInter); |
403 | if (!aGInter.IsDone() || aGInter.IsEmpty()) { |
345d3056 |
404 | continue; |
3b77eff6 |
405 | } |
345d3056 |
406 | } |
3b77eff6 |
407 | // |
345d3056 |
408 | Wadd = Standard_True; |
409 | if (! WFmap.IsBound( aWire )) |
410 | WFmap.Bind( aWire, CurFace ); |
411 | Standard_Integer ind = 0; |
3b77eff6 |
412 | for (j = 1; j <= NonSeam.Length(); j++) { |
413 | if (anEdge.IsSame(NonSeam(j))) |
345d3056 |
414 | { |
415 | ind = j; |
416 | break; |
417 | } |
3b77eff6 |
418 | } |
419 | if (ind == 0) |
420 | { |
421 | NonSeam.Append(anEdge); |
422 | NonSeamWires.Append(aWire); |
423 | ind = NonSeam.Length(); |
424 | TColStd_SequenceOfReal emptyseq1, emptyseq2; |
425 | TopTools_SequenceOfShape emptyedgeseq; |
426 | ParsNonSeam.Append(emptyseq1); |
427 | Seam.Append(emptyedgeseq); |
428 | ParsSeam.Append(emptyseq2); |
429 | } |
430 | if (!Emap.IsBound(CurEdge)) |
431 | { |
432 | TColStd_SequenceOfReal emptyseq; |
433 | Emap.Bind(CurEdge, emptyseq); |
434 | } |
435 | // |
436 | // Get the tolerance of edge to compare intersection points |
437 | Standard_Real aTolE = BRep_Tool::Tolerance(anEdge); |
438 | // Tolerance to compare the intersection points is the maximal |
439 | // tolerance of intersecting edges |
440 | Standard_Real aTolCmp = Max(aTolCurE, aTolE); |
441 | // |
442 | Standard_Integer k, aNbIntPnt = aGInter.NbPoints(); |
443 | for (k = 1; k <= aNbIntPnt; ++k) { |
444 | const IntRes2d_IntersectionPoint& aP2DInt = aGInter.Point(k); |
445 | const gp_Pnt2d& aP2D = aP2DInt.Value(); |
446 | gp_Pnt aP3D = aSurf->Value(aP2D.X(), aP2D.Y()); |
447 | // |
448 | // Check if the intersection point is new |
449 | Standard_Integer ied = 0; |
450 | for (j = 1; j <= pts.Length(); j++) { |
451 | if (aP3D.IsEqual(pts(j), aTolCmp)) |
452 | { |
453 | ied = j; |
454 | break; |
455 | } |
345d3056 |
456 | } |
3b77eff6 |
457 | if (ied == 0) |
345d3056 |
458 | { |
3b77eff6 |
459 | pts.Append(aP3D); |
460 | Emap(CurEdge).Append(aP2DInt.ParamOnFirst()); |
461 | ParsNonSeam(ind).Append(aP2DInt.ParamOnSecond()); |
462 | Seam(ind).Append(CurEdge); |
463 | ParsSeam(ind).Append(aP2DInt.ParamOnFirst()); |
345d3056 |
464 | } |
3b77eff6 |
465 | } |
345d3056 |
466 | } //for (; eit.More(); eit.Next()) |
467 | if (Wadd) |
468 | { |
469 | if (! WWmap.IsBound( CurWire )) |
470 | { |
471 | TopTools_ListOfShape emptylist; |
472 | WWmap.Bind( CurWire, emptylist ); |
473 | } |
474 | WWmap(CurWire).Append( aWire ); |
475 | } |
476 | } //if (! aWire.IsSame( CurWire )) |
477 | } //for (; wit.More(); wit.Next()) |
478 | } //for (i = 1; i <= Eseq.Length(); i++) |
7fd59977 |
479 | |
480 | //Sorting |
481 | for (i = 1; i <= NonSeam.Length(); i++) |
482 | for (j = 1; j < ParsNonSeam(i).Length(); j++) |
483 | for (k = j+1; k <= ParsNonSeam(i).Length(); k++) |
345d3056 |
484 | if (ParsNonSeam(i)(k) < ParsNonSeam(i)(j)) |
485 | { |
486 | Standard_Real temp = ParsNonSeam(i)(j); |
487 | ParsNonSeam(i)(j) = ParsNonSeam(i)(k); |
488 | ParsNonSeam(i)(k) = temp; |
489 | TopoDS_Shape tmp = Seam(i)(j); |
490 | Seam(i)(j) = Seam(i)(k); |
491 | Seam(i)(k) = tmp; |
492 | temp = ParsSeam(i)(j); |
493 | ParsSeam(i)(j) = ParsSeam(i)(k); |
494 | ParsSeam(i)(k) = temp; |
495 | } |
496 | BRepFill_DataMapIteratorOfDataMapOfShapeSequenceOfReal iter( Emap ); |
497 | for (; iter.More(); iter.Next()) |
498 | { |
499 | TColStd_SequenceOfReal Seq; |
500 | Seq = iter.Value(); |
501 | for (i = 1; i < Seq.Length(); i++) |
502 | for (j = i+1; j <= Seq.Length(); j++) |
503 | if (Seq(j) < Seq(i)) |
504 | { |
505 | Standard_Real temp = Seq(i); |
506 | Seq(i) = Seq(j); |
507 | Seq(j) = temp; |
508 | } |
509 | Emap( iter.Key() ) = Seq; |
510 | } |
511 | BRepFill_DataMapOfShapeSequenceOfReal EPmap; |
512 | TopTools_DataMapOfShapeSequenceOfShape EVmap; //Seam |
513 | TopTools_DataMapOfShapeSequenceOfShape EWmap; //Seam and wires intersecting it |
514 | iter.Initialize( Emap ); |
515 | for (; iter.More(); iter.Next()) |
516 | { |
517 | TColStd_SequenceOfReal parseq; |
518 | EPmap.Bind( iter.Key(), parseq ); |
519 | TopTools_SequenceOfShape shapeseq; |
520 | EVmap.Bind( iter.Key(), shapeseq ); |
521 | TopTools_SequenceOfShape shapeseq2; |
522 | EWmap.Bind( iter.Key(), shapeseq2 ); |
523 | } |
524 | |
525 | //Reconstruction of non-seam edges |
526 | BRepTools_Substitution aSub; |
527 | BRep_Builder BB; |
528 | for (i = 1; i <= NonSeam.Length(); i++) |
529 | { |
530 | TopoDS_Edge anEdge = TopoDS::Edge( NonSeam(i) ); |
531 | TopTools_ListOfShape NewEdges; |
532 | TopoDS_Edge NewE; |
533 | TopoDS_Vertex Vfirst, Vlast; |
534 | TopExp::Vertices( anEdge, Vfirst, Vlast ); |
535 | Standard_Real par, FirstPar, LastPar; |
536 | BRep_Tool::Range( anEdge, FirstPar, LastPar ); |
537 | Standard_Integer firstind = 1; |
538 | par = ParsNonSeam(i)(1); |
539 | TopoDS_Edge SeamEdge = TopoDS::Edge( Seam(i)(1) ); |
540 | //Find the face |
541 | for (j = 1; j <= Eseq.Length(); j++) |
542 | if (SeamEdge.IsSame( Eseq(j) )) |
543 | break; |
544 | TopoDS_Face theFace = TopoDS::Face( Fseq(j) ); |
545 | TopLoc_Location L; |
546 | Handle( Geom_Surface ) theSurf = BRep_Tool::Surface( theFace, L ); |
547 | if (Abs(par-FirstPar) <= Precision::Confusion()) |
548 | { |
549 | BB.UpdateVertex( Vfirst, ParsSeam(i)(1), SeamEdge, BRep_Tool::Tolerance(Vfirst) ); |
550 | EPmap( SeamEdge ).Append( ParsSeam(i)(1) ); |
551 | EVmap( SeamEdge ).Append( Vfirst ); |
552 | EWmap( SeamEdge ).Append( NonSeamWires(i) ); |
553 | firstind = 2; |
554 | } |
555 | Standard_Real prevpar = FirstPar; |
556 | TopoDS_Vertex PrevV = Vfirst; |
557 | for (j = firstind; j <= ParsNonSeam(i).Length(); j++) |
558 | { |
559 | TopoDS_Shape aLocalShape = anEdge.EmptyCopied(); |
560 | NewE = TopoDS::Edge( aLocalShape ); |
561 | //NewE = TopoDS::Edge( anEdge.EmptyCopied() ); |
562 | TopoDS_Vertex NewV; |
563 | par = ParsNonSeam(i)(j); |
564 | BB.Range( NewE, prevpar, par ); |
565 | SeamEdge = TopoDS::Edge( Seam(i)(j) ); |
566 | if (j == ParsNonSeam(i).Length() && Abs(par-LastPar) <= Precision::Confusion()) |
567 | { |
568 | NewV = Vlast; |
569 | if (firstind == 2 && j == 2) |
570 | { |
571 | BB.UpdateVertex( Vlast, ParsSeam(i)(j), SeamEdge, BRep_Tool::Tolerance(Vlast) ); |
572 | EPmap( SeamEdge ).Append( ParsSeam(i)(j) ); |
573 | EVmap( SeamEdge ).Append( Vlast ); |
574 | EWmap( SeamEdge ).Append( NonSeamWires(i) ); |
575 | break; |
576 | } |
577 | } |
578 | else |
579 | { |
580 | BRepAdaptor_Curve bcur( NewE ); |
581 | gp_Pnt Point = bcur.Value( par ); |
582 | NewV = BRepLib_MakeVertex( Point ); |
583 | BB.UpdateVertex( NewV, par, NewE, 10.*Precision::Confusion() ); |
584 | } |
585 | BB.UpdateVertex( NewV, ParsSeam(i)(j), SeamEdge, 10.*Precision::Confusion() ); |
586 | NewE.Orientation( TopAbs_FORWARD ); |
587 | BB.Add( NewE, PrevV.Oriented(TopAbs_FORWARD) ); |
588 | BB.Add( NewE, NewV.Oriented(TopAbs_REVERSED) ); |
589 | |
590 | NewEdges.Append( NewE ); |
591 | EPmap( SeamEdge ).Append( ParsSeam(i)(j) ); |
592 | EVmap( SeamEdge ).Append( NewV ); |
593 | EWmap( SeamEdge ).Append( NonSeamWires(i) ); |
594 | |
595 | prevpar = par; |
596 | PrevV = NewV; |
597 | } |
598 | //The last edge |
599 | TopoDS_Shape aLocalShape = anEdge.EmptyCopied(); |
600 | NewE = TopoDS::Edge( aLocalShape ); |
601 | //NewE = TopoDS::Edge( anEdge.EmptyCopied() ); |
602 | par = LastPar; |
603 | if (Abs(prevpar-par) > Precision::Confusion()) |
604 | { |
605 | BB.Range( NewE, prevpar, par ); |
606 | NewE.Orientation( TopAbs_FORWARD ); |
607 | BB.Add( NewE, PrevV.Oriented(TopAbs_FORWARD) ); |
608 | BB.Add( NewE, Vlast.Oriented(TopAbs_REVERSED) ); |
609 | NewEdges.Append( NewE ); |
610 | } |
611 | |
612 | //Substitute anEdge by NewEdges |
613 | aSub.Substitute( anEdge, NewEdges ); |
614 | } |
615 | |
616 | //Sorting of EPmap and EVmap and removing repeating points from them |
617 | iter.Initialize( EPmap ); |
618 | for (; iter.More(); iter.Next()) |
619 | { |
620 | TColStd_SequenceOfReal Seq; |
621 | Seq = iter.Value(); |
622 | TopTools_SequenceOfShape SeqShape; |
623 | SeqShape = EVmap( iter.Key() ); |
624 | TopTools_SequenceOfShape SeqShape2; |
625 | SeqShape2 = EWmap( iter.Key() ); |
626 | for (i = 1; i < Seq.Length(); i++) |
627 | for (j = i+1; j <= Seq.Length(); j++) |
628 | if (Seq(j) < Seq(i)) |
629 | { |
630 | Standard_Real temp = Seq(i); |
631 | Seq(i) = Seq(j); |
632 | Seq(j) = temp; |
633 | TopoDS_Shape tmp = SeqShape(i); |
634 | SeqShape(i) = SeqShape(j); |
635 | SeqShape(j) = tmp; |
636 | tmp = SeqShape2(i); |
637 | SeqShape2(i) = SeqShape2(j); |
638 | SeqShape2(j) = tmp; |
639 | } |
640 | EPmap( iter.Key() ) = Seq; |
641 | EVmap( iter.Key() ) = SeqShape; |
642 | EWmap( iter.Key() ) = SeqShape2; |
643 | } |
644 | iter.Initialize( EPmap ); |
645 | for (; iter.More(); iter.Next()) |
646 | { |
647 | TColStd_SequenceOfReal Seq; |
648 | Seq = iter.Value(); |
649 | TopTools_SequenceOfShape SeqShape; |
650 | SeqShape = EVmap( iter.Key() ); |
651 | TopTools_SequenceOfShape SeqShape2; |
652 | SeqShape2 = EWmap( iter.Key() ); |
653 | Standard_Boolean remove = Standard_True; |
654 | while (remove) |
655 | { |
656 | remove = Standard_False; |
657 | for (i = 1; i < Seq.Length(); i++) |
658 | if (Abs(Seq(i)-Seq(i+1)) <= Precision::Confusion()) |
659 | { |
660 | Seq.Remove(i+1); |
661 | SeqShape.Remove(i+1); |
662 | SeqShape2.Remove(i+1); |
663 | remove = Standard_True; |
664 | } |
665 | } |
666 | EPmap( iter.Key() ) = Seq; |
667 | EVmap( iter.Key() ) = SeqShape; |
668 | EWmap( iter.Key() ) = SeqShape2; |
669 | } |
670 | |
671 | //Reconstruction of seam edges |
672 | TopTools_DataMapOfShapeShape VEmap; |
673 | iter.Initialize( Emap ); |
674 | for (; iter.More(); iter.Next()) |
675 | { |
676 | TopoDS_Edge anEdge = TopoDS::Edge( iter.Key() ); |
677 | Standard_Boolean onepoint = Standard_False; |
678 | TopTools_ListOfShape NewEdges; |
679 | TColStd_SequenceOfReal Seq; |
680 | Seq = iter.Value(); |
681 | TColStd_SequenceOfReal Seq2; |
682 | Seq2 = EPmap( anEdge ); |
683 | TopTools_SequenceOfShape SeqVer; |
684 | SeqVer = EVmap( anEdge ); |
685 | TopTools_SequenceOfShape SeqWire; |
686 | SeqWire = EWmap( anEdge ); |
687 | TopoDS_Vertex Vfirst, Vlast; |
688 | TopExp::Vertices( anEdge, Vfirst, Vlast ); |
689 | Standard_Real fpar, lpar, FirstPar, LastPar; |
690 | BRep_Tool::Range( anEdge, FirstPar, LastPar ); |
691 | fpar = FirstPar; |
692 | lpar = Seq(1); |
693 | TopoDS_Edge NewE; |
694 | Standard_Integer firstind = 1; |
695 | if (Abs(fpar-lpar) <= Precision::Confusion()) |
696 | { |
697 | firstind = 2; |
698 | fpar = Seq(1); |
699 | lpar = Seq(2); |
700 | } |
701 | else |
702 | { |
703 | if (Seq.Length()%2 != 0) |
704 | { |
705 | VEmap.Bind( Vfirst, anEdge ); |
706 | firstind = 2; |
707 | fpar = Seq(1); |
708 | if (Seq.Length() > 2) |
709 | lpar = Seq(2); |
710 | else |
711 | onepoint = Standard_True; |
712 | } |
713 | } |
714 | if (!onepoint) |
715 | { |
716 | TopoDS_Shape aLocalShape = anEdge.EmptyCopied(); |
717 | NewE = TopoDS::Edge( aLocalShape ); |
718 | //NewE = TopoDS::Edge( anEdge.EmptyCopied() ); |
719 | BB.Range( NewE, fpar, lpar ); |
720 | NewE.Orientation( TopAbs_FORWARD ); |
721 | if (firstind == 1) |
722 | { |
723 | BB.Add( NewE, Vfirst.Oriented(TopAbs_FORWARD) ); |
724 | aLocalShape = SeqVer(1).Oriented(TopAbs_REVERSED); |
725 | BB.Add( NewE, TopoDS::Vertex( aLocalShape ) ); |
726 | //BB.Add( NewE, TopoDS::Vertex( SeqVer(1).Oriented(TopAbs_REVERSED) ) ); |
727 | } |
728 | else |
729 | { |
730 | aLocalShape = SeqVer(1).Oriented(TopAbs_FORWARD); |
731 | BB.Add( NewE, TopoDS::Vertex( aLocalShape ) ); |
732 | aLocalShape = SeqVer(2).Oriented(TopAbs_REVERSED); |
733 | BB.Add( NewE, TopoDS::Vertex( aLocalShape ) ); |
734 | //BB.Add( NewE, TopoDS::Vertex( SeqVer(1).Oriented(TopAbs_FORWARD) ) ); |
735 | //BB.Add( NewE, TopoDS::Vertex( SeqVer(2).Oriented(TopAbs_REVERSED) ) ); |
736 | } |
737 | NewEdges.Append( NewE ); |
738 | |
739 | firstind++; |
740 | for (i = firstind; i < Seq.Length(); i += 2) |
741 | { |
742 | aLocalShape = anEdge.EmptyCopied(); |
743 | NewE = TopoDS::Edge( aLocalShape ); |
744 | //NewE = TopoDS::Edge( anEdge.EmptyCopied() ); |
745 | fpar = Seq(i); |
746 | lpar = Seq(i+1); |
747 | BB.Range( NewE, fpar, lpar ); |
748 | //Find vertices |
749 | for (j = 1; j <= Seq2.Length(); j++) |
750 | if (Abs(fpar-Seq2(j)) <= Precision::Confusion()) |
751 | break; |
752 | NewE.Orientation( TopAbs_FORWARD ); |
753 | TopoDS_Shape aLocalShapeCur = SeqVer(j).Oriented(TopAbs_FORWARD); |
754 | BB.Add( NewE, TopoDS::Vertex( aLocalShapeCur) ); |
755 | aLocalShapeCur = SeqVer(j+1).Oriented(TopAbs_REVERSED); |
756 | BB.Add( NewE, TopoDS::Vertex( aLocalShapeCur ) ); |
757 | //BB.Add( NewE, TopoDS::Vertex( SeqVer(j).Oriented(TopAbs_FORWARD) ) ); |
758 | //BB.Add( NewE, TopoDS::Vertex( SeqVer(j+1).Oriented(TopAbs_REVERSED) ) ); |
759 | NewEdges.Append( NewE ); |
760 | } |
761 | } |
762 | |
763 | i = Seq.Length(); |
764 | fpar = Seq(i); |
765 | lpar = LastPar; |
766 | if (Abs(fpar-lpar) <= Precision::Confusion()) |
767 | continue; |
768 | TopoDS_Shape aLocalShape = anEdge.EmptyCopied(); |
769 | NewE = TopoDS::Edge( aLocalShape ); |
770 | //NewE = TopoDS::Edge( anEdge.EmptyCopied() ); |
771 | BB.Range( NewE, fpar, lpar ); |
772 | NewE.Orientation( TopAbs_FORWARD ); |
773 | aLocalShape = SeqVer(SeqVer.Length()).Oriented(TopAbs_FORWARD); |
774 | BB.Add( NewE, TopoDS::Vertex( aLocalShape ) ); |
775 | //BB.Add( NewE, TopoDS::Vertex( SeqVer(SeqVer.Length()).Oriented(TopAbs_FORWARD) ) ); |
776 | BB.Add( NewE, Vlast.Oriented(TopAbs_REVERSED) ); |
777 | NewEdges.Append( NewE ); |
778 | |
779 | //Substitute anEdge by NewEdges |
780 | aSub.Substitute( anEdge, NewEdges ); |
781 | } |
782 | |
783 | //Removing edges connected with missing extremities of seam edges |
784 | TopTools_DataMapIteratorOfDataMapOfShapeShape itve( VEmap ); |
785 | for (; itve.More(); itve.Next()) |
786 | { |
787 | TopoDS_Shape V = itve.Key(); |
788 | TopoDS_Shape E = itve.Value(); |
789 | TopoDS_Shape W; |
790 | for (i = 1; i <= Eseq.Length(); i++) |
791 | if (E.IsSame( Eseq(i) )) |
792 | { |
793 | W = Wseq(i); |
794 | break; |
795 | } |
796 | TopoDS_Shape Etoremove; |
797 | eit.Initialize( W ); |
798 | for (; eit.More(); eit.Next()) |
799 | { |
800 | TopoDS_Edge CurE = TopoDS::Edge( eit.Value() ); |
801 | if (CurE.IsSame( E )) |
802 | continue; |
803 | TopoDS_Vertex Vfirst, Vlast; |
804 | TopExp::Vertices( CurE, Vfirst, Vlast ); |
805 | if (Vfirst.IsSame( V ) || Vlast.IsSame( V )) |
806 | { |
807 | Etoremove = CurE; |
808 | break; |
809 | } |
810 | } |
811 | if (! Etoremove.IsNull()) |
812 | { |
813 | W.Free( Standard_True ); |
814 | BB.Remove( W, Etoremove ); |
815 | } |
816 | } |
817 | |
818 | aSub.Build( myShape ); |
819 | if (aSub.IsCopied( myShape )) |
820 | { |
821 | const TopTools_ListOfShape& listSh = aSub.Copy( myShape ); |
822 | if (! listSh.IsEmpty()) |
823 | myShape = listSh.First(); |
824 | } |
825 | |
826 | //Reconstruction of wires |
827 | TopTools_ListOfShape theCopy; |
828 | TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itww( WWmap ); |
829 | for (; itww.More(); itww.Next()) |
830 | { |
831 | CurWire = itww.Key(); |
832 | theCopy = aSub.Copy( CurWire ); |
833 | CurWire = theCopy.First(); |
834 | CurWire.Free( Standard_True ); |
835 | TopTools_ListIteratorOfListOfShape itl( itww.Value() ); |
836 | for (; itl.More(); itl.Next()) |
837 | { |
838 | TopoDS_Shape aWire = itl.Value(); |
839 | CurFace = WFmap( aWire ); |
840 | theCopy = aSub.Copy( aWire ); |
841 | aWire = theCopy.First(); |
842 | //Adjusting period |
843 | TopLoc_Location L; |
844 | Handle( Geom_Surface ) theSurf = BRep_Tool::Surface( TopoDS::Face(CurFace), L ); |
845 | eit.Initialize( aWire ); |
846 | for (; eit.More(); eit.Next()) |
847 | { |
848 | TopoDS_Edge anEdge = TopoDS::Edge( eit.Value() ); |
849 | gp_Pnt2d Pfirst, Plast, Pmid; |
850 | BRep_Tool::UVPoints( anEdge, TopoDS::Face(CurFace), Pfirst, Plast ); |
851 | BRepAdaptor_Curve2d bc2d( anEdge, TopoDS::Face(CurFace) ); |
852 | Pmid = bc2d.Value( (bc2d.FirstParameter()+bc2d.LastParameter())/2. ); |
853 | gp_Vec2d offset; |
854 | Standard_Boolean translate = Standard_False; |
855 | if (Pfirst.X()-2.*M_PI > Precision::Confusion() || |
856 | Plast.X()-2.*M_PI > Precision::Confusion() || |
857 | Pmid.X()-2.*M_PI > Precision::Confusion()) |
858 | { |
859 | offset.SetCoord( -2.*M_PI, 0 ); |
860 | translate = Standard_True; |
861 | } |
862 | if (Pfirst.X() < -Precision::Confusion() || |
863 | Plast.X() < -Precision::Confusion() || |
864 | Pmid.X() < -Precision::Confusion()) |
865 | { |
866 | offset.SetCoord( 2.*M_PI, 0 ); |
867 | translate = Standard_True; |
868 | } |
869 | if (translate) |
870 | { |
871 | const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &anEdge.TShape()); |
872 | BRep_ListIteratorOfListOfCurveRepresentation itcr( TE->ChangeCurves() ); |
873 | Handle(BRep_GCurve) GC; |
874 | |
875 | for (; itcr.More(); itcr.Next()) |
876 | { |
877 | GC = Handle(BRep_GCurve)::DownCast(itcr.Value()); |
878 | if (!GC.IsNull() && GC->IsCurveOnSurface( theSurf, L )) |
879 | { |
880 | Handle(Geom2d_Curve) PC = GC->PCurve(); |
881 | PC = Handle(Geom2d_Curve)::DownCast( PC->Translated( offset ) ); |
882 | GC->PCurve( PC ); |
883 | TE->ChangeCurves().Remove( itcr ); |
884 | TE->ChangeCurves().Append( GC ); |
885 | break; |
886 | } |
887 | } |
888 | } |
889 | } |
890 | /////////////////// |
891 | eit.Initialize( aWire, Standard_False ); |
892 | for (; eit.More(); eit.Next()) |
893 | { |
894 | TopoDS_Shape anEdge = eit.Value(); |
895 | BB.Add( CurWire, anEdge ); |
896 | } |
897 | if (aSub.IsCopied( CurFace )) |
898 | { |
899 | theCopy = aSub.Copy( CurFace ); |
900 | CurFace = theCopy.First(); |
901 | } |
902 | CurFace.Free( Standard_True ); |
903 | BB.Remove( CurFace, aWire ); |
904 | } |
905 | } |
906 | } |
907 | //======================================================================= |
908 | //function : CorrectVertexTol |
909 | //purpose : |
910 | //======================================================================= |
7fd59977 |
911 | |
345d3056 |
912 | void BRepOffsetAPI_DraftAngle::CorrectVertexTol() |
913 | { |
914 | TopTools_MapOfShape anInitVertices, anInitEdges, aNewEdges; |
915 | TopExp_Explorer anExp(myInitialShape, TopAbs_EDGE); |
916 | for(; anExp.More(); anExp.Next()) |
917 | { |
918 | anInitEdges.Add(anExp.Current()); |
919 | TopoDS_Iterator anIter(anExp.Current()); |
920 | for(; anIter.More(); anIter.Next()) |
7fd59977 |
921 | { |
345d3056 |
922 | anInitVertices.Add(anIter.Value()); |
7fd59977 |
923 | } |
345d3056 |
924 | } |
925 | // |
926 | |
927 | BRep_Builder aBB; |
928 | myVtxToReplace.Clear(); |
929 | anExp.Init(myShape, TopAbs_EDGE); |
930 | for(; anExp.More(); anExp.Next()) |
931 | { |
932 | const TopoDS_Shape& anE = anExp.Current(); |
933 | //Skip old (not modified) edges |
934 | if(anInitEdges.Contains(anE)) |
935 | continue; |
936 | // |
937 | //Skip processed edges |
938 | if(aNewEdges.Contains(anE)) |
939 | continue; |
940 | // |
941 | aNewEdges.Add(anE); |
942 | // |
943 | Standard_Real anETol = BRep_Tool::Tolerance(TopoDS::Edge(anE)); |
944 | TopoDS_Iterator anIter(anE); |
945 | for(; anIter.More(); anIter.Next()) |
7fd59977 |
946 | { |
345d3056 |
947 | const TopoDS_Vertex& aVtx = TopoDS::Vertex(anIter.Value()); |
948 | if(anInitVertices.Contains(aVtx)) |
949 | { |
950 | if(myVtxToReplace.IsBound(aVtx)) |
951 | { |
952 | aBB.UpdateVertex(TopoDS::Vertex(myVtxToReplace(aVtx)), anETol + Epsilon(anETol)); |
953 | } |
954 | else |
955 | { |
956 | Standard_Real aVTol = BRep_Tool::Tolerance(aVtx); |
957 | if(aVTol < anETol) |
958 | { |
959 | TopoDS_Vertex aNewVtx; |
960 | gp_Pnt aVPnt = BRep_Tool::Pnt(aVtx); |
961 | aBB.MakeVertex(aNewVtx, aVPnt,anETol + Epsilon(anETol)); |
2651bfde |
962 | aNewVtx.Orientation(aVtx.Orientation()); |
345d3056 |
963 | myVtxToReplace.Bind(aVtx, aNewVtx); |
964 | } |
965 | } |
966 | } |
7fd59977 |
967 | else |
345d3056 |
968 | { |
969 | aBB.UpdateVertex(aVtx, anETol + Epsilon(anETol)); |
970 | } |
7fd59977 |
971 | } |
345d3056 |
972 | } |
973 | // |
974 | if(myVtxToReplace.IsEmpty()) |
975 | { |
976 | return; |
977 | } |
978 | // |
2651bfde |
979 | mySubs.Clear(); |
345d3056 |
980 | TopTools_DataMapIteratorOfDataMapOfShapeShape anIter(myVtxToReplace); |
981 | for(; anIter.More(); anIter.Next()) |
982 | { |
2651bfde |
983 | mySubs.Replace(anIter.Key(), anIter.Value()); |
345d3056 |
984 | } |
2651bfde |
985 | mySubs.Apply( myShape ); |
986 | myShape = mySubs.Value(myShape); |
345d3056 |
987 | // |
7fd59977 |
988 | } |