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